From VisualWorks®, 7.6 of February 1, 2008 on February 1, 2008 at 1:13:11 pm (Dialog confirm: 'You are filing-in a Parcel source file!\\While this is possible it will not have\the same effect as loading the parcel.\None of the Parcel''s prerequisites will\be loaded and none of its load actions\will be performed.\\Are you sure you want to file-in?' withCRs) ifFalse: [self error: 'Parcel file-in abandoned. Choose terminate or close.'] <class> <name>MySQLConnection</name> <environment>Database</environment> <super>Database.ExternalDatabaseConnection</super> <private>false</private> none hConnHolder database port <imports></imports> <category>Database-MySQL</category> <attributes> <package>MySQLEXDI</package> </attributes> </class> <comment> Database.MySQLConnection
MySQLConnection is the concrete class implementation of connection services using the MySQL library. See the MySQLSession class for more information. Instance Variables: database <String> the name of the database database in use (see USE command). hConnHolder <ValueHolder> Holder for the connection handle. port <Integer> Which port the server is listening on.
</comment> <class> <name>MySQLInterface</name> <environment>Database</environment> <super>External.ExternalInterface</super> <private>false</private> none <imports> Database.MySQLInterfaceDictionary.* </imports> <category>Database-External-Libraries</category> <attributes> <includeFiles></includeFiles> <includeDirectories></includeDirectories> <libraryFiles></libraryFiles> <libraryDirectories></libraryDirectories> true full <package>MySQLEXDI</package> </attributes> </class> <comment> Database.MySQLInterface
MySQLInterface defines calling the conventions for the MySQL database client API.
</comment> <class> <name>MySQLBuffer</name> <environment>Database</environment> <super>Database.ExternalDatabaseBuffer</super> <private>false</private> none smalltalkType bufferIndex isNullable isBinary isUnsigned getSelector putSelector session pIsNull pLength pError maxDbDatumLength <imports></imports> <category>Database-MySQL</category> <attributes> <package>MySQLEXDI</package> </attributes> </class> <comment> Database.MySQLBuffer
A MySQLBuffer instance holds a CPointer to the data traveling to or from the database. It also holds information about the SQL type of the object, and its Smalltalk type, so it knows how to convert between the SQL type and Smalltalk. For the architecturally inclined, there is one difference between the way a MySQLBuffer works, as opposed to the way, say, Oracle and ODBC buffers work. With these, each buffer is responsible for making an api call to transfer the data. In MySQL's case, its api was designed to transfer all buffered row data in a single call. MySQL require's an array of structs, each struct holding the data and info for a single bound object (ie., the material held by a single MySQLBuffer object). To bend the inherrited class structure to accomodate the MySQL requirements, the buffer still holds the pointers, but instead of sending them to the api, it sends them to the session object, which holds array of structs. After all buffers have checked in, the session hands the entire array of data to the api. The api uses the same arrangement of pointers to fetch or insert data. It either copies data to or from the pointers. Instance Variables: bufferIndex <Integer> index in the query of this buffer. bufferValue <Object> Smalltalk value to be bound. getSelector <Object> method (based on SQL type returned) to decode the CPointer's contents. isBinary <Boolean> true if the data held is binary, false if character based. isNullable <Boolean> true if the column is nullable (for INSERTs). isUnsigned <Boolean> true if the integer type of this buffer is unsigned. maxDbDatumLength <Integer> storage size of the pBuffer's data. pBuffer <CPointer (byte)> pointer allocated buffer, meant to hold the data to be transfered. pError <CPointer (integer)> pointer to api's error indicator. pIsNull <CPointer (boolean)> pointer to C integer- (0 if the data at pBuffer should be ignored, else 1). pLength <CPointer> pointer to the number of characters intended to be sent within pBuffer. putSelector <Object> method (based on Smalltalk type sent) to encode the buffer's contents to C. session <MySQLSession> the session object which owns this buffer.
</comment> <class> <name>MySQLHybridSession</name> <environment>Database</environment> <super>Core.Object</super> <private>false</private> none regularSession adminSession usingAdmin <imports></imports> <category>Database-MySQL</category> <attributes> <package>MySQLEXDI</package> </attributes> </class> <comment> Database.MySQLHybridSession
MySQLHybridSession is a hybrid object, consisting of two kinds of sessions. Each time a query is prepared:, the query is parsed to determine if the query requires an 'admin' session. If not, the other session is used. Admin sessions have almost no binding ability, and only work with string values. However, they can do administrative queries like: 'CREATE DATABASE' 'CREATE PROCEDURE' 'CREATE FUNCTION' 'CREATE USER' 'CALL' 'USE' 'GRANT' 'SHOW GRANT' 'DROP DATABASE' 'DROP PROCEDURE' 'DROP FUNCTION' 'DROP USER'. The other kind of session, which uses prepared statements (MySQLSession), is not capable of these queries, since the MySQL api does not allow them. See also the class comments for MySQLSession, which offers the usual binding, and MyAdminSession, which offers admin queries. Instance Variables: adminSession <MySQLAdminSession> This session is used for DBA-style queries. regularSession <MySQLSession> This session is used for all other queries, and allows bound variables. usingAdmin <Boolean> true if the current query requires using an admin session.
</comment> <class> <name>MySQLAdminBuffer</name> <environment>Database</environment> <super>Core.Object</super> <private>false</private> none databaseType encoding bufferIndex isNullable isBinary isUnsigned isNull length byteArray maxDbDatumLength session <imports></imports> <category>Database-MySQL</category> <attributes> <package>MySQLEXDI</package> </attributes> </class> <comment> Database.MySQLAdminBuffer
A MySQLAdminBuffer instance holds a string or bytearray copy of the data retrieved from the database. It corresponds to a column in the database, and holds information about the SQL type of the object. It receives a string (or byte array) representation of the data, and leaves the data in that form. No conversion is made to a corresponding Smalltalk type. This buffer is a very simplified version of the ExternalDatabaseBuffer, but uses only strings, and only receives data. It has no INSERT or UPDATE capability. Instance Variables: databaseType <Integer> the MySQL column type. encoding <Symbol> The encoding that Strings will be subjected to. bufferIndex <Integer> index in the query of this buffer. isNullable <Boolean> true if the column is nullable (for INSERTs). isBinary <Boolean> true if the data held is binary, false if character based. isUnsigned <Boolean> true if the integer type of this buffer is unsigned. isNull <Boolean> true if the retrieved column is NULL. length <Integer> size of the current ByteArray. byteArray <ByteArray> the actual data retrieved (nil if column was NULL). maxDbDatumLength <Integer> size of largest datum encountered (before any truncation). session <MySQLSession> the session object which owns this buffer.
</comment> <class> <name>MySQLSolarisInterface</name> <environment>Database</environment> <super>Database.MySQLInterface</super> <private>false</private> none <imports> Database.MySQLSolarisInterfaceDictionary.* </imports> <category>Database-External-Libraries</category> <attributes> <includeFiles></includeFiles> <includeDirectories></includeDirectories> <libraryFiles><item>libmysqlclient.so</item></libraryFiles> <libraryDirectories></libraryDirectories> false full <package>MySQLEXDI</package> </attributes> </class> <comment> Database.MySQLSolarisInterface
This class defines calling conventions for the MySQL client library on the Solaris platform. Please refer to the environment variable on your machine for the path containing necessary MySQL library files.
</comment> <class> <name>MySQLBitfield</name> <environment>Database</environment> <super>Core.Set</super> <private>false</private> objects <imports></imports> <category>Database-MySQL</category> <attributes> <package>MySQLEXDI</package> </attributes> </class> <comment> Database.MySQLBitfield
MySQLBitfield, derived from Set, is a helper class for those who use the BITFIELD MySQL column type. At the server, this column is stored as a 64-bit value. It can be inserted as a ByteArrray, with 8 bytes. The leading bytes correspond to the most significant bits. If you set the class-side flag of MySQLBuffer, BITFIELD columns will be retrieved to instances of MySQLBitfield. Otherwise, they are retrieved as ByteArrays. For example, MySQLBuffer useSetsFor64Bits: true will convert the retrieved ByteArrays to MySQLBitfield objects, and MySQLBuffer useSetsFor64Bits: false will retrieve them as ByteArrays.
</comment> <class> <name>MySQLTransaction</name> <environment>Database</environment> <super>Database.ExternalDatabaseTransaction</super> <private>false</private> none <imports></imports> <category>Database-MySQL</category> <attributes> <package>MySQLEXDI</package> </attributes> </class> <comment> Database.MySQLTransaction
Class MySQLTransaction is the concrete implementation of the transaction concept for the Database Connect for MySQL.
</comment> <class> <name>MySQLNTInterface</name> <environment>Database</environment> <super>Database.MySQLInterface</super> <private>false</private> none <imports> Database.MySQLNTInterfaceDictionary.* </imports> <category>Database-External-Libraries</category> <attributes> <includeFiles></includeFiles> <includeDirectories></includeDirectories> <libraryFiles><item>libmySQL.dll</item></libraryFiles> <libraryDirectories></libraryDirectories> false full <package>MySQLEXDI</package> </attributes> </class> <comment> Database.MySQLNTInterface
This class defines calling conventions for the MySQL client library on the Windows NT/2K/XP platform. Please refer to the environment variable on your machine for the path containing necessary MySQL library files.
</comment> <class> <name>MySQLError</name> <environment>Database</environment> <super>Database.ExternalDatabaseError</super> <private>false</private> none sqlState <imports></imports> <category>Database-MySQL</category> <attributes> <package>MySQLEXDI</package> </attributes> </class> <comment> Database.MySQLError
MySQLError is the error holder class for MySQL. Instance Variables: sqlState <Integer> indicates the current connection state.
</comment> <class> <name>MySQLAdminConnection</name> <environment>Database</environment> <super>Database.MySQLConnection</super> <private>false</private> none <imports></imports> <category>Database-MySQL</category> <attributes> <package>MySQLEXDI</package> </attributes> </class> <comment> Database.MySQLAdminConnection
MySQLAdminConnection works with MySQLAdminSession. See that class for more information.
</comment> <class> <name>MySQLSession</name> <environment>Database</environment> <super>Database.ExternalDatabaseSession</super> <private>false</private> none hstmtHolder resultsCache maxLongData numParameters boundValueBuffersHolder inputBufferPtrsArrayHolder outputBufferPtrsArrayHolder rowCount isRowCountKnown <imports></imports> <category>Database-MySQL</category> <attributes> <package>MySQLEXDI</package> </attributes> </class> <comment> Database.MySQLSession
MySQLSession contains the MySQL-specfic protocols for the External Database Interface (EXDI). It uses the "prepared statement" interface of MySQL. In most DBs, full functionality is available using prepared statements. However, with MySQL, only the following are offered: CREATE TABLE, DELETE, DO, INSERT, REPLACE, SELECT, SET, UPDATE, and most SHOW statements. Notably absent are 'admin' statements like: CREATE DATABASE, CREATE PROCEDURE, CREATE FUNCTION, CALL, USE. See also the class comments for MySQLAdminSession, which offers admin queries, and MySQLHybridSession, which offers both binding and admin queries. Instance Variables: bindValuePointers <(Dictionary of: (CPointer | ExternalDatabaseBuffer))> description of bindValuePointers hstmtHolder <ValueModel> holds the statement handle. inputBufferPtrsArray <CPointer> Array of MSQL_BIND structs, used for sending (binding) input parameters. maxLongData <Integer> Maximum number of bytes to retrieve for long colums. numParameters <Integer> The number of bound inputs (?) used by the query. outputBufferPtrsArray <CPointer> Array of MSQL_BIND structs, used for retrieving (binding) output columns. resultsCache <Object> description of resultsCache
</comment> <class> <name>MySQLLinuxInterface</name> <environment>Database</environment> <super>Database.MySQLInterface</super> <private>false</private> none <imports> Database.MySQLLinuxInterfaceDictionary.* </imports> <category>Database-External-Libraries</category> <attributes> <includeFiles></includeFiles> <includeDirectories></includeDirectories> <libraryFiles><item>libmysqlclient.so</item></libraryFiles> <libraryDirectories></libraryDirectories> false full <package>MySQLEXDI</package> </attributes> </class> <comment> Database.MySQLLinuxInterface
This class defines calling conventions for the MySQL client library on the Linux platform. Please refer to the environment variable on your machine for the path containing necessary MySQL library files.
</comment> <class> <name>MySQLAdminSession</name> <environment>Database</environment> <super>Database.ExternalDatabaseSession</super> <private>false</private> none resultsCache maxLongData hResultHolder rowCount isRowCountKnown <imports></imports> <category>Database-MySQL</category> <attributes> <package>MySQLEXDI</package> </attributes> </class> <comment> Database.MySQLAdminSession
MySQLAdminSession contains the MySQL-specfic protocols for the External Database Interface (EXDI). It uses the earlier interface for MySQL, which did not use prepared statements. This means that you cannot bind input data to queries. Your query must be a single string, instead. Query answer sets work as usual, except that the output columns are retrieved as Strings or ByteArrays (for BLOB types). No effort is made to convert the string representations to specific Smalltalk types. See also the class comments for MySQLSession, which offers the usual binding, and MySQLHybridSession, which offers binding and admin queries. This class is intended only for special situations where the newer prepared statement api doesn't work. For example, these queries are available: CREATE DATABASE, CREATE PROCEDURE, CREATE FUNCTION, CALL, USE, GRANT. They cannot be executed using the prepared statement api (used by MySQLSession). They are only available using the older interface. This may change in the future, but for now, this is the session to use for such queries. Note that you cannot separately bind inputs. The query must be a single string. However, to pass parameters to stored procedures, server side variables can work, as follows: sess prepare: 'SET @x = 10'. sess execute. sess answer. sess prepare: 'SET @y = 20'. sess execute. sess answer. sess prepare: 'CALL my_favorite_proc( @x, @y)'. sess execute. sess answer. ans1 := sess answer. "If proc returns more than one answer set, iterate through until #noMoreAnswers." sess prepare: 'SELECT @x, @y'. sess execute. ans2 := sess answer. Instance Variables: maxLongData <Integer> Maximum number of bytes to retrieve for long colums. resultsCache <Object> description of resultsCache resultsHolder
</comment> <class> <name>MySQLHPUXInterface</name> <environment>Database</environment> <super>Database.MySQLInterface</super> <private>false</private> none <imports> Database.MySQLHPUXInterfaceDictionary.* </imports> <category>Database-External-Libraries</category> <attributes> <includeFiles></includeFiles> <includeDirectories></includeDirectories> <libraryFiles><item>libmysqlclient.sl</item></libraryFiles> <libraryDirectories></libraryDirectories> false full <package>MySQLEXDI</package> </attributes> </class> <comment> Database.MySQLHPUXInterface
This class defines calling conventions for the MySQL client library on the HPUX platform. Please refer to the environment variable on your machine for the path containing necessary MySQL library files.
</comment> <class> <name>MySQLHybridConnection</name> <environment>Database</environment> <super>Database.MySQLConnection</super> <private>false</private> none <imports></imports> <category>Database-MySQL</category> <attributes> <package>MySQLEXDI</package> </attributes> </class> <comment> Database.MySQLHybridConnection
MySQLHybridConnection works with MySQLHybridSession. See that class for more detailed comments.
</comment> <class> <name>MySQLColumnDescription</name> <environment>Database</environment> <super>Database.ExternalDatabaseColumnDescription</super> <private>false</private> none org_name table org_table db catalog def mysqlType charsetnr isBinaryCollation isUnsigned <imports></imports> <category>Database-MySQL</category> <attributes> <package>MySQLEXDI</package> </attributes> </class> <comment> Database.MySQLColumnDescription
MySQLColumnDescription adds information to the generic ExternalDatabaseColumnDescription which is unique to MySQL. This class is inflated with information about the column being SELECTed. It is populated by the MySQL api, and used for making a MySQLBuffer instance to receive the data when it is fetched. Instance Variables: catalog <Object> not used currently. charsetnr <Integer> character set indicator. eg., 63 means binary (number, varbinary or blob or bit). db <String> the name of the database which owns the table holding this column. def <Object> description of def. isBinaryCollation<Boolean> true if the object was created with a binary collation (ordering is based on byte value). isUnsigned <Boolean> true if the datum is an unsigned numeric type. mysqlType <Integer> the database type indicator of the object. org_name <String> actual column name, not necessarily the alias name. org_table <String> actual table name, not necessarily the alias name. table <String> table name, or an alias for it.
</comment> <name>RegisteredMySQLAdminConnections</name> <environment>Database.MySQLAdminConnection</environment> <private>false</private> <constant>false</constant> <category>Shared Information</category> <attributes> <package>MySQLEXDI</package> </attributes> <name>FieldTypenamesToTypesMap</name> <environment>Database.MySQLInterface</environment> <private>false</private> <constant>false</constant> <category>Shared Data</category> <attributes> <package>MySQLEXDI</package> </attributes> <name>LongTypes</name> <environment>Database.MySQLInterface</environment> <private>false</private> <constant>false</constant> <category>Shared Data</category> <attributes> <package>MySQLEXDI</package> </attributes> <name>TimeTypes</name> <environment>Database.MySQLInterface</environment> <private>false</private> <constant>false</constant> <category>Shared Data</category> <attributes> <package>MySQLEXDI</package> </attributes> <name>CharacterTypes</name> <environment>Database.MySQLInterface</environment> <private>false</private> <constant>false</constant> <category>Shared Data</category> <attributes> <package>MySQLEXDI</package> </attributes> <name>IntegerTypes</name> <environment>Database.MySQLInterface</environment> <private>false</private> <constant>false</constant> <category>Shared Data</category> <attributes> <package>MySQLEXDI</package> </attributes> <name>BlobTypes</name> <environment>Database.MySQLInterface</environment> <private>false</private> <constant>false</constant> <category>Shared Data</category> <attributes> <package>MySQLEXDI</package> </attributes> <name>StringTypes</name> <environment>Database.MySQLInterface</environment> <private>false</private> <constant>false</constant> <category>Shared Data</category> <attributes> <package>MySQLEXDI</package> </attributes> <name>FieldTypesToTypenamesMap</name> <environment>Database.MySQLInterface</environment> <private>false</private> <constant>false</constant> <category>Shared Data</category> <attributes> <package>MySQLEXDI</package> </attributes> <name>RegisteredMySQLHybridConnections</name> <environment>Database.MySQLHybridConnection</environment> <private>false</private> <constant>false</constant> <category>As yet unclassified</category> <attributes> <package>MySQLEXDI</package> </attributes> <name>DefaultTypesGetSelectorMap</name> <environment>Database.MySQLBuffer</environment> <private>false</private> <constant>false</constant> <category>As yet unclassified</category> <attributes> <package>MySQLEXDI</package> </attributes> <name>SizesOfFixedSmalltalkTypes</name> <environment>Database.MySQLBuffer</environment> <private>false</private> <constant>false</constant> <category>As yet unclassified</category> <attributes> <package>MySQLEXDI</package> </attributes> <name>DefaultTypesPutSelectorMap</name> <environment>Database.MySQLBuffer</environment> <private>false</private> <constant>false</constant> <category>As yet unclassified</category> <attributes> <package>MySQLEXDI</package> </attributes> <name>UseSetsForMySQL64BitSets</name> <environment>Database.MySQLBuffer</environment> <private>false</private> <constant>false</constant> <category>As yet unclassified</category> <attributes> <package>MySQLEXDI</package> </attributes> <name>MySQLToSmalltalkTypesMap</name> <environment>Database.MySQLBuffer</environment> <private>false</private> <constant>false</constant> <category>As yet unclassified</category> <attributes> <package>MySQLEXDI</package> </attributes> <name>SizesOfFixedDatabaseTypes</name> <environment>Database.MySQLBuffer</environment> <private>false</private> <constant>false</constant> <category>As yet unclassified</category> <attributes> <package>MySQLEXDI</package> </attributes> <name>SmalltalkToMySQLTypesMap</name> <environment>Database.MySQLBuffer</environment> <private>false</private> <constant>false</constant> <category>As yet unclassified</category> <attributes> <package>MySQLEXDI</package> </attributes> <name>InitializeLibraryLock</name> <environment>Database.MySQLConnection</environment> <private>false</private> <constant>false</constant> <category>Shared Information</category> <attributes> <package>MySQLEXDI</package> </attributes> <name>SignalMap</name> <environment>Database.MySQLConnection</environment> <private>false</private> <constant>false</constant> <category>Shared Information</category> <attributes> <package>MySQLEXDI</package> </attributes> <name>RegisteredMySQLConnections</name> <environment>Database.MySQLConnection</environment> <private>false</private> <constant>false</constant> <category>Shared Information</category> <attributes> <package>MySQLEXDI</package> </attributes> <name>IsLibraryInitialized</name> <environment>Database.MySQLConnection</environment> <private>false</private> <constant>false</constant> <category>Shared Information</category> <attributes> <package>MySQLEXDI</package> </attributes> <name>EncoderMap</name> <environment>Database.MySQLConnection</environment> <private>false</private> <constant>false</constant> <category>Shared Information</category> <attributes> <package>MySQLEXDI</package> </attributes> <name>RegisteredMySQLSessions</name> <environment>Database.MySQLSession</environment> <private>false</private> <constant>false</constant> <category>Shared Variables</category> <attributes> <package>MySQLEXDI</package> </attributes> <name>DefaultMaxLongData</name> <environment>Database.MySQLSession</environment> <private>false</private> <constant>false</constant> <category>Shared Variables</category> <attributes> <package>MySQLEXDI</package> </attributes> <name>DefaultMaxLongData</name> <environment>Database.MySQLAdminSession</environment> <private>false</private> <constant>false</constant> <category>Shared Variables</category> <attributes> <package>MySQLEXDI</package> </attributes> <name>RegisteredMySQLCharacterSessions</name> <environment>Database.MySQLAdminSession</environment> <private>false</private> <constant>false</constant> <category>Shared Variables</category> <attributes> <package>MySQLEXDI</package> </attributes> <methods> Database.MySQLInterface <category>procedures</category>
myodbc_remove_escape: mysql with: name <C: void __stdcall myodbc_remove_escape(MYSQL * mysql, char * name)> ^self externalAccessFailedWith: _errorCode
mysqlLibraryEnd "This call is #defined as _server_end, even for client programs." <C: void __stdcall mysql_server_end(void)> ^self externalAccessFailedWith: _errorCode
mysqlLibraryInitArgc: argc argv: argv groups: groups "This is #defined as a call to server_init, even for client programs." <C: int __stdcall mysql_server_init(int argc, char * * argv, char * * groups)> ^self externalAccessFailedWith: _errorCode
mysql_add_slave: mysql with: host with: port with: user with: passwd <C: int __stdcall mysql_add_slave(MYSQL * mysql, const char * host, unsigned int port, const char * user, const char * passwd)> ^self externalAccessFailedWith: _errorCode
mysql_affected_rows: mysql <C: my_ulonglong __stdcall mysql_affected_rows(MYSQL * mysql)> ^self externalAccessFailedWith: _errorCode
mysql_autocommit: mysql with: auto_mode <C: my_bool __stdcall mysql_autocommit(MYSQL * mysql, my_bool auto_mode)> ^self externalAccessFailedWith: _errorCode
mysql_change_user: mysql with: user with: passwd with: db <C: my_bool __stdcall mysql_change_user(MYSQL * mysql, const char * user, const char * passwd, const char * db)> ^self externalAccessFailedWith: _errorCode
mysql_character_set_name: mysql <C: const char * __stdcall mysql_character_set_name(MYSQL * mysql)> ^self externalAccessFailedWith: _errorCode
mysql_close: sock <C: void __stdcall mysql_close(MYSQL * sock)> ^self externalAccessFailedWith: _errorCode
mysql_commit: mysql <C: my_bool __stdcall mysql_commit(MYSQL * mysql)> ^self externalAccessFailedWith: _errorCode
mysql_data_seek: result with: offset <C: void __stdcall mysql_data_seek(MYSQL_RES * result, my_ulonglong offset)> ^self externalAccessFailedWith: _errorCode
mysql_debug: debug <C: void __stdcall mysql_debug(const char * debug)> ^self externalAccessFailedWith: _errorCode
mysql_disable_reads_from_master: mysql <C: void __stdcall mysql_disable_reads_from_master(MYSQL * mysql)> ^self externalAccessFailedWith: _errorCode
mysql_disable_rpl_parse: mysql <C: void __stdcall mysql_disable_rpl_parse(MYSQL * mysql)> ^self externalAccessFailedWith: _errorCode
mysql_dump_debug_info: mysql <C: int __stdcall mysql_dump_debug_info(MYSQL * mysql)> ^self externalAccessFailedWith: _errorCode
mysql_embedded <C: my_bool __stdcall mysql_embedded(void)> ^self externalAccessFailedWith: _errorCode
mysql_enable_reads_from_master: mysql <C: void __stdcall mysql_enable_reads_from_master(MYSQL * mysql)> ^self externalAccessFailedWith: _errorCode
mysql_enable_rpl_parse: mysql <C: void __stdcall mysql_enable_rpl_parse(MYSQL * mysql)> ^self externalAccessFailedWith: _errorCode
mysql_eof: res <C: my_bool __stdcall mysql_eof(MYSQL_RES * res)> ^self externalAccessFailedWith: _errorCode
mysql_errno: mysql <C: unsigned int __stdcall mysql_errno(MYSQL * mysql)> ^self externalAccessFailedWith: _errorCode
mysql_errno_to_sqlstate: mysql_errorNo <C: const char * mysql_errno_to_sqlstate(unsigned int mysql_errorNo)> ^self externalAccessFailedWith: _errorCode
mysql_error: mysql <C: const char * __stdcall mysql_error(MYSQL * mysql)> ^self externalAccessFailedWith: _errorCode
mysql_escape_string: to with: from with: from_length <C: unsigned long __stdcall mysql_escape_string(char * to, const char * from, unsigned long from_length)> ^self externalAccessFailedWith: _errorCode
mysql_fetch_field: result <C: MYSQL_FIELD * __stdcall mysql_fetch_field(MYSQL_RES * result)> ^self externalAccessFailedWith: _errorCode
mysql_fetch_fields: res <C: MYSQL_FIELD * __stdcall mysql_fetch_fields(MYSQL_RES * res)> ^self externalAccessFailedWith: _errorCode
mysql_fetch_field_direct: res with: fieldnr <C: MYSQL_FIELD * __stdcall mysql_fetch_field_direct(MYSQL_RES * res, unsigned int fieldnr)> ^self externalAccessFailedWith: _errorCode
mysql_fetch_lengths: result <C: unsigned long * __stdcall mysql_fetch_lengths(MYSQL_RES * result)> ^self externalAccessFailedWith: _errorCode
mysql_fetch_row: result <C: MYSQL_ROW __stdcall mysql_fetch_row(MYSQL_RES * result)> ^self externalAccessFailedWith: _errorCode
mysql_field_count: mysql <C: unsigned int __stdcall mysql_field_count(MYSQL * mysql)> ^self externalAccessFailedWith: _errorCode
mysql_field_seek: result with: offset <C: MYSQL_FIELD_OFFSET __stdcall mysql_field_seek(MYSQL_RES * result, MYSQL_FIELD_OFFSET offset)> ^self externalAccessFailedWith: _errorCode
mysql_field_tell: res <C: MYSQL_FIELD_OFFSET __stdcall mysql_field_tell(MYSQL_RES * res)> ^self externalAccessFailedWith: _errorCode
mysql_free_result: result <C: void __stdcall mysql_free_result(MYSQL_RES * result)> ^self externalAccessFailedWith: _errorCode
mysql_get_character_set_info: mysql with: charset <C: void __stdcall mysql_get_character_set_info(MYSQL * mysql, MY_CHARSET_INFO * charset)> ^self externalAccessFailedWith: _errorCode
mysql_get_client_info <C: const char * __stdcall mysql_get_client_info(void)> ^self externalAccessFailedWith: _errorCode
mysql_get_client_version <C: unsigned long __stdcall mysql_get_client_version(void)> ^self externalAccessFailedWith: _errorCode
mysql_get_host_info: mysql <C: const char * __stdcall mysql_get_host_info(MYSQL * mysql)> ^self externalAccessFailedWith: _errorCode
mysql_get_parameters <C: MYSQL_PARAMETERS * __stdcall mysql_get_parameters(void)> ^self externalAccessFailedWith: _errorCode
mysql_get_proto_info: mysql <C: unsigned int __stdcall mysql_get_proto_info(MYSQL * mysql)> ^self externalAccessFailedWith: _errorCode
mysql_get_server_info: mysql <C: const char * __stdcall mysql_get_server_info(MYSQL * mysql)> ^self externalAccessFailedWith: _errorCode
mysql_get_server_version: mysql <C: unsigned long __stdcall mysql_get_server_version(MYSQL * mysql)> ^self externalAccessFailedWith: _errorCode
mysql_hex_string: to with: from with: from_length <C: unsigned long __stdcall mysql_hex_string(char * to, const char * from, unsigned long from_length)> ^self externalAccessFailedWith: _errorCode
mysql_info: mysql <C: const char * __stdcall mysql_info(MYSQL * mysql)> ^self externalAccessFailedWith: _errorCode
mysql_init: mysql <C: MYSQL * __stdcall mysql_init(MYSQL * mysql)> ^self externalAccessFailedWith: _errorCode
mysql_insert_id: mysql <C: my_ulonglong __stdcall mysql_insert_id(MYSQL * mysql)> ^self externalAccessFailedWith: _errorCode
mysql_kill: mysql with: pid <C: int __stdcall mysql_kill(MYSQL * mysql, unsigned long pid)> ^self externalAccessFailedWith: _errorCode
mysql_list_dbs: mysql with: wild <C: MYSQL_RES * __stdcall mysql_list_dbs(MYSQL * mysql, const char * wild)> ^self externalAccessFailedWith: _errorCode
mysql_list_fields: mysql with: table with: wild <C: MYSQL_RES * __stdcall mysql_list_fields(MYSQL * mysql, const char * table, const char * wild)> ^self externalAccessFailedWith: _errorCode
mysql_list_processes: mysql <C: MYSQL_RES * __stdcall mysql_list_processes(MYSQL * mysql)> ^self externalAccessFailedWith: _errorCode
mysql_list_tables: mysql with: wild <C: MYSQL_RES * __stdcall mysql_list_tables(MYSQL * mysql, const char * wild)> ^self externalAccessFailedWith: _errorCode
mysql_manager_close: con <C: void __stdcall mysql_manager_close(MYSQL_MANAGER * con)> ^self externalAccessFailedWith: _errorCode
mysql_manager_command: con with: cmd with: cmd_len <C: int __stdcall mysql_manager_command(MYSQL_MANAGER * con, const char * cmd, int cmd_len)> ^self externalAccessFailedWith: _errorCode
mysql_manager_connect: con with: host with: user with: passwd with: port <C: MYSQL_MANAGER * __stdcall mysql_manager_connect(MYSQL_MANAGER * con, const char * host, const char * user, const char * passwd, unsigned int port)> ^self externalAccessFailedWith: _errorCode
mysql_manager_fetch_line: con with: res_buf with: res_buf_size <C: int __stdcall mysql_manager_fetch_line(MYSQL_MANAGER * con, char * res_buf, int res_buf_size)> ^self externalAccessFailedWith: _errorCode
mysql_manager_init: con <C: MYSQL_MANAGER * __stdcall mysql_manager_init(MYSQL_MANAGER * con)> ^self externalAccessFailedWith: _errorCode
mysql_master_query: mysql with: q with: length <C: my_bool __stdcall mysql_master_query(MYSQL * mysql, const char * q, unsigned long length)> ^self externalAccessFailedWith: _errorCode
mysql_master_send_query: mysql with: q with: length <C: my_bool __stdcall mysql_master_send_query(MYSQL * mysql, const char * q, unsigned long length)> ^self externalAccessFailedWith: _errorCode
mysql_more_results: mysql <C: my_bool __stdcall mysql_more_results(MYSQL * mysql)> ^self externalAccessFailedWith: _errorCode
mysql_next_result: mysql <C: int __stdcall mysql_next_result(MYSQL * mysql)> ^self externalAccessFailedWith: _errorCode
mysql_num_fields: res <C: unsigned int __stdcall mysql_num_fields(MYSQL_RES * res)> ^self externalAccessFailedWith: _errorCode
mysql_num_rows: res <C: my_ulonglong __stdcall mysql_num_rows(MYSQL_RES * res)> ^self externalAccessFailedWith: _errorCode
mysql_odbc_escape_string: mysql with: to with: to_length with: from with: from_length with: param with: extend_buffer <C: char * __stdcall mysql_odbc_escape_string(MYSQL * mysql, char * to, unsigned long to_length, const char * from, unsigned long from_length, void * param, char * (* extend_buffer)(void * _arg1, char * to, unsigned long * length))> ^self externalAccessFailedWith: _errorCode
mysql_options: mysql with: option with: arg <C: int __stdcall mysql_options(MYSQL * mysql, enum mysql_option option, const char * arg)> ^self externalAccessFailedWith: _errorCode
mysql_ping: mysql <C: int __stdcall mysql_ping(MYSQL * mysql)> ^self externalAccessFailedWith: _errorCode
mysql_query: mysql with: q <C: int __stdcall mysql_query(MYSQL * mysql, const char * q)> ^self externalAccessFailedWith: _errorCode
mysql_reads_from_master_enabled: mysql <C: my_bool __stdcall mysql_reads_from_master_enabled(MYSQL * mysql)> ^self externalAccessFailedWith: _errorCode
mysql_read_query_result: mysql <C: my_bool __stdcall mysql_read_query_result(MYSQL * mysql)> ^self externalAccessFailedWith: _errorCode
mysql_real_connect: mysql host: host user: user passwd: passwd db: db port: port unix_socket: unix_socket clientflag: clientflag <C: MYSQL * __stdcall 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 clientflag)> ^self externalAccessFailedWith: _errorCode
mysql_real_escape_string: mysql with: to with: from with: length <C: unsigned long __stdcall mysql_real_escape_string(MYSQL * mysql, char * to, const char * from, unsigned long length)> ^self externalAccessFailedWith: _errorCode
mysql_real_query: mysql query: q length: length <C: int __stdcall mysql_real_query(MYSQL * mysql, const char * q, unsigned long length)> ^self externalAccessFailedWith: _errorCode
mysql_refresh: mysql with: refresh_options <C: int __stdcall mysql_refresh(MYSQL * mysql, unsigned int refresh_options)> ^self externalAccessFailedWith: _errorCode
mysql_rollback: mysql <C: my_bool __stdcall mysql_rollback(MYSQL * mysql)> ^self externalAccessFailedWith: _errorCode
mysql_row_seek: result with: offset <C: MYSQL_ROW_OFFSET __stdcall mysql_row_seek(MYSQL_RES * result, MYSQL_ROW_OFFSET offset)> ^self externalAccessFailedWith: _errorCode
mysql_row_tell: res <C: MYSQL_ROW_OFFSET __stdcall mysql_row_tell(MYSQL_RES * res)> ^self externalAccessFailedWith: _errorCode
mysql_rpl_parse_enabled: mysql <C: int __stdcall mysql_rpl_parse_enabled(MYSQL * mysql)> ^self externalAccessFailedWith: _errorCode
mysql_rpl_probe: mysql <C: my_bool __stdcall mysql_rpl_probe(MYSQL * mysql)> ^self externalAccessFailedWith: _errorCode
mysql_rpl_query_type: q with: len <C: enum mysql_rpl_type __stdcall mysql_rpl_query_type(const char * q, int len)> ^self externalAccessFailedWith: _errorCode
mysql_select_db: mysql with: db <C: int __stdcall mysql_select_db(MYSQL * mysql, const char * db)> ^self externalAccessFailedWith: _errorCode
mysql_send_query: mysql with: q with: length <C: int __stdcall mysql_send_query(MYSQL * mysql, const char * q, unsigned long length)> ^self externalAccessFailedWith: _errorCode
mysql_server_end <C: void __stdcall mysql_server_end(void)> ^self externalAccessFailedWith: _errorCode
mysql_server_init: argc with: argv with: groups <C: int __stdcall mysql_server_init(int argc, char * * argv, char * * groups)> ^self externalAccessFailedWith: _errorCode
mysql_set_character_set: mysql with: csname <C: int __stdcall mysql_set_character_set(MYSQL * mysql, const char * csname)> ^self externalAccessFailedWith: _errorCode
mysql_set_local_infile_default: mysql <C: void mysql_set_local_infile_default(MYSQL * mysql)> ^self externalAccessFailedWith: _errorCode
mysql_set_local_infile_handler: mysql with: local_infile_init with: local_infile_read with: local_infile_end with: local_infile_error with: _arg1 <C: void mysql_set_local_infile_handler(MYSQL * mysql, int (* local_infile_init)(void * * , const char * , void * ), int (* local_infile_read)(void * , char * , unsigned int), void (* local_infile_end)(void * ), int (* local_infile_error)(void * , char * , unsigned int), void * _arg1)> ^self externalAccessFailedWith: _errorCode
mysql_set_master: mysql with: host with: port with: user with: passwd <C: int __stdcall mysql_set_master(MYSQL * mysql, const char * host, unsigned int port, const char * user, const char * passwd)> ^self externalAccessFailedWith: _errorCode
mysql_set_server_option: mysql with: option <C: int __stdcall mysql_set_server_option(MYSQL * mysql, enum enum_mysql_set_option option)> ^self externalAccessFailedWith: _errorCode
mysql_shutdown: mysql with: shutdown_level <C: int __stdcall mysql_shutdown(MYSQL * mysql, enum mysql_enum_shutdown_level shutdown_level)> ^self externalAccessFailedWith: _errorCode
mysql_slave_query: mysql with: q with: length <C: my_bool __stdcall mysql_slave_query(MYSQL * mysql, const char * q, unsigned long length)> ^self externalAccessFailedWith: _errorCode
mysql_slave_send_query: mysql with: q with: length <C: my_bool __stdcall mysql_slave_send_query(MYSQL * mysql, const char * q, unsigned long length)> ^self externalAccessFailedWith: _errorCode
mysql_sqlstate: mysql <C: const char * __stdcall mysql_sqlstate(MYSQL * mysql)> ^self externalAccessFailedWith: _errorCode
mysql_ssl_set: mysql with: key with: cert with: ca with: capath with: cipher <C: my_bool __stdcall mysql_ssl_set(MYSQL * mysql, const char * key, const char * cert, const char * ca, const char * capath, const char * cipher)> ^self externalAccessFailedWith: _errorCode
mysql_stat: mysql <C: const char * __stdcall mysql_stat(MYSQL * mysql)> ^self externalAccessFailedWith: _errorCode
mysql_stmt_affected_rows: stmt <C: my_ulonglong __stdcall mysql_stmt_affected_rows(MYSQL_STMT * stmt)> ^self externalAccessFailedWith: _errorCode
mysql_stmt_attr_get: stmt with: attr_type with: attr <C: my_bool __stdcall mysql_stmt_attr_get(MYSQL_STMT * stmt, enum enum_stmt_attr_type attr_type, void * attr)> ^self externalAccessFailedWith: _errorCode
mysql_stmt_attr_set: stmt attr_type: attr_type attr: attr <C: my_bool __stdcall mysql_stmt_attr_set(MYSQL_STMT * stmt, enum enum_stmt_attr_type attr_type, const void * attr)> ^self externalAccessFailedWith: _errorCode
mysql_stmt_bind_param: stmt bind: bnd <C: my_bool __stdcall mysql_stmt_bind_param(MYSQL_STMT * stmt, MYSQL_BIND * bnd)> ^self externalAccessFailedWith: _errorCode
mysql_stmt_bind_result: stmt bind: bnd <C: my_bool __stdcall mysql_stmt_bind_result(MYSQL_STMT * stmt, MYSQL_BIND * bnd)> ^self externalAccessFailedWith: _errorCode
mysql_stmt_close: stmt <C: my_bool __stdcall mysql_stmt_close(MYSQL_STMT * stmt)> ^self externalAccessFailedWith: _errorCode
mysql_stmt_data_seek: stmt with: offset <C: void __stdcall mysql_stmt_data_seek(MYSQL_STMT * stmt, my_ulonglong offset)> ^self externalAccessFailedWith: _errorCode
mysql_stmt_errno: stmt <C: unsigned int __stdcall mysql_stmt_errno(MYSQL_STMT * stmt)> ^self externalAccessFailedWith: _errorCode
mysql_stmt_error: stmt <C: const char * __stdcall mysql_stmt_error(MYSQL_STMT * stmt)> ^self externalAccessFailedWith: _errorCode
mysql_stmt_execute: stmt <C: int __stdcall mysql_stmt_execute(MYSQL_STMT * stmt)> ^self externalAccessFailedWith: _errorCode
mysql_stmt_fetch: stmt <C: int __stdcall mysql_stmt_fetch(MYSQL_STMT * stmt)> ^self externalAccessFailedWith: _errorCode
mysql_stmt_fetch_column: stmt with: bind with: column with: offset <C: int __stdcall mysql_stmt_fetch_column(MYSQL_STMT * stmt, MYSQL_BIND * bind, unsigned int column, unsigned long offset)> ^self externalAccessFailedWith: _errorCode
mysql_stmt_field_count: stmt <C: unsigned int __stdcall mysql_stmt_field_count(MYSQL_STMT * stmt)> ^self externalAccessFailedWith: _errorCode
mysql_stmt_free_result: stmt <C: my_bool __stdcall mysql_stmt_free_result(MYSQL_STMT * stmt)> ^self externalAccessFailedWith: _errorCode
mysql_stmt_init: mysql <C: MYSQL_STMT * __stdcall mysql_stmt_init(MYSQL * mysql)> ^self externalAccessFailedWith: _errorCode
mysql_stmt_insert_id: stmt <C: my_ulonglong __stdcall mysql_stmt_insert_id(MYSQL_STMT * stmt)> ^self externalAccessFailedWith: _errorCode
mysql_stmt_num_rows: stmt <C: my_ulonglong __stdcall mysql_stmt_num_rows(MYSQL_STMT * stmt)> ^self externalAccessFailedWith: _errorCode
mysql_stmt_param_count: stmt <C: unsigned long __stdcall mysql_stmt_param_count(MYSQL_STMT * stmt)> ^self externalAccessFailedWith: _errorCode
mysql_stmt_param_metadata: stmt <C: MYSQL_RES * __stdcall mysql_stmt_param_metadata(MYSQL_STMT * stmt)> ^self externalAccessFailedWith: _errorCode
mysql_stmt_prepare: stmt query: query length: length <C: int __stdcall mysql_stmt_prepare(MYSQL_STMT * stmt, const char * query, unsigned long length)> ^self externalAccessFailedWith: _errorCode
mysql_stmt_reset: stmt <C: my_bool __stdcall mysql_stmt_reset(MYSQL_STMT * stmt)> ^self externalAccessFailedWith: _errorCode
mysql_stmt_result_metadata: stmt <C: MYSQL_RES * __stdcall mysql_stmt_result_metadata(MYSQL_STMT * stmt)> ^self externalAccessFailedWith: _errorCode
mysql_stmt_row_seek: stmt with: offset <C: MYSQL_ROW_OFFSET __stdcall mysql_stmt_row_seek(MYSQL_STMT * stmt, MYSQL_ROW_OFFSET offset)> ^self externalAccessFailedWith: _errorCode
mysql_stmt_row_tell: stmt <C: MYSQL_ROW_OFFSET __stdcall mysql_stmt_row_tell(MYSQL_STMT * stmt)> ^self externalAccessFailedWith: _errorCode
mysql_stmt_send_long_data: stmt with: param_number with: data with: length <C: my_bool __stdcall mysql_stmt_send_long_data(MYSQL_STMT * stmt, unsigned int param_number, const char * data, unsigned long length)> ^self externalAccessFailedWith: _errorCode
mysql_stmt_sqlstate: stmt <C: const char * __stdcall mysql_stmt_sqlstate(MYSQL_STMT * stmt)> ^self externalAccessFailedWith: _errorCode
mysql_stmt_store_result: stmt <C: int __stdcall mysql_stmt_store_result(MYSQL_STMT * stmt)> ^self externalAccessFailedWith: _errorCode
mysql_store_result: mysql <C: MYSQL_RES * __stdcall mysql_store_result(MYSQL * mysql)> ^self externalAccessFailedWith: _errorCode
mysql_thread_end <C: void __stdcall mysql_thread_end(void)> ^self externalAccessFailedWith: _errorCode
mysql_thread_id: mysql <C: unsigned long __stdcall mysql_thread_id(MYSQL * mysql)> ^self externalAccessFailedWith: _errorCode
mysql_thread_init <C: my_bool __stdcall mysql_thread_init(void)> ^self externalAccessFailedWith: _errorCode
mysql_thread_safe <C: unsigned int __stdcall mysql_thread_safe(void)> ^self externalAccessFailedWith: _errorCode
mysql_use_result: mysql <C: MYSQL_RES * __stdcall mysql_use_result(MYSQL * mysql)> ^self externalAccessFailedWith: _errorCode
mysql_warning_count: mysql <C: unsigned int __stdcall mysql_warning_count(MYSQL * mysql)> ^self externalAccessFailedWith: _errorCode
my_connect: s with: name with: namelen with: timeout <C: int my_connect(my_socket s, const struct sockaddr * name, unsigned int namelen, unsigned int timeout)> ^self externalAccessFailedWith: _errorCode
my_init <C: my_bool my_init(void)> ^self externalAccessFailedWith: _errorCode
my_net_init: net with: vio <C: my_bool my_net_init(NET * net, Vio * vio)> ^self externalAccessFailedWith: _errorCode
my_net_local_init: net <C: void my_net_local_init(NET * net)> ^self externalAccessFailedWith: _errorCode
my_net_read: net <C: unsigned long my_net_read(NET * net)> ^self externalAccessFailedWith: _errorCode
my_net_write: net with: packet with: len <C: my_bool my_net_write(NET * net, const char * packet, unsigned long len)> ^self externalAccessFailedWith: _errorCode
my_rnd: arg <C: double my_rnd(struct rand_struct * )> ^self externalAccessFailedWith: _errorCode
my_thread_end <C: void my_thread_end(void)> ^self externalAccessFailedWith: _errorCode
my_thread_init <C: my_bool my_thread_init(void)> ^self externalAccessFailedWith: _errorCode
</methods> <methods> Database.MySQLConnection <category>accessing</category>
database database ifNil: [self database: self class defaultDatabase]. ^database
database: aDbName "Assign me a new default database. If I'm connected, select this db right away." database := aDbName. self isConnected ifTrue: [self useDatabaseExternal]
port "Return the port number. This value can be changed while connected, but will not go into effect until the next connection is made." port ifNil: [self port: self class defaultPort]. ^port
port: aNumber "Assign me a new port number. This port will be used the next time I try to connect." port := aNumber
xif ^self class xif
</methods> <methods> Database.MySQLConnection <category>private-handles</category>
aquireConnectionHandle "Let the library allocate and initialize a pointer to a MYSQL struct for us. The library will de-allocate the struct when we eventually call close with that pointer. There are warnings against doing the allocation ourselves, because the library may not have the same compilation (packing/alignment) settings as our OE does." | xif hConn | xif := self class xif. hConn := xif mysql_init: 0. (traceLevel >= 3) ifTrue: [self trace_mysql_init: 0 pConn: hConn]. (hConn isValid ) ifFalse: [ | errs | errs := self getEnvironmentErrors. ^self class unableToAllocateHandleSignal raiseWith: errs errorString: errs first dbmsErrorString]. self hConn: hConn.
closeAndFreeConnectionHandle "Close the connection, and let the library free the allocated MYSQL data structure." | xif | self hasValidConnectionHandle ifTrue: [xif := self class xif. xif mysql_close: self hConn. traceLevel >= 3 ifTrue: [self traceFunc: 'mysql_close' result: nil params: self hConn]]. self hConn: nil
hasValidConnectionHandle "Return true only if the allocated MYSQL data structure has a valid pointer." | hConn | ^(hConn := self hConn) isNil ifTrue: [false] ifFalse: [hConn isValid]
hConn ^self hConnHolder value
hConn: aCPointerOrNil self hConnHolder value: aCPointerOrNil
hConnHolder ^hConnHolder
hConnHolder: aValueHolder hConnHolder := aValueHolder
unprotectedFinalizeLibrary "Let the library deallocate its private memory, before we unload the library. This function can be called before we unload the library." IsLibraryInitialized ifTrue: [self class xif mysqlLibraryEnd. traceLevel >= 2 ifTrue: [self traceFunc: 'mysql_library_end' result: nil params: nil]. IsLibraryInitialized := false]
unprotectedInitializeLibrary "Let the library to initialize itself. This call is necessary for threaded applications. It should only be called once, and the caller should be wrapped in a mutex." | rc argc argv groups | IsLibraryInitialized ifFalse: [argc := -1. argv := 0 gcCopyToHeap. groups := 0 gcCopyToHeap. rc := self class xif mysqlLibraryInitArgc: argc argv: argv groups: groups. traceLevel >= 2 ifTrue: [self traceFunc: 'mysql_library_init' result: rc params: (Array with: argc with: argv with: groups)]. rc == self class xif SUCCESS ifTrue: [IsLibraryInitialized := true] ifFalse: [^self class externalDatabaseLibraryInaccessibleSignal raiseWith: nil errorString: 'Cannot initialize the MySQL client library.']]
</methods> <methods> Database.MySQLConnection <category>private-finalization</category>
executor | ex | ex := super executor. ex hConnHolder: self hConnHolder. ^ex
finalizeExternal (self hConn isNil or: [self hConn referentAddress isNil]) ifTrue: [ ^self ]. ( traceLevel >= 1 ) ifTrue: [ self class trace: nil ]. super finalizeExternal
key "The hdbcHolder is unique to the connection and is constant across pause/resume." ^self hConnHolder
</methods> <methods> Database.MySQLConnection <category>initialize-release</category>
initialize "Establish initial value for instance variables." super initialize. self hConnHolder: nil asValue. "self isolationLevel: #RR"
</methods> <methods> Database.MySQLConnection <category>private-execution</category>
acquireExternal: aPassword "Acquire the external resources involved with a connection to the SQL-environment." | name pw env db aPort | name := self username. [name isString] whileFalse: [name := self class requiredUsernameSignal raiseRequest]. pw := aPassword. [pw isString] whileFalse: [pw := self class requiredPasswordSignal raiseRequest]. (env := self environment) isNil ifTrue: [env := self class defaultEnvironment]. [env isString] whileFalse: [env := self class requiredEnvironmentSignal raiseRequest]. env := self class mapLogical: env. db := self database. aPort := self port. "Make sure the library has been initialized." InitializeLibraryLock critical: [self unprotectedInitializeLibrary]. self hasValidConnectionHandle ifFalse: [self aquireConnectionHandle]. self connectExternalHost: env user: name passwd: pw db: db port: aPort. self singleStatementTransactions
beginExternal super beginExternal. self multiStatementTransactions
connectExternalHost: host user: user passwd: passwd db: db port: aPort "We must connect with CLIENT_MULTI_RESULTS to enable calling any stored procedure, since the proc will always return at least one result set, and typically, more." | flags | flags := self class xif CLIENT_MULTI_RESULTS. self connectExternalHost: host user: user passwd: passwd db: db port: aPort socket: 0 flags: flags
connectExternalHost: host user: user passwd: passwd db: db port: aPort socket: unix_socket flags: clientFlags "mysql_real_connect() MYSQL *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) " | pConn sig | pConn := self class xif mysql_real_connect: self hConn host: host user: user passwd: passwd db: db port: aPort unix_socket: unix_socket clientflag: clientFlags. traceLevel >= 3 ifTrue: [self traceFunc: 'mysql_real_connect' result: pConn printString params: ((OrderedCollection new) add: self hConn printString; add: host; add: user; add: passwd; add: db; add: aPort; add: unix_socket; add: clientFlags; yourself)]. pConn isValid ifFalse: [| errs | errs := self getConnectionErrors. sig := (self class signalForErrorCode: errs first dbmsErrorCode) ifNil: [self class unableToConnectToSQLserverSignal]. ^sig raiseWith: errs errorString: errs first dbmsErrorString]
dismissExternal self closeAndFreeConnectionHandle " | xif rc | xif := self class xif. [ Begin unwind protection. rc := xif SQLDisconnect: self hdbc . (traceLevel >= 2) ifTrue: [ (self traceStream) print: rc; nextPutAll: ' = SQLDisconnect( hdbc = '; nextPutAll: (self hdbc referentAddress printStringRadix: 16); nextPutAll: ' )'. self class trace: self emitTrace ]. (rc == xif SQL_SUCCESS) ifFalse: [ | errs | errs := self getConnectionErrors. ^self class unableToDisconnectSignal raiseRequestWith: errs ]. End unwind protection.] ensure: [ Whether or not there was a failure, there's no point in hanging onto the handles. HenvLock critical: [ self unprotectedFreeConnect ]. self supportedFunctions: IdentityDictionary new. self generalInformationCache: IdentityDictionary new ]"
getErrorsExternal "Return the most recent error code, or nil if none. From MySQL Docs: Note that some functions like mysql_fetch_row() don't reset mysql_errno() if they succeed. A rule of thumb is that all functions that have to ask the server for information reset mysql_errno() if they succeed." | xif errorMsg rc error | xif := self class xif. rc := xif mysql_errno: self hConn. rc == xif SUCCESS ifFalse: [ errorMsg := (xif mysql_error: self hConn) copyCStringFromHeap. error := self class errorClass new. error dbmsErrorCode: rc. error dbmsErrorString: errorMsg. error sqlState: (xif mysql_sqlstate: self hConn) copyCStringFromHeap. ( traceLevel >= 2 ) ifTrue: [self traceFunc: 'mysql_error' result: errorMsg params: self hConn ]]. ^error
installExternal super installExternal. self hConn: nil.
multiStatementTransactions "Take the receiver's connection out of auto-commit mode for transaction behavior." | rc | rc := self class xif mysql_autocommit: self hConn with: 0. rc == self class xif SUCCESS ifFalse: [| errs | errs := self getConnectionErrors. self class transactionExceptionSignal raiseWith: errs errorString: errs first dbmsErrorString]
setOptionsExternal: aPassword "int STDCALL mysql_options(MYSQL *mysql,enum mysql_option option, const char *arg); " | xif name pw env | xif := self class xif. name := self username. [ name isString ] whileFalse: [ name := self class requiredUsernameSignal raiseRequest ]. pw := aPassword. [ pw isString ] whileFalse: [ pw := self class requiredPasswordSignal raiseRequest ]. (env := self environment) isNil ifTrue: [ env := self class defaultEnvironment ]. [ env isString ] whileFalse: [ env := self class requiredEnvironmentSignal raiseRequest ]. env := self class mapLogical: env. [ "Begin unwind protection (1)" "Allocate necessary handles." self aquireConnectionHandle. ["Begin unwind protection (2)" self serverAttachEnvironmentExternal: env. self setAttribute: self hsrvr type: #OCI_ATTR_SERVER descriptor: self hsvcctx type: #OCI_HTYPE_SVCCTX. ( (name size == 0) and: [ pw size == 0 ]) ifTrue: [ self authenticationMode: xif OCI_CRED_EXT. ] ifFalse: [ self authenticationMode: xif OCI_CRED_RDBMS. self setAttribute: name type: #OCI_ATTR_USERNAME descriptor: self hsess type: #OCI_HTYPE_SESSION . self setAttribute: pw type: #OCI_ATTR_PASSWORD descriptor: self hsess type: #OCI_HTYPE_SESSION. ]. self setAttribute: self htxn type: #OCI_ATTR_TRANS descriptor: self hsvcctx type: #OCI_HTYPE_SVCCTX. self setAttribute: self hsess type: #OCI_ATTR_SESSION descriptor: self hsvcctx type: #OCI_HTYPE_SVCCTX. [ "Begin unwind protection (3)" self sessionBeginExternal "End unwind protection (3)" ] ifCurtailed: [self sessionEndExternal]. "End unwind protection (2)" ] ifCurtailed: [self serverDetachExternal]. "End unwind protection (1)" ] ifCurtailed: [ "Something went wrong so we must implicitly free any handles we've allocated." self unprotectedFreeHenv ]. self singleStatementTransactions
setSSLExternal: aPassword "Acquire the external resources involved with a connection to the SQL-environment. mysql_ssl_set" | xif name pw env | xif := self class xif. name := self username. [ name isString ] whileFalse: [ name := self class requiredUsernameSignal raiseRequest ]. pw := aPassword. [ pw isString ] whileFalse: [ pw := self class requiredPasswordSignal raiseRequest ]. (env := self environment) isNil ifTrue: [ env := self class defaultEnvironment ]. [ env isString ] whileFalse: [ env := self class requiredEnvironmentSignal raiseRequest ]. env := self class mapLogical: env. [ "Begin unwind protection (1)" "Allocate necessary handles." self aquireConnectionHandle. ["Begin unwind protection (2)" self serverAttachEnvironmentExternal: env. self setAttribute: self hsrvr type: #OCI_ATTR_SERVER descriptor: self hsvcctx type: #OCI_HTYPE_SVCCTX. ( (name size == 0) and: [ pw size == 0 ]) ifTrue: [ self authenticationMode: xif OCI_CRED_EXT. ] ifFalse: [ self authenticationMode: xif OCI_CRED_RDBMS. self setAttribute: name type: #OCI_ATTR_USERNAME descriptor: self hsess type: #OCI_HTYPE_SESSION . self setAttribute: pw type: #OCI_ATTR_PASSWORD descriptor: self hsess type: #OCI_HTYPE_SESSION. ]. self setAttribute: self htxn type: #OCI_ATTR_TRANS descriptor: self hsvcctx type: #OCI_HTYPE_SVCCTX. self setAttribute: self hsess type: #OCI_ATTR_SESSION descriptor: self hsvcctx type: #OCI_HTYPE_SVCCTX. [ "Begin unwind protection (3)" self sessionBeginExternal "End unwind protection (3)" ] ifCurtailed: [self sessionEndExternal]. "End unwind protection (2)" ] ifCurtailed: [self serverDetachExternal]. "End unwind protection (1)" ] ifCurtailed: [ "Something went wrong so we must implicitly free any handles we've allocated." self unprotectedFreeHenv ]. self singleStatementTransactions
singleStatementTransactions "Put the receiver's connection into auto-commit mode for transaction behavior." | rc | rc := self class xif mysql_autocommit: self hConn with: 1. rc == self class xif SUCCESS ifFalse: [| errs | errs := self getConnectionErrors. self class transactionExceptionSignal raiseWith: errs errorString: errs first dbmsErrorString]
useDatabaseExternal "Assign the receiver's connection to the given default database. If the user doesn't have the required privileges, an error will be returned." | rc | rc := self class xif mysql_select_db: self hConn with: self database. rc == self class xif SUCCESS ifFalse: [| errs | errs := self getConnectionErrors. self class unableToConnectToSQLenvironmentSignal raiseWith: errs errorString: errs first dbmsErrorString]
</methods> <methods> Database.MySQLConnection <category>private-tracing</category>
traceFunc: functionName result: result params: params | strm | strm := self traceStream. strm nextPutAll: result printString , '= '; nextPutAll: functionName , '('. (params isKindOf: Collection) ifTrue: [params do: [:param | strm nextPutAll: param printString, ', ']] ifFalse: [strm nextPutAll: params printString]. strm nextPutAll: ') '. self class trace: self emitTrace
trace_mysql_init: ptr pConn: pConn (self traceStream) nextPutAll: ', pConn = '; nextPutAll: (pConn referentAddress printStringRadix: 16); nextPutAll: ' = mysql_init(' , ptr printString , ') '. self class trace: self emitTrace
</methods> <methods> Database.MySQLConnection <category>private-accessing</category>
getConnectionErrors "Return a non-empty collection of MySQL Errors associated with the connection handle. Many senders assume non-empty collection, so use a default if no official error available." | errors err | errors := OrderedCollection new. err := self getErrorsExternal ifNil: [self class defaultError]. errors add: err. ^errors
getEnvironmentErrors "Answer an empty collection, since without a connection handle, we cannot fetch errors. Callers expect an OrderedCollection." ^OrderedCollection new.
</methods> <methods> Database.MySQLConnection <category>private-library calls</category>
commitExternal "Commits the current transaction. As of MySQL 5.0.3, the action of this function is subject to the value of the completion_type system variable. In particular, if the value of completion_type is 2, the server performs a release after terminating a transaction and closes the client connection. The client program should call mysql_close() to close the connection from the client side." | rc | super commitExternal ifFalse: [^self]. rc := self class xif mysql_commit: self hConn. traceLevel >= 3 ifTrue: [self traceFunc: 'mysql_commit' result: rc params: self hConn]. rc == self class xif SUCCESS ifFalse: [| errs | errs := self getConnectionErrors. ^self class transactionExceptionSignal raiseWith: errs errorString: errs first dbmsErrorString]. self singleStatementTransactions
rollbackExternal "Note that the 'completion_type' server variable =2, then the server will disconnect us. (1 will begin a new transaction, 0 is default). See more in #commitExternal." | rc | super rollbackExternal ifFalse: [^self]. rc := self class xif mysql_rollback: self hConn. traceLevel >= 3 ifTrue: [self traceFunc: 'mysql_rollback' result: rc params: self hConn]. rc == self class xif SUCCESS ifFalse: [| errs | errs := self getConnectionErrors. ^self class transactionExceptionSignal raiseWith: errs errorString: errs first dbmsErrorString]. self singleStatementTransactions
</methods> <methods> Database.MySQLConnection class <category>private-registry</category>
registry ^RegisteredMySQLConnections
registry: aCollection RegisteredMySQLConnections := aCollection
</methods> <methods> Database.MySQLConnection class <category>private-accessing</category>
charsetNameToEncoding "Return a dictionary which maps MySQL character set names to VW encoding symbols." | map | map := Dictionary new. map at: 'ascii' put: #ascii; at: 'cp1250' put: #ms_cp_1250; at: 'cp1251' put: #ms_cp_1251; at: 'cp1256' put: #ms_cp_1256 ; at: 'cp1257' put: #ms_cp_1257; at: 'cp850' put: #ms_cp_850; at: 'cp852' put: #ms_cp_852; at: 'cp866' put: #ms_cp_866; at: 'greek' put: #iso8859_7; at: 'hebrew' put: #iso8859_8; at: 'hp8' put: #hp_roman8; at: 'koi8r' put: #koi8r; at: 'koi8u' put: #koi8u; at: 'latin1' put: #ms_cp_1252; at: 'latin2' put: #iso8859_2; at: 'latin5' put: #iso8859_9; at: 'latin7' put: #iso8859_13; at: 'macce' put: #maccenteuro; at: 'macroman' put: #macroman; at: 'sjis' put: #ShiftJIS; "Shift-JIS Japanese" at: 'ucs2' put: #ucs_2; at: 'ujis' put: #JapaneseEUC; "EUC-JP Japanese" at: 'utf8' put: #utf_8; "The following do not currently have corresponding encodings in VW" at: 'armscii8' put: #armscii_8; "ARMSCII-8 Armenian" at: 'big5' put: #big5; "Big5 Traditional Chinese" at: 'binary' put: #binary; "Binary pseudo charset" at: 'cp932' put: #ms_cp_932; "SJIS for Windows Japanese" at: 'dec8' put: #dec8; "DEC West European" at: 'eucjpms' put: #eucjpms; "UJIS for Windows Japanese" at: 'euckr' put: #euckr; "EUC-KR Korean" at: 'gb2312' put: #gb2312; "'GB2312 Simplified Chinese'" at: 'gbk' put: #gbk; "GBK Simplified Chinese" at: 'geostd8' put: #geostd8; "GEOSTD8 Georgian" at: 'keybcs2' put: #keybcs2; "DOS Kamenicky Czech-Slovak" at: 'swe7' put: #swe_7; "7bit Swedish" at: 'tis620' put: #tis_620. "TIS620 Thai" ^map
collationIdToCharsetName "MySQLConnection collationIdToCharsetName" | dict | dict := Dictionary new. ^dict add: 1 -> 'big5'; add: 2 -> 'latin2'; add: 3 -> 'dec8'; add: 4 -> 'cp850'; add: 5 -> 'latin1'; add: 6 -> 'hp8'; add: 7 -> 'koi8r'; add: 8 -> 'latin1'; add: 9 -> 'latin2'; add: 10 -> 'swe7'; add: 11 -> 'ascii'; add: 12 -> 'ujis'; add: 13 -> 'sjis'; add: 14 -> 'cp1251'; add: 15 -> 'latin1'; add: 16 -> 'hebrew'; add: 18 -> 'tis620'; add: 19 -> 'euckr'; add: 20 -> 'latin7'; add: 21 -> 'latin2'; add: 22 -> 'koi8u'; add: 23 -> 'cp1251'; add: 24 -> 'gb2312'; add: 25 -> 'greek'; add: 26 -> 'cp1250'; add: 27 -> 'latin2'; add: 28 -> 'gbk'; add: 29 -> 'cp1257'; add: 30 -> 'latin5'; add: 31 -> 'latin1'; add: 32 -> 'armscii8'; add: 33 -> 'utf8'; add: 34 -> 'cp1250'; add: 35 -> 'ucs2'; add: 36 -> 'cp866'; add: 37 -> 'keybcs2'; add: 38 -> 'macce'; add: 39 -> 'macroman'; add: 40 -> 'cp852'; add: 41 -> 'latin7'; add: 42 -> 'latin7'; add: 43 -> 'macce'; add: 44 -> 'cp1250'; add: 47 -> 'latin1'; add: 48 -> 'latin1'; add: 49 -> 'latin1'; add: 50 -> 'cp1251'; add: 51 -> 'cp1251'; add: 52 -> 'cp1251'; add: 53 -> 'macroman'; add: 57 -> 'cp1256'; add: 58 -> 'cp1257'; add: 59 -> 'cp1257'; add: 63 -> 'binary'; add: 64 -> 'armscii8'; add: 65 -> 'ascii'; add: 66 -> 'cp1250'; add: 67 -> 'cp1256'; add: 68 -> 'cp866'; add: 69 -> 'dec8'; add: 70 -> 'greek'; add: 71 -> 'hebrew'; add: 72 -> 'hp8'; add: 73 -> 'keybcs2'; add: 74 -> 'koi8r'; add: 75 -> 'koi8u'; add: 77 -> 'latin2'; add: 78 -> 'latin5'; add: 79 -> 'latin7'; add: 80 -> 'cp850'; add: 81 -> 'cp852'; add: 82 -> 'swe7'; add: 83 -> 'utf8'; add: 84 -> 'big5'; add: 85 -> 'euckr'; add: 86 -> 'gb2312'; add: 87 -> 'gbk'; add: 88 -> 'sjis'; add: 89 -> 'tis620'; add: 90 -> 'ucs2'; add: 91 -> 'ujis'; add: 92 -> 'geostd8'; add: 93 -> 'geostd8'; add: 94 -> 'latin1'; add: 95 -> 'cp932'; add: 96 -> 'cp932'; add: 97 -> 'eucjpms'; add: 98 -> 'eucjpms'; add: 128 -> 'ucs2'; add: 129 -> 'ucs2'; add: 130 -> 'ucs2'; add: 131 -> 'ucs2'; add: 132 -> 'ucs2'; add: 133 -> 'ucs2'; add: 134 -> 'ucs2'; add: 135 -> 'ucs2'; add: 136 -> 'ucs2'; add: 137 -> 'ucs2'; add: 138 -> 'ucs2'; add: 139 -> 'ucs2'; add: 140 -> 'ucs2'; add: 141 -> 'ucs2'; add: 142 -> 'ucs2'; add: 143 -> 'ucs2'; add: 144 -> 'ucs2'; add: 145 -> 'ucs2'; add: 146 -> 'ucs2'; add: 192 -> 'utf8'; add: 193 -> 'utf8'; add: 194 -> 'utf8'; add: 195 -> 'utf8'; add: 196 -> 'utf8'; add: 197 -> 'utf8'; add: 198 -> 'utf8'; add: 199 -> 'utf8'; add: 200 -> 'utf8'; add: 201 -> 'utf8'; add: 202 -> 'utf8'; add: 203 -> 'utf8'; add: 204 -> 'utf8'; add: 205 -> 'utf8'; add: 206 -> 'utf8'; add: 207 -> 'utf8'; add: 208 -> 'utf8'; add: 209 -> 'utf8'; add: 210 -> 'utf8'; yourself
collationIdToEncoding "Return and encoder map which converts a collation Id (charsetnr of collumnDescription) to a VW character set encoding symbol." "MySQLConnection collationIdToEncoding" | collationMap charsetMap collationIdToEncoding encoding | collationMap := self collationIdToCharsetName. charsetMap := self charsetNameToEncoding. collationIdToEncoding := Dictionary new. collationMap keysAndValuesDo: [:collationId :charsetName | encoding := charsetMap at: charsetName. collationIdToEncoding at: collationId put: encoding]. ^collationIdToEncoding
transactionClass ^MySQLTransaction
</methods> <methods> Database.MySQLConnection class <category>accessing</category>
columnDescriptionClass "Answer the class to use for column description objects associated with receiver." ^MySQLColumnDescription
defaultDatabase ^'mysql'
defaultError "Answer a default error instance for the receiver." | err | err := self errorClass new. err dbmsErrorCode: 0. err dbmsErrorString: 'Connection Error'. err sqlState: String new. ^err
defaultNamedPipe ^self xif MYSQL_NAMEDPIPE
defaultPort "Ignored unless using TCP/IP." ^3306
defaultUnixSocket "If not NULL, it specifies the socket or named pipe to be used." self error: 'Default unix socket not established.'. ^self xif MYSQL_NAMEDPIPE
encodingForCollationId: aCollationId "Return the Smalltalk encoding symbol for the given MySQL collation id, typically returned as charsetnr in a columnDescription." | encoding | encoding := EncoderMap at: aCollationId ifAbsent: [nil]. ^encoding
errorClass "Answer the error class for the receiver." ^MySQLError
interfaceClass "Answer the interface class for the current OS." "MySQLConnection interfaceClass" | interfaceClassName | interfaceClassName := xifMap at: self platformType ifAbsent: [nil]. ^interfaceClassName notNil ifTrue: [self environment at: interfaceClassName ifAbsent: [nil]] ifFalse: [nil]
kind "Answer a symbol representing the type of DMBS the receiver provides services for." ^#'MySQL'
sessionClass "Answer the class to use for session objects associated with receiver." ^MySQLSession
signalForErrorCode: anErrorNumber "Answer the signal to use for this error number if found, else nil." | sig | sig := self signalMap at: anErrorNumber ifAbsent: [nil]. ^sig ifNotNil: [self perform: sig]
signalMap "Answer the signal map, which maps error codes to exceptions (signals)." SignalMap isNil ifTrue: [self initializeSignalMap]. ^SignalMap
xif "Answer the ExternalInterface subclass instance to use." xif isNil ifTrue: [ self initializeExternalInterface ]. ^xif
</methods> <methods> Database.MySQLConnection class <category>class initialization</category>
initialize "MySQLConnection initialize" self initializeExternalInterfaceMap. InitializeLibraryLock := RecursionLock new. IsLibraryInitialized := false. EncoderMap := self collationIdToEncoding. self xif: nil. self initRegistry. "SupportedIsolationLevels := IdentityDictionary new. SupportedIsolationLevels at: #RR put: #SQL_TXN_REPEATABLE_READ. SupportedIsolationLevels at: #RC put: #SQL_TXN_READ_COMMITTED. SupportedIsolationLevels at: #RU put: #SQL_TXN_READ_UNCOMMITED. SupportedIsolationLevels at: #serializable put: #SQL_TXN_SERIALIZABLE. SupportedIsolationLevels at: #versioning put: #SQL_TXN_VERSIONING. self sessionClass initialize."
initializeExternalInterface "Reset xif call with the right interface class based on the current platform." | xifClass | xifClass := self interfaceClass. self xif: (xifClass ifNotNil: [xifClass new] ifNil: [nil]). xif ifNil: [^Dialog warn: 'The MySQL Client Driver is not correctly installed.' withCRs]
initializeExternalInterfaceMap "self initializeExternalInterfaceMap" xifMap := IdentityDictionary new. xifMap at: #nt put: #MySQLNTInterface. xifMap at: #linux_i386_unix put: #MySQLLinuxInterface. xifMap at: #sun5_unix put: #MySQLSolarisInterface. xifMap at: #hp_unix put: #MySQLHPUXInterface
</methods> <methods> Database.MySQLConnection class <category>activation</category>
pause ^self quiesce
resume ^self activate
</methods> <methods> Database.MySQLConnection class <category>private-activation</category>
install ( TraceLevel >= 1 ) ifTrue: [ self trace: nil ]. self xif: nil. self sessionClass install. self returnFromSnapshot
</methods> <methods> Database.MySQLConnection class <category>signal constants</category>
initializeSignalMap "There are very many error and warning return codes. A few are pasted below, and offer custom error signals." "MySQLConnection initializeSignalMap" SignalMap := IdentityDictionary new. SignalMap at: 1146 put: #invalidTableNameSignal. "Error: 1146 SQLSTATE: 42S02 (ER_NO_SUCH_TABLE)" SignalMap at: 1066 put: #invalidTableNameSignal. "Error: 1066 SQLSTATE: 42000 (ER_NONUNIQ_TABLE)" SignalMap at: 1022 put: #duplicateIndexesErrorSignal. "Error: 1022 SQLSTATE: 23000 (ER_DUP_KEY)" SignalMap at: 1401 put: #externalDatabaseTransactionErrorSignal. "Error: 1401 SQLSTATE: XAE03 (ER_XAER_RMERR)" SignalMap at: 1280 put: #indexConflictSignal. "Error: 1280 SQLSTATE: 42000 (ER_WRONG_NAME_FOR_INDEX)" SignalMap at: 1099 put: #objectLockedSignal. "Error: 1099 SQLSTATE: HY000 (ER_TABLE_NOT_LOCKED_FOR_WRITE)" SignalMap at: 1100 put: #objectLockedSignal. "Error: 1100 SQLSTATE: HY000 (ER_TABLE_NOT_LOCKED)" SignalMap at: 1044 put: #authenticationFailureSignal. "Error: 1044 SQLSTATE: 42000 (ER_DBACCESS_DENIED_ERROR)" SignalMap at: 1045 put: #authenticationFailureSignal. "Error: 1045 SQLSTATE: 28000 (ER_ACCESS_DENIED_ERROR)" SignalMap at: 2003 put: #couldNotResolveServiceNameSignal. "Error: 2003 (CR_CONN_HOST_ERROR)" SignalMap at: 2005 put: #couldNotResolveServiceNameSignal. "Error: 2005 (CR_UNKNOWN_HOST)" SignalMap at: 1217 put: #rowIsReferencedErrorSignal. "Error: 1217 SQLSTATE: 23000 (ER_ROW_IS_REFERENCED)" SignalMap at: 1087 put: #successWithInformationSignal. "Error: 1087 SQLSTATE: HY000 (ER_LOAD_INFO)" SignalMap at: 1088 put: #successWithInformationSignal. "Error: 1088 SQLSTATE: HY000 (ER_ALTER_INFO)" SignalMap at: 1092 put: #successWithInformationSignal. "Error: 1092 SQLSTATE: HY000 (ER_INSERT_INFO)" SignalMap at: 1134 put: #successWithInformationSignal. "Error: 1134 SQLSTATE: HY000 (ER_UPDATE_INFO)" SignalMap at: 1201 put: #successWithInformationSignal. "Error: 1201 SQLSTATE: HY000 (ER_MASTER_INFO)"
</methods> <methods> Database.MySQLConnection class <category>tracing</category>
trace: aStringOrNil "Emit the standard trace header followed by aString (if not nil) into the trace log. This method overrides the base method because we need to grab the context one level deeper in the stack. The only difference is to add a second >>sender." | header when sender depth | TraceCollector == nil ifTrue: [ ^self ]. header := WriteStream on: (String new: 64). when := Time dateAndTimeNow. sender := thisContext sender sender. "The immediate caller is traceFunc:, so skip beyond it." depth := TraceLevel > 4 ifTrue: [ TraceLevel - 4 ] ifFalse: [ 1 ]. "Emit a timestamp" header nextPutAll: '{'; "print: (when at: 1);" nextPutAll: ((when at: 1) printFormat: #(1 2 3 $ 2 2)); nextPutAll: ' '; print: (when at: 2); nextPutAll: '} '. "curly-brace, space and a tab" "Emit a stack trace" [ depth > 0 ] whileTrue: [ header nextPutAll: sender mclass printString; nextPutAll: '>>'; nextPutAll: sender selector asString. sender := sender sender. (depth := depth - 1) > 0 ifTrue: [ header cr; tab: 6 ] ]. TraceSequencer critical: [ TraceCollector nextPutAll: header contents; cr. ( aStringOrNil size > 0 ) ifTrue: [ TraceCollector tab; nextPutAll: aStringOrNil; cr ]. TraceCollector flush ]
</methods> <methods> Database.MySQLConnection class <category>examples</category>
allExamples "MySQLConnection allExamples" ^OrderedCollection new add: self example1; add: self example2; add: self example3; add: self example4; yourself
example1 "MySQLConnection example1" ^self exampleQuery: 'SHOW TABLES'
example2 "MySQLConnection example2" ^self exampleQuery: 'SHOW DATABASES'.
example3 "MySQLConnection example3" | params | params := Array with: 'SELECT'. ^self exampleQuery: 'SELECT description, example FROM help_topic WHERE name=?' bind: params
example4 "MySQLConnection example4" ^self exampleQuery: 'show character set'.
exampleQuery: aQuery "Note that this method deliberately uses self, so subclasses will do things their own way." "MySQLConnection exampleQuery: 'SHOW TABLES'." | conn sess ans data | conn := self new. conn username: 'root'; password: 'user'; environment: 'localhost'. [conn connect. sess := conn getSession. sess prepare: aQuery. sess execute. ans := sess answer. [ans = #noMoreAnswers] whileFalse: [ans = #noAnswerStream ifFalse: [data := ans upToEnd]. ans := sess answer]] ensure: [conn disconnect]. ^data
exampleQuery: aQuery bind: aBoundInputParam "MySQLConnection exampleQuery: 'SHOW TABLES'." | conn sess ans data | conn := self new. conn username: 'root'; password: 'user'; environment: 'localhost'. [conn connect. sess := conn getSession. sess prepare: aQuery. sess bindInput: aBoundInputParam. sess execute. ans := sess answer. [ans = #noMoreAnswers] whileFalse: [ans = #noAnswerStream ifFalse: [data := ans upToEnd]. ans := sess answer]] ensure: [conn disconnect]. ^data
generateCharsetDictionary "MySQLConnection generateCharsetDictionary" | data dict | data := MySQLConnection exampleQuery: 'show collation'. dict := Dictionary new. data do: [:each | dict at: (each at: 3) put: (each at: 2)]. ^dict
generateCharsetNames "MySQLConnection generateCharsetNames" | data dict | data := MySQLConnection exampleQuery: 'show character set'. dict := Dictionary new. data do: [:each | dict at: (each at: 2) put: (each at: 1)]. ^dict
</methods> <methods> Database.MySQLInterface <category>types</category>
bool <C: typedef char bool>
byte <C: typedef char byte>
clock_t <C: typedef long clock_t>
EMBEDDED_QUERY_RESULT <C: typedef struct embedded_query_result EMBEDDED_QUERY_RESULT>
FILE <C: typedef void * FILE>
fpos_t <C: typedef struct __fpos_t fpos_t>
gptr <C: typedef char * gptr>
int15 <C: typedef short int15>
int16 <C: typedef short int16>
int7 <C: typedef uint8 int7>
int8 <C: typedef char int8>
LIST <C: typedef struct st_list LIST>
list_walk_action <C: typedef int (* list_walk_action)(void * , void * )>
longlong <C: typedef long longlong>
MEM_ROOT <C: typedef struct st_mem_root MEM_ROOT>
myf <C: typedef int myf>
MYSQL <C: typedef struct st_mysql MYSQL>
MYSQL_BIND <C: typedef struct st_mysql_bind MYSQL_BIND>
MYSQL_DATA <C: typedef struct st_mysql_data MYSQL_DATA>
MYSQL_FIELD <C: typedef struct st_mysql_field MYSQL_FIELD>
MYSQL_FIELD_OFFSET <C: typedef unsigned int MYSQL_FIELD_OFFSET>
MYSQL_MANAGER <C: typedef struct st_mysql_manager MYSQL_MANAGER>
MYSQL_METHODS <C: typedef struct st_mysql_methods MYSQL_METHODS>
MYSQL_PARAMETERS <C: typedef struct st_mysql_parameters MYSQL_PARAMETERS>
MYSQL_RES <C: typedef struct st_mysql_res MYSQL_RES>
MYSQL_ROW <C: typedef char * * MYSQL_ROW>
MYSQL_ROWS <C: typedef struct st_mysql_rows MYSQL_ROWS>
MYSQL_ROW_OFFSET <C: typedef MYSQL_ROWS * MYSQL_ROW_OFFSET>
MYSQL_STMT <C: typedef struct st_mysql_stmt MYSQL_STMT>
MYSQL_TIME <C: typedef struct st_mysql_time MYSQL_TIME>
my_bool <C: typedef char my_bool>
MY_CHARSET_INFO <C: typedef struct character_set MY_CHARSET_INFO>
my_off_t <C: typedef unsigned long my_off_t>
my_ptrdiff_t <C: typedef long long my_ptrdiff_t>
my_socket <C: typedef int my_socket>
my_string <C: typedef char * my_string>
my_ulonglong <C: typedef unsigned long long my_ulonglong>
NET <C: typedef struct st_net NET>
off_t <C: typedef void * off_t>
os_off_t <C: typedef off_t os_off_t>
pbool <C: typedef int pbool>
pchar <C: typedef int pchar>
pfloat <C: typedef double pfloat>
pshort <C: typedef int pshort>
puchar <C: typedef uint puchar>
qsort_cmp <C: typedef int (* qsort_cmp)(const void * , const void * )>
qsort_cmp2 <C: typedef int (* qsort_cmp2)(void * , const void * , const void * )>
sig_return <C: typedef void (* sig_return)(...)>
size_s <C: typedef unsigned long size_s>
size_socket <C: typedef SOCKET_SIZE_TYPE size_socket>
size_t <C: typedef unsigned int size_t>
SOCKET_SIZE_TYPE <C: typedef void * SOCKET_SIZE_TYPE>
time_t <C: typedef long time_t>
TYPELIB <C: typedef struct st_typelib TYPELIB>
uchar <C: typedef unsigned char uchar>
UDF_ARGS <C: typedef struct st_udf_args UDF_ARGS>
UDF_INIT <C: typedef struct st_udf_init UDF_INIT>
uint <C: typedef unsigned int uint>
uint16 <C: typedef unsigned short uint16>
uint8 <C: typedef unsigned char uint8>
ulong <C: typedef unsigned long ulong>
ulonglong <C: typedef unsigned long ulonglong>
USED_MEM <C: typedef struct st_used_mem USED_MEM>
ushort <C: typedef unsigned short ushort>
va_list <C: typedef char * va_list>
Vio <C: typedef struct st_vio Vio>
wchar_t <C: typedef unsigned short wchar_t>
wctype_t <C: typedef wchar_t wctype_t>
wint_t <C: typedef wchar_t wint_t>
</methods> <methods> Database.MySQLInterface <category>enums</category>
enum_cursor_type <C: enum enum_cursor_type { CURSOR_TYPE_NO_CURSOR, CURSOR_TYPE_READ_ONLY, CURSOR_TYPE_FOR_UPDATE, CURSOR_TYPE_SCROLLABLE = 4 }>
enum_field_types <C: enum enum_field_types { MYSQL_TYPE_DECIMAL, MYSQL_TYPE_TINY, MYSQL_TYPE_SHORT, MYSQL_TYPE_LONG, MYSQL_TYPE_FLOAT, MYSQL_TYPE_DOUBLE, MYSQL_TYPE_NULL, MYSQL_TYPE_TIMESTAMP, MYSQL_TYPE_LONGLONG, MYSQL_TYPE_INT24, MYSQL_TYPE_DATE, MYSQL_TYPE_TIME, MYSQL_TYPE_DATETIME, MYSQL_TYPE_YEAR, MYSQL_TYPE_NEWDATE, MYSQL_TYPE_VARCHAR, MYSQL_TYPE_BIT, MYSQL_TYPE_NEWDECIMAL = 246, MYSQL_TYPE_ENUM, MYSQL_TYPE_SET, MYSQL_TYPE_TINY_BLOB, MYSQL_TYPE_MEDIUM_BLOB, MYSQL_TYPE_LONG_BLOB, MYSQL_TYPE_BLOB, MYSQL_TYPE_VAR_STRING, MYSQL_TYPE_STRING, MYSQL_TYPE_GEOMETRY }>
enum_mysql_set_option <C: enum enum_mysql_set_option { MYSQL_OPTION_MULTI_STATEMENTS_ON, MYSQL_OPTION_MULTI_STATEMENTS_OFF }>
enum_mysql_stmt_state <C: enum enum_mysql_stmt_state { MYSQL_STMT_INIT_DONE = 1, MYSQL_STMT_PREPARE_DONE, MYSQL_STMT_EXECUTE_DONE, MYSQL_STMT_FETCH_DONE }>
enum_mysql_timestamp_type <C: enum enum_mysql_timestamp_type { MYSQL_TIMESTAMP_NONE = -2, MYSQL_TIMESTAMP_ERROR, MYSQL_TIMESTAMP_DATE, MYSQL_TIMESTAMP_DATETIME, MYSQL_TIMESTAMP_TIME }>
enum_server_command <C: enum enum_server_command { COM_SLEEP, COM_QUIT, COM_INIT_DB, COM_QUERY, COM_FIELD_LIST, COM_CREATE_DB, COM_DROP_DB, COM_REFRESH, COM_SHUTDOWN, COM_STATISTICS, COM_PROCESS_INFO, COM_CONNECT, COM_PROCESS_KILL, COM_DEBUG, COM_PING, COM_TIME, COM_DELAYED_INSERT, COM_CHANGE_USER, COM_BINLOG_DUMP, COM_TABLE_DUMP, COM_CONNECT_OUT, COM_REGISTER_SLAVE, COM_STMT_PREPARE, COM_STMT_EXECUTE, COM_STMT_SEND_LONG_DATA, COM_STMT_CLOSE, COM_STMT_RESET, COM_SET_OPTION, COM_STMT_FETCH, COM_END }>
enum_stmt_attr_type <C: enum enum_stmt_attr_type { STMT_ATTR_UPDATE_MAX_LENGTH, STMT_ATTR_CURSOR_TYPE, STMT_ATTR_PREFETCH_ROWS }>
Item_result <C: enum Item_result { STRING_RESULT, REAL_RESULT, INT_RESULT, ROW_RESULT, DECIMAL_RESULT }>
mysql_enum_shutdown_level <C: enum mysql_enum_shutdown_level { SHUTDOWN_DEFAULT, SHUTDOWN_WAIT_CONNECTIONS, SHUTDOWN_WAIT_TRANSACTIONS, SHUTDOWN_WAIT_UPDATES = 8, SHUTDOWN_WAIT_ALL_BUFFERS = 16, SHUTDOWN_WAIT_CRITICAL_BUFFERS, KILL_CONNECTION = 255 }>
mysql_option <C: enum mysql_option { 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_protocol_type <C: enum mysql_protocol_type { MYSQL_PROTOCOL_DEFAULT, MYSQL_PROTOCOL_TCP, MYSQL_PROTOCOL_SOCKET, MYSQL_PROTOCOL_PIPE, MYSQL_PROTOCOL_MEMORY }>
mysql_rpl_type <C: enum mysql_rpl_type { MYSQL_RPL_MASTER, MYSQL_RPL_SLAVE, MYSQL_RPL_ADMIN }>
mysql_status <C: enum mysql_status { MYSQL_STATUS_READY, MYSQL_STATUS_GET_RESULT, MYSQL_STATUS_USE_RESULT }>
</methods> <methods> Database.MySQLInterface <category>structs</category>
character_set <C: struct character_set { unsigned int number, state; const char * csname; const char * name; const char * comment; const char * dir; unsigned int mbminlen, mbmaxlen; }>
charset_info_st <C: struct charset_info_st>
embedded_query_result <C: struct embedded_query_result>
rand_struct <C: struct rand_struct { unsigned long seed1, seed2, max_value; double max_value_dbl; }>
sockaddr <C: struct sockaddr>
st_dynamic_array <C: struct st_dynamic_array>
st_list <C: struct st_list { struct st_list * prev; struct st_list * next; void * data; }>
st_mem_root <C: struct st_mem_root { USED_MEM * free; USED_MEM * used; USED_MEM * pre_alloc; unsigned int min_malloc, block_size, block_num, first_block_usage; void (* error_handler)(void); }>
st_mysql <C: struct st_mysql { NET net; gptr connector_fd; char * host; char * user; char * passwd; char * unix_socket; char * server_version; char * host_info; char * info; char * db; struct charset_info_st * charset; MYSQL_FIELD * fields; MEM_ROOT field_alloc; my_ulonglong affected_rows, insert_id, extra_info; unsigned long thread_id, packet_length; unsigned int port; unsigned long client_flag, server_capabilities; unsigned int protocol_version, field_count, server_status, server_language, warning_count; struct st_mysql_options options; enum mysql_status status; my_bool free_me, reconnect; char scramble[21]; my_bool rpl_pivot; struct st_mysql * master; struct st_mysql * next_slave; struct st_mysql * last_used_slave; struct st_mysql * last_used_con; LIST * stmts; const struct st_mysql_methods * methods; void * thd; my_bool * unbuffered_fetch_owner; }>
st_mysql_bind <C: struct st_mysql_bind { unsigned long * length; my_bool * is_null; void * buffer; my_bool * error; enum enum_field_types buffer_type; unsigned long buffer_length; unsigned char * row_ptr; unsigned long offset, length_value; unsigned int param_number, pack_length; my_bool error_value, is_unsigned, long_data_used, is_null_value; void (* store_param_func)(NET * net, struct st_mysql_bind * param); void (* fetch_result)(struct st_mysql_bind * _arg1, MYSQL_FIELD * _arg2, unsigned char * * row); void (* skip_result)(struct st_mysql_bind * _arg1, MYSQL_FIELD * _arg2, unsigned char * * row); }>
st_mysql_data <C: struct st_mysql_data { my_ulonglong rows; unsigned int fields; MYSQL_ROWS * data; MEM_ROOT alloc; struct embedded_query_result * embedded_info; }>
st_mysql_field <C: struct st_mysql_field { char * name; char * org_name; char * table; char * org_table; char * db; char * catalog; char * def; unsigned long length, max_length; unsigned int name_length, org_name_length, table_length, org_table_length, db_length, catalog_length, def_length, flags, decimals, charsetnr; enum enum_field_types type; }>
st_mysql_manager <C: struct st_mysql_manager { NET net; char * host; char * user; char * passwd; unsigned int port; my_bool free_me, eof; int cmd_status, last_errno; char * net_buf; char * net_buf_pos; char * net_data_end; int net_buf_size; char last_error[256]; }>
st_mysql_methods <C: struct st_mysql_methods { my_bool (* read_query_result)(MYSQL * mysql); my_bool (* advanced_command)(MYSQL * mysql, enum enum_server_command command, const char * header, unsigned long header_length, const char * arg, unsigned long arg_length, my_bool skip_check); MYSQL_DATA * (* read_rows)(MYSQL * mysql, MYSQL_FIELD * mysql_fields, unsigned int fields); MYSQL_RES * (* use_result)(MYSQL * mysql); void (* fetch_lengths)(unsigned long * to, MYSQL_ROW column, unsigned int field_count); void (* flush_use_result)(MYSQL * mysql); MYSQL_FIELD * (* list_fields)(MYSQL * mysql); my_bool (* read_prepare_result)(MYSQL * mysql, MYSQL_STMT * stmt); int (* stmt_execute)(MYSQL_STMT * stmt); int (* read_binary_rows)(MYSQL_STMT * stmt); int (* unbuffered_fetch)(MYSQL * mysql, char * * row); void (* free_embedded_thd)(MYSQL * mysql); const char * (* read_statistics)(MYSQL * mysql); my_bool (* next_result)(MYSQL * mysql); int (* read_change_user_result)(MYSQL * mysql, char * buff, const char * passwd); int (* read_rows_from_cursor)(MYSQL_STMT * stmt); }>
st_mysql_options <C: struct st_mysql_options { unsigned int connect_timeout, read_timeout, write_timeout, port, protocol; unsigned long client_flag; char * host; char * user; char * password; char * unix_socket; char * db; struct st_dynamic_array * init_commands; char * my_cnf_file; char * my_cnf_group; char * charset_dir; char * charset_name; char * ssl_key; char * ssl_cert; char * ssl_ca; char * ssl_capath; char * ssl_cipher; char * shared_memory_base_name; unsigned long max_allowed_packet; my_bool use_ssl, compress, named_pipe, rpl_probe, rpl_parse, no_master_reads, separate_thread; enum mysql_option methods_to_use; char * client_ip; my_bool secure_auth, report_data_truncation; int (* local_infile_init)(void * * , const char * , void * ); int (* local_infile_read)(void * , char * , unsigned int); void (* local_infile_end)(void * ); int (* local_infile_error)(void * , char * , unsigned int); void * local_infile_userdata; }>
st_mysql_parameters <C: struct st_mysql_parameters { unsigned long * p_max_allowed_packet; unsigned long * p_net_buffer_length; }>
st_mysql_res <C: struct st_mysql_res { my_ulonglong row_count; MYSQL_FIELD * fields; MYSQL_DATA * data; MYSQL_ROWS * data_cursor; unsigned long * lengths; MYSQL * handle; MEM_ROOT field_alloc; unsigned int field_count, current_field; MYSQL_ROW row, current_row; my_bool eof, unbuffered_fetch_cancelled; const struct st_mysql_methods * methods; }>
st_mysql_rows <C: struct st_mysql_rows { struct st_mysql_rows * next; MYSQL_ROW data; unsigned long length; }>
st_mysql_stmt <C: struct st_mysql_stmt { MEM_ROOT mem_root; LIST list; MYSQL * mysql; MYSQL_BIND * params; MYSQL_BIND * bind; MYSQL_FIELD * fields; MYSQL_DATA result; MYSQL_ROWS * data_cursor; my_ulonglong affected_rows, insert_id; int (* read_row_func)(struct st_mysql_stmt * stmt, unsigned char * * row); unsigned long stmt_id, flags, prefetch_rows; unsigned int server_status, last_errno, param_count, field_count; enum enum_mysql_stmt_state state; char last_error[512]; char sqlstate[6]; my_bool send_types_to_server, bind_param_done; unsigned char bind_result_done; my_bool unbuffered_fetch_cancelled, update_max_length; }>
st_mysql_time <C: struct st_mysql_time { unsigned int year, month, day, hour, minute, second; unsigned long second_part; my_bool neg; enum enum_mysql_timestamp_type time_type; }>
st_net <C: struct st_net { Vio * vio; unsigned char * buff; unsigned char * buff_end; unsigned char * write_pos; unsigned char * read_pos; my_socket fd; unsigned long max_packet, max_packet_size; unsigned int pkt_nr, compress_pkt_nr, write_timeout, read_timeout, retry_count; int fcntl; my_bool compress; unsigned long remain_in_buf, length, buf_length, where_b; unsigned int * return_status; unsigned char reading_or_writing; char save_char; my_bool no_send_ok, no_send_eof, no_send_error; char last_error[512]; char sqlstate[6]; unsigned int last_errno; unsigned char error; gptr query_cache_query; my_bool report_error, return_errno; }>
st_typelib <C: struct st_typelib { unsigned int count; const char * name; const char * * type_names; unsigned int * type_lengths; }>
st_udf_args <C: struct st_udf_args { unsigned int arg_count; enum Item_result * arg_type; char * * args; unsigned long * lengths; char * maybe_null; char * * attributes; unsigned long * attribute_lengths; }>
st_udf_init <C: struct st_udf_init { my_bool maybe_null; unsigned int decimals; unsigned long max_length; char * ptr; my_bool const_item; }>
st_used_mem <C: struct st_used_mem { struct st_used_mem * next; unsigned int left, size; }>
st_vio <C: struct st_vio>
tm <C: struct tm { int tm_sec, tm_min, tm_hour, tm_mday, tm_mon, tm_year, tm_wday, tm_yday, tm_isdst; }>
_complex <C: struct _complex { double x, y; }>
_exception <C: struct _exception { int type; char * name; double arg1, arg2, retval; }>
_iobuf <C: struct _iobuf { char * _ptr; int _cnt; char * _base; int _flag, _file, _charbuf, _bufsiz; char * _tmpfname; }>
__fpos_t <C: struct __fpos_t { unsigned int lopart; int hipart; }>
</methods> <methods> Database.MySQLInterface <category>defines</category>
ALLOC_MAX_BLOCK_TO_DROP <C: #define ALLOC_MAX_BLOCK_TO_DROP 4096 >
ALLOC_MAX_BLOCK_USAGE_BEFORE_DROP <C: #define ALLOC_MAX_BLOCK_USAGE_BEFORE_DROP 10 >
ASCII_BITS_USED <C: #define ASCII_BITS_USED 8 >
AUTO_INCREMENT_FLAG <C: #define AUTO_INCREMENT_FLAG 512 >
BINARY_FLAG <C: #define BINARY_FLAG 128 >
BINCMP_FLAG <C: #define BINCMP_FLAG 131072 >
BLOB_FLAG <C: #define BLOB_FLAG 16 >
BUFSIZ <C: #define BUFSIZ 512 >
CLIENT_COMPRESS <C: #define CLIENT_COMPRESS 32 >
CLIENT_CONNECT_WITH_DB <C: #define CLIENT_CONNECT_WITH_DB 8 >
CLIENT_FOUND_ROWS <C: #define CLIENT_FOUND_ROWS 2 >
CLIENT_IGNORE_SIGPIPE <C: #define CLIENT_IGNORE_SIGPIPE 4096 >
CLIENT_IGNORE_SPACE <C: #define CLIENT_IGNORE_SPACE 256 >
CLIENT_INTERACTIVE <C: #define CLIENT_INTERACTIVE 1024 >
CLIENT_LOCAL_FILES <C: #define CLIENT_LOCAL_FILES 128 >
CLIENT_LONG_FLAG <C: #define CLIENT_LONG_FLAG 4 >
CLIENT_LONG_PASSWORD <C: #define CLIENT_LONG_PASSWORD 1 >
CLIENT_MULTI_QUERIES <C: #define CLIENT_MULTI_QUERIES CLIENT_MULTI_STATEMENTS >
CLIENT_MULTI_RESULTS <C: #define CLIENT_MULTI_RESULTS 131072 >
CLIENT_MULTI_STATEMENTS <C: #define CLIENT_MULTI_STATEMENTS 65536 >
CLIENT_NET_READ_TIMEOUT <C: #define CLIENT_NET_READ_TIMEOUT 365*24*3600 >
CLIENT_NET_WRITE_TIMEOUT <C: #define CLIENT_NET_WRITE_TIMEOUT 365*24*3600 >
CLIENT_NO_SCHEMA <C: #define CLIENT_NO_SCHEMA 16 >
CLIENT_ODBC <C: #define CLIENT_ODBC 64 >
CLIENT_PROTOCOL_41 <C: #define CLIENT_PROTOCOL_41 512 >
CLIENT_REMEMBER_OPTIONS <C: #define CLIENT_REMEMBER_OPTIONS (((ulong)1)<<31) >
CLIENT_RESERVED <C: #define CLIENT_RESERVED 16384 >
CLIENT_SECURE_CONNECTION <C: #define CLIENT_SECURE_CONNECTION 32768 >
CLIENT_SSL <C: #define CLIENT_SSL 2048 >
CLIENT_TRANSACTIONS <C: #define CLIENT_TRANSACTIONS 8192 >
CLOCKS_PER_SEC <C: #define CLOCKS_PER_SEC 1000 >
COMP_HEADER_SIZE <C: #define COMP_HEADER_SIZE 3 >
C_MODE_END <C: #define C_MODE_END >
C_MODE_START <C: #define C_MODE_START >
DBL_MAX <C: #define DBL_MAX 1.7976931348623d308 >
DBL_MIN <C: #define DBL_MIN 0.0d >
DBUG_FILE <C: #define DBUG_FILE (_db_fp_) >
DBUG_IN_USE <C: #define DBUG_IN_USE (_db_fp_&&_db_fp_!=stderr) >
DBUG_LEAVE <C: #define DBUG_LEAVE (_db_return_(__LINE__,&_db_func_,&_db_file_,&_db_level_)) >
DBUG_LOCK_FILE <C: #define DBUG_LOCK_FILE {_db_lock_file();} >
DBUG_UNLOCK_FILE <C: #define DBUG_UNLOCK_FILE {_db_unlock_file();} >
DBUG_VOID_RETURN <C: #define DBUG_VOID_RETURN {DBUG_LEAVE;return;} >
dbug_volatile <C: #define dbug_volatile volatile >
DEBUGGER_OFF <C: #define DEBUGGER_OFF _no_db_=1;_db_on_=0; >
DEBUGGER_ON <C: #define DEBUGGER_ON _no_db_=0 >
DONT_REMEMBER_SIGNAL <C: #define DONT_REMEMBER_SIGNAL >
E2BIG <C: #define E2BIG 7 >
EACCES <C: #define EACCES 13 >
EAGAIN <C: #define EAGAIN 11 >
EBADF <C: #define EBADF 9 >
EBUSY <C: #define EBUSY 16 >
ECHILD <C: #define ECHILD 10 >
EDEADLK <C: #define EDEADLK 36 >
EDEADLOCK <C: #define EDEADLOCK EDEADLK >
EDOM <C: #define EDOM 33 >
EEXIST <C: #define EEXIST 17 >
EFAULT <C: #define EFAULT 14 >
EFBIG <C: #define EFBIG 27 >
EILSEQ <C: #define EILSEQ 42 >
EINTR <C: #define EINTR 4 >
EINVAL <C: #define EINVAL 22 >
EIO <C: #define EIO 5 >
EISDIR <C: #define EISDIR 21 >
EMFILE <C: #define EMFILE 24 >
EMLINK <C: #define EMLINK 31 >
ENAMETOOLONG <C: #define ENAMETOOLONG 38 >
ENFILE <C: #define ENFILE 23 >
ENGLISH <C: #define ENGLISH 1 >
ENODEV <C: #define ENODEV 19 >
ENOENT <C: #define ENOENT 2 >
ENOEXEC <C: #define ENOEXEC 8 >
ENOLCK <C: #define ENOLCK 39 >
ENOMEM <C: #define ENOMEM 12 >
ENOSPC <C: #define ENOSPC 28 >
ENOSYS <C: #define ENOSYS 40 >
ENOTDIR <C: #define ENOTDIR 20 >
ENOTEMPTY <C: #define ENOTEMPTY 41 >
ENOTTY <C: #define ENOTTY 25 >
ENUM_FLAG <C: #define ENUM_FLAG 256 >
ENXIO <C: #define ENXIO 6 >
EOF <C: #define EOF (-1) >
EPERM <C: #define EPERM 1 >
EPIPE <C: #define EPIPE 32 >
ERANGE <C: #define ERANGE 34 >
EROFS <C: #define EROFS 30 >
ER_WARN_DATA_TRUNCATED <C: #define ER_WARN_DATA_TRUNCATED WARN_DATA_TRUNCATED >
ESPIPE <C: #define ESPIPE 29 >
ESRCH <C: #define ESRCH 3 >
EXDEV <C: #define EXDEV 18 >
FALSE <C: #define FALSE (0) >
FAR <C: #define FAR >
FIELD_TYPE_BIT <C: #define FIELD_TYPE_BIT MYSQL_TYPE_BIT >
FIELD_TYPE_BLOB <C: #define FIELD_TYPE_BLOB MYSQL_TYPE_BLOB >
FIELD_TYPE_CHAR <C: #define FIELD_TYPE_CHAR MYSQL_TYPE_TINY >
FIELD_TYPE_DATE <C: #define FIELD_TYPE_DATE MYSQL_TYPE_DATE >
FIELD_TYPE_DATETIME <C: #define FIELD_TYPE_DATETIME MYSQL_TYPE_DATETIME >
FIELD_TYPE_DECIMAL <C: #define FIELD_TYPE_DECIMAL MYSQL_TYPE_DECIMAL >
FIELD_TYPE_DOUBLE <C: #define FIELD_TYPE_DOUBLE MYSQL_TYPE_DOUBLE >
FIELD_TYPE_ENUM <C: #define FIELD_TYPE_ENUM MYSQL_TYPE_ENUM >
FIELD_TYPE_FLOAT <C: #define FIELD_TYPE_FLOAT MYSQL_TYPE_FLOAT >
FIELD_TYPE_GEOMETRY <C: #define FIELD_TYPE_GEOMETRY MYSQL_TYPE_GEOMETRY >
FIELD_TYPE_INT24 <C: #define FIELD_TYPE_INT24 MYSQL_TYPE_INT24 >
FIELD_TYPE_INTERVAL <C: #define FIELD_TYPE_INTERVAL MYSQL_TYPE_ENUM >
FIELD_TYPE_LONG <C: #define FIELD_TYPE_LONG MYSQL_TYPE_LONG >
FIELD_TYPE_LONGLONG <C: #define FIELD_TYPE_LONGLONG MYSQL_TYPE_LONGLONG >
FIELD_TYPE_LONG_BLOB <C: #define FIELD_TYPE_LONG_BLOB MYSQL_TYPE_LONG_BLOB >
FIELD_TYPE_MEDIUM_BLOB <C: #define FIELD_TYPE_MEDIUM_BLOB MYSQL_TYPE_MEDIUM_BLOB >
FIELD_TYPE_NEWDATE <C: #define FIELD_TYPE_NEWDATE MYSQL_TYPE_NEWDATE >
FIELD_TYPE_NEWDECIMAL <C: #define FIELD_TYPE_NEWDECIMAL MYSQL_TYPE_NEWDECIMAL >
FIELD_TYPE_NULL <C: #define FIELD_TYPE_NULL MYSQL_TYPE_NULL >
FIELD_TYPE_SET <C: #define FIELD_TYPE_SET MYSQL_TYPE_SET >
FIELD_TYPE_SHORT <C: #define FIELD_TYPE_SHORT MYSQL_TYPE_SHORT >
FIELD_TYPE_STRING <C: #define FIELD_TYPE_STRING MYSQL_TYPE_STRING >
FIELD_TYPE_TIME <C: #define FIELD_TYPE_TIME MYSQL_TYPE_TIME >
FIELD_TYPE_TIMESTAMP <C: #define FIELD_TYPE_TIMESTAMP MYSQL_TYPE_TIMESTAMP >
FIELD_TYPE_TINY <C: #define FIELD_TYPE_TINY MYSQL_TYPE_TINY >
FIELD_TYPE_TINY_BLOB <C: #define FIELD_TYPE_TINY_BLOB MYSQL_TYPE_TINY_BLOB >
FIELD_TYPE_VAR_STRING <C: #define FIELD_TYPE_VAR_STRING MYSQL_TYPE_VAR_STRING >
FIELD_TYPE_YEAR <C: #define FIELD_TYPE_YEAR MYSQL_TYPE_YEAR >
FILENAME_MAX <C: #define FILENAME_MAX 260 >
FILE_BINARY <C: #define FILE_BINARY O_BINARY >
FLT_MAX <C: #define FLT_MAX ((float)3.4028234663853d38) >
FLT_MIN <C: #define FLT_MIN ((float)1.4012984643248d-45) >
FN_CURLIB <C: #define FN_CURLIB 46 >
FN_DEVCHAR <C: #define FN_DEVCHAR 58 >
FN_EXTCHAR <C: #define FN_EXTCHAR 46 >
FN_EXTLEN <C: #define FN_EXTLEN 20 >
FN_HEADLEN <C: #define FN_HEADLEN 253 >
FN_HOMELIB <C: #define FN_HOMELIB 126 >
FN_LEN <C: #define FN_LEN 256 >
FN_LIBCHAR <C: #define FN_LIBCHAR 47 >
FN_PARENTDIR <C: #define FN_PARENTDIR ".." >
FN_REFLEN <C: #define FN_REFLEN 512 >
FN_ROOTDIR <C: #define FN_ROOTDIR "/" >
FOPEN_MAX <C: #define FOPEN_MAX 20 >
FRM_VER <C: #define FRM_VER 6 >
GROUP_FLAG <C: #define GROUP_FLAG 32768 >
HAVE_EXTERNAL_CLIENT <C: #define HAVE_EXTERNAL_CLIENT >
HAVE_MYSQL_REAL_CONNECT <C: #define HAVE_MYSQL_REAL_CONNECT >
HAVE_REPLICATION <C: #define HAVE_REPLICATION >
HAVE_UINT <C: #define HAVE_UINT >
HOSTNAME_LENGTH <C: #define HOSTNAME_LENGTH 60 >
HUGE_PTR <C: #define HUGE_PTR >
HUGE_VAL <C: #define HUGE_VAL _HUGE >
INT_MAX16 <C: #define INT_MAX16 32767 >
INT_MAX24 <C: #define INT_MAX24 0x007FFFFF >
INT_MAX32 <C: #define INT_MAX32 2147483647 >
INT_MAX8 <C: #define INT_MAX8 127 >
INT_MIN16 <C: #define INT_MIN16 (~32767) >
INT_MIN24 <C: #define INT_MIN24 (~0x007FFFFF) >
INT_MIN32 <C: #define INT_MIN32 (~2147483647) >
INT_MIN8 <C: #define INT_MIN8 (~127) >
INVALID_SOCKET <C: #define INVALID_SOCKET -1 >
IO_SIZE <C: #define IO_SIZE 4096 >
KEY_CACHE_BLOCK_SIZE <C: #define KEY_CACHE_BLOCK_SIZE (uint)1024 >
KEY_CACHE_SIZE <C: #define KEY_CACHE_SIZE (uint)(8*1024*1024-MALLOC_OVERHEAD) >
LICENSE <C: #define LICENSE GPL >
LOCAL_HOST <C: #define LOCAL_HOST "localhost" >
LOCAL_HOST_NAMEDPIPE <C: #define LOCAL_HOST_NAMEDPIPE "." >
LOCAL_INFILE_ERROR_LEN <C: #define LOCAL_INFILE_ERROR_LEN 512 >
L_tmpnam <C: #define L_tmpnam sizeof(_P_tmpdir)+12 >
MALLOC_OVERHEAD <C: #define MALLOC_OVERHEAD 8 >
MANAGER_ACCESS <C: #define MANAGER_ACCESS 401 >
MANAGER_CLIENT_ERR <C: #define MANAGER_CLIENT_ERR 450 >
MANAGER_INFO <C: #define MANAGER_INFO 250 >
MANAGER_INTERNAL_ERR <C: #define MANAGER_INTERNAL_ERR 500 >
MANAGER_OK <C: #define MANAGER_OK 200 >
MASTER <C: #define MASTER 1 >
max_allowed_packet <C: #define max_allowed_packet (*mysql_get_parameters()->p_max_allowed_packet) >
MAX_BIGINT_WIDTH <C: #define MAX_BIGINT_WIDTH 20 >
MAX_BLOB_WIDTH <C: #define MAX_BLOB_WIDTH 8192 >
MAX_CHAR_WIDTH <C: #define MAX_CHAR_WIDTH 255 >
MAX_INT_WIDTH <C: #define MAX_INT_WIDTH 10 >
MAX_MEDIUMINT_WIDTH <C: #define MAX_MEDIUMINT_WIDTH 8 >
MAX_MYSQL_MANAGER_ERR <C: #define MAX_MYSQL_MANAGER_ERR 256 >
MAX_MYSQL_MANAGER_MSG <C: #define MAX_MYSQL_MANAGER_MSG 256 >
MAX_SMALLINT_WIDTH <C: #define MAX_SMALLINT_WIDTH 5 >
MAX_TINYINT_WIDTH <C: #define MAX_TINYINT_WIDTH 3 >
MIN_ARRAY_SIZE <C: #define MIN_ARRAY_SIZE 0 >
MULTIPLE_KEY_FLAG <C: #define MULTIPLE_KEY_FLAG 8 >
MYSQL_BASE_VERSION <C: #define MYSQL_BASE_VERSION "mysqld-5.0" >
MYSQL_CLIENT <C: #define MYSQL_CLIENT >
MYSQL_COMPILATION_COMMENT <C: #define MYSQL_COMPILATION_COMMENT "MySQL Community Edition - Max (GPL)" >
MYSQL_CONFIG_NAME <C: #define MYSQL_CONFIG_NAME "my" >
MYSQL_COUNT_ERROR <C: #define MYSQL_COUNT_ERROR (~(my_ulonglong)0) >
MYSQL_DATA_TRUNCATED <C: #define MYSQL_DATA_TRUNCATED 101 >
MYSQL_ERRMSG_SIZE <C: #define MYSQL_ERRMSG_SIZE 512 >
mysql_library_end <C: #define mysql_library_end mysql_server_end >
mysql_library_init <C: #define mysql_library_init mysql_server_init >
MYSQL_LONG_DATA_HEADER <C: #define MYSQL_LONG_DATA_HEADER 6 >
MYSQL_NAMEDPIPE <C: #define MYSQL_NAMEDPIPE "MySQL" >
MYSQL_NO_DATA <C: #define MYSQL_NO_DATA 100 >
MYSQL_PORT <C: #define MYSQL_PORT 3306 >
MYSQL_SERVER_SUFFIX_DEF <C: #define MYSQL_SERVER_SUFFIX_DEF "-community-max-nt" >
MYSQL_SERVER_VERSION <C: #define MYSQL_SERVER_VERSION "5.0.22" >
MYSQL_SERVICENAME <C: #define MYSQL_SERVICENAME "MySQL" >
MYSQL_SHUTDOWN_KILLABLE_CONNECT <C: #define MYSQL_SHUTDOWN_KILLABLE_CONNECT (unsigned char)(1<<0) >
MYSQL_SHUTDOWN_KILLABLE_LOCK_TABLE <C: #define MYSQL_SHUTDOWN_KILLABLE_LOCK_TABLE (unsigned char)(1<<2) >
MYSQL_SHUTDOWN_KILLABLE_TRANS <C: #define MYSQL_SHUTDOWN_KILLABLE_TRANS (unsigned char)(1<<1) >
MYSQL_SHUTDOWN_KILLABLE_UPDATE <C: #define MYSQL_SHUTDOWN_KILLABLE_UPDATE (unsigned char)(1<<3) >
MYSQL_STMT_HEADER <C: #define MYSQL_STMT_HEADER 4 >
MYSQL_UNIVERSAL_CLIENT_CHARSET <C: #define MYSQL_UNIVERSAL_CLIENT_CHARSET MYSQL_DEFAULT_CHARSET_NAME >
MYSQL_UNIX_ADDR <C: #define MYSQL_UNIX_ADDR "/tmp/mysql.sock" >
MYSQL_VERSION_ID <C: #define MYSQL_VERSION_ID 50022 >
MY_FILEPOS_ERROR <C: #define MY_FILEPOS_ERROR (~(my_off_t)0) >
MY_HOW_OFTEN_TO_ALARM <C: #define MY_HOW_OFTEN_TO_ALARM 2 >
MY_HOW_OFTEN_TO_WRITE <C: #define MY_HOW_OFTEN_TO_WRITE 1000 >
MY_NFILE <C: #define MY_NFILE 64 >
M_E <C: #define M_E 2.718281828459d >
M_LN2 <C: #define M_LN2 0.69314718055995d >
M_PI <C: #define M_PI 3.1415926535898d >
NAME_LEN <C: #define NAME_LEN 64 >
NEAR <C: #define NEAR >
NEAR_F <C: #define NEAR_F >
NETWARE_YIELD <C: #define NETWARE_YIELD >
net_buffer_length <C: #define net_buffer_length (*mysql_get_parameters()->p_net_buffer_length) >
NET_HEADER_SIZE <C: #define NET_HEADER_SIZE 4 >
NET_READ_TIMEOUT <C: #define NET_READ_TIMEOUT 30 >
NET_WAIT_TIMEOUT <C: #define NET_WAIT_TIMEOUT 8*60*60 >
NET_WRITE_TIMEOUT <C: #define NET_WRITE_TIMEOUT 60 >
NOT_NULL_FLAG <C: #define NOT_NULL_FLAG 1 >
NO_DEFAULT_VALUE_FLAG <C: #define NO_DEFAULT_VALUE_FLAG 4096 >
NO_HASH <C: #define NO_HASH >
NULL <C: #define NULL ((void*)0) >
NullS <C: #define NullS (char*)0 >
NULL_LENGTH <C: #define NULL_LENGTH ((unsigned long)~0) >
NUM_FLAG <C: #define NUM_FLAG 32768 >
ONCE_ALLOC_INIT <C: #define ONCE_ALLOC_INIT (uint)(4096-MALLOC_OVERHEAD) >
ONLY_KILL_QUERY <C: #define ONLY_KILL_QUERY 1 >
OS_FILE_LIMIT <C: #define OS_FILE_LIMIT 65535 >
O_BINARY <C: #define O_BINARY 0 >
O_NOFOLLOW <C: #define O_NOFOLLOW 0 >
O_SHARE <C: #define O_SHARE 0 >
O_SHORT_LIVED <C: #define O_SHORT_LIVED 0 >
O_TEMPORARY <C: #define O_TEMPORARY 0 >
packet_error <C: #define packet_error (~(unsigned long)0) >
PART_KEY_FLAG <C: #define PART_KEY_FLAG 16384 >
POSIX_MISTAKE <C: #define POSIX_MISTAKE 1 >
PRI_KEY_FLAG <C: #define PRI_KEY_FLAG 2 >
PROTOCOL_VERSION <C: #define PROTOCOL_VERSION 10 >
qsort_t <C: #define qsort_t RETQSORTTYPE >
RECORD_CACHE_SIZE <C: #define RECORD_CACHE_SIZE (uint)(64*1024-MALLOC_OVERHEAD) >
REFRESH_DES_KEY_FILE <C: #define REFRESH_DES_KEY_FILE 262144 >
REFRESH_FAST <C: #define REFRESH_FAST 32768 >
REFRESH_GRANT <C: #define REFRESH_GRANT 1 >
REFRESH_HOSTS <C: #define REFRESH_HOSTS 8 >
REFRESH_LOG <C: #define REFRESH_LOG 2 >
REFRESH_MASTER <C: #define REFRESH_MASTER 128 >
REFRESH_QUERY_CACHE <C: #define REFRESH_QUERY_CACHE 65536 >
REFRESH_QUERY_CACHE_FREE <C: #define REFRESH_QUERY_CACHE_FREE 131072 >
REFRESH_READ_LOCK <C: #define REFRESH_READ_LOCK 16384 >
REFRESH_SLAVE <C: #define REFRESH_SLAVE 64 >
REFRESH_STATUS <C: #define REFRESH_STATUS 16 >
REFRESH_TABLES <C: #define REFRESH_TABLES 4 >
REFRESH_THREADS <C: #define REFRESH_THREADS 32 >
REFRESH_USER_RESOURCES <C: #define REFRESH_USER_RESOURCES 524288 >
reg1 <C: #define reg1 register >
reg10 <C: #define reg10 register >
reg11 <C: #define reg11 register >
reg12 <C: #define reg12 register >
reg13 <C: #define reg13 register >
reg14 <C: #define reg14 register >
reg15 <C: #define reg15 register >
reg16 <C: #define reg16 register >
reg2 <C: #define reg2 register >
reg3 <C: #define reg3 register >
reg4 <C: #define reg4 register >
reg5 <C: #define reg5 register >
reg6 <C: #define reg6 register >
reg7 <C: #define reg7 register >
reg8 <C: #define reg8 register >
reg9 <C: #define reg9 register >
SCALE_SEC <C: #define SCALE_SEC 100 >
SCALE_USEC <C: #define SCALE_USEC 10000 >
SCRAMBLED_PASSWORD_CHAR_LENGTH <C: #define SCRAMBLED_PASSWORD_CHAR_LENGTH (SCRAMBLE_LENGTH*2+1) >
SCRAMBLED_PASSWORD_CHAR_LENGTH_323 <C: #define SCRAMBLED_PASSWORD_CHAR_LENGTH_323 (SCRAMBLE_LENGTH_323*2) >
SCRAMBLE_LENGTH <C: #define SCRAMBLE_LENGTH 20 >
SCRAMBLE_LENGTH_323 <C: #define SCRAMBLE_LENGTH_323 8 >
SC_MAXWIDTH <C: #define SC_MAXWIDTH 256 >
SEEK_CUR <C: #define SEEK_CUR 1 >
SEEK_END <C: #define SEEK_END 2 >
SEEK_SET <C: #define SEEK_SET 0 >
SERVER_MORE_RESULTS_EXISTS <C: #define SERVER_MORE_RESULTS_EXISTS 8 >
SERVER_QUERY_NO_GOOD_INDEX_USED <C: #define SERVER_QUERY_NO_GOOD_INDEX_USED 16 >
SERVER_QUERY_NO_INDEX_USED <C: #define SERVER_QUERY_NO_INDEX_USED 32 >
SERVER_STATUS_AUTOCOMMIT <C: #define SERVER_STATUS_AUTOCOMMIT 2 >
SERVER_STATUS_CURSOR_EXISTS <C: #define SERVER_STATUS_CURSOR_EXISTS 64 >
SERVER_STATUS_DB_DROPPED <C: #define SERVER_STATUS_DB_DROPPED 256 >
SERVER_STATUS_IN_TRANS <C: #define SERVER_STATUS_IN_TRANS 1 >
SERVER_STATUS_LAST_ROW_SENT <C: #define SERVER_STATUS_LAST_ROW_SENT 128 >
SERVER_STATUS_MORE_RESULTS <C: #define SERVER_STATUS_MORE_RESULTS 4 >
SERVER_STATUS_NO_BACKSLASH_ESCAPES <C: #define SERVER_STATUS_NO_BACKSLASH_ESCAPES 512 >
SERVER_VERSION_LENGTH <C: #define SERVER_VERSION_LENGTH 60 >
SET_FLAG <C: #define SET_FLAG 2048 >
sig_handler <C: #define sig_handler RETSIGTYPE >
SOCKET_EADDRINUSE <C: #define SOCKET_EADDRINUSE EADDRINUSE >
SOCKET_EAGAIN <C: #define SOCKET_EAGAIN EAGAIN >
SOCKET_EINTR <C: #define SOCKET_EINTR EINTR >
SOCKET_EMFILE <C: #define SOCKET_EMFILE EMFILE >
SOCKET_ENFILE <C: #define SOCKET_ENFILE ENFILE >
socket_errno <C: #define socket_errno errno >
SOCKET_ETIMEDOUT <C: #define SOCKET_ETIMEDOUT SOCKET_EINTR >
SOCKET_EWOULDBLOCK <C: #define SOCKET_EWOULDBLOCK EWOULDBLOCK >
SOCKOPT_OPTLEN_TYPE <C: #define SOCKOPT_OPTLEN_TYPE size_socket >
SQLSTATE_LENGTH <C: #define SQLSTATE_LENGTH 5 >
STDCALL <C: #define STDCALL __stdcall >
stderr <C: #define stderr (&_iob[2]) >
stdin <C: #define stdin (&_iob[0]) >
stdout <C: #define stdout (&_iob[1]) >
SUCCESS <C: #define SUCCESS 0 >
SYSTEM_SIZEOF_OFF_T <C: #define SYSTEM_SIZEOF_OFF_T SIZEOF_OFF_T >
TIMESTAMP_FLAG <C: #define TIMESTAMP_FLAG 1024 >
TMP_MAX <C: #define TMP_MAX 32767 >
TRUE <C: #define TRUE (1) >
UINT_MAX16 <C: #define UINT_MAX16 65535 >
UINT_MAX24 <C: #define UINT_MAX24 0x00FFFFFF >
UINT_MAX32 <C: #define UINT_MAX32 4294967295 >
UINT_MAX8 <C: #define UINT_MAX8 255 >
UNIQUE_FLAG <C: #define UNIQUE_FLAG 65536 >
UNIQUE_KEY_FLAG <C: #define UNIQUE_KEY_FLAG 4 >
UNSIGNED_FLAG <C: #define UNSIGNED_FLAG 32 >
UNSINT16 <C: #define UNSINT16 >
UNSINT32 <C: #define UNSINT32 >
UNSINT8 <C: #define UNSINT8 >
USERNAME_LENGTH <C: #define USERNAME_LENGTH 16 >
USER_HOST_BUFF_SIZE <C: #define USER_HOST_BUFF_SIZE HOSTNAME_LENGTH+USERNAME_LENGTH+2 >
USE_BMOVE512 <C: #define USE_BMOVE512 1 >
USE_MYFUNC <C: #define USE_MYFUNC 1 >
USE_REGEX <C: #define USE_REGEX 1 >
WEOF <C: #define WEOF (wint_t)(65535) >
ZEROFILL_FLAG <C: #define ZEROFILL_FLAG 64 >
_cabsl <C: #define _cabsl _cabs >
_CLOCK_T_DEFINED <C: #define _CLOCK_T_DEFINED >
_COMPLEX_DEFINED <C: #define _COMPLEX_DEFINED >
_CRTAPI1 <C: #define _CRTAPI1 >
_CRTIMP <C: #define _CRTIMP >
_dbug_h <C: #define _dbug_h >
_DOMAIN <C: #define _DOMAIN 1 >
_EXCEPTION_DEFINED <C: #define _EXCEPTION_DEFINED >
_FILE_DEFINED <C: #define _FILE_DEFINED >
_FPOS_T_DEFINED <C: #define _FPOS_T_DEFINED >
_global_h <C: #define _global_h >
_INC_ERRNO <C: #define _INC_ERRNO >
_INC_MATH <C: #define _INC_MATH >
_INC_STDIO <C: #define _INC_STDIO >
_INC_TIME <C: #define _INC_TIME >
_IOEOF <C: #define _IOEOF 0x0010 >
_IOERR <C: #define _IOERR 0x0020 >
_IOFBF <C: #define _IOFBF 0x0000 >
_IOLBF <C: #define _IOLBF 0x0040 >
_IOMYBUF <C: #define _IOMYBUF 0x0008 >
_IONBF <C: #define _IONBF 0x0004 >
_IOREAD <C: #define _IOREAD 0x0001 >
_IORW <C: #define _IORW 0x0080 >
_IOSTRG <C: #define _IOSTRG 0x0040 >
_IOWRT <C: #define _IOWRT 0x0002 >
_list_h_ <C: #define _list_h_ >
_matherrl <C: #define _matherrl _matherr >
_mysql_com_h <C: #define _mysql_com_h >
_mysql_h <C: #define _mysql_h >
_mysql_time_h_ <C: #define _mysql_time_h_ >
_mysql_version_h <C: #define _mysql_version_h >
_my_alloc_h <C: #define _my_alloc_h >
_NFILE <C: #define _NFILE _NSTREAM_ >
_NSTREAM_ <C: #define _NSTREAM_ 20 >
_OVERFLOW <C: #define _OVERFLOW 3 >
_PLOSS <C: #define _PLOSS 6 >
_P_tmpdir <C: #define _P_tmpdir "\\" >
_SING <C: #define _SING 2 >
_SIZE_T_DEFINED <C: #define _SIZE_T_DEFINED >
_STDIO_DEFINED <C: #define _STDIO_DEFINED >
_SYS_OPEN <C: #define _SYS_OPEN 20 >
_TIME_T_DEFINED <C: #define _TIME_T_DEFINED >
_TLOSS <C: #define _TLOSS 5 >
_TM_DEFINED <C: #define _TM_DEFINED >
_typelib_h <C: #define _typelib_h >
_UNDERFLOW <C: #define _UNDERFLOW 4 >
_VA_LIST_DEFINED <C: #define _VA_LIST_DEFINED >
_WCHAR_T_DEFINED <C: #define _WCHAR_T_DEFINED >
_WCTYPE_T_DEFINED <C: #define _WCTYPE_T_DEFINED >
_WIN32 <C: #define _WIN32 >
_wP_tmpdir <C: #define _wP_tmpdir L "\\" >
_WSTDIO_DEFINED <C: #define _WSTDIO_DEFINED >
_WTIME_DEFINED <C: #define _WTIME_DEFINED >
__cdecl <C: #define __cdecl >
__DATE__ <C: #define __DATE__ "June 26, 2006" >
__EXTENSIONS__ <C: #define __EXTENSIONS__ 1 >
__FILE__ <C: #define __FILE__ >
__LINE__ <C: #define __LINE__ 0 >
__STDC_EXT__ <C: #define __STDC_EXT__ 1 >
__STDC__ <C: #define __STDC__ 1 >
__TIME__ <C: #define __TIME__ "9:20:02 pm" >
__WIN__ <C: #define __WIN__ >
</methods> <methods> Database.MySQLInterface <category>variables</category>
errno <C: int errno>
errno: aValue <C: int errno>
mysql_port <C: unsigned int mysql_port>
mysql_port: aValue <C: unsigned int mysql_port>
mysql_unix_port <C: char * mysql_unix_port>
mysql_unix_port: aValue <C: char * mysql_unix_port>
sql_protocol_typelib <C: TYPELIB sql_protocol_typelib>
sql_protocol_typelib: aValue <C: TYPELIB sql_protocol_typelib>
_daylight <C: int _daylight>
_daylight: aValue <C: int _daylight>
_db_fp_ <C: FILE * _db_fp_>
_db_fp_: aValue <C: FILE * _db_fp_>
_db_on_ <C: int _db_on_>
_db_on_: aValue <C: int _db_on_>
_db_process_ <C: char * _db_process_>
_db_process_: aValue <C: char * _db_process_>
_dstbias <C: long _dstbias>
_dstbias: aValue <C: long _dstbias>
_HUGE <C: double _HUGE>
_HUGE: aValue <C: double _HUGE>
_iob <C: FILE _iob[]>
_iob: aValue <C: FILE _iob[]>
_no_db_ <C: int _no_db_>
_no_db_: aValue <C: int _no_db_>
_timezone <C: long _timezone>
_timezone: aValue <C: long _timezone>
_tzname <C: char * _tzname[2]>
_tzname: aValue <C: char * _tzname[2]>
</methods> <methods> Database.MySQLInterface <category>accessing</category>
decimalSize "65 digits, plus a sign and decimal makes 67." ^67
isBlobType: aMySQLType ^self class blobTypes includes: aMySQLType
isCharacterType: aMySQLType "The type is based on character (byte) arrays." ^self class characterTypes includes: aMySQLType
isIntegerType: aMySQLType ^self class integerTypes includes: aMySQLType
isLongType: aMySQLType ^self class longTypes includes: aMySQLType
isStringType: aMySQLType ^self class stringTypes includes: aMySQLType
isTimeType: aMySQLType ^self class timeTypes includes: aMySQLType
isValidCPointer: aCPointerOrNil "Return true only if aCPointerOrNil is a valid pointer." ^(aCPointerOrNil notNil) and: [aCPointerOrNil isValid]
mallocSelector ^#gcMalloc:
signedFromUnsignedLong: anUnsignedLong "Convert an unsigned long long value to a signed value." | pUnsignedLong pSignedLong | pUnsignedLong := anUnsignedLong gcCopyToHeap. pSignedLong := CIntegerType signedLong pointerType cast: pUnsignedLong. ^pSignedLong contents
signedFromUnsignedLongLong: anUnsignedLongLong "Convert an unsigned long long value to a signed value." | pUnsignedLongLong pSignedLongLong | pUnsignedLongLong := anUnsignedLongLong gcCopyToHeap. pSignedLongLong := CIntegerType signedLongLong pointerType cast: pUnsignedLongLong. ^pSignedLongLong contents
typeNameFor: aTypenumber self error: 'This should not be used.'. ^self class fieldTypesToTypenamesMap at: aTypenumber
typeNumberFor: aTypenameSymbol " ^self class fieldTypenamesToTypesMap at: aTypenameSymbol" | fieldTypes | fieldTypes := self enum_field_types. ^fieldTypes memberNamed: aTypenameSymbol
</methods> <methods> Database.MySQLInterface <category>accessing-enums</category>
timeType: aSymbol " Valid symbols are those contained in the enum: MYSQL_TIMESTAMP_NONE = -2, MYSQL_TIMESTAMP_ERROR, MYSQL_TIMESTAMP_DATE, MYSQL_TIMESTAMP_DATETIME, MYSQL_TIMESTAMP_TIME MYSQL_TIMESTAMP_DATE" ^enum_mysql_timestamp_type memberNamed: aSymbol
</methods> <methods> Database.MySQLInterface class <category>private - accessing</category>
blobTypes "Return a Set of databaseType numbers for BLOB types. Note that for MYSQL, a BLOB or String column, if not binary, represents TEXT data. Therefore, one needs to check the type and the binary flag to see if a buffer holds byte or char data." ^BlobTypes
characterTypes "Return the set of all StringTypes and all BlobTypes. If a column type is in CharacterTypes, it can be either binary or not." ^CharacterTypes
integerTypes "Return a Set of databaseType numbers for Integer types." ^IntegerTypes
longTypes ^LongTypes
stringTypes "Return a Set of databaseType numbers for VARCHAR and String types. Note that for MYSQL, a BLOB or String column, if not binary, represents TEXT data. Therefore, one needs to check the type and the binary flag to see if a buffer holds byte or char data." ^StringTypes
timeTypes ^TimeTypes
</methods> <methods> Database.MySQLInterface class <category>accessing</category>
fieldTypenamesToTypesMap FieldTypenamesToTypesMap isNil ifTrue: [self initializeMaps]. ^FieldTypenamesToTypesMap
fieldTypesToTypenamesMap FieldTypesToTypenamesMap isNil ifTrue: [self initializeMaps]. ^FieldTypesToTypenamesMap
</methods> <methods> Database.MySQLInterface class <category>class initialization</category>
initialize "MySQLInterface initialize" self initializeMaps
initializeMaps "MySQLInterface initializeMaps" | xif | xif := self new. "Build dictionary of type-name -> enum value. (The xif gave us an enum instead of #defines.) Eg., #MYSQL_TYPE_TINY_BLOB -> 249" FieldTypenamesToTypesMap := IdentityDictionary new. xif enum_field_types keysAndValuesDo: [:key :value | FieldTypenamesToTypesMap at: key put: value]. "Build dictionary of enum value -> type-name. (The xif gave us an enum instead of #defines.) Eg., 249 -> #MYSQL_TYPE_TINY_BLOB" FieldTypesToTypenamesMap := IdentityDictionary new. xif enum_field_types keysAndValuesDo: [:key :value | FieldTypesToTypenamesMap at: value put: key]. "TINYBLOB is 2^8-1, BLOB is 2^16-1, MEDIUMBLOB is 2^24-1, LONGBLOB is 2^32-1. TEXT types have same mysqlType as BLOBs, but isBinary is false for TEXT." LongTypes := (Set new) add: (xif typeNumberFor: #MYSQL_TYPE_MEDIUM_BLOB); add: (xif typeNumberFor: #MYSQL_TYPE_LONG_BLOB); yourself. "These are the Integer types 8-, 16-, 32- and 64-bits." IntegerTypes := (Set new) add: (xif typeNumberFor: #MYSQL_TYPE_TINY); add: (xif typeNumberFor: #MYSQL_TYPE_SHORT); add: (xif typeNumberFor: #MYSQL_TYPE_INT24); add: (xif typeNumberFor: #MYSQL_TYPE_LONG); add: (xif typeNumberFor: #MYSQL_TYPE_LONGLONG); yourself. "These are the time column types." TimeTypes := (Set new) add: (xif typeNumberFor: #MYSQL_TYPE_TIME); add: (xif typeNumberFor: #MYSQL_TYPE_DATE); add: (xif typeNumberFor: #MYSQL_TYPE_DATETIME); add: (xif typeNumberFor: #MYSQL_TYPE_TIMESTAMP); add: (xif typeNumberFor: #MYSQL_TYPE_YEAR); yourself. "These are the String types, but BLOB types can also have TEXT data." StringTypes := (Set new) add: (xif typeNumberFor: #MYSQL_TYPE_STRING); add: (xif typeNumberFor: #MYSQL_TYPE_VAR_STRING); yourself. "These are the Blob types, but String types can also have binary data." BlobTypes := (Set new) add: (xif typeNumberFor: #MYSQL_TYPE_TINY_BLOB); add: (xif typeNumberFor: #MYSQL_TYPE_BLOB); add: (xif typeNumberFor: #MYSQL_TYPE_MEDIUM_BLOB); add: (xif typeNumberFor: #MYSQL_TYPE_LONG_BLOB); yourself. CharacterTypes := (Set new) addAll: StringTypes; addAll: BlobTypes; yourself.
</methods> <methods> Database.MySQLInterface class <category>private</category>
platformSymbol "this must contain the platform symbol that will match that returned by determinePlatformType." "platform symbols known today include: #nt Windows/NT #win95 Windows95 #hp_unix HP/UX #sun5_unix Solaris #aix_unix AIX #alpha_unix DEC/Unix #os2 OS/2 #powermac Power Mac #mac Mac 68K #linux_i386_unix Linux #linux_x86_64_unix Linux 64-bit #unix_sysV_sun_solaris64 Solaris 64-bit" ^#unknown
</methods> <methods> Database.MySQLBuffer <category>accessing</category>
at: anIndex "Answer the object in the buffer at anIndex." ^(pIsNull contents = true) ifTrue: [ nil ] ifFalse: [ self perform: getSelector with: anIndex ]
at: anIndex put: anObject "Store anObject into the buffer at anIndex." anObject isNil ifTrue: [pIsNull contents: true] ifFalse: [pIsNull contents: false. self perform: putSelector with: anIndex with: anObject]. ^anObject
isBinary ^isBinary
isUnsigned ^isUnsigned
maxBufferSizeNeeded ^maxDbDatumLength
smalltalkType ^smalltalkType
wasDataTruncated ^maxDbDatumLength > elementSize
</methods> <methods> Database.MySQLBuffer <category>private-data conversion {get}</category>
get64BitsAt: index "MySQL 64-bit Set data type is retrieved as an 8-byte ByteArray. Return a MySQLSet, or ByteArray, based on the flag." | byteArray | byteArray := self getByteArrayAt: index. ^self class useSetsFor64Bits ifTrue: [MySQLBitfield newFromMySQLByteArray: byteArray] ifFalse: [byteArray]
getByteArrayAt: index "Answer a ByteArray populated from the buffer. MySQL tells us the length required to retrieve all of this datum, so that we can resize our buffer and try again, if we so wish. Keep track of the maximum for this column so far." | numBytes byteArray dbDatumLength | dbDatumLength := (pLength contents). maxDbDatumLength := maxDbDatumLength max: dbDatumLength. numBytes := elementSize min: dbDatumLength. byteArray := ByteArray new: numBytes. bufferPointer copyAt: (index -1) to: byteArray size: numBytes startingAt: 1. ^byteArray
getDateAt: index ^self getTimestampAt: index
getDoubleAt: index "Answer a Double populated from the buffer." "Assume: bufferPointer points to at least 8 bytes in the heap." | conversionBuffer | conversionBuffer := UninterpretedBytes new: 8. bufferPointer copyAt: (index -1) to: conversionBuffer size: 8 startingAt: 1. ^conversionBuffer doubleAt: 1
getFixedPointAt: index "Answer a FixedPoint number populated from the buffer" | numBytes str | numBytes := pLength contents. str := ByteString new: numBytes. bufferPointer copyAt: (index -1) to: str size: numBytes startingAt: 1. "Change E to e to help Fixedpoint conversion." str := str copyReplaceAll: 'E' with: 'e'. ^FixedPoint readFrom: str readStream
getFloatAt: index "Answer a float populated from the buffer." "Assume: bufferPointer points to at least 4 bytes in the heap." | conversionBuffer | conversionBuffer := UninterpretedBytes new: 4. bufferPointer copyAt: (index -1) to: conversionBuffer size: 4 startingAt: 1. ^conversionBuffer floatAt: 1
getInt16At: index "Answer a 16-bit, signed or unsigned, Integer populated from the buffer." "Assume: bufferPointer points to at least 4 bytes in the heap." | conversionBuffer | conversionBuffer := UninterpretedBytes new: 2. bufferPointer copyAt: (index -1) to: conversionBuffer size: 2 startingAt: 1. ^self isUnsigned ifTrue: [conversionBuffer unsignedShortAt: 1] ifFalse: [conversionBuffer shortAt: 1]
getInt24At: index "Answer a 24-bit signed or unsigned Integer populated from the buffer. Assume: bufferPointer points to at least 3 bytes in the heap. If the column is signed, determine the sign bit (msb, 3rd byte) and extend it through the 4th byte." | conversionBuffer | conversionBuffer := UninterpretedBytes new: 4. conversionBuffer byteAt: 4 put: 16r00. bufferPointer copyAt: index - 1 to: conversionBuffer size: 3 startingAt: 1. ^self isUnsigned ifTrue: [conversionBuffer unsignedLongAt: 1] ifFalse: [((conversionBuffer byteAt: 3) bitAnd: 16r80) = 0 ifFalse: [conversionBuffer byteAt: 4 put: 16rFF]. conversionBuffer longAt: 1]
getInt32At: index "Answer a 32-bit signed or unsigned Integer populated from the buffer." "Assume: bufferPointer points to at least 4 bytes in the heap." | conversionBuffer | conversionBuffer := UninterpretedBytes new: 4. bufferPointer copyAt: index - 1 to: conversionBuffer size: 4 startingAt: 1. ^self isUnsigned ifTrue: [conversionBuffer unsignedLongAt: 1] ifFalse: [conversionBuffer longAt: 1]
getInt64At: index "Answer a 64-bit, signed or unsigned, Integer populated from the buffer." "Assume: bufferPointer points to at least 4 bytes in the heap." | conversionBuffer | conversionBuffer := UninterpretedBytes new: 8. bufferPointer copyAt: (index -1) to: conversionBuffer size: 8 startingAt: 1. ^self isUnsigned ifTrue: [conversionBuffer unsignedLongLongAt: 1] ifFalse: [conversionBuffer longLongAt: 1]
getInt8At: index "Answer an 8-bit char, signed or unsigned, populated from the buffer." "Assume: bufferPointer points to at least 4 bytes in the heap." | conversionBuffer | conversionBuffer := UninterpretedBytes new: 1. bufferPointer copyAt: (index -1) to: conversionBuffer size: 1 startingAt: 1. ^self isUnsigned ifTrue: [conversionBuffer byteAt: 1] ifFalse: [conversionBuffer signedByteAt: 1]
getStringAt: index "If I am Binary, then return a byteArray. Otherwise, a String populated from the buffer with my encoding." | byteArray | byteArray := self getByteArrayAt: index. ^self isBinary ifTrue: [byteArray] ifFalse: [byteArray asStringEncoding: self encoding]
getTimeAt: index ^self getTimestampAt: index
getTimestampAt: index ^self getTimeStructAt: index
getTimeStructAt: index "Return the correspoinding Smalltalk time type from the retrieved structure. The type, as determined from a flag in the struct, is Date, Time, or Timestamp, or nil. Negative time values are currently not supported, and result in an error. Note that mysql uses hour=24 when vw uses hour=0, which is a fixed up here." | xif timeStructPtr year month day hour minute second neg time_type timestamp data | xif := session xif. timeStructPtr := xif MYSQL_TIME pointerType cast: bufferPointer. year := timeStructPtr memberAt: #year. month := timeStructPtr memberAt: #month. day := timeStructPtr memberAt: #day. hour := timeStructPtr memberAt: #hour. minute := timeStructPtr memberAt: #minute. second := timeStructPtr memberAt: #second. "second_part := timeStructPtr memberAt: #second_part. Not used in MySQL 5.03" neg := timeStructPtr memberAt: #neg. "Indicates that this time is negative." time_type := timeStructPtr memberAt: #time_type. timestamp := (Timestamp new) year: year; month: month; day: day; hour: (hour \\ 24); minute: minute; second: second. data := nil. (time_type = (xif timeType: #MYSQL_TIMESTAMP_ERROR)) ifTrue: [self error: 'Bad timestamp contents']. neg = xif TRUE ifTrue: [self error: 'Negative time value']. (time_type = (xif timeType: #MYSQL_TIMESTAMP_NONE)) ifTrue: [data := nil]. "= -2" (time_type = (xif timeType: #MYSQL_TIMESTAMP_DATE)) ifTrue: [data := timestamp asDate]. (time_type = (xif timeType: #MYSQL_TIMESTAMP_DATETIME)) ifTrue: [data := timestamp]. (time_type = (xif timeType: #MYSQL_TIMESTAMP_TIME)) ifTrue: [data := timestamp asTime]. ^data
getYearAt: index ^self getInt16At: index
</methods> <methods> Database.MySQLBuffer <category>testing</category>
canHold: aValue "For input buffers (send data to db). Can we re-use this buffer? Return true if this buffer has the correct type and is big enough to hold aValue." | elemSize | ^((self smalltalkType = (self smalltalkTypeForValue: aValue)) and: [self databaseType = (self databaseTypeForSmalltalkType: smalltalkType)]) ifTrue: [elemSize := self class sizesOfFixedSmalltalkTypes at: smalltalkType ifAbsent: [self elementSizeFor: aValue asType: smalltalkType]. elemSize ifNil: [self error: 'Bad type.'] ifNotNil: [elemSize <= self elementSize]]
isLong "Answer true if the receiver represents a long result column." ^false
</methods> <methods> Database.MySQLBuffer <category>private-data conversion {put}</category>
at: index put64Bits: aByteArray "Copy the 8-byte array to the buffer. Append zeros for missing trailing bytes." "Assume: bufferPointer points to at least 8 bytes in the heap." | conversionBuffer | pLength contents: 8. conversionBuffer := aByteArray , #[0 0 0 0 0 0 0 0] copyFrom: 1 to: 8. bufferPointer copyAt: index - 1 from: conversionBuffer size: 8 startingAt: 1. ^aByteArray
at: index putBoolean: aBoolean "Set the buffer to hold an encoded bit." "pIsNull contents == self class connectionClass xif TRUE" self at: index putInt8: (aBoolean ifTrue: [1] ifFalse: [0]). ^aBoolean
at: index putByteArray: aByteArray "Copy the byte array to the buffer." | len | len := aByteArray size. len > elementSize ifTrue: [ self class connectionClass unableToBindSignal raise ]. pLength contents: len. bufferPointer copyAt: index - 1 from: aByteArray size: len startingAt: 1. ^aByteArray
at: index putDate: aDate "Convert to a timestamp, and apply to db." self at: index putTimestamp: aDate asTimestamp. ^aDate
at: index putDouble: aDouble "Answer a Double populated from the buffer." "Assume: bufferPointer points to at least 8 bytes in the heap." | conversionBuffer | pLength contents: 8. conversionBuffer := UninterpretedBytes new: 8. conversionBuffer doubleAt: 1 put: aDouble. bufferPointer copyAt: (index -1) from: conversionBuffer size: 8 startingAt: 1. ^aDouble
at: index putFixedPoint: aFixedPoint "Put a string version of aFixedPoint, without the trailng $s into the buffer." | strm byteArray | strm := (String new: 40) writeStream. aFixedPoint printOn: strm. strm skip: -1. byteArray := strm contents asByteArray. self at: index putByteArray: byteArray. ^aFixedPoint
at: index putFloat: aFloat "Answer a Double populated from the buffer." "Assume: bufferPointer points to at least 8 bytes in the heap." | conversionBuffer | pLength contents: 4. conversionBuffer := UninterpretedBytes new: 4. conversionBuffer floatAt: 1 put: aFloat. bufferPointer copyAt: (index -1) from: conversionBuffer size: 4 startingAt: 1. ^aFloat
at: index putInt16: anInteger "Put anInteger into the buffer" | conversionBuffer | pLength contents: 2. conversionBuffer := UninterpretedBytes new: 2. conversionBuffer shortAt: 1 put: anInteger. bufferPointer copyAt: (index -1) from: conversionBuffer size: 2 startingAt: 1. ^anInteger
at: index putInt32: anInteger "Put anInteger into the buffer" | conversionBuffer | pLength contents: 4. conversionBuffer := UninterpretedBytes new: 4. conversionBuffer longAt: 1 put: anInteger. bufferPointer copyAt: (index -1) from: conversionBuffer size: 4 startingAt: 1. ^anInteger
at:index putInt64: aLargeInteger "Unused. Instead, LargeInteger now maps as a FixedPoint. Assume: bufferPointer points to at least 8 bytes in the heap." | conversionBuffer | pLength contents: 8. conversionBuffer := UninterpretedBytes new: 8. conversionBuffer longLongAt: 1 put: aLargeInteger. bufferPointer copyAt: (index -1) from: conversionBuffer size: 8 startingAt: 1. ^aLargeInteger
at: index putInt8: anInteger "Put anInteger into the buffer" | conversionBuffer | pLength contents: 1. conversionBuffer := UninterpretedBytes new: 1. conversionBuffer byteAt: 1 put: anInteger. bufferPointer copyAt: (index -1) from: conversionBuffer size: 1 startingAt: 1. ^anInteger
at: index putLargeInteger: aLargeInteger "LargeInteger now maps as a FixedPoint (databasetype), which is transfered as a ByteArray." | strm byteArray | strm := (String new: 40) writeStream. aLargeInteger printOn: strm. byteArray := strm contents asByteArray. self at: index putByteArray: byteArray. ^aLargeInteger
at: index putMySQLBitfield: aSet "Convert the set to an 8-byte ByteArray, and input this." | ba | ba := aSet asMySQLByteArray. self at: index putByteArray: ba. ^aSet
at: index putString: aString "Put aString into the buffer, as a ByteArray. If isBinary is true, then the input var is already a ByteArray." | aByteArray | aByteArray := self isBinary ifTrue: [aString asByteArray] ifFalse: [aString asByteArrayEncoding: self encoding]. self at: index putByteArray: aByteArray. ^aString
at: index putTime: aTime "Convert to a timestamp, and apply to db." self at: index putTimestamp: aTime asTimestamp. ^aTime
at: index putTimestamp: aTimestamp "Return the correspoinding Smalltalk time type from the retrieved structure. The type, as determined from a flag in the struct, is Date, Time, or Timestamp, or nil. Negative time values are currently not supported, and result in an error." | xif timeStructPtr time_type | xif := session xif. pLength contents: elementSize. time_type := xif timeType: #MYSQL_TIMESTAMP_DATETIME. timeStructPtr := xif MYSQL_TIME pointerType cast: bufferPointer. timeStructPtr memberAt: #year put: aTimestamp year. timeStructPtr memberAt: #month put: aTimestamp month. timeStructPtr memberAt: #day put: aTimestamp day. timeStructPtr memberAt: #hour put: aTimestamp hour. timeStructPtr memberAt: #minute put: aTimestamp minute. timeStructPtr memberAt: #second put: aTimestamp second. timeStructPtr memberAt: #second_part put: 0. "Not used in MySQL 5.03" timeStructPtr memberAt: #neg put: 0. "(0 (false) Indicates that this time is not negative." timeStructPtr memberAt: #time_type put: time_type. ^aTimestamp
</methods> <methods> Database.MySQLBuffer <category>binding</category>
bindForInputValue: aValue "Setup the receiver to hold the object being sent to the api." "We won't re-use pointers." self free. "Allocate external CPointers." self mallocUsingSelector: session class xif mallocSelector. self value: aValue. "Now give the session pointers to my data objects. Session will pass them on in a MYSQL_BIND array." self bindInputExternal
bindForOutput "Setup the receiver to hold the contents of a single column." "We won't re-use pointers." self free. "Allocate external CPointers." self mallocUsingSelector: session class xif mallocSelector. "Now give the session pointers to my data objects. Session will pass them on in a MYSQL_BIND array." self bindOutputExternal
rebindForInput "Bind contents of the receiver to the server." self bindInputExternal.
</methods> <methods> Database.MySQLBuffer <category>allocation</category>
free "Free the main bufferPointer, owned by super, and our other pointers. Note: use CPointer>>free, since it is more robust than >>freePointer, which is disastrous if the pointer was gcMalloc'd." bufferPointer notNil ifTrue: [bufferPointer free. bufferPointer := nil]. pLength notNil ifTrue: [pLength free. pLength := nil]. pIsNull notNil ifTrue: [pIsNull free. pIsNull := nil]. pError notNil ifTrue: [pError free. pError := nil]. super free
mallocUsingSelector: mallocSelector "Allocate pointers (bufferPointer allocated elsewhere) and assign default values." super mallocUsingSelector: mallocSelector. pLength := CIntegerType unsignedLong perform: mallocSelector with: 1. pIsNull := CIntegerType booleanChar perform: mallocSelector with: 1. pError := CIntegerType booleanChar perform: mallocSelector with: 1. pLength contents: 0. pIsNull contents: true. pError contents: true.
</methods> <methods> Database.MySQLBuffer <category>private-binding</category>
bindExternal: aMYSQL_BIND "Connect this buffer to send parameter data. Get the MYSQL_BIND array from my session, and put these items in it at the correct index. My data, refered to by these pointers, will be read by the api for input, and read and updated by the api for output." aMYSQL_BIND memberAt: #length put: pLength; memberAt: #buffer put: bufferPointer; memberAt: #error put: pError; memberAt: #is_null put: pIsNull; memberAt: #buffer_type put: databaseType; memberAt: #buffer_length put: elementSize
bindInputExternal "Connect this buffer to send parameter data. Get the MYSQL_BIND array from my session, and put these items in it at the correct index. My data, refered to by these pointers, will be accepted by the api." | aMYSQL_BIND | aMYSQL_BIND := session inputBufferPtrsArrayRefAt: bufferIndex - 1. self bindExternal: aMYSQL_BIND
bindOutputExternal "Connect this buffer to receive column data. Get the MYSQL_BIND array from my session, and put these items in it at the correct index. My data, refered to by these pointers, will be updated by the api." | aMYSQL_BIND | aMYSQL_BIND := session outputBufferPtrsArrayRefAt: bufferIndex - 1. self bindExternal: aMYSQL_BIND
</methods> <methods> Database.MySQLBuffer <category>private-accessing</category>
databaseTypeForSmalltalkType: aSmalltalkType "Return the MySQL database type number corresponding to the St type." ^self class smalltalkToMySQLTypesMap at: aSmalltalkType
determineGetSelector "Based on my databaseType, use default getSelector. If my data is Binary, use a blob selector (byteArray). If my data is Unsigned, use an unsigned integer selector." | map selector | map := self class defaultTypesGetSelectorMap. selector := map at: databaseType ifAbsent: [session class connectionClass unableToDescribeSignal raiseRequestErrorString: #unknownDatabaseType << #mysql >> 'Unknown database type']. ^selector
determinePutSelector "Based on my smalltalkType, use default putSelector. If my data is Binary, use a blob selector (byteArray). If my data is Unsigned, use an unsigned integer selector." | map selector | map := self class defaultTypesPutSelectorMap. selector := map at: smalltalkType ifAbsent: [session class connectionClass unableToDescribeSignal raiseRequestErrorString: #unknownDatabaseType << #mysql >> 'Unknown database type']. ^selector
elementSizeFor: aValue asType: aSmalltalkType "This method is used when sending data to the api (Input). We need to know the number of bytes to allocate to hold the object (bufferPointer). String and ByteArray types get a size equal to their length+1 for null terminators. FixedPoint and LargeIntegers are input as DECIMAL type, passed as a string. Other types have size equal to their MySQL C-language type representations." | aByteArray | ^(#(#String #LargeString #ByteArray #LargeByteArray) includes: aSmalltalkType) ifTrue: [aValue ifNotNil: [aByteArray := (#(#String #LargeString) includes: aSmalltalkType) ifTrue: [aValue asByteArrayEncoding: self encoding] ifFalse: [aValue asByteArray]. aByteArray size+1] ifNil: [1]] ifFalse: [(#(#FixedPoint #LargeInteger) includes: aSmalltalkType) ifTrue: [self class xif decimalSize + 1 ]]
encodingForCollationId: aCollationId "Return the Smalltalk encoding name (a symbol) based on the MySQL collation id." ^(self class connectionClass encodingForCollationId: aCollationId) ifNil: [session class connectionClass unableToDescribeSignal raiseRequestErrorString: #unknownCollationId << #mysql >> 'Unknown character encoding collation id.']
reUse: aValue "Re-use this buffer for an object with the same mapped database type, and same or smaller size." (self canHold: aValue) ifFalse: [self class connectionClass unableToBindSignal raise]. self value: aValue. self rebindForInput
smalltalkTypeForDatabaseType: aDatabaseType "Return the Smalltalk type corresponding to the MySQL database type number." ^self class mySQLToSmalltalkTypesMap at: aDatabaseType
smalltalkTypeForValue: aValue ^aValue isNil ifTrue: [#String] ifFalse: [aValue mysqlConversion]
</methods> <methods> Database.MySQLBuffer <category>initialize-release</category>
columnDescription: aColDesc position: position session: aSession "Initialize an instance of receiver which is set up to hold values as described.f We don't receive arrays, so allocCount is always 1. elemSize is set to the max_length field, if it is available for this type. If charsetnr = 63, then it is a binary object (eg., number, BINARY, VARBINARY, BLOB)." | elemSize enc | maxDbDatumLength := 0. databaseType := aColDesc mysqlType. smalltalkType := self smalltalkTypeForDatabaseType: databaseType. isNullable := aColDesc nullable. isBinary := aColDesc charsetnr = 63. isUnsigned := aColDesc isUnsigned. elemSize := self class sizesOfFixedDatabaseTypes at: databaseType ifAbsent: [aSession maxLongData min: (aColDesc precision max: aColDesc maxColumnConstraint) + 2]. bufferIndex := position. session := aSession. enc := self encodingForCollationId: aColDesc charsetnr. self encoding: enc. getSelector := self determineGetSelector. putSelector := self determinePutSelector. self elementSize: elemSize count: 0 databaseType: databaseType
on: aValue position: position session: aSession "Initialize an instance of receiver which is set up to hold aValue. This method does not remember the actual value, but gets ready for it. Note: the databaseType is the type of data that we are sending--not necessarily the type of the destination column. The api will translate for us." | elemSize | count := 0. smalltalkType := self smalltalkTypeForValue: aValue. databaseType := self databaseTypeForSmalltalkType: smalltalkType. bufferIndex := position. session := aSession. isNullable := true. isUnsigned := false. isBinary := #(#ByteArray with: #LargeByteArray) includes: smalltalkType. self encoding: session connection encoding. elemSize := self class sizesOfFixedSmalltalkTypes at: smalltalkType ifAbsent: [self elementSizeFor: aValue asType: smalltalkType]. elemSize ifNil: [self error: 'Bad type.']. getSelector := self determineGetSelector. putSelector := self determinePutSelector. self elementSize: elemSize count: 0 databaseType: databaseType
</methods> <methods> Database.MySQLBuffer class <category>accessing</category>
connectionClass ^MySQLConnection
largeObjectBufferClass "Currently, there is no dedicated LargeObject buffer class. MySQL allows INSERTing data piecewise (in a loop), but it does not allow SELECTing data that way. It's all fetched in a single chunk. So, for now, there is no special large buffer, and we insert and select using a single chunk." ^MySQLBuffer
useSetsFor64Bits "If True, return a 64-bit Set (a MySQL column type) object to a Smalltalk Set. If False, return such an object as an 8-byte ByteArray." ^UseSetsForMySQL64BitSets
useSetsFor64Bits: aBoolean "If True, return a 64-bit Set (a MySQL column type) object to a Smalltalk Set. If False, return such an object as an 8-byte ByteArray." ^UseSetsForMySQL64BitSets := aBoolean
xif "Answer an instance of the ExternalInterface." ^self connectionClass xif
</methods> <methods> Database.MySQLBuffer class <category>private-accessing</category>
defaultTypesGetSelectorMap ^DefaultTypesGetSelectorMap
defaultTypesPutSelectorMap ^DefaultTypesPutSelectorMap
mySQLToSmalltalkTypesMap ^MySQLToSmalltalkTypesMap
sizesOfFixedDatabaseTypes ^SizesOfFixedDatabaseTypes
sizesOfFixedSmalltalkTypes ^SizesOfFixedSmalltalkTypes
smalltalkToMySQLTypesMap ^SmalltalkToMySQLTypesMap
</methods> <methods> Database.MySQLBuffer class <category>filein/fileout</category>
prerequisitesForLoading "The receiver requires MySQLConnection to have initialized its interface mapping before it initializes." ^super prerequisitesForLoading addLast: MySQLConnection; addLast: MySQLInterface; yourself
</methods> <methods> Database.MySQLBuffer class <category>private-activation</category>
install
</methods> <methods> Database.MySQLBuffer class <category>class initialization</category>
initialize "MySQLBuffer initialize" self install. self initializeSelectorsMap. self initializeTypesMap. self initializeSizesMap. UseSetsForMySQL64BitSets := true
initializeSelectorsMap | xif | xif := self xif. "This map shows what databaseType to use for a given Smalltalk type." "Use the xif's dictionary of type-name put: enum value. These are the usual types, unless the Binary or Unsigned flag is set. MYSQL_TYPE_STRING implies CHAR or BINARY column type. MYSQL_TYPE_VAR_STRING implies VARCHAR or VARBINARY column type. MYSQL_TYPE_BLOB implies TEXT or BLOB column type. If charsetnr = 63, then it is a binary (#ByteArray) column, otherwise it is a character (#String) column." (DefaultTypesGetSelectorMap := IdentityDictionary new) at: (xif typeNumberFor: #MYSQL_TYPE_BIT) put: #get64BitsAt:; at: (xif typeNumberFor: #MYSQL_TYPE_TINY) put: #getInt8At:; at: (xif typeNumberFor: #MYSQL_TYPE_SHORT) put: #getInt16At:; at: (xif typeNumberFor: #MYSQL_TYPE_INT24) put: #getInt24At:; at: (xif typeNumberFor: #MYSQL_TYPE_LONG) put: #getInt32At:; at: (xif typeNumberFor: #MYSQL_TYPE_LONGLONG) put: #getInt64At:; at: (xif typeNumberFor: #MYSQL_TYPE_FLOAT) put: #getFloatAt:; at: (xif typeNumberFor: #MYSQL_TYPE_DOUBLE) put: #getDoubleAt:; at: (xif typeNumberFor: #MYSQL_TYPE_NEWDECIMAL) put: #getFixedPointAt:; at: (xif typeNumberFor: #MYSQL_TYPE_TIME) put: #getTimeAt:; at: (xif typeNumberFor: #MYSQL_TYPE_DATE) put: #getDateAt:; at: (xif typeNumberFor: #MYSQL_TYPE_DATETIME) put: #getTimestampAt:; at: (xif typeNumberFor: #MYSQL_TYPE_TIMESTAMP) put: #getTimestampAt:; at: (xif typeNumberFor: #MYSQL_TYPE_YEAR) put: #getYearAt:; at: (xif typeNumberFor: #MYSQL_TYPE_STRING) put: #getStringAt:; at: (xif typeNumberFor: #MYSQL_TYPE_VAR_STRING) put: #getStringAt:; at: (xif typeNumberFor: #MYSQL_TYPE_TINY_BLOB) put: #getStringAt:; at: (xif typeNumberFor: #MYSQL_TYPE_BLOB) put: #getStringAt:; at: (xif typeNumberFor: #MYSQL_TYPE_MEDIUM_BLOB) put: #getStringAt:; at: (xif typeNumberFor: #MYSQL_TYPE_LONG_BLOB) put: #getStringAt:. "This map shows what put-selector to use for a given Smalltalk type." (DefaultTypesPutSelectorMap := IdentityDictionary new) at: #String put: #at:putString:; at: #ByteArray put: #at:putByteArray:; at: #LargeString put: #at:putString:; at: #LargeByteArray put: #at:putByteArray:; at: #MySQLBitfield put: #at:putMySQLBitfield:; "The set should have integer elements within 1..64" at: #Integer put: #at:putInt32:; at: #LargeInteger put: #at:putLargeInteger:; at: #Timestamp put: #at:putTimestamp:; at: #Date put: #at:putDate:; at: #Time put: #at:putTime:; at: #FixedPoint put: #at:putFixedPoint:; at: #Double put: #at:putDouble:; at: #Float put: #at:putFloat:; at: #Boolean put: #at:putBoolean:
initializeSizesMap "These are the fixed-size types, and their sizes, used for moving data to/from the db. Note that the integer types are all assinged 4-bytes length, even though they range from 1, 2, 3 and 4 bytes length. So, 4 bytes is an adequate buffer size for each, although long long (64-bits) is granted 8 bytes. STRING, VARCHAR, BLOB and NEWDECIMAL are variable-sized. For variable-sized input data (from the db), we can determine necessary buffer size using the precision field in the columDescription object." | xif | xif := self xif. "Used for output data (SELECT)." (SizesOfFixedDatabaseTypes := IdentityDictionary new) at: (xif typeNumberFor: #MYSQL_TYPE_TINY) put: CIntegerType long sizeof; at: (xif typeNumberFor: #MYSQL_TYPE_SHORT) put: CIntegerType long sizeof; at: (xif typeNumberFor: #MYSQL_TYPE_INT24) put: CIntegerType long sizeof; at: (xif typeNumberFor: #MYSQL_TYPE_LONG) put: CIntegerType long sizeof; at: (xif typeNumberFor: #MYSQL_TYPE_LONGLONG) put: CIntegerType signedLongLong sizeof; at: (xif typeNumberFor: #MYSQL_TYPE_DATETIME) put: xif MYSQL_TIME sizeof; at: (xif typeNumberFor: #MYSQL_TYPE_DATE) put: xif MYSQL_TIME sizeof; at: (xif typeNumberFor: #MYSQL_TYPE_TIME) put: xif MYSQL_TIME sizeof; at: (xif typeNumberFor: #MYSQL_TYPE_TIMESTAMP) put: xif MYSQL_TIME sizeof; at: (xif typeNumberFor: #MYSQL_TYPE_YEAR) put: CIntegerType long sizeof; at: (xif typeNumberFor: #MYSQL_TYPE_DOUBLE) put: CLimitedPrecisionRealType double sizeof; at: (xif typeNumberFor: #MYSQL_TYPE_FLOAT) put: CLimitedPrecisionRealType float sizeof; at: (xif typeNumberFor: #MYSQL_TYPE_BIT) put: CIntegerType unsignedChar sizeof * 8. "SizesOfFixedSmalltalkTypes (sttype -> size). Used for input data (INSERT)." (SizesOfFixedSmalltalkTypes := IdentityDictionary new) at: #Boolean put: CIntegerType long sizeof; at: #Double put: CLimitedPrecisionRealType double sizeof; at: #Time put: xif MYSQL_TIME sizeof; at: #Integer put: CIntegerType long sizeof; at: #Date put: xif MYSQL_TIME sizeof; at: #Timestamp put: xif MYSQL_TIME sizeof; at: #MySQLBitfield put: CIntegerType unsignedChar sizeof * 8; at: #Float put: CLimitedPrecisionRealType float sizeof.
initializeTypesMap "Note that LargeInteger maps to NEWDECIMAL, since it can exceed the 64-bits of LONGLONG." | xif | xif := self xif. "This map shows what databaseType to use for a given Smalltalk type." (SmalltalkToMySQLTypesMap := IdentityDictionary new) at: #String put: (xif typeNumberFor: #MYSQL_TYPE_STRING); at: #ByteArray put: (xif typeNumberFor: #MYSQL_TYPE_BLOB); at: #LargeString put: (xif typeNumberFor: #MYSQL_TYPE_STRING); at: #LargeByteArray put: (xif typeNumberFor: #MYSQL_TYPE_BLOB); at: #MySQLBitfield put: (xif typeNumberFor: #MYSQL_TYPE_BLOB); at: #Integer put: (xif typeNumberFor: #MYSQL_TYPE_LONG); at: #LargeInteger put: (xif typeNumberFor: #MYSQL_TYPE_BLOB); at: #Timestamp put: (xif typeNumberFor: #MYSQL_TYPE_DATETIME); at: #Date put: (xif typeNumberFor: #MYSQL_TYPE_DATE); at: #Time put: (xif typeNumberFor: #MYSQL_TYPE_TIME); at: #FixedPoint put: (xif typeNumberFor: #MYSQL_TYPE_BLOB); at: #Double put: (xif typeNumberFor: #MYSQL_TYPE_DOUBLE); at: #Float put: (xif typeNumberFor: #MYSQL_TYPE_FLOAT); at: #Boolean put: (xif typeNumberFor: #MYSQL_TYPE_TINY). "This map shows what Smalltalk to use with a given databaseType type." (MySQLToSmalltalkTypesMap := IdentityDictionary new) at: (xif typeNumberFor: #MYSQL_TYPE_BIT) put: #MySQLBitfield; at: (xif typeNumberFor: #MYSQL_TYPE_TINY) put: #Integer; at: (xif typeNumberFor: #MYSQL_TYPE_SHORT) put: #Integer; at: (xif typeNumberFor: #MYSQL_TYPE_INT24) put: #Integer; at: (xif typeNumberFor: #MYSQL_TYPE_LONG) put: #Integer; at: (xif typeNumberFor: #MYSQL_TYPE_LONGLONG) put: #LargeInteger; at: (xif typeNumberFor: #MYSQL_TYPE_FLOAT) put: #Float; at: (xif typeNumberFor: #MYSQL_TYPE_DOUBLE) put: #Double; at: (xif typeNumberFor: #MYSQL_TYPE_NEWDECIMAL) put: #FixedPoint; at: (xif typeNumberFor: #MYSQL_TYPE_TIME) put: #Time; at: (xif typeNumberFor: #MYSQL_TYPE_DATE) put: #Date; at: (xif typeNumberFor: #MYSQL_TYPE_DATETIME) put: #Timestamp; at: (xif typeNumberFor: #MYSQL_TYPE_TIMESTAMP) put: #Timestamp; at: (xif typeNumberFor: #MYSQL_TYPE_YEAR) put: #Integer; at: (xif typeNumberFor: #MYSQL_TYPE_STRING) put: #String; at: (xif typeNumberFor: #MYSQL_TYPE_VAR_STRING) put: #String; at: (xif typeNumberFor: #MYSQL_TYPE_TINY_BLOB) put: #ByteArray; at: (xif typeNumberFor: #MYSQL_TYPE_BLOB) put: #ByteArray; at: (xif typeNumberFor: #MYSQL_TYPE_MEDIUM_BLOB) put: #ByteArray; at: (xif typeNumberFor: #MYSQL_TYPE_LONG_BLOB) put: #LargeByteArray.
</methods> <methods> Database.MySQLHybridSession <category>data processing</category>
answer ^self activeSession answer
cancel ^self activeSession cancel
connect "Send this message to both of my sessions." regularSession connect. adminSession connect
disconnect "Send this message to both of my sessions." regularSession disconnect. adminSession disconnect
execute ^self activeSession execute
maxBufferSizeNeededDuringQuery "Of all my buffers, return the largest size necessary for un-truncated retrieval." ^self activeSession maxBufferSizeNeededDuringQuery
maxLongData "Return the maximum amount of data to be copied from LONGVARCHAR or LONGVARBINARY columns." ^self activeSession maxLongData
prepare: aString "Prepare a query string for processing. Decide here and only here which session to use for this query." usingAdmin := self isAnAdminQuery: aString. ^self activeSession prepare: aString
rowCount "Answer an Integer representing the number of rows affected by the previous query. For INSERT, UPDATE statements, it is the number of rows actually updated. For SELECT statements, it is the number of rows returned. Valid only after the query has been answered." ^self activeSession rowCount
setMaxLongData: anInteger "Specify the maximum amount of data to be copied from LONGVARCHAR or LONGVARBINARY columns. Send this message to both of my sessions." regularSession setMaxLongData: anInteger. adminSession setMaxLongData: anInteger
</methods> <methods> Database.MySQLHybridSession <category>printing</category>
printOn: aStream "Append to the argument aStream a sequence of characters that identifies the receiver." super printOn: aStream. regularSession printOn: aStream. adminSession printOn: aStream.
</methods> <methods> Database.MySQLHybridSession <category>private-accessing</category>
activeSession "Return the session being used for the current query, or the most recent query." ^usingAdmin ifTrue: [adminSession] ifFalse: [regularSession]
adminSessionClass ^MySQLAdminSession
connection: aConnection "Set the connection in which receiver should execute. Send this message to both of my sessions." regularSession connection: aConnection. adminSession connection: aConnection.
regularSessionClass ^MySQLSession
</methods> <methods> Database.MySQLHybridSession <category>accessing</category>
allocateForEachRow ^self activeSession allocateForEachRow
allocateForEachRow: aBoolean "Specify whether the answer stream should create a copy of the output bind object to hold each row." regularSession allocateForEachRow: aBoolean. adminSession allocateForEachRow: aBoolean
bindInput "Answer the object from which input values will be obtained for host variable references in the SQL text. Note: adminSession doesn't do input binding, but can accept the message." ^self activeSession bindInput
bindInput: aBindObject "Note: adminSession doesn't do input binding, but can accept the message." regularSession bindInput: aBindObject. adminSession bindInput: aBindObject
bindOutput "Answer the bind object used for returned rows." ^self activeSession bindOutput
bindOutput: aBindObject "Specify the bind object used for returned rows." regularSession bindOutput: aBindObject. adminSession bindOutput: aBindObject
bindOutputIndexed: aBindObject "Specify the bind object used for returned rows. aBindObject may have either instance variables or indexed variables; if both are present, the indexed variables are used." regularSession bindOutputIndexed: aBindObject. adminSession bindOutputIndexed: aBindObject
bindOutputNamed: aBindObject "Specify the bind object used for returned rows." regularSession bindOutputNamed: aBindObject. adminSession bindOutputNamed: aBindObject
blockFactor "Answer the blocking factor for using buffers to accelerate fetching of row data." ^self activeSession blockFactor
blockFactor: aSmallInteger "Specify the blocking factor to use when fetching of row data." regularSession blockFactor: aSmallInteger. adminSession blockFactor: aSmallInteger
query "Answer SQL text for this session." ^self activeSession query
</methods> <methods> Database.MySQLHybridSession <category>private-testing</category>
isAnAdminQuery: aString "Return true if aString needs a MySQLAdminSession, i.e., it begins with any of these: #('CREATE DATABASE' 'CREATE PROCEDURE' 'CREATE FUNCTION' 'CREATE USER' 'CALL' 'USE' 'GRANT' 'SHOW GRANT' 'DROP DATABASE' 'DROP PROCEDURE' 'DROP FUNCTION' 'DROP USER')." | noSpaces templates | templates := #('CREATEDATABASE' 'CREATEPROCEDURE' 'CREATEFUNCTION' 'CALL' 'USE' 'GRANT' 'SHOWGRANT' 'DROPDATABASE' 'DROPPROCEDURE' 'DROPFUNCTION' 'DROPUSER'). noSpaces := aString asUppercase copyWithout: $ . ^(templates detect: [:template | (noSpaces indexOfSubCollection: template startingAt: 1) = 1] ifNone: [nil]) notNil
</methods> <methods> Database.MySQLHybridSession <category>testing</category>
isReady "Answer a boolean for whether processing has completed and an answer is ready." ^self activeSession isReady
useNamedOutputBinding "Answer true if the session is using named output binding" ^self activeSession useNamedOutputBinding
</methods> <methods> Database.MySQLHybridSession <category>initialize-release</category>
initialize regularSession := (self regularSessionClass basicNew) initialize. adminSession := (self adminSessionClass basicNew) initialize. usingAdmin := false
</methods> <methods> Database.MySQLHybridSession class <category>accessing</category>
connectionClass "Answer the class to use for connection objects associated with receiver." ^MySQLHybridConnection
defaultConnection ^(MySQLHybridConnection new) username: 'root'; password: 'user'; environment: 'localhost'
</methods> <methods> Database.MySQLHybridSession class <category>private-instance creation</category>
newForConnection: aConnection "Answer a new ExternalDatabaseSession associated with aConnection." | req | (req := self basicNew) initialize. req connection: aConnection. ^req
</methods> <methods> Database.MySQLAdminBuffer <category>accessing</category>
copyFromPointer: aPointer length: numBytes "Copy the ByteArray from the pointer, and assign to myself. If aPoiner is nil, NULL (or invalid), assign myself nil." | ba len | (self class xif isValidCPointer: aPointer) ifTrue: [maxDbDatumLength := maxDbDatumLength max: numBytes. len := numBytes min: session maxLongData. ba := ByteArray new: len. aPointer copyAt: 0 to: ba size: len startingAt: 1]. self value: ba
encoding ^encoding
isBinary ^isBinary
isByteArray "Return true only for columns which are character based, and binary. Numeric and other types claim to be binary, but are returned as strings." ^(self class xif isCharacterType: databaseType) and: [self isBinary]
isNull ^isNull
isUnsigned ^isUnsigned
value "Answer the buffer value, converted to a string if it is not binary or nil." ^self isNull ifTrue: [nil] ifFalse: [self isByteArray ifTrue: [byteArray] ifFalse: [self encoding = #binary ifTrue: [byteArray asString] ifFalse: [byteArray asStringEncoding: self encoding]]]
</methods> <methods> Database.MySQLAdminBuffer <category>private-accessing</category>
encodingForCollationId: aCollationId "Return the Smalltalk encoding name (a symbol) based on the MySQL collation id." ^(self class connectionClass encodingForCollationId: aCollationId) ifNil: [session class connectionClass unableToDescribeSignal raiseRequestErrorString: #unknownCollationId << #mysql >> 'Unknown character encoding collation id.']
free "We don't have any allocated memory, but we must implement this method as part of the expected buffer protocol."
isIntegerBased ^self class xif isIntegerType: databaseType
value: aByteArrayOrNil byteArray := aByteArrayOrNil. length := aByteArrayOrNil size. isNull := aByteArrayOrNil isNil
</methods> <methods> Database.MySQLAdminBuffer <category>summary-accessing</category>
maxBufferSizeNeeded "This method should only be called after the entire result set has been read. It returns the size of the largest datum retrieved." ^maxDbDatumLength
wasDataTruncated "This method should only be called after the entire result set has been read. It returns true if one or more retrieved data exceeded the allowed size." ^maxDbDatumLength > session maxLongData
</methods> <methods> Database.MySQLAdminBuffer <category>initialize-release</category>
columnDescription: aColDesc position: position session: aSession "Initialize an instance of receiver which is set up to hold byteArrray values. If charsetnr = 63, then it is a binary object (eg., number, BINARY, VARBINARY, BLOB)." maxDbDatumLength := 0. databaseType := aColDesc mysqlType. isNullable := aColDesc nullable. isBinary := aColDesc charsetnr = 63. isUnsigned := aColDesc isUnsigned. bufferIndex := position. session := aSession. encoding := self encodingForCollationId: aColDesc charsetnr. databaseType := databaseType. self value: nil
</methods> <methods> Database.MySQLAdminBuffer class <category>accessing</category>
connectionClass ^MySQLConnection
xif "Answer an instance of the ExternalInterface." ^self connectionClass xif
</methods> <methods> Database.MySQLAdminBuffer class <category>filein/fileout</category>
prerequisitesForLoading "The receiver requires MySQLConnection to have initialized its interface mapping before it initializes." ^super prerequisitesForLoading addLast: MySQLConnection; addLast: MySQLInterface; yourself
</methods> <methods> Database.MySQLAdminBuffer class <category>class initialization</category>
initialize "MySQLCharacterBuffer initialize" self install
</methods> <methods> Database.MySQLAdminBuffer class <category>private-activation</category>
install "OracleConnection is64Bit ifTrue: [ Unsigned32BitIntType := CIntegerType unsignedInt. Signed32BitIntType := CIntegerType signedInt. ] ifFalse: [ Unsigned32BitIntType := CIntegerType unsignedLong. Signed32BitIntType := CIntegerType signedLong. ]. DefaultDoublePointerType := CLimitedPrecisionRealType double pointerType. DefaultFloatPointerType := CLimitedPrecisionRealType float pointerType. DefaultLongPointerType := Signed32BitIntType pointerType. DefaultShortPointerType := CIntegerType short pointerType. DefaultUnsignedCharPointerType := CIntegerType unsignedChar pointerType. DefaultUnsignedShortPointerType := CIntegerType unsignedShort pointerType. OracleConnection platformType == #win32s ifTrue: [DefaultDoublePointerType beFar. DefaultFloatPointerType beFar. DefaultLongPointerType beFar. DefaultShortPointerType beFar. DefaultUnsignedCharPointerType beFar. DefaultUnsignedShortPointerType beFar]."
</methods> <methods> Database.MySQLBitfield <category>private-mysql</category>
mysqlConversion ^#MySQLBitfield
</methods> <methods> Database.MySQLBitfield <category>private</category>
asByteArray "MySQL 64-bit Set data type is retrieved as an 8-byte ByteArray. Note that the MySQL object is limited to the bits 0..63 (ints 1..64). The convention used here is that lowest order bit of the lowest order byte comes first (Corresponds to self add: 1)" | byteArray byteNum bitNum byte mask zeroBasedItem | byteArray := ByteArray new: 8 withAll: 0. self do: [:item | zeroBasedItem := item - 1. byteNum := zeroBasedItem // 8 + 1. bitNum := zeroBasedItem \\ 8. byte := byteArray at: byteNum. mask := 2r00000001 bitShift: bitNum. byteArray at: byteNum put: (byte bitOr: mask)]. ^byteArray
asMySQLByteArray "Reverse the array, since MySQL wants high order bits at the beginning of the array." ^self asByteArray reverse.
asSet ^(Set new) addAll: self; yourself
</methods> <methods> Database.MySQLBitfield <category>adding</category>
add: newObject "If newObject is an integer in [1..64], then add it." ^(newObject class == SmallInteger and: [1 <= newObject and: [newObject <= 64]]) ifTrue: [super add: newObject] ifFalse: [self error: 'Added element must be an integer in 1..64']
</methods> <methods> Database.MySQLBitfield class <category>instance creation</category>
newFrom8ByteArray: aByteArray "MySQL 64-bit Set data type is retrieved as an 8-byte ByteArray. Note that the closest Smalltalk type is Set, but the MySQL object is limited to the integers 1..64 (or perhaps 0..63). The convention used here is that lowest order bit of the lowest order byte comes first (Corresponds to Set new add: 1)" | mySet byte mask | mySet := MySQLBitfield new. 1 to: (aByteArray size min: 8) do: [:byteNum | byte := aByteArray at: byteNum. 1 to: 8 do: [:bitNum | mask := 2r00000001 bitShift: bitNum - 1. (byte bitAnd: mask) = 0 ifFalse: [mySet add: (byteNum - 1) * 8 + bitNum]]]. ^mySet
newFromMySQLByteArray: aByteArray "The convention used by MySQL is to reverse byte ordering. So, #[0 1 2 3 4 5 6 7 8] has low-order byte value = 8." ^MySQLBitfield newFrom8ByteArray: (aByteArray reverse).
</methods> <methods> Database.MySQLBitfield class <category>converting</category>
leftPaddArray: aByteArray "Padd the input with 0s up to length 8." ^aByteArray size < 8 ifTrue: [(#[0 0 0 0 0 0 0 0] copyFrom: 1 to: 8 - aByteArray size), aByteArray] ifFalse: [aByteArray]
paddArray: aByteArray "Padd the input with 0s up to length 8." ^aByteArray size < 8 ifTrue: [(#[0 0 0 0 0 0 0 0] copyFrom: 1 to: 8 - aByteArray size), aByteArray] ifFalse: [aByteArray]
</methods> <methods> Database.MySQLTransaction <category>private-library calls</category>
acquireExternal ^self
beginExternal ^self
commitExternal ^self
dismissExternal ^self
rollbackExternal ^self
</methods> <methods> Database.MySQLTransaction <category>private-finalization</category>
executor ^self shouldNotImplement
finalizeExternal ^self shouldNotImplement
key ^self shouldNotImplement
</methods> <methods> Database.MySQLTransaction class <category>accessing</category>
connectionClass ^MySQLConnection
</methods> <methods> Database.MySQLError <category>accessing</category>
sqlState ^sqlState
sqlState: anInteger sqlState := anInteger
</methods> <methods> Database.MySQLAdminConnection class <category>accessing</category>
kind "Answer a symbol representing the type of DMBS the receiver provides services for." ^#'MySQL Admin'
sessionClass "Answer the class to use for session objects associated with receiver." ^MySQLAdminSession
</methods> <methods> Database.MySQLAdminConnection class <category>private-registry</category>
registry ^RegisteredMySQLAdminConnections
registry: aCollection RegisteredMySQLAdminConnections := aCollection
</methods> <methods> Database.MySQLAdminConnection class <category>class initialization</category>
initialize "MySQLAdminConnection initialize" ^super initialize
</methods> <methods> Database.MySQLSession <category>private-answer set</category>
acquireBuffers "Generate the array which holds copies of our buffer pointers. The library will populate the buffer data through these pointers. Each buffer corresponds to one index in the array." self generateBindArrayForOutput. "Acquire buffers for fetching the answer set from the server." super acquireBuffers. "Now pass the bind array (which the buffers have plugged themselves into) to the api." "self bindBufferPtrsArray."
advanceExternal "Advance to the next row. If now more rows, answer nil. While not isRowCountKnown, increment rowCount after every fetch. (If we used 'fetchAllRowsAtOnce', then rowCount has already been established.) To do: don't let data truncation errors go uncaught..." | xif rc | xif := self xif. rc := xif mysql_stmt_fetch: self hstmt. (traceLevel >= 3) ifTrue: [self connection traceFunc: 'mysql_stmt_fetch' result: rc params: self hstmt]. (rc == xif MYSQL_NO_DATA) ifTrue: "No more data." [ self isRowCountKnown: true. ^nil ]. (rc == xif SUCCESS or: [rc == xif MYSQL_DATA_TRUNCATED]) ifFalse: [ | errs | errs := self getStatementErrors. self class connectionClass unableToFetchDataSignal raiseWith: errs errorString: errs first dbmsErrorString ]. self isRowCountKnown ifFalse: [self rowCount: (self rowCount + 1)].
allocateRowBufferExternal: aColumn "Answer an mysql buffer allocated for holding one column's worth of information as returned by the library. An appropriate buffer class for the result column will be choosen automatically." | aColDescription bufferClass buffer | aColDescription := columnDescriptions at: aColumn. bufferClass := (aColDescription isLong) ifFalse: [self class bufferClass] ifTrue: [self class largeObjectBufferClass]. buffer := bufferClass new columnDescription: aColDescription position: aColumn session: self. buffer bindForOutput. ^buffer
answerOfClass: anAnswerStreamClass "Answer an instance of the given subclass of ExternalDatabaseAnswerStream" "Assert: anAnswerStreamClass isKindOf: ExternalDatabaseAnswerStream" | initialAnswer | initialAnswer := ( self state == #ready ). self state: #validResults. initialAnswer ifTrue: [ "Verify that the query executed without error." self resultsExternal ] ifFalse: [ "If we're still holding on to a prior answer stream, dismiss it." answerStream notNil ifTrue: [ answerStream close ]. "Assert: self state == #validResults" self moreResultsExternal ifFalse: [ self state: #prepared. ^#noMoreAnswers ] ]. self hasAnswerSetExternal ifTrue: [ | answer | initialAnswer ifFalse: [ "Previous descriptions/buffers are no longer valid" self releaseBuffers. self releaseAdaptors. self columnDescriptions: nil ]. self getColumnDescriptions. self acquireBuffers. self setupAdaptors. self executeAndBindArrays. self resultsExternal. "Fetch errors now that query has been executed." self aboutToAnswer. answer := anAnswerStreamClass newForSession: self. self answerStream: answer. self state: #fetchingData. ^answer ] ifFalse: [self executeAndBindArrays. self resultsExternal. "Fetch errors now that query has been executed." ]. ^#noAnswerStream.
answerStreamDismissed "Close the cursor and discard pending results." super answerStreamDismissed. self freeStatementResults
cancelAnswerSet "Cancel an answer set. Used to release server resources. This destroys the current cursor, and returns the statement to the prepared state." self cancelAnswerSetExternal. self state: #prepared.
cancelAnswerSetExternal "Cancel current answer set from the server. i.e., close the cursor. Keep the statement handle. MySQL will revert the statement back to the prepared state. To do: see how this affects the ongoing transaction." | stateTemp | stateTemp := self state. (stateTemp == #new or: [stateTemp == #paused or: [self hstmt isNil]]) ifTrue: [^self]. self resetStatementExternal.
describeAnswerColumns "Fill in the columnDescriptions array. We check that numCols is as expected. based on an earlier call using only the statement handle (not the results handle)." |pFields pField flags type descrs columnDescriptionClass isNullable length colDesc isUnsigned isBinaryCollation isAutoIncrement charsetnr pResult name org_name table org_table db catalog def decimals max_length numCols | pResult := self getResultMetaDataHandle. numCols := self getNumResultColumns: pResult. numCols ~= self numColumns ifTrue: [ self numColumns: numCols ]. "These should match." pFields := self getFields: pResult. descrs := Array new: self numColumns. columnDescriptionClass := self connection class columnDescriptionClass. 1 to: self numColumns do: [ :aColumn | pField := pFields refAt: aColumn-1. name := (pField memberAt: #name) copyCStringFromHeap. "Could be a SQL alias (using AS)." org_name := (pField memberAt: #org_name) copyCStringFromHeap. "True column name." table := (pField memberAt: #table) copyCStringFromHeap. "Could be alias (AS tablename)." org_table := (pField memberAt: #org_table) copyCStringFromHeap. "True table name." db := (pField memberAt: #db) copyCStringFromHeap. catalog := (pField memberAt: #table) copyCStringFromHeap. def := (pField memberAt: #def) isValid ifTrue: [ (pField memberAt: #def) copyCStringFromHeap] ifFalse: [nil]. length := pField memberAt: #length. "The precision--total number of digits (max is 64)." max_length := pField memberAt: #max_length. "Only makes sense if stmt attiribute was set." flags := pField memberAt: #flags. decimals := pField memberAt: #decimals. "The scale--digits after decimal point (max is 30). Sign and DP are added after retrieval." charsetnr := pField memberAt: #charsetnr. "63 means BINARY, ie., BLOB or BIT." isNullable := (flags bitAnd: self xif NOT_NULL_FLAG) ~= 0. isUnsigned := (flags bitAnd: self xif UNSIGNED_FLAG) ~= 0. isBinaryCollation := (flags bitAnd: self xif BINARY_FLAG) ~= 0. isAutoIncrement := (flags bitAnd: self xif AUTO_INCREMENT_FLAG) ~= 0. type := pField memberAt: #type. ( traceLevel >= 2) ifTrue: [ (self traceStream) nextPutAll: ' column ='; print: aColumn; nextPutAll: ', name: '; print: name; nextPutAll: ', org_name: '; print: org_name; nextPutAll: ', table: '; print: table; nextPutAll: ', org_table: '; print: org_table; nextPutAll: ', type: '; print: type; nextPutAll: ', db: '; print: db; nextPutAll: ', catalog: '; print: catalog; nextPutAll: ', def: '; print: def; nextPutAll: ', length: '; print: length; nextPutAll: ', max length: '; print: max_length; nextPutAll: ', flags: '; print: flags; nextPutAll: ', decimals '; print: decimals; nextPutAll: ', charsetnr: '; print: charsetnr; nextPutAll: ', is nullable: '; print: isNullable; nextPutAll: ', is unsigned: '; print: isUnsigned; nextPutAll: ', is binary collation: '; print: isBinaryCollation; nextPutAll: ', is auto-incr: '; print: isAutoIncrement; nextPutAll: ' )'. self class trace: self emitTrace ]. (colDesc := columnDescriptionClass new) name: name; index: aColumn; type: nil; maxColumnConstraint: max_length; org_name: org_name; table: table; org_table: org_table; db: db; catalog: catalog; def: def; mysqlType: type; maxColumnConstraint: max_length; precision: length; scale: decimals; isUnsigned: isUnsigned; nullable: isNullable; isBinaryCollation: isBinaryCollation; charsetnr: charsetnr. descrs at: aColumn put: colDesc ]. self freeResultMetaDataHandle: pResult. self columnDescriptions: descrs
executeAndBindArrays "Tell the api to execute the query, and then pass the bind array (which the buffers have plugged themselves into) to the api. If there are column return results expected, bind the buffers." self numParameters > 0 ifTrue: [self bindBufferPtrsForInput]. self executeExternalAfterDescribe. self numColumns > 0 ifTrue: [self bindBufferPtrsForOutput]. self class fetchEntireResultAtOnce ifTrue: [self storeResults]. "Get the count for pre-fetched rows, or affected rows for inserts/updates." (self class fetchEntireResultAtOnce or: [self numColumns = 0]) ifTrue: [self fetchRowCount]
fetchRowCount "Answer an Integer representing the number of rows affected by the executed query. For SELECT queries, valid only if results have been 'stored' on client machine, using mysql_store_result(). See self class fetchEntireResultAtOnce." self rowCount: (self numColumns > 0 ifTrue: [self rowCountForAnswered] ifFalse: [self rowCountForNoAnswer]). self isRowCountKnown: true
freeResultMetaDataHandle: pResult "Let the library free this meta-data handle via mysql_free_result:. There is no return value, and no error code." self xif mysql_free_result: pResult. traceLevel >= 3 ifTrue: [self connection traceFunc: 'mysql_free_result' result: nil params: pResult].
freeStatementResults "Free the statement result set. This is done after the results have been fetched." | rc | rc := self xif mysql_stmt_free_result: self hstmt. traceLevel >= 3 ifTrue: [self connection traceFunc: 'mysql_stmt_free_result' result: rc params: self hstmt]. rc = self xif SUCCESS ifFalse: [| errs | errs := self getStatementErrors. self class connectionClass unableToFreeResourceSignal raiseRequestWith: errs errorString: errs first dbmsErrorString]
getFieldExternal: aColumn | buffer | buffer := (self rowBuffers) at: aColumn. ^buffer value
getFields: pResult " Get total columns in the query. The client library owns and will dispose of the pointers." | pFields | pFields := self xif mysql_fetch_fields: pResult. traceLevel >= 3 ifTrue: [self connection traceFunc: 'mysql_fetch_fields' result: pFields params: pResult]. ^pFields
getNumResultColumns: pResult " Get total columns in the query. This answer should be the same as that returned by getNumStatementColumns. This method uses the api call for the result set handle. The other uses the api for the statement handle itself." | numCols | numCols := self xif mysql_num_fields: pResult. traceLevel >= 3 ifTrue: [self connection traceFunc: 'mysql_num_fields' result: numCols params: pResult]. numCols >= 0 ifFalse: [| errs | errs := self getStatementErrors. self class connectionClass unableToFreeResourceSignal raiseRequestWith: errs errorString: errs first dbmsErrorString]. ^numCols
getNumStatementColumns "Is this a SELECT statement, with rows of answers? If numColumns is not zero, rows are expected (0 or more) . This method can be called after the statement has been prepared. (prepare:)" | numCols | numCols := self xif mysql_stmt_field_count: self hstmt. traceLevel >= 3 ifTrue: [self connection traceFunc: 'mysql_stmt_field_count' result: numCols params: self hstmt]. ^numCols
getResultMetaDataHandle "Ask for a meta-data handle so that we can fetch info about the result set. Note: The library expects to free this handle via mysql_free_result:." | pResult | pResult := self xif mysql_stmt_result_metadata: self hstmt. traceLevel >= 3 ifTrue: [self connection traceFunc: 'mysql_stmt_result_metadata' result: pResult params: self hstmt]. pResult isValid ifFalse: [| errs | errs := self getStatementErrors. self class connectionClass unableToAllocateHandleSignal raiseWith: errs errorString: errs first dbmsErrorString]. ^pResult
hasAnswerSetExternal "Is this a SELECT statement, with rows of answers? If numColumns is not zero, rows are expected (0 or more). If numColumns is zero, no results are expected. This method can be called after the statement has been prepared. (prepare:)." | numCols | numCols := self getNumStatementColumns. self numColumns: numCols. ^numCols > 0
releaseBuffers "Release buffers and their associated resources." | rbs | (rbs := self rowBuffers) notNil ifTrue: [1 to: rbs size do: [:aColumn | (rbs at: aColumn) free]]. traceLevel >= 3 ifTrue: [self connection traceFunc: 'releaseBuffers' result: 0 params: 0]. super releaseBuffers
resetStatementExternal "Cancel current answer set from the server. i.e., close the cursor. Reset a prepared statement in case there was a recoverable error. SYNOPSIS mysql_stmt_reset() thd Thread handle packet Packet with stmt id DESCRIPTION This function resets statement to the state it was right after prepare. It can be used to: - clear an error happened during mysql_stmt_send_long_data - cancel long data stream for all placeholders without having to call mysql_stmt_execute. - close an open cursor Sends 'OK' packet in case of success (statement was reset) or 'ERROR' packet (unrecoverable error/statement not found/etc). " | xif rc | xif := self xif. rc := xif mysql_stmt_reset: self hstmt. (traceLevel >= 3) ifTrue: [self connection traceFunc: 'mysql_stmt_reset' result: rc params: self hstmt]. (rc == xif SUCCESS) ifFalse: [ | errs | errs := self getStatementErrors. self class connectionClass unableToCancelCursorSignal raiseWith: errs errorString: errs first dbmsErrorString ].
storeResults "Fetch the entire result set to the local machine. This can be demanding on local memory for large result sets. An advantage is that >>rowCount returns the actual result set size before fetching each row individually." | rc | rc := self xif mysql_stmt_store_result: self hstmt. traceLevel >= 3 ifTrue: [self connection traceFunc: 'mysql_stmt_store_result:' result: rc params: self hstmt]. (rc == self xif SUCCESS) ifFalse: [ | errs | errs := self getStatementErrors. self class connectionClass unableToCancelCursorSignal raiseWith: errs errorString: errs first dbmsErrorString ].
</methods> <methods> Database.MySQLSession <category>private-accessing</category>
getStatementErrors "Return a collection of MySQLError(s) associated with the statement handle." | errors err | errors := OrderedCollection new. "Many senders assume non-empty collection." err := self getStatementErrorsExternal ifNil: [self connection class defaultError]. errors add: err. ^errors
getStatementErrorsExternal "Return the most recent error code, or nil if none." | xif errorMsg rc error | xif := self xif. rc := xif mysql_stmt_errno: self hstmt. rc == xif SUCCESS ifFalse: [ errorMsg := (xif mysql_stmt_error: self hstmt) copyCStringFromHeap. error := self class errorClass new. error dbmsErrorCode: rc. error dbmsErrorString: errorMsg. error sqlState: (xif mysql_stmt_sqlstate: self hstmt) copyCStringFromHeap. ( traceLevel >= 2 ) ifTrue: [self connection traceFunc: 'mysql_hstmt_error' result: errorMsg params: self hstmt ]]. ^error
hstmt ^hstmtHolder value
hstmt: aCPointerOrNil hstmtHolder value: aCPointerOrNil
isRowCountKnown: aBoolean "True i,eans we have either executed a query and - retrieved the rowCount (which is only possible using fetchAllRowsAtOnce), - or retrieved all the result rows individually, to the end of the stream." isRowCountKnown := aBoolean
numParameters ^numParameters
numParameters: anObject numParameters := anObject
resultsCache "Answer the contents of the result cache. Clear the cache." | results | results := resultsCache. resultsCache := nil. ^results
resultsCache: results "Cache results." resultsCache := results
rowCount: aNumber "Set using an Integer representing the number of rows affected by the previous query." rowCount := aNumber
rowCountForAnswered "Answer an Integer representing the number of rows returned by the previous query. For SELECT statements, it is the number of rows returned. Valid only after the query has been answered. Unlike mysql_stmt_affected_rows(), there is no error return value for mysql_stmt_num_rows(), but a harmless check is made anyway." | xif rc count | xif := self xif. self hstmt isNil ifTrue: [^nil]. rc := xif mysql_stmt_num_rows: self hstmt. traceLevel >= 2 ifTrue: [self connection traceFunc: 'mysql_stmt_num_rows' result: rc params: self hstmt]. "This is declared by the api as an unsigned long long, but appears to be only a ulong." rc highBit >= 64 ifTrue: [count := -1] ifFalse: [count := xif signedFromUnsignedLong: rc]. count == -1 ifTrue: [| errs | errs := self getStatementErrors. self class connectionClass externalDatabaseErrorSignal raiseWith: errs errorString: errs first dbmsErrorString]. ^count
rowCountForNoAnswer "Answer an Integer representing the number of rows affected by the previous query. For INSERT, UPDATE statements, it is the number of rows actually updated. Valid only after the query has been answered." | xif rc count | xif := self xif. self hstmt isNil ifTrue: [^nil]. rc := xif mysql_stmt_affected_rows: self hstmt. traceLevel >= 2 ifTrue: [self connection traceFunc: 'mysql_stmt_affected_rows' result: rc params: self hstmt]. rc highBit >= 64 ifTrue: [count := -1] ifFalse: [count := xif signedFromUnsignedLong: rc]. "Api says 64-bit, but here it's 32-bits valid." count == -1 ifTrue: [| errs | errs := self getStatementErrors. self class connectionClass externalDatabaseErrorSignal raiseWith: errs errorString: errs first dbmsErrorString]. ^count
setStatementAttributeExternal: type value: value | rc arg | arg := value gcCopyToHeap. rc := self xif mysql_stmt_attr_set: self hstmt attr_type: type attr: arg. traceLevel >= 3 ifTrue: [self connection traceFunc: 'mysql_stmt_attr_set' result: rc params: (Array with: self hstmt with: type with: value)]. rc = self xif SUCCESS ifFalse: [| errs | errs := self getStatementErrors. self class connectionClass unableToOpenCursorSignal raiseWith: errs errorString: errs first dbmsErrorString]
setStatementAttributes "There are three generalf attributes. 1. Always (or not) indicate the maximum length for each returned column when we describe answer columns. 2. Use a cursor to retrieve rows in blocks (of size blcockFactor). Otherwise retrieve rows all at once, or singly--no cursor. 3. Specify the size of the blockFactor (if it has been enabled). Currently, we use cursors, blockFactor, and indicate column max_length. A failure in applying these settings results in an UnableToOpenCursor exception. More detailed exceptions might be appropriate at some point." | attributeTypes cursorTypes | attributeTypes := self xif enum_stmt_attr_type. cursorTypes := self xif enum_cursor_type. self setStatementAttributeExternal: (attributeTypes memberNamed: #STMT_ATTR_UPDATE_MAX_LENGTH) value: self xif TRUE. self setStatementAttributeExternal:(attributeTypes memberNamed: #STMT_ATTR_CURSOR_TYPE) value: (cursorTypes memberNamed: #CURSOR_TYPE_READ_ONLY). self setStatementAttributeExternal: (attributeTypes memberNamed: #STMT_ATTR_PREFETCH_ROWS) value: self blockFactor
</methods> <methods> Database.MySQLSession <category>private-execution</category>
acquireExternal "Acquire a statement handle. If nil, get the error report from the connection, since session errors need a valid statement handle." | phstmt | phstmt := self xif mysql_stmt_init: self connection hConn. traceLevel >= 3 ifTrue: [self connection traceFunc: 'mysql_stmt_init' result: phstmt params: connection hConn]. phstmt isValid ifTrue: [self hstmt: phstmt] ifFalse: [| errs | errs := self connection getStatementErrors. self class connectionClass unableToAllocateHandleSignal raiseWith: errs errorString: errs first dbmsErrorString]
cancelExternal "Handle cleanup when current query is cancelled." ^self
dismissExternal "Free allocated resources. This includes the statement handle." self freeStatementExternal. self hstmt: nil
executeExternal "Set rowCount indicators prior to retrieval." "Do not execute the prepared SQL text yet. Wait until column described!" self rowCount: 0. self isRowCountKnown: false. ^self
executeExternalAfterDescribe "Execute the prepared SQL text." | xif rc | xif := self xif. "Does the query text need to be sent to the server again?" "self mustResendQuery ifTrue: [ self prepareExternal. self mustResendQuery: false ]." rc := xif mysql_stmt_execute: self hstmt. traceLevel >= 1 ifTrue: [self connection traceFunc: 'mysql_stmt_execute' result: rc params: self hstmt]. rc = self xif SUCCESS ifFalse: [self resultsCache: self getStatementErrors]
freeStatementExternal "Close the statement handle so the library can free related resources. The caller should formally reassign nil to my statement holder afterwards." | rc | self hasValidStatementHandle ifFalse: [^self]. rc := self xif mysql_stmt_close: self hstmt. traceLevel >= 3 ifTrue: [self connection traceFunc: 'mysql_stmt_close' result: rc params: self hstmt]. rc = self xif SUCCESS ifFalse: [| errs | errs := self getStatementErrors. self class connectionClass unableToFreeResourceSignal raiseRequestWith: errs errorString: errs first dbmsErrorString]
getParamCountExternal "Get the parameter count from the statement just prepared. If there are no parameters, the count will be zero." | param_count | param_count := self xif mysql_stmt_param_count: self hstmt. traceLevel >= 1 ifTrue: [self connection traceFunc: 'mysql_stmt_param_count' result: param_count params: self hstmt]. ^param_count
installExternal super installExternal. self hstmt: nil. self setMaxLongData: DefaultMaxLongData.
moreResultsExternal "To do: check for more results." ^false
readyExternal "Answer whether or not the dbms has processed the SQL statement (batch). Answer true, and let the client block." ^true
resultsExternal "Retrieve any error information." | errs sqlState | (errs := self resultsCache) notNil ifTrue: [ 1 to: errs size do: [ :position| ((sqlState := (errs at: position) sqlState asSymbol) == #'01000' or: [ sqlState == #'S1000' ]) ifFalse: [ ^self class connectionClass unableToExecuteSQLSignal raiseWith: errs errorString: (errs at: position) dbmsErrorString ] ]. self class connectionClass externalDatabaseInformationSignal raiseRequestWith: errs. ]. ^true
</methods> <methods> Database.MySQLSession <category>private-binding</category>
bindBufferPtrsForInput "Tell api that this is the MYSQL_BIND array, with all the buffer pointers." | rc | rc := self xif mysql_stmt_bind_param: self hstmt bind: self inputBufferPtrsArray. traceLevel >= 3 ifTrue: [self connection traceFunc: 'mysql_stmt_bind_param' result: rc params: (Array with: self hstmt with: self inputBufferPtrsArray)]. rc == self xif SUCCESS ifFalse: [| errs | errs := self getStatementErrors. self class connectionClass unableToBindSignal raiseWith: errs errorString: errs first dbmsErrorString]
bindBufferPtrsForOutput "Tell api that this is the MYSQL_BIND array, with all the buffer pointers." | rc | rc := self xif mysql_stmt_bind_result: self hstmt bind: self outputBufferPtrsArray. traceLevel >= 3 ifTrue: [self connection traceFunc: 'mysql_stmt_bind_result' result: rc params: (Array with: self hstmt with: self outputBufferPtrsArray)]. rc == self xif SUCCESS ifFalse: [| errs | errs := self getStatementErrors. self class connectionClass unableToBindSignal raiseWith: errs errorString: errs first dbmsErrorString]
bindExternal "Bind values to parameters in the query, avoiding unnecessary rebinding where possible." "For each bind marker in the query fragments, get the corresponding value from the bindInput object. If the value isn't already bound, bind and remember it." | leftToRightIndex numParams | "Number of params MySQL expects from the query." self numParameters: self getParamCountExternal. "Number of params VW expects from the query." numParams := (queryFragments size - 1) / 2. numParams ~= self numParameters ifTrue: [self class unableToBindSignal raiseWith: 'Wrong number of parameters expected.']. self numParameters > 0 ifTrue: ["Generate the array which holds copies of our buffer pointers. The library will accept the buffer data through these pointers. Each buffer corresponds to one index in the array." self generateBindArrayForInput]. leftToRightIndex := 1. 2 to: queryFragments size by: 2 do: [:index | | bindMarker value | bindMarker := queryFragments at: index. value := self inBindInputAt: bindMarker. (self boundValueAt: bindMarker is: value) ifFalse: ["A bindMarker can be a symbol if the prepared SQL contained <:name>. Therefore we will have to manually specify a left-to-right index for our parameter positions" self bindValue: value at: leftToRightIndex. self bindValues at: bindMarker put: value]. leftToRightIndex := leftToRightIndex + 1]
bindValue: aValue at: position "Bind a value to a parameter position in the query. Re-use an existing buffer only if it is big enough. An existing buffer can be too small if it holds a #String, but the new value is a #LargeString, for example." | buffer val | val := (aValue isKindOf: Stream) ifTrue: [aValue contents] ifFalse: [aValue]. buffer := self boundValueBuffers at: position ifAbsent: [nil]. buffer isNil ifFalse: [(buffer canHold: val) ifFalse: [buffer free. buffer := nil]]. buffer isNil ifTrue: [buffer := self class bufferClass new on: val position: position session: self. buffer bindForInputValue: val. self boundValueBuffers at: position put: buffer] ifFalse: [buffer reUse: val]
boundValueBuffers "Answer with the receiver's dictionary of bound rgbValue pointers (input parameters). In some other EXDIs, this var is named bindValuePointers." | bvph | (bvph := self boundValueBuffersHolder) value isNil ifTrue: [ bvph value: IdentityDictionary new ]. ^bvph value
prepareExternal "Prepare the server to execute a query." | xif sql sqlBa sqlBaPointer rc sig | xif := self xif. "Assemble the query, substituting the correct parameter markers." queryFragments size == 1 ifTrue: [sql := queryFragments at: 1] ifFalse: [| sqlStream | sqlStream := (String new: query size) writeStream. sqlStream nextPutAll: (queryFragments at: 1). 2 to: queryFragments size by: 2 do: [:index | sqlStream nextPut: $?; nextPutAll: (queryFragments at: index + 1)]. sql := sqlStream contents]. "MySQL doesn't expect a ByteArray, but we want correct encoding." sqlBa := sql asByteArrayEncoding: self connection encoding. sqlBaPointer := sqlBa gcCopyToHeap. rc := xif mysql_stmt_prepare: self hstmt query: sqlBaPointer length: sqlBa size. traceLevel >= 1 ifTrue: [self connection traceFunc: 'mysql_stmt_prepare' result: rc params: (Array with: self hstmt with: sql with: sqlBa size)]. rc == xif SUCCESS ifFalse: [| errs | errs := self getStatementErrors. sig := (self class connectionClass signalForErrorCode: errs first dbmsErrorCode) ifNil: [self class connectionClass unableToPrepareSignal]. ^sig raiseWith: errs errorString: errs first dbmsErrorString]
releaseBindings "If we have any, free our statement handle and our buffers." | bvp | self freeBindArrays. (bvp := self boundValueBuffersHolder value) notNil ifTrue: [bvp do: [:buffer | buffer notNil ifTrue: [buffer free]]. self boundValueBuffersHolder value: nil]. super releaseBindings
</methods> <methods> Database.MySQLSession <category>private-handles</category>
hasValidStatementHandle "Return true only if the allocated MYSQL_STMT data structure has a valid pointer." ^self xif isValidCPointer: self hstmt
xif ^self class xif
</methods> <methods> Database.MySQLSession <category>data processing</category>
isRowCountKnown "Answer true if we have either executed a query and - retrieved the rowCount (which is only possible using fetchAllRowsAtOnce), - or retrieved all the result rows individually." ^isRowCountKnown
maxBufferSizeNeededDuringQuery "Of all my buffers, return the largest size necessary for un-truncated retrieval." | buffers | buffers := rowBuffersHolder value. ^buffers inject: 0 into: [:max :buf | buf maxBufferSizeNeeded max: max]
maxLongData "Return the maximum amount of data to be copied from LONGVARCHAR or LONGVARBINARY columns." ^maxLongData
prepare: aString "Prepare a query string for processing." super prepare: aString. self setStatementAttributes.
rowCount "Answer an Integer representing the number of rows affected by the previous query. For INSERT, UPDATE statements, it is the number of rows actually updated. For SELECT statements, it is the number of rows returned. Valid only after the query has been answered." ^rowCount
setMaxLongData: anInteger "Specify the maximum amount of data to be copied from LONGVARCHAR or LONGVARBINARY columns." maxLongData := (self class defaultMaxLongData min: anInteger).
</methods> <methods> Database.MySQLSession <category>private-finalization</category>
executor "Answer with an executor for the receiver--my shallow copy. It includes statementHolder, a ValueHolder, which points to my statement object." | ex | ex := super executor. ex hstmtHolder: self hstmtHolder. ex boundValueBuffersHolder: self boundValueBuffersHolder. ex inputBufferPtrsArrayHolder: self inputBufferPtrsArrayHolder. ex outputBufferPtrsArrayHolder: self outputBufferPtrsArrayHolder. ^ex
finalizeExternal "Release all external resources" self releaseBuffersAndAdaptors. self releaseBindings. "self hasValidStatementHandle ifFalse: [^self]. This is handled by >>dismissExternal." traceLevel >= 1 ifTrue: [self class trace: nil]. super finalizeExternal
key "The hstmtHolder is unique to the session and is constant across pause/resume." ^self hstmtHolder
</methods> <methods> Database.MySQLSession <category>private-buffer pointers array</category>
freeBindArrays "Free the memory used by the input and output buffer ptrs arrays." (self connection notNil and: [ traceLevel >= 3]) ifTrue: [self connection traceFunc: 'freeBindArrays' result: 0 params: (Array with: (self inputBufferPtrsArray) with: (self outputBufferPtrsArray))]. self inputBufferPtrsArray ifNotNil: [self inputBufferPtrsArray isValid ifTrue: [self inputBufferPtrsArray free. self inputBufferPtrsArray: nil]]. self outputBufferPtrsArray ifNotNil: [self outputBufferPtrsArray isValid ifTrue: [self outputBufferPtrsArray free. self outputBufferPtrsArray: nil]]
generateBindArrayForInput "MySQL doesn't individually bind a separate buffer pointer for each bound parameter. Instead, it expects an array of MYSQL_BIND structs, each element of which has a copy of the corresponding buffer's data pointer. For input parameters, the api will read our buffers through the pointers it sees in the array, each array element (a struct) is dedicated to a separate buffer." self inputBufferPtrsArray: (self newBindArray: self numParameters)
generateBindArrayForOutput "MySQL doesn't individually bind a separate buffer pointer for each returned column. Instead, it expects an array of MYSQL_BIND structs, each element of which has a copy of the corresponding buffer's data pointer. For each fetched row, the api will populate our buffers through the pointers it sees in the array, each array element (a struct) is dedicated to a separate buffer." self outputBufferPtrsArray: (self newBindArray: self numColumns)
inputBufferPtrsArray ^inputBufferPtrsArrayHolder value
inputBufferPtrsArray: aCArrayObject ^inputBufferPtrsArrayHolder value: aCArrayObject
inputBufferPtrsArrayRefAt: indexMinusOne "Return a pointer to the corresponding element of the bufferPtrsArray." (indexMinusOne >= 0 and: [indexMinusOne < self numParameters]) ifFalse: [self error: 'Bad parameter index.']. ^self inputBufferPtrsArray refAt: indexMinusOne
newBindArray: numElements "Allocate an array of MYSQL_BIND structs, each element of which can hold a copy of the corresponding buffer's data pointer." | mallocSelector bufferPtrsArray num | num := numElements max: 1. mallocSelector := self xif mallocSelector. bufferPtrsArray := self xif MYSQL_BIND perform: mallocSelector with: num. 0 to: num - 1 do: [:i | (bufferPtrsArray refAt: i) zeroFill]. ^bufferPtrsArray
outputBufferPtrsArray ^outputBufferPtrsArrayHolder value
outputBufferPtrsArray: aCArrayObject ^outputBufferPtrsArrayHolder value: aCArrayObject
outputBufferPtrsArrayRefAt: indexMinusOne "Return a pointer to the corresponding element of the bufferPtrsArray." (indexMinusOne >= 0 and: [indexMinusOne < self numColumns]) ifFalse: [self error: 'Bad column index.']. ^self outputBufferPtrsArray refAt: indexMinusOne
</methods> <methods> Database.MySQLSession <category>private-value holders</category>
boundValueBuffersHolder ^boundValueBuffersHolder
boundValueBuffersHolder: aValueHolder boundValueBuffersHolder := aValueHolder
hstmtHolder ^hstmtHolder
hstmtHolder: aValueHolder hstmtHolder := aValueHolder
inputBufferPtrsArrayHolder ^inputBufferPtrsArrayHolder
inputBufferPtrsArrayHolder: anObject inputBufferPtrsArrayHolder := anObject
outputBufferPtrsArrayHolder ^outputBufferPtrsArrayHolder
outputBufferPtrsArrayHolder: anObject outputBufferPtrsArrayHolder := anObject
</methods> <methods> Database.MySQLSession <category>initialize-release</category>
initialize super initialize. hstmtHolder := nil asValue. boundValueBuffersHolder := nil asValue. inputBufferPtrsArrayHolder := nil asValue. outputBufferPtrsArrayHolder := nil asValue. self setMaxLongData: self class defaultMaxLongData. self rowCount: 0. self isRowCountKnown: false.
</methods> <methods> Database.MySQLSession class <category>accessing</category>
bufferClass "Answer the class to use for bindInput/Output objects associated with receiver." ^MySQLBuffer
connectionClass "Answer the class to use for connection objects associated with receiver." ^MySQLConnection
defaultMaxLongData ^DefaultMaxLongData
defaultMaxLongData: anInteger DefaultMaxLongData := anInteger
errorClass "Answer the error class for the receiver." ^MySQLError
fetchEntireResultAtOnce "Return true to download all rows at once, false to download one row at a time. Downloading all results at once can userp a lot of client memory for large result sets, but this is the only way MySQL will tell you the rowCount before fetching every row." ^false
largeObjectBufferClass "Answer the class to use for bindInput/Output objects associated with receiver." ^MySQLBuffer
</methods> <methods> Database.MySQLSession class <category>private-activation</category>
install self bufferClass install.
</methods> <methods> Database.MySQLSession class <category>private-registry</category>
registry ^RegisteredMySQLSessions
registry: aCollection RegisteredMySQLSessions := aCollection
</methods> <methods> Database.MySQLSession class <category>class initialization</category>
initialize "MySQLBuffer initialize" self initRegistry. DefaultMaxLongData := 16777216. "Default to 16 megs of long data" "self initializeSQLStatementOptionConversionMap." self install.
</methods> <methods> Database.MySQLAdminSession <category>private-finalization</category>
executor "Answer with an executor for the receiver--my shallow copy." | ex | ex := super executor. ex hResultHolder: self hResultHolder. ^ex
finalizeExternal "Release all external resources" self releaseBuffersAndAdaptors. self releaseBindings. "self hasValidStatementHandle ifFalse: [^self]. this is done in >>dismissExternal." traceLevel >= 1 ifTrue: [self class trace: nil]. super finalizeExternal
key "The resultsHolder is unique to the session and is constant across pause/resume." ^hResultHolder
</methods> <methods> Database.MySQLAdminSession <category>private-answer set</category>
acquireBuffers "Generate the array which holds copies of our buffer pointers. The library will populate the buffer data through these pointers. Each buffer corresponds to one index in the array." "Acquire buffers for fetching the answer set from the server." super acquireBuffers
advanceExternal "Advance to the next row. If now more rows, answer nil." | pRow pFieldLengths | pRow := self fetchRow. (self xif isValidCPointer: pRow) ifFalse: "No more data." [self isRowCountKnown: true. ^nil]. pFieldLengths := self getFieldLengthsThisRow. self updateBuffers: pRow lengths: pFieldLengths. "Increment number of rows, unless it was already retrieved and set." self isRowCountKnown ifFalse: [self rowCount: self rowCount + 1]
allocateRowBufferExternal: aColumn "Answer an MySQLCharacterBuffer allocated for holding one column's worth of information as returned by the library. An appropriate buffer class for the result column will be choosen automatically." | aColDescription bufferClass buffer | aColDescription := columnDescriptions at: aColumn. bufferClass := self class bufferClass. buffer := bufferClass new columnDescription: aColDescription position: aColumn session: self. ^buffer
answerOfClass: anAnswerStreamClass "Answer an instance of the given subclass of ExternalDatabaseAnswerStream" "Assert: anAnswerStreamClass isKindOf: ExternalDatabaseAnswerStream" | initialAnswer | initialAnswer := ( self state == #ready ). self state: #validResults. initialAnswer ifTrue: [ "Verify that the query executed without error." self fetchResult. self resultsExternal ] ifFalse: [ "If we're still holding on to a prior answer stream, dismiss it." answerStream notNil ifTrue: [ answerStream close ]. "Assert: self state == #validResults" self moreResultsExternal ifTrue: [self fetchResult] ifFalse: [ self state: #prepared. ^#noMoreAnswers ] ]. self hasAnswerSetExternal ifTrue: [ | answer | initialAnswer ifFalse: [ "Previous descriptions/buffers are no longer valid" self releaseBuffers. self releaseAdaptors. self columnDescriptions: nil ]. self getColumnDescriptions. self acquireBuffers. self setupAdaptors. self fetchNumAffectedRows. self aboutToAnswer. answer := anAnswerStreamClass newForSession: self. self answerStream: answer. self state: #fetchingData. ^answer ] ifFalse: [self fetchNumAffectedRows]. ^#noAnswerStream.
answerStreamDismissed "Close the cursor and discard pending results." super answerStreamDismissed. self freeResultHandle
cancelAnswerSet "Cancel an answer set. Used to release server resources. This destroys the current cursor, and returns the statement to the prepared state." self cancelAnswerSetExternal. self state: #prepared.
cancelAnswerSetExternal "Cancel current answer set from the server. i.e., close the cursor. Keep the statement handle. MySQL will revert the statement back to the prepared state. To do: see how this affects the ongoing transaction." | stateTemp | stateTemp := self state. (stateTemp == #new or: [stateTemp == #paused or: [self hResult isNil]]) ifTrue: [^self]. self freeResultHandle.
describeAnswerColumns "Fill in the columnDescriptions array. We check that numCols is as expected. based on an earlier call using only the statement handle (not the results handle)." |pFields pField flags type descrs columnDescriptionClass isNullable length colDesc isUnsigned isBinaryCollation isAutoIncrement charsetnr name org_name table org_table db catalog def decimals max_length numCols | numCols := self getNumResultColumns. numCols ~= self numColumns ifTrue: [ self numColumns: numCols ]. "These should match." pFields := self getFields. descrs := Array new: self numColumns. columnDescriptionClass := self connection class columnDescriptionClass. 1 to: self numColumns do: [ :aColumn | pField := pFields refAt: aColumn-1. name := (pField memberAt: #name) copyCStringFromHeap. "Could be a SQL alias (using AS)." org_name := (pField memberAt: #org_name) copyCStringFromHeap. "True column name." table := (pField memberAt: #table) copyCStringFromHeap. "Could be alias (AS tablename)." org_table := (pField memberAt: #org_table) copyCStringFromHeap. "True table name." db := (pField memberAt: #db) copyCStringFromHeap. catalog := (pField memberAt: #table) copyCStringFromHeap. def := (pField memberAt: #def) isValid ifTrue: [ (pField memberAt: #def) copyCStringFromHeap] ifFalse: [nil]. length := pField memberAt: #length. "The precision--total number of digits (max is 64)." max_length := pField memberAt: #max_length. "Only makes sense if stmt attiribute was set." flags := pField memberAt: #flags. decimals := pField memberAt: #decimals. "The scale--digits after decimal point (max is 30). Sign and DP are added after retrieval." charsetnr := pField memberAt: #charsetnr. "63 means BINARY, ie., BLOB or BIT." isNullable := (flags bitAnd: self xif NOT_NULL_FLAG) ~= 0. isUnsigned := (flags bitAnd: self xif UNSIGNED_FLAG) ~= 0. isBinaryCollation := (flags bitAnd: self xif BINARY_FLAG) ~= 0. isAutoIncrement := (flags bitAnd: self xif AUTO_INCREMENT_FLAG) ~= 0. type := pField memberAt: #type. ( traceLevel >= 2) ifTrue: [ (self traceStream) nextPutAll: ' column ='; print: aColumn; nextPutAll: ', name: '; print: name; nextPutAll: ', org_name: '; print: org_name; nextPutAll: ', table: '; print: table; nextPutAll: ', org_table: '; print: org_table; nextPutAll: ', type: '; print: type; nextPutAll: ', db: '; print: db; nextPutAll: ', catalog: '; print: catalog; nextPutAll: ', def: '; print: def; nextPutAll: ', length: '; print: length; nextPutAll: ', max length: '; print: max_length; nextPutAll: ', flags: '; print: flags; nextPutAll: ', decimals '; print: decimals; nextPutAll: ', charsetnr: '; print: charsetnr; nextPutAll: ', is nullable: '; print: isNullable; nextPutAll: ', is unsigned: '; print: isUnsigned; nextPutAll: ', is binaryCollation: '; print: isBinaryCollation; nextPutAll: ', is auto-incr: '; print: isAutoIncrement; nextPutAll: ' )'. self class trace: self emitTrace ]. (colDesc := columnDescriptionClass new) name: name; index: aColumn; type: nil; maxColumnConstraint: max_length; org_name: org_name; table: table; org_table: org_table; db: db; catalog: catalog; def: def; mysqlType: type; maxColumnConstraint: max_length; precision: length; scale: decimals; isUnsigned: isUnsigned; nullable: isNullable; isBinaryCollation: isBinaryCollation; charsetnr: charsetnr. descrs at: aColumn put: colDesc ]. self columnDescriptions: descrs
fetchNumAffectedRows "Get the count for pre-fetched rows, or affected rows for inserts/updates. For SELECT queries, valid only if results have been 'stored' on client machine, using mysql_store_result(). See self class fetchEntireResultAtOnce. If we are not allowed to fetch the affected rows in advance, do nothing." (self class fetchEntireResultAtOnce or: [self numColumns = 0]) ifTrue: [self fetchRowCount]
fetchRowCount "Answer an Integer representing the number of rows affected by the executed query. For SELECT queries, valid only if results have been 'stored' on client machine, using mysql_store_result(). See self class fetchEntireResultAtOnce." self rowCount: (self numColumns > 0 ifTrue: [self rowCountForAnswered] ifFalse: [self rowCountForNoAnswer]). self isRowCountKnown: true
freeResultHandle "Let the library free this meta-data handle via mysql_free_result:. There is no return value, and no error code." (self isValidHandle: self hResult) ifTrue: [self xif mysql_free_result: self hResult. traceLevel >= 3 ifTrue: [self connection traceFunc: 'mysql_free_result' result: nil params: self hResult]]. self hResult: nil
getFieldExternal: aColumn | buffer | buffer := (self rowBuffers) at: aColumn. ^buffer value
getFields "Get total columns in the query. The client library owns and will dispose of the pointers." | pFields | pFields := self xif mysql_fetch_fields: self hResult. traceLevel >= 3 ifTrue: [self connection traceFunc: 'mysql_fetch_fields' result: pFields params: self hResult]. ^pFields
getNumResultColumns " Get total columns in the query. This answer should be the same as that returned by getNumStatementColumns. This method uses the api call for the result set handle. The other uses the api for the statement handle itself." | numCols | numCols := self xif mysql_num_fields: self hResult. traceLevel >= 3 ifTrue: [self connection traceFunc: 'mysql_num_fields' result: numCols params: self hResult]. numCols >= 0 ifFalse: [| errs | errs := self getStatementErrors. self class connectionClass unableToFreeResourceSignal raiseRequestWith: errs errorString: errs first dbmsErrorString]. ^numCols
getNumStatementColumns "Is this a SELECT statement, with rows of answers? If numColumns is not zero, rows are expected (0 or more) . This method can be called after the statement has been executed." | numCols | numCols := self xif mysql_field_count: self hConn. traceLevel >= 3 ifTrue: [self connection traceFunc: 'mysql_field_count' result: numCols params: self hConn]. ^numCols
hasAnswerSetExternal "Is this a SELECT statement, with rows of answers? If numColumns is not zero, rows are expected (0 or more). If numColumns is zero, no results are expected. This method can be called after the statement has been sent (mysql_real_query:)." | numCols | numCols := self getNumStatementColumns. self numColumns: numCols. ^numCols > 0
rowCountForAnswered "For the admin api, the same function call (mysql_affected_rows) works in both cases." ^self rowCountForNoAnswer
rowCountForNoAnswer "Answer an Integer representing the number of rows affected by the previous query. For INSERT, UPDATE statements, it is the number of rows actually updated. For SELECT statements, it is the number of rows returned. Valid only after the query has been answered. -1 means there was an error, possibly because the call was made out of sequence." | xif rc count | xif := self xif. self hConn isNil ifTrue: [^nil]. "rc := xif mysql_num_rows: self hConn." rc := xif mysql_affected_rows: self hConn. traceLevel >= 2 ifTrue: [self connection traceFunc: 'mysql_affected_rows' result: rc params: self hConn]. rc highBit >= 64 ifTrue: [count := -1] ifFalse: [count := xif signedFromUnsignedLong: rc]. "Api says 64-bit, but here it's 32-bits valid." count == -1 ifTrue: [| errs | errs := self getStatementErrors. self class connectionClass externalDatabaseErrorSignal raiseWith: errs errorString: errs first dbmsErrorString]. ^count
</methods> <methods> Database.MySQLAdminSession <category>private-binding</category>
bindValue: aValue at: position "Input binding is not available for this class, so signal an error." self error: 'Input binding is not available for MySQLAdHocSession instances'.
prepareExternal "With this kind of session, there is no prepare: simply execute the query."
releaseBindings "If we have any, free our statement handle and our buffers." super releaseBindings
updateBuffers: pRow lengths: pFieldLengths "Retrieve the data for this row. pRow is a pointer to an array of pointers, one for each returned column (field). A null pointer to data indicates a NULL in that column." | buffer pData length | 1 to: self numColumns do: [:aColumn | pData := pRow at: aColumn - 1. length := pFieldLengths at: aColumn - 1. buffer := self rowBuffers at: aColumn. buffer copyFromPointer: pData length: length]
</methods> <methods> Database.MySQLAdminSession <category>private-handles</category>
isValidHandle: aHandle "Return true only if the handle is a valid pointer." ^aHandle isNil ifTrue: [false] ifFalse: [aHandle isValid]
xif ^self class xif
</methods> <methods> Database.MySQLAdminSession <category>private-execution</category>
acquireExternal "Normally, this method aquires a statement handle, but for this class, we use the connection handle. Simply ensure that we have a valid connection handle." self hConn isValid ifFalse: [| errs | errs := self getStatementErrors. self class connectionClass unableToAllocateHandleSignal raiseWith: errs errorString: errs first dbmsErrorString]
cancelExternal "Handle cleanup when current query is cancelled." ^self
checkForMoreResults "Return true if there are more results, false otherwise." | xif rc | xif := self xif. rc := xif mysql_next_result: self hConn. traceLevel >= 3 ifTrue: [self connection traceFunc: 'mysql_next_result:' result: rc params: self hConn]. "rc=-1, no more results. rc=0: more results. rc>0: there was an error." rc > 0 ifTrue: [self class connectionClass unableToExecuteSQLSignal raiseRequestErrorString: #unableToRetrieveResults << #mysql >>'Unable to retrieve all results.']. ^rc = 0
dismissExternal "Free allocated resources, if any." self freeResultHandle
executeExternal "Execute the prepared SQL text." | xif rc length sqlBa sqlBaPointer | xif := self xif. sqlBa := self query asByteArrayEncoding: self connection encoding. sqlBaPointer := sqlBa gcCopyToHeap. length := sqlBa size. rc := xif mysql_real_query: self hConn query: sqlBaPointer length: length. traceLevel >= 1 ifTrue: [self connection traceFunc: 'mysql_real_query' result: rc params: (Array with: self hConn with: sqlBa with: length)]. rc = self xif SUCCESS ifFalse: [self resultsCache: self getStatementErrors]. "Set rowCount indicators prior to retrieval." self rowCount: 0. self isRowCountKnown: false
fetchResult "Fetch the handle to the result set." | xif func pResult | xif := self xif. func := self class fetchEntireResultAtOnce ifTrue: [#mysql_store_result:] ifFalse: [#mysql_use_result:]. pResult := xif perform: func with: self hConn. traceLevel >= 3 ifTrue: [self connection traceFunc: func asString result: pResult params: self hConn]. self hResult: (pResult == xif NULL ifTrue: [nil] ifFalse: [pResult]). "Check to ensure that there is a result set if one was expected." (self hResult isNil and: [self getNumStatementColumns > 0]) ifTrue: [self class connectionClass unableToFetchDataSignal raiseRequestErrorString: #unableToFetchData << #mysql >> 'Unable to fetch data.']
fetchRow "Fetch the current row. If now more rows, answer nil." | xif pRow | xif := self xif. pRow := xif mysql_fetch_row: self hResult. traceLevel >= 3 ifTrue: [self connection traceFunc: 'mysql_fetch_row' result: pRow params: self hResult]. ^pRow == xif NULL ifTrue: ["No more data." nil] ifFalse: [pRow]
getFieldLengthsThisRow "Get the column lengths for the current returned row. The client library owns and will dispose of the pointers." | pFieldLengths | pFieldLengths := self xif mysql_fetch_lengths: self hResult. traceLevel >= 3 ifTrue: [self connection traceFunc: 'mysql_fetch_lengths' result: pFieldLengths params: self hResult]. ^pFieldLengths
installExternal super installExternal. self hResult: nil. self setMaxLongData: DefaultMaxLongData.
moreResultsExternal "Return true if there are more results." ^self checkForMoreResults
readyExternal "Answer whether or not the dbms has processed the SQL statement (batch). Answer true, and let the client block." ^true
resultsExternal "Result set assumed already fetched. Check for errors." | errs sqlState | (errs := self resultsCache) notNil ifTrue: [ 1 to: errs size do: [ :position| ((sqlState := (errs at: position) sqlState asSymbol) == #'01000' or: [ sqlState == #'S1000' ]) ifFalse: [ ^self class connectionClass unableToExecuteSQLSignal raiseWith: errs errorString: (errs at: position) dbmsErrorString ] ]. self class connectionClass externalDatabaseInformationSignal raiseRequestWith: errs. ]. ^true
</methods> <methods> Database.MySQLAdminSession <category>accessing</category>
hResultHolder ^hResultHolder
hResultHolder: anObject hResultHolder := anObject
isRowCountKnown ^isRowCountKnown
</methods> <methods> Database.MySQLAdminSession <category>private-accessing</category>
getStatementErrors "Return a collection of MySQLError(s) associated with the connection handle." ^self connection getConnectionErrors
hConn ^connection hConn
hResult "Return the results pointer, used for iterating through the query results." ^self hResultHolder value
hResult: aResultsPointerOrNil "Save the results pointer, used for iterating through the query results." ^self hResultHolder value: aResultsPointerOrNil
isRowCountKnown: anObject isRowCountKnown := anObject
resultsCache "Answer the contents of the result cache. Clear the cache." | results | results := resultsCache. resultsCache := nil. ^results
resultsCache: results "Cache results." resultsCache := results
rowCount: anObject rowCount := anObject
</methods> <methods> Database.MySQLAdminSession <category>data processing</category>
maxBufferSizeNeededDuringQuery "Of all my buffers, return the largest size necessary for un-truncated retrieval." | buffers | buffers := rowBuffersHolder value. ^buffers inject: 0 into: [:max :buf | buf maxBufferSizeNeeded max: max]
maxLongData "Return the maximum amount of data to be copied from LONGVARCHAR or LONGVARBINARY columns." ^maxLongData
prepare: aString "Prepare a query string for processing." super prepare: aString.
rowCount "Answer an Integer representing the number of rows affected by the previous query. For INSERT, UPDATE statements, it is the number of rows actually updated. For SELECT statements, it is the number of rows returned. Valid only after the query has been answered." ^rowCount
setMaxLongData: anInteger "Specify the maximum amount of data to be copied from LONGVARCHAR or LONGVARBINARY columns." maxLongData := (self class defaultMaxLongData min: anInteger).
</methods> <methods> Database.MySQLAdminSession <category>initialize-release</category>
initialize super initialize. hResultHolder := nil asValue. self setMaxLongData: self class defaultMaxLongData. self rowCount: 0. self isRowCountKnown: false.
</methods> <methods> Database.MySQLAdminSession class <category>accessing</category>
bufferClass "Answer the class to use for bindInput/Output objects associated with receiver." ^MySQLAdminBuffer
connectionClass "Answer the class to use for connection objects associated with receiver." ^MySQLAdminConnection
defaultConnection ^(self connectionClass new) username: 'root'; password: 'user'; environment: 'localhost'
defaultMaxLongData ^DefaultMaxLongData
defaultMaxLongData: anInteger DefaultMaxLongData := anInteger
errorClass "Answer the error class for the receiver." ^MySQLError
fetchEntireResultAtOnce "Return true to download all rows at once, false to download one row at a time." ^true
</methods> <methods> Database.MySQLAdminSession class <category>private-registry</category>
registry ^RegisteredMySQLCharacterSessions
registry: aCollection RegisteredMySQLCharacterSessions := aCollection
</methods> <methods> Database.MySQLAdminSession class <category>class initialization</category>
initialize "MySQLCharacterSession initialize" self initRegistry. DefaultMaxLongData := 16777216. "Default to 16 megs of long data" self install.
</methods> <methods> Database.MySQLAdminSession class <category>private-activation</category>
install self bufferClass install.
</methods> <methods> Database.MySQLHybridConnection class <category>accessing</category>
kind "Answer a symbol representing the type of DMBS the receiver provides services for." ^#'MySQL Hybrid'
sessionClass "Answer the class to use for session objects associated with receiver." ^MySQLHybridSession
</methods> <methods> Database.MySQLHybridConnection class <category>private-registry</category>
registry ^RegisteredMySQLHybridConnections
registry: aCollection RegisteredMySQLHybridConnections := aCollection
</methods> <methods> Database.MySQLHybridConnection class <category>class initialization</category>
initialize "MySQLHybridConnection initialize" ^super initialize
</methods> <methods> Database.MySQLHybridConnection class <category>examples</category>
allExamples "MySQLHybridConnection allExamples" ^super allExamples add: self example5; yourself
example5 "The following example query requires a MySQLAdminConnection, since MySQL doesn't permit certain queries for prepared statements. This class, MySQLHybridConnection, automatically channels queries through the appropriate session object. Likewise, bound queries will fail for MySQLAdminConnections. See the class comments for MySQLSession, MySQLAdminSession and MySQLHybridSession for a list of allowed queries for each session type. There is no actual returned value for the USE command, so the result is nil, but the session now lives in the requested database." "MySQLHybridConnection example5" ^self exampleQuery: 'USE mysql'
</methods> <methods> Database.MySQLColumnDescription <category>accessing</category>
catalog ^catalog
catalog: anObject catalog := anObject
charsetnr ^charsetnr
charsetnr: anObject charsetnr := anObject
db ^db
db: anObject db := anObject
def ^def
def: anObject def := anObject
isBinaryCollation ^isBinaryCollation
isBinaryCollation: anObject isBinaryCollation := anObject
isUnsigned ^isUnsigned
isUnsigned: anObject isUnsigned := anObject
mysqlType ^mysqlType
mysqlType: anObject mysqlType := anObject
org_name ^org_name
org_name: anObject org_name := anObject
org_table ^org_table
org_table: anObject org_table := anObject
table ^table
table: anObject table := anObject
</methods> <methods> Database.MySQLColumnDescription <category>testing</category>
isATimeType "Answer true if the receiver represents a time-type column." | xif | xif := self class connectionClass xif. ^xif isTimeType: mysqlType.
isLong "Answer true if the receiver represents a long result column. TINYBLOB is 2^8-1, BLOB is 2^16-1, MEDIUMBLOB is 2^24-1, LONGBLOB is 2^32-1. TEXT types have same mysqlType as BLOBs, but isBinary is false for TEXT." | xif | xif := self class connectionClass xif. ^xif isLongType: mysqlType.
</methods> <methods> Database.MySQLColumnDescription class <category>accessing</category>
connectionClass ^MySQLConnection
</methods> <methods> Core.Integer <category>private-mysql</category>
mysqlConversion "Answer the symbolic conversion name for instances of this class or subclasses." ^#Integer
</methods> <methods> Core.String <category>private-mysql</category>
asBooleanForMySQL "Try to interpret the string as a Boolean using a common Cobol paradigm. Treat the value as null if it doesn't match the encoded value for true or false." self size == 1 ifTrue: [ self = 'Y' ifTrue: [ ^true ]. self = 'N' ifTrue: [ ^false ] ]. ^nil
</methods> <methods> Core.Object <category>private-mysql</category>
mysqlConversion "Answer the symbolic conversion name for instances of this class or subclasses. The default is no conversion is defined" ^nil
</methods> <methods> Core.FixedPoint <category>private-mysql</category>
mysqlConversion "Answer the symbolic conversion name for instances of this class or subclasses." ^#FixedPoint
</methods> <methods> Core.ByteArray <category>private-mysql</category>
mysqlConversion "Answer the symbolic conversion name for instances of this class or subclasses." self size > 255 ifTrue: [^#LargeByteArray]. ^#ByteArray
</methods> <methods> Core.LargeInteger <category>private-mysql</category>
mysqlConversion "Answer the symbolic conversion name for instances of this class or subclasses." ^#LargeInteger
</methods> <methods> Core.Double <category>private-mysql</category>
mysqlConversion "Answer the symbolic conversion name for instances of this class or subclasses." ^#Double
</methods> <methods> Core.Timestamp <category>private-mysql</category>
mysqlConversion "Answer the symbolic conversion name for instances of this class or subclasses." ^#Timestamp
</methods> <methods> Core.Boolean <category>private-mysql</category>
mysqlConversion "Answer the symbolic conversion name for instances of this class or subclasses." ^#Boolean
printStringForMySQL "Encode receiver in one character using a common Cobol paradigm." ^self ifTrue: [ 'Y' ] ifFalse: [ 'N' ]
</methods> <methods> Core.Time <category>private-mysql</category>
mysqlConversion "Answer the symbolic conversion name for instances of this class or subclasses." ^#Time
</methods> <methods> Core.Float <category>private-mysql</category>
mysqlConversion "Answer the symbolic conversion name for instances of this class or subclasses." ^#Float
</methods> <methods> Core.Date <category>private-mysql</category>
mysqlConversion "Answer the symbolic conversion name for instances of this class or subclasses." ^#Date
</methods> <methods> Core.CharacterArray <category>private-mysql</category>
mysqlConversion "Answer the symbolic conversion name for instances of this class or subclasses." self size > 255 ifTrue: [^#LargeString]. ^#String
</methods> <initialize> Database.MySQLConnection </initialize> <initialize> Database.MySQLInterface </initialize> <initialize> Database.MySQLBuffer </initialize> <initialize> Database.MySQLAdminBuffer </initialize> <initialize> Database.MySQLAdminConnection </initialize> <initialize> Database.MySQLSession </initialize> <initialize> Database.MySQLAdminSession </initialize> <initialize> Database.MySQLHybridConnection </initialize> "Imported Classes:" self error: 'Attempting to file-in parcel imports. Choose terminate or close' <class> <name>Object</name> <environment>Core</environment> <super></super> <private>false</private> none <imports></imports> <category>Kernel-Objects</category> <attributes> <package>Kernel-Objects</package> </attributes> </class> <class> <name>Time</name> <environment>Core</environment> <super>Core.Magnitude</super> <private>false</private> none hours minutes seconds <imports></imports> <category>Magnitude-General</category> <attributes> <package>Magnitude-General</package> </attributes> </class> <class> <name>Integer</name> <environment>Core</environment> <super>Core.Number</super> <private>false</private> none <imports></imports> <category>Magnitude-Numbers</category> <attributes> <package>Magnitude-Numbers</package> </attributes> </class> <class> <name>LargeInteger</name> <environment>Core</environment> <super>Core.Integer</super> <private>false</private> bytes <imports></imports> <category>Magnitude-Numbers</category> <attributes> <package>Magnitude-Numbers</package> </attributes> </class> <class> <name>Float</name> <environment>Core</environment> <super>Core.LimitedPrecisionReal</super> <private>false</private> bytes <imports></imports> <category>Magnitude-Numbers</category> <attributes> <package>Magnitude-Numbers</package> </attributes> </class> <class> <name>CharacterArray</name> <environment>Core</environment> <super>Core.ArrayedCollection</super> <private>false</private> none <imports></imports> <category>Collections-Text</category> <attributes> <package>Collections-Text</package> </attributes> </class> <class> <name>ByteArray</name> <environment>Core</environment> <super>Core.IntegerArray</super> <private>false</private> bytes <imports></imports> <category>Collections-Arrayed</category> <attributes> <package>Collections-Arrayed</package> </attributes> </class> <class> <name>Double</name> <environment>Core</environment> <super>Core.LimitedPrecisionReal</super> <private>false</private> bytes <imports></imports> <category>Magnitude-Numbers</category> <attributes> <package>Magnitude-Numbers</package> </attributes> </class> <class> <name>Timestamp</name> <environment>Core</environment> <super>Core.Magnitude</super> <private>false</private> none year month day hour minute second millisecond <imports></imports> <category>UIBasics-Support</category> <attributes> <package>UIBasics-Support</package> </attributes> </class> <class> <name>Set</name> <environment>Core</environment> <super>Core.Collection</super> <private>false</private> objects tally <imports></imports> <category>Collections-Unordered</category> <attributes> <package>Collections-Unordered</package> </attributes> </class> <class> <name>ExternalDatabaseColumnDescription</name> <environment>Database</environment> <super>Core.Object</super> <private>false</private> none name index type length precision scale nullable <imports></imports> <category>Database-Interface</category> <attributes> <package>Database</package> </attributes> </class> <class> <name>Boolean</name> <environment>Core</environment> <super>Core.Object</super> <private>false</private> none <imports></imports> <category>Kernel-Objects</category> <attributes> <package>Kernel-Objects</package> </attributes> </class> <class> <name>ExternalInterface</name> <environment>External</environment> <super>Core.Object</super> <private>false</private> none includeFiles includeDirectories libraryFiles libraryDirectories virtual optimizationLevel <imports> private Kernel.OpcodePool.* </imports> <category>External-Interface</category> <attributes> <package>External-Interface</package> </attributes> </class> <class> <name>FixedPoint</name> <environment>Core</environment> <super>Core.Number</super> <private>false</private> none numerator denominator scale <imports></imports> <category>Magnitude-Numbers</category> <attributes> <package>Magnitude-Numbers</package> </attributes> </class> <class> <name>ExternalDatabaseSession</name> <environment>Database</environment> <super>Database.ExternalDatabaseFramework</super> <private>false</private> none connection query queryFragments bindInput bindTemplate bindOutput useNamedOutputBinding bindValues resultTemplate allocateForEachRow blockFactor numColumns columnDescriptions rowAdaptors rowBuffersHolder bufferIndex answerStream currentRow scrollable <imports></imports> <category>Database-Interface</category> <attributes> <package>Database</package> </attributes> </class> <class> <name>ExternalDatabaseError</name> <environment>Database</environment> <super>Core.Object</super> <private>false</private> none dbmsErrorCode dbmsErrorString osErrorCode osErrorString <imports></imports> <category>Database-Interface</category> <attributes> <package>Database</package> </attributes> </class> <class> <name>ExternalDatabaseBuffer</name> <environment>Database</environment> <super>Core.Object</super> <private>false</private> none databaseType encoding elementSize count bufferPointer <imports></imports> <category>Database-Interface</category> <attributes> <package>Database</package> </attributes> </class> <class> <name>String</name> <environment>Core</environment> <super>Core.CharacterArray</super> <private>false</private> none <imports></imports> <category>Collections-Text</category> <attributes> <package>Collections-Text</package> </attributes> </class> <class> <name>ExternalDatabaseTransaction</name> <environment>Database</environment> <super>Database.ExternalDatabaseFramework</super> <private>false</private> none memberCountHolder remainingCountHolder <imports></imports> <category>Database-Interface</category> <attributes> <package>Database</package> </attributes> </class> <class> <name>Date</name> <environment>Core</environment> <super>Core.Magnitude</super> <private>false</private> none day year <imports></imports> <category>Magnitude-General</category> <attributes> <package>Magnitude-General</package> </attributes> </class> <class> <name>ExternalDatabaseConnection</name> <environment>Database</environment> <super>Database.ExternalDatabaseFramework</super> <private>false</private> none transaction username password environment transactionCoordinator cachedSession isolationLevel environmentMap xif xifMap dependents <imports></imports> <category>Database-Interface</category> <attributes> <package>Database</package> </attributes> </class>