package DBIx::MyServer; use warnings; use strict; use Socket; use Carp qw(cluck carp croak); use Digest::SHA1; our $VERSION = '0.41'; use constant MYSERVER_PACKET_COUNT => 0; use constant MYSERVER_SOCKET => 1; use constant MYSERVER_DATABASE => 4; use constant MYSERVER_THREAD_ID => 5; use constant MYSERVER_SCRAMBLE => 6; use constant MYSERVER_DBH => 7; use constant MYSERVER_PARSER => 8; use constant MYSERVER_BANNER => 9; use constant MYSERVER_SERVER_CHARSET => 10; use constant MYSERVER_CLIENT_CHARSET => 11; use constant MYSERVER_SALT => 12; use constant FIELD_CATALOG => 0; use constant FIELD_DB => 1; use constant FIELD_TABLE => 2; use constant FIELD_ORG_TABLE => 3; use constant FIELD_NAME => 4; use constant FIELD_ORG_NAME => 5; use constant FIELD_LENGTH => 6; use constant FIELD_TYPE => 7; use constant FIELD_FLAGS => 8; use constant FIELD_DECIMALS => 9; use constant FIELD_DEFAULT => 10; # # This comes from include/mysql_com.h of the MySQL source # use constant CLIENT_LONG_PASSWORD => 1; use constant CLIENT_FOUND_ROWS => 2; use constant CLIENT_LONG_FLAG => 4; use constant CLIENT_CONNECT_WITH_DB => 8; use constant CLIENT_NO_SCHEMA => 16; use constant CLIENT_COMPRESS => 32; # Must implement that one use constant CLIENT_ODBC => 64; use constant CLIENT_LOCAL_FILES => 128; use constant CLIENT_IGNORE_SPACE => 256; use constant CLIENT_PROTOCOL_41 => 512; use constant CLIENT_INTERACTIVE => 1024; use constant CLIENT_SSL => 2048; # Must implement that one use constant CLIENT_IGNORE_SIGPIPE => 4096; use constant CLIENT_TRANSACTIONS => 8192; use constant CLIENT_RESERVED => 16384; use constant CLIENT_SECURE_CONNECTION => 32768; use constant CLIENT_MULTI_STATEMENTS => 1 << 16; use constant CLIENT_MULTI_RESULTS => 1 << 17; use constant CLIENT_SSL_VERIFY_SERVER_CERT => 1 << 30; use constant CLIENT_REMEMBER_OPTIONS => 1 << 31; use constant SERVER_STATUS_IN_TRANS => 1; use constant SERVER_STATUS_AUTOCOMMIT => 2; use constant SERVER_MORE_RESULTS_EXISTS => 8; use constant SERVER_QUERY_NO_GOOD_INDEX_USED => 16; use constant SERVER_QUERY_NO_INDEX_USED => 32; use constant SERVER_STATUS_CURSOR_EXISTS => 64; use constant SERVER_STATUS_LAST_ROW_SENT => 128; use constant SERVER_STATUS_DB_DROPPED => 256; use constant SERVER_STATUS_NO_BACKSLASH_ESCAPES => 512; use constant COM_SLEEP => 0; use constant COM_QUIT => 1; use constant COM_INIT_DB => 2; use constant COM_QUERY => 3; use constant COM_FIELD_LIST => 4; use constant COM_CREATE_DB => 5; use constant COM_DROP_DB => 6; use constant COM_REFRESH => 7; use constant COM_SHUTDOWN => 8; use constant COM_STATISTICS => 9; use constant COM_PROCESS_INFO => 10; use constant COM_CONNECT => 11; use constant COM_PROCESS_KILL => 12; use constant COM_DEBUG => 13; use constant COM_PING => 14; use constant COM_TIME => 15; use constant COM_DELAYED_INSERT => 16; use constant COM_CHANGE_USER => 17; use constant COM_BINLOG_DUMP => 18; use constant COM_TABLE_DUMP => 19; use constant COM_CONNECT_OUT => 20; use constant COM_REGISTER_SLAVE => 21; use constant COM_STMT_PREPARE => 22; use constant COM_STMT_EXECUTE => 23; use constant COM_STMT_SEND_LONG_DATA => 24; use constant COM_STMT_CLOSE => 25; use constant COM_STMT_RESET => 26; use constant COM_SET_OPTION => 27; use constant COM_STMT_FETCH => 28; use constant COM_END => 29; # This is taken from include/mysql_com.h use constant MYSQL_TYPE_DECIMAL => 0; use constant MYSQL_TYPE_TINY => 1; use constant MYSQL_TYPE_SHORT => 2; use constant MYSQL_TYPE_LONG => 3; use constant MYSQL_TYPE_FLOAT => 4; use constant MYSQL_TYPE_DOUBLE => 5; use constant MYSQL_TYPE_NULL => 6; use constant MYSQL_TYPE_TIMESTAMP => 7; use constant MYSQL_TYPE_LONGLONG => 8; use constant MYSQL_TYPE_INT24 => 9; use constant MYSQL_TYPE_DATE => 10; use constant MYSQL_TYPE_TIME => 11; use constant MYSQL_TYPE_DATETIME => 12; use constant MYSQL_TYPE_YEAR => 13; use constant MYSQL_TYPE_NEWDATE => 14; use constant MYSQL_TYPE_VARCHAR => 15; use constant MYSQL_TYPE_BIT => 16; use constant MYSQL_TYPE_NEWDECIMAL => 246; use constant MYSQL_TYPE_ENUM => 247; use constant MYSQL_TYPE_SET => 248; use constant MYSQL_TYPE_TINY_BLOB => 249; use constant MYSQL_TYPE_MEDIUM_BLOB => 250; use constant MYSQL_TYPE_LONG_BLOB => 251; use constant MYSQL_TYPE_BLOB => 252; use constant MYSQL_TYPE_VAR_STRING => 253; use constant MYSQL_TYPE_STRING => 254; use constant MYSQL_TYPE_GEOMETRY => 255; use constant NOT_NULL_FLAG => 1; use constant PRI_KEY_FLAG => 2; use constant UNIQUE_KEY_FLAG => 4; use constant MULTIPLE_KEY_FLAG => 8; use constant BLOB_FLAG => 16; use constant UNSIGNED_FLAG => 32; use constant ZEROFILL_FLAG => 64; use constant BINARY_FLAG => 128; use constant ENUM_FLAG => 256; use constant AUTO_INCREMENT_FLAG => 512; use constant TIMESTAMP_FLAG => 1024; use constant SET_FLAG => 2048; use constant NO_DEFAULT_VALUE_FLAG => 4096; use constant NUM_FLAG => 32768; =head1 NAME DBIx::MyServer - Server-side implementation of the MySQL network protocol =head1 SYNOPSIS Please see the scripts in the C directory. C along with C shows how to use this module by subclassing it. C shows how to use this module directly. =head1 DESCRIPTION This module emulates the server side of the MySQL protocol. This allows you to run your own faux-MySQL servers which can accept commands and queries and reply accordingly. Please see C for a system that allows building functional mysql servers that rewrite queries or return arbitary data. =head1 CONSTRUCTOR =item C<< my $myserver = DBIx::MyServer->new( socket => $socket, parser => $parser, dbh => $dbh ... ) >> The following parameters are accepted: C - the socket that will be used for communication with the client. The socket must be created in advance with L and an incoming connection must be already established using L C - a L handle. L does not use it however it can be used by modules inheriting from L C - a L handle. If you do not override the C method, this handle will be used to parse the SQL in order to call the appropriate C method. C - the server version string that is announced to the client. If not specified, the name and the version of the L module is sent. Some clients, e.g. L attempt to parse that string as a version number in order to determine the server capabilities. Therefore, it may be a good idea to start your C with a string in the form C<5.0.37>. For example, the C example takes the C from the actual MySQL server the connection is forwarded to. Please note that the MySQL client may isssue a C