My favorites | Sign in
Project Home Downloads Wiki Issues Source
Search
for
infernomysql  
Here is some Inferno Limbo code that was the start of a native mysql module.
Updated Feb 18, 2010 by demer...@gmail.com

Introduction

The code below is what I had started working on to develop a native Infero/Limbo mysql module. It is essentially a bunch of tests wrapping some pretty basic MySQL calls. Most of what you see below allows one to connect, authenticate and then start sending/receiving data back and from a MySQL 4.x+ database server. I imagine it would be a pretty good starting point for someone who was interested in doing something like this. I put it up here for educational purposes.

Download

mysql.tar.gz

Building Source

The code in the source archive is built using the normal Inferno/Limbo tools. However, I create a shell script (build) that creates a make file (mkfile) automatically depending on various files within the "deps" directory. It works in a similar fashion to Dan Berstein's (qmail guy) build scripts. Is experimental, but keeps from having to do recursive make; whic is HARMFUL!

Just run "build all" from the command line. A complete mkfile generated by the build command is shown below.

Some Code (see tar archive for full source)

mkfile

all:V: prog

clean:V: clean-std

compile:V: conf-limbo-exec



mysql.dis: compile  mysql.m  mysql.b  mysql_constants.m  mysql_utils.dis  mysql_security.dis 
	./compile mysql.b

mysql:V: mysql.dis

mysql_client.dis: compile 
 mysql_client.m 
 mysql_client.b 
 mysql_constants.m 
 mysql_utils.dis 
 mysql_security.dis
 
	./compile mysql_client.b

mysql_client:V: mysql_client.dis

mysql_security.dis: compile  mysql_constants.m  mysql_utils.dis  mysql_security.m  mysql_security.b 
	./compile mysql_security.b

mysql_security:V: mysql_security.dis

mysql_test.dis: compile
 mysql_client.m
 mysql_constants.m
 mysql_test.m
 mysql_utils.m
 mysql_security.m
 mysql_client.b
 mysql_test.b
 mysql_utils.b
 mysql_security.b
 
	./compile mysql_test.b

mysql_test:V: mysql_test.dis

mysql_utils.dis: compile mysql_constants.m  mysql_utils.m  mysql_utils.b 
	./compile mysql_utils.b

mysql_utils:V: mysql_utils.dis

mysqlcli.dis: compile 
 mysql_constants.m 
 mysqlcli.b 
 mysql_client.dis 
 mysql_test.dis 
 mysql_utils.dis 
 mysql_security.dis
 
	./compile mysqlcli.b

mysqlcli:V: mysqlcli.dis

prog:V: mysql.dis mysql_test.dis mysqlcli.dis 

clean-std:V:
    rm -f *.dis *.sbl

conf-limbo-exec:V: conf-limbo
    cat conf-limbo > compile
    chmod 755 compile

mysql_con.m

PVERSION41_CHAR: con '*';
COM_BINLOG_DUMP: con 18;
COM_CHANGE_USER: con 17;
COM_CLOSE_STATEMENT: con 25;
COM_CONNECT_OUT: con 20;
COM_END: con 28;
COM_EXECUTE: con 23;
COM_LONG_DATA: con 24;
COM_PREPARE: con 22;
COM_REGISTER_SLAVE: con 21;
COM_RESET_STMT: con 26;
COM_SET_OPTION: con 27;
COM_TABLE_DUMP: con 19;
CONNECT: con 11;
CREATE_DB: con 5;
DEBUG: con 13;
DELAYED_INSERT: con 16;
DROP_DB: con 6;
FIELD_LIST: con 4;
FIELD_TYPE_BIT: con 16;
FIELD_TYPE_BLOB: con 252;
FIELD_TYPE_DATE: con 10;
FIELD_TYPE_DATETIME: con 12;
FIELD_TYPE_DECIMAL: con 0;
FIELD_TYPE_DOUBLE: con 5;
FIELD_TYPE_ENUM: con 247;
FIELD_TYPE_FLOAT: con 4;
FIELD_TYPE_GEOMETRY: con 255;
FIELD_TYPE_INT24: con 9;
FIELD_TYPE_LONG: con 3;
FIELD_TYPE_LONG_BLOB: con 251;
FIELD_TYPE_LONGLONG: con 8;
FIELD_TYPE_MEDIUM_BLOB: con 250;
FIELD_TYPE_NEW_DECIMAL: con 246;
FIELD_TYPE_NEWDATE: con 14;
FIELD_TYPE_NULL: con 6;
FIELD_TYPE_SET: con 248;
FIELD_TYPE_SHORT: con 2;
FIELD_TYPE_STRING: con 254;
FIELD_TYPE_TIME: con 11;
FIELD_TYPE_TIMESTAMP: con 7;
FIELD_TYPE_TINY: con 1;
FIELD_TYPE_TINY_BLOB: con 249;
FIELD_TYPE_VAR_STRING: con 253;
FIELD_TYPE_VARCHAR: con 15;
FIELD_TYPE_YEAR: con 13;
INIT_DB: con 2;
LENGTH_BLOB: con 65535;
LENGTH_LONGBLOB: con 4294967295;
LENGTH_MEDIUMBLOB: con 16777215;
LENGTH_TINYBLOB: con 255;
MAX_ROWS: con 50000000; 
PING: con 14;
PROCESS_INFO: con 10;
PROCESS_KILL: con 12;
QUERY: con 3;
QUIT: con 1;
RELOAD: con 7;
SHUTDOWN: con 8;
SLEEP: con 0;
STATISTICS: con 9;
TIME: con 15; 

# MYSQL Errors

ER_ABORTING_CONNECTION: con 1152;
ER_ACCESS_DENIED_ERROR: con 1045;
ER_ALTER_INFO: con 1088;
ER_AUTO_CONVERT: con 1246;
ER_BAD_DB_ERROR: con 1049;
ER_BAD_FIELD_ERROR: con 1054;
ER_BAD_FT_COLUMN: con 1283;
ER_BAD_HOST_ERROR: con 1042;
ER_BAD_NULL_ERROR: con 1048;
ER_BAD_SLAVE: con 1200;
ER_BAD_SLAVE_UNTIL_COND: con 1277;
ER_BAD_TABLE_ERROR: con 1051;
ER_BLOB_CANT_HAVE_DEFAULT: con 1101;
ER_BLOB_KEY_WITHOUT_LENGTH: con 1170;
ER_BLOB_USED_AS_KEY: con 1073;
ER_BLOBS_AND_NO_TERMINATED: con 1084;
ER_CANNOT_ADD_FOREIGN: con 1215;
ER_CANT_AGGREGATE_2COLLATIONS: con 1267;
ER_CANT_AGGREGATE_3COLLATIONS: con 1270;
ER_CANT_AGGREGATE_NCOLLATIONS: con 1271;
ER_CANT_CREATE_DB: con 1006;
ER_CANT_CREATE_FILE: con 1004;
ER_CANT_CREATE_TABLE: con 1005;
ER_CANT_CREATE_THREAD: con 1135;
ER_CANT_DELETE_FILE: con 1011;
ER_CANT_DO_THIS_DURING_AN_TRANSACTION: con 1179;
ER_CANT_DROP_FIELD_OR_KEY: con 1091;
ER_CANT_FIND_DL_ENTRY: con 1127;
ER_CANT_FIND_SYSTEM_REC: con 1012;
ER_CANT_FIND_UDF: con 1122;
ER_CANT_GET_STAT: con 1013;
ER_CANT_GET_WD: con 1014;
ER_CANT_INITIALIZE_UDF: con 1123;
ER_CANT_LOCK: con 1015;
ER_CANT_OPEN_FILE: con 1016;
ER_CANT_OPEN_LIBRARY: con 1126;
ER_CANT_READ_DIR: con 1018;
ER_CANT_REMOVE_ALL_FIELDS: con 1090;
ER_CANT_REOPEN_TABLE: con 1137;
ER_CANT_SET_WD: con 1019;
ER_CANT_UPDATE_WITH_READLOCK: con 1223;
ER_CANT_USE_OPTION_HERE: con 1234;
ER_CHECK_NO_SUCH_TABLE: con 1177;
ER_CHECK_NOT_IMPLEMENTED: con 1178;
ER_CHECKREAD: con 1020;
ER_COLLATION_CHARSET_MISMATCH: con 1253;
ER_COLUMNACCESS_DENIED_ERROR: con 1143;
ER_CON_COUNT_ERROR: con 1040;
ER_CONNECT_TO_MASTER: con 1218;
ER_CORRUPT_HELP_DB: con 1244;
ER_CRASHED_ON_REPAIR: con 1195;
ER_CRASHED_ON_USAGE: con 1194;
ER_CREATE_DB_WITH_READ_LOCK: con 1209;
ER_CUT_VALUE_GROUP_CONCAT: con 1260;
ER_CYCLIC_REFERENCE: con 1245;
ER_DB_CREATE_EXISTS: con 1007;
ER_DB_DROP_DELETE: con 1009;
ER_DB_DROP_EXISTS: con 1008;
ER_DB_DROP_RMDIR: con 1010;
ER_DBACCESS_DENIED_ERROR: con 1044;
ER_DELAYED_CANT_CHANGE_LOCK: con 1150;
ER_DELAYED_INSERT_TABLE_LOCKED: con 1165;
ER_DERIVED_MUST_HAVE_ALIAS: con 1248;
ER_DISK_FULL: con 1021;
ER_DROP_DB_WITH_READ_LOCK: con 1208;
ER_DROP_USER: con 1268;
ER_DUMP_NOT_IMPLEMENTED: con 1185;
ER_DUP_ARGUMENT: con 1225;
ER_DUP_ENTRY: con 1062;
ER_DUP_FIELDNAME: con 1060;
ER_DUP_KEY: con 1022;
ER_DUP_KEYNAME: con 1061;
ER_DUP_UNIQUE: con 1169;
ER_DUPLICATED_VALUE_IN_TYPE: con 1291;
ER_EMPTY_QUERY: con 1065;
ER_ERROR_DURING_CHECKPOINT: con 1183;
ER_ERROR_DURING_COMMIT: con 1180;
ER_ERROR_DURING_FLUSH_LOGS: con 1182;
ER_ERROR_DURING_ROLLBACK: con 1181;
ER_ERROR_MESSAGES: con 298;
ER_ERROR_ON_CLOSE: con 1023;
ER_ERROR_ON_READ: con 1024;
ER_ERROR_ON_RENAME: con 1025;
ER_ERROR_ON_WRITE: con 1026;
ER_ERROR_WHEN_EXECUTING_COMMAND: con 1220;
ER_FEATURE_DISABLED: con 1289;
ER_FIELD_SPECIFIED_TWICE: con 1110;
ER_FILE_EXISTS_ERROR: con 1086;
ER_FILE_NOT_FOUND: con 1017;
ER_FILE_USED: con 1027;
ER_FILSORT_ABORT: con 1028;
ER_FLUSH_MASTER_BINLOG_CLOSED: con 1186;
ER_FORCING_CLOSE: con 1080;
ER_FORM_NOT_FOUND: con 1029;
ER_FT_MATCHING_KEY_NOT_FOUND: con 1191;
ER_FUNCTION_NOT_DEFINED: con 1128;
ER_GET_ERRMSG: con 1296;
ER_GET_ERRNO: con 1030;
ER_GET_TEMPORARY_ERRMSG: con 1297;
ER_GLOBAL_VARIABLE: con 1229;
ER_GOT_SIGNAL: con 1078;
ER_GRANT_WRONG_HOST_OR_USER: con 1145;
ER_HANDSHAKE_ERROR: con 1043;
ER_HASHCHK: con 1000;
ER_HOST_IS_BLOCKED: con 1129;
ER_HOST_NOT_PRIVILEGED: con 1130;
ER_ILLEGAL_GRANT_FOR_TABLE: con 1144;
ER_ILLEGAL_HA: con 1031;
ER_ILLEGAL_REFERENCE: con 1247;
ER_INCORRECT_GLOBAL_LOCAL_VAR: con 1238;
ER_INDEX_REBUILD: con 1187;
ER_INSERT_INFO: con 1092;
ER_INVALID_DEFAULT: con 1067;
ER_INVALID_GROUP_FUNC_USE: con 1111;
ER_INVALID_ON_UPDATE: con 1294;
ER_INVALID_USE_OF_NULL: con 1138;
ER_IPSOCK_ERROR: con 1081;
ER_KEY_COLUMN_DOES_NOT_EXITS: con 1072;
ER_KEY_DOES_NOT_EXITS: con 1176;
ER_KEY_NOT_FOUND: con 1032;
ER_KEY_REF_DO_NOT_MATCH_TABLE_REF: con 1240;
ER_KILL_DENIED_ERROR: con 1095;
ER_LOAD_INFO: con 1087;
ER_LOCAL_VARIABLE: con 1228;
ER_LOCK_DEADLOCK: con 1213;
ER_LOCK_OR_ACTIVE_TRANSACTION: con 1192;
ER_LOCK_TABLE_FULL: con 1206;
ER_LOCK_WAIT_TIMEOUT: con 1205;
ER_MASTER: con 1188;
ER_MASTER_FATAL_ERROR_READING_BINLOG: con 1236;
ER_MASTER_INFO: con 1201;
ER_MASTER_NET_READ: con 1189;
ER_MASTER_NET_WRITE: con 1190;
ER_MISSING_SKIP_SLAVE: con 1278;
ER_MIX_OF_GROUP_FUNC_AND_FIELDS: con 1140;
ER_MIXING_NOT_ALLOWED: con 1224;
ER_MULTIPLE_PRI_KEY: con 1068;
ER_NET_ERROR_ON_WRITE: con 1160;
ER_NET_FCNTL_ERROR: con 1155;
ER_NET_PACKET_TOO_LARGE: con 1153;
ER_NET_PACKETS_OUT_OF_ORDER: con 1156;
ER_NET_READ_ERROR: con 1158;
ER_NET_READ_ERROR_FROM_PIPE: con 1154;
ER_NET_READ_INTERRUPTED: con 1159;
ER_NET_UNCOMPRESS_ERROR: con 1157;
ER_NET_WRITE_INTERRUPTED: con 1161;
ER_NEW_ABORTING_CONNECTION: con 1184;
ER_NISAMCHK: con 1001;
ER_NO: con 1002;
ER_NO_DB_ERROR: con 1046;
ER_NO_DEFAULT: con 1230;
ER_NO_PERMISSION_TO_CREATE_USER: con 1211;
ER_NO_RAID_COMPILED: con 1174;
ER_NO_REFERENCED_ROW: con 1216;
ER_NO_SUCH_INDEX: con 1082;
ER_NO_SUCH_TABLE: con 1146;
ER_NO_SUCH_THREAD: con 1094;
ER_NO_TABLES_USED: con 1096;
ER_NO_UNIQUE_LOGFILE: con 1098;
ER_NON_UNIQ_ERROR: con 1052;
ER_NON_UPDATABLE_TABLE: con 1288;
ER_NONEXISTING_GRANT: con 1141;
ER_NONEXISTING_TABLE_GRANT: con 1147;
ER_NONUNIQ_TABLE: con 1066;
ER_NORMAL_SHUTDOWN: con 1077;
ER_NOT_ALLOWED_COMMAND: con 1148;
ER_NOT_FORM_FILE: con 1033;
ER_NOT_KEYFILE: con 1034;
ER_NOT_SUPPORTED_AUTH_MODE: con 1251;
ER_NOT_SUPPORTED_YET: con 1235;
ER_NULL_COLUMN_IN_INDEX: con 1121;
ER_OLD_KEYFILE: con 1035;
ER_OPEN_AS_READONLY: con 1036;
ER_OPERAND_COLUMNS: con 1241;
ER_OPTION_PREVENTS_STATEMENT: con 1290;
ER_OUT_OF_RESOURCES: con 1041;
ER_OUT_OF_SORTMEMORY: con 1038;
ER_OUTOFMEMORY: con 1037;
ER_PARSE_ERROR: con 1064;
ER_PASSWORD_ANONYMOUS_USER: con 1131;
ER_PASSWORD_NO_MATCH: con 1133;
ER_PASSWORD_NOT_ALLOWED: con 1132;
ER_PRIMARY_CANT_HAVE_NULL: con 1171;
ER_QUERY_ON_MASTER: con 1219;
ER_READ_ONLY_TRANSACTION: con 1207;
ER_READY: con 1076;
ER_RECORD_FILE_FULL: con 1114;
ER_REGEXP_ERROR: con 1139;
ER_REQUIRES_PRIMARY_KEY: con 1173;
ER_REVOKE_GRANTS: con 1269;
ER_ROW_IS_REFERENCED: con 1217;
ER_SELECT_REDUCED: con 1249;
ER_SERVER_IS_IN_SECURE_AUTH_MODE: con 1275;
ER_SERVER_SHUTDOWN: con 1053;
ER_SET_CONSTANTS_ONLY: con 1204;
ER_SHUTDOWN_COMPLETE: con 1079;
ER_SLAVE_IGNORED_SSL_PARAMS: con 1274;
ER_SLAVE_IGNORED_TABLE: con 1237;
ER_SLAVE_MUST_STOP: con 1198;
ER_SLAVE_NOT_RUNNING: con 1199;
ER_SLAVE_THREAD: con 1202;
ER_SLAVE_WAS_NOT_RUNNING: con 1255;
ER_SLAVE_WAS_RUNNING: con 1254;
ER_SPATIAL_CANT_HAVE_NULL: con 1252;
ER_SPECIFIC_ACCESS_DENIED_ERROR: con 1227;
ER_STACK_OVERRUN: con 1119;
ER_SUBQUERY_NO_1_ROW: con 1242;
ER_SYNTAX_ERROR: con 1149;
ER_TABLE_CANT_HANDLE_AUTO_INCREMENT: con 1164;
ER_TABLE_CANT_HANDLE_BLOB: con 1163;
ER_TABLE_CANT_HANDLE_FT: con 1214;
ER_TABLE_EXISTS_ERROR: con 1050;
ER_TABLE_MUST_HAVE_COLUMNS: con 1113;
ER_TABLE_NOT_LOCKED: con 1100;
ER_TABLE_NOT_LOCKED_FOR_WRITE: con 1099;
ER_TABLEACCESS_DENIED_ERROR: con 1142;
ER_TABLENAME_NOT_ALLOWED_HERE: con 1250;
ER_TEXTFILE_NOT_READABLE: con 1085;
ER_TOO_BIG_FIELDLENGTH: con 1074;
ER_TOO_BIG_FOR_UNCOMPRESS: con 1256;
ER_TOO_BIG_ROWSIZE: con 1118;
ER_TOO_BIG_SELECT: con 1104;
ER_TOO_BIG_SET: con 1097;
ER_TOO_LONG_IDENT: con 1059;
ER_TOO_LONG_KEY: con 1071;
ER_TOO_LONG_STRING: con 1162;
ER_TOO_MANY_DELAYED_THREADS: con 1151;
ER_TOO_MANY_FIELDS: con 1117;
ER_TOO_MANY_KEY_PARTS: con 1070;
ER_TOO_MANY_KEYS: con 1069;
ER_TOO_MANY_ROWS: con 1172;
ER_TOO_MANY_TABLES: con 1116;
ER_TOO_MANY_USER_CONNECTIONS: con 1203;
ER_TOO_MUCH_AUTO_TIMESTAMP_COLS: con 1293;
ER_TRANS_CACHE_FULL: con 1197;
ER_TRUNCATED_WRONG_VALUE: con 1292;
ER_UDF_EXISTS: con 1125;
ER_UDF_NO_PATHS: con 1124;
ER_UNEXPECTED_EOF: con 1039;
ER_UNION_TABLES_IN_DIFFERENT_DIR: con 1212;
ER_UNKNOWN_CHARACTER_SET: con 1115;
ER_UNKNOWN_COLLATION: con 1273;
ER_UNKNOWN_COM_ERROR: con 1047;
ER_UNKNOWN_ERROR: con 1105;
ER_UNKNOWN_KEY_CACHE: con 1284;
ER_UNKNOWN_PROCEDURE: con 1106;
ER_UNKNOWN_STMT_HANDLER: con 1243;
ER_UNKNOWN_STORAGE_ENGINE: con 1286;
ER_UNKNOWN_SYSTEM_VARIABLE: con 1193;
ER_UNKNOWN_TABLE: con 1109;
ER_UNSUPPORTED_EXTENSION: con 1112;
ER_UNSUPPORTED_PS: con 1295;
ER_UNTIL_COND_IGNORED: con 1279;
ER_UPDATE_INFO: con 1134;
ER_UPDATE_TABLE_USED: con 1093;
ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE: con 1175;
ER_USER_LIMIT_REACHED: con 1226;
ER_VAR_CANT_BE_READ: con 1233;
ER_VARIABLE_IS_NOT_STRUCT: con 1272;
ER_WARN_DATA_OUT_OF_RANGE: con 1264;
ER_WARN_DATA_TRUNCATED: con 1265;
ER_WARN_DEPRECATED_SYNTAX: con 1287;
ER_WARN_FIELD_RESOLVED: con 1276;
ER_WARN_HOSTNAME_WONT_WORK: con 1285;
ER_WARN_NULL_TO_NOTNULL: con 1263;
ER_WARN_QC_RESIZE: con 1282;
ER_WARN_TOO_FEW_RECORDS: con 1261;
ER_WARN_TOO_MANY_RECORDS: con 1262;
ER_WARN_USING_OTHER_HANDLER: con 1266;
ER_WARNING_NOT_COMPLETE_ROLLBACK: con 1196;
ER_WRONG_ARGUMENTS: con 1210;
ER_WRONG_AUTO_KEY: con 1075;
ER_WRONG_COLUMN_NAME: con 1166;
ER_WRONG_DB_NAME: con 1102;
ER_WRONG_FIELD_SPEC: con 1063;
ER_WRONG_FIELD_TERMINATORS: con 1083;
ER_WRONG_FIELD_WITH_GROUP: con 1055;
ER_WRONG_FK_DEF: con 1239;
ER_WRONG_GROUP_FIELD: con 1056;
ER_WRONG_KEY_COLUMN: con 1167;
ER_WRONG_MRG_TABLE: con 1168;
ER_WRONG_NAME_FOR_CATALOG: con 1281;
ER_WRONG_NAME_FOR_INDEX: con 1280;
ER_WRONG_NUMBER_OF_COLUMNS_IN_SELECT: con 1222;
ER_WRONG_OUTER_JOIN: con 1120;
ER_WRONG_PARAMCOUNT_TO_PROCEDURE: con 1107;
ER_WRONG_PARAMETERS_TO_PROCEDURE: con 1108;
ER_WRONG_SUB_KEY: con 1089;
ER_WRONG_SUM_SELECT: con 1057;
ER_WRONG_TABLE_NAME: con 1103;
ER_WRONG_TYPE_FOR_VAR: con 1232;
ER_WRONG_USAGE: con 1221;
ER_WRONG_VALUE_COUNT: con 1058;
ER_WRONG_VALUE_COUNT_ON_ROW: con 1136;
ER_WRONG_VALUE_FOR_VAR: con 1231;
ER_YES: con 1003;
ER_ZLIB_Z_BUF_ERROR: con 1258;
ER_ZLIB_Z_DATA_ERROR: con 1259;
ER_ZLIB_Z_MEM_ERROR: con 1257;

mysql_client.m

    
MySql: module
{
    PATH: con "/usr/TMendoza/mysql/mysql_client.dis";

    Packet: adt {        
        length:           int;
        sequence:         int;
        pos:              int;
        data:             array of byte;        

        mysql_error:      fn(pkt: self ref Packet): string;
        has_error:        fn(pkt: self ref Packet): int;
        read_protocol:    fn(pkt: self ref Packet): int;
        read_threadid:    fn(pkt: self ref Packet): int;
        read_version:     fn(pkt: self ref Packet): string;
        read_caps:        fn(pkt: self ref Packet): int;
        read_charset:     fn(pkt: self ref Packet): int;
        read_servstat:    fn(pkt: self ref Packet): int;
        read_salt:        fn(pkt: self ref Packet): string;
        read_salt0:       fn(pkt: self ref Packet): string;
        incr_pos:         fn(pkt: self ref Packet, c: int);
        rewind:           fn(pkt: self ref Packet);
        allocate:         fn(io: ref IO): ref Packet;
    };
    
};

mysql.b

implement MySql;
      
include "mysql_utils.m";
    utils: MySqlUtils;
    ModLoader:  import utils;
    FDTools:    import utils;
    Misc:       import utils;
    Msg:        import utils;
    Conv:       import utils;
    Dump:       import utils;
    IO:         import utils;

include "mysql.m";
    mysql: MySql;
    
load_modules()
{
    utils = load MySqlUtils MySqlUtils->PATH;
}

Packet.mysql_error(pkt: self ref Packet): string
{
    misc: ref Misc = ref Misc;
    
    errStr := "";
    errorNumber := (int pkt.data[1] & 16rff) + ((int pkt.data[2] & 16rff) << 8);
    errorMessage := misc.error2txt(errorNumber);
    errStr = errStr + errorMessage + "[" + string errorNumber + "] " + string pkt.data[3:pkt.length];
    return errStr;
}

Packet.has_error(pkt: self ref Packet): int
{
    if (int pkt.data[0] == 255)
    {
        return -1;
    }
    return 0;
}

Packet.read_protocol(pkt: self ref Packet): int
{
    retval := int pkt.data[0];
    pkt.pos++;
    return retval; 
}

Packet.read_threadid(pkt: self ref Packet): int
{
    threadid: int;
    threadid  = (int pkt.data[pkt.pos] & 16rff) + 
                ((int pkt.data[pkt.pos+1] & 16rff) << 8) + 
                ((int pkt.data[pkt.pos+2] & 16rff) << 16) + 
                ((int pkt.data[pkt.pos+3] & 16rff) << 32);
    pkt.pos += 4;
    return threadid;
}

Packet.read_caps(pkt: self ref Packet): int
{
    caps: int;
    caps = (int pkt.data[pkt.pos] & 16rff) +
               ((int pkt.data[pkt.pos+1] & 16rff) << 8);
    pkt.pos += 2;
    return caps;
}

Packet.read_charset(pkt: self ref Packet): int
{
    charset: int;
    charset = int pkt.data[pkt.pos] & 16rff;
    pkt.pos++;
    return charset;
}

Packet.read_servstat(pkt: self ref Packet): int
{
    servstat: int;
    servstat = (int pkt.data[pkt.pos] & 16rff) +
              ((int pkt.data[pkt.pos+1] & 16rff) << 8);
    pkt.pos += 2;
    return servstat;
}

Packet.read_version(pkt: self ref Packet): string
{
    BUFSIZE: con 64;
    bufcount := BUFSIZE;
    
    buf := array[bufcount] of byte;
    idx := 0;
    b: byte;
    
    do
    {
        b = pkt.data[idx];
        
        if (idx == bufcount)
        {
            bufcount = bufcount + BUFSIZE;
            tempbuf := buf;
            buf = array[bufcount] of byte;
            for (x:=0; x<len tempbuf; x++)
                buf[x] = tempbuf[x];
        }

        buf[idx] = b;
                    
        idx++; 
        
    } while (int b != 0);

    pkt.pos = pkt.pos + (idx-1);
    
    return string buf[1:idx-1];
}

Packet.read_salt(pkt: self ref Packet): string
{
    BUFSIZE: con 64;
    bufcount := BUFSIZE;
    
    buf := array[bufcount] of byte;
    idx := 0;
    b: byte;
    
    do
    {
        b = pkt.data[pkt.pos+idx];
        
        if (idx == bufcount)
        {
            bufcount = bufcount + BUFSIZE;
            tempbuf := buf;
            buf = array[bufcount] of byte;
            for (x:=0; x<len tempbuf; x++)
                buf[x] = tempbuf[x];
        }
        
        buf[idx] = b;
                    
        idx++; 
       
    } while (int b != 0);
    
    pkt.pos += idx;
    
    return string buf[:idx-1];
}

Packet.read_salt0(pkt: self ref Packet): string
{
    BUFSIZE: con 64;
    bufcount := BUFSIZE;
    
    buf := array[bufcount] of byte;
    idx := 0;
    b: byte;
    
    do
    {
        b = pkt.data[pkt.pos+idx];
        
        if (idx == bufcount)
        {
            bufcount = bufcount + BUFSIZE;
            tempbuf := buf;
            buf = array[bufcount] of byte;
            for (x:=0; x<len tempbuf; x++)
                buf[x] = tempbuf[x];
        }
        
        buf[idx] = b;
                    
        idx++; 
        
    } while (int b != 0);
    
    pkt.pos += idx;
    
    return string buf[:idx-1];
}

Packet.incr_pos(pkt: self ref Packet, c: int)
{
    pkt.pos =+ c;
}

Packet.rewind(pkt: self ref Packet)
{
    pkt.pos = 0;
}

Packet.allocate(io: ref IO): ref Packet
{
    load_modules();
    
    pkt0: ref Packet = ref Packet;

    b := io.readstream(4);
    bl := len b;
    
    pkt0.length      = (int b[0] & 16rff) + ((int b[1] & 16rff) << 8) + ((int b[2] & 16rff) << 16);
    pkt0.sequence    = int b[3];
    pkt0.data        = io.readstream(pkt0.length);
    pkt0.pos         = 0;
        
    return pkt0;
}

mysql_client.b

implement MySql;
      
include "mysql_utils.m";
    utils: MySqlUtils;
    ModLoader:  import utils;
    FDTools:    import utils;
    Misc:       import utils;
    Msg:        import utils;
    Conv:       import utils;
    Dump:       import utils;
    IO:         import utils;

include "mysql_client.m";
    mysql: MySql;
    
load_modules()
{
    utils = load MySqlUtils MySqlUtils->PATH;
}

Packet.mysql_error(pkt: self ref Packet): string
{
    misc: ref Misc = ref Misc;
    
    errStr := "";
    errorNumber := (int pkt.data[1] & 16rff) + ((int pkt.data[2] & 16rff) << 8);
    errorMessage := misc.error2txt(errorNumber);
    errStr = errStr + errorMessage + "[" + string errorNumber + "] " + string pkt.data[3:pkt.length];
    return errStr;
}

Packet.has_error(pkt: self ref Packet): int
{
    if (int pkt.data[0] == 255)
    {
        return -1;
    }
    return 0;
}

Packet.read_protocol(pkt: self ref Packet): int
{
    retval := int pkt.data[0];
    pkt.pos++;
    return retval; 
}

Packet.read_threadid(pkt: self ref Packet): int
{
    threadid: int;
    threadid  = (int pkt.data[pkt.pos] & 16rff) + 
                ((int pkt.data[pkt.pos+1] & 16rff) << 8) + 
                ((int pkt.data[pkt.pos+2] & 16rff) << 16) + 
                ((int pkt.data[pkt.pos+3] & 16rff) << 32);
    pkt.pos += 4;
    return threadid;
}

Packet.read_caps(pkt: self ref Packet): int
{
    caps: int;
    caps = (int pkt.data[pkt.pos] & 16rff) +
               ((int pkt.data[pkt.pos+1] & 16rff) << 8);
    pkt.pos += 2;
    return caps;
}

Packet.read_charset(pkt: self ref Packet): int
{
    charset: int;
    charset = int pkt.data[pkt.pos] & 16rff;
    pkt.pos++;
    return charset;
}

Packet.read_servstat(pkt: self ref Packet): int
{
    servstat: int;
    servstat = (int pkt.data[pkt.pos] & 16rff) +
              ((int pkt.data[pkt.pos+1] & 16rff) << 8);
    pkt.pos += 2;
    return servstat;
}

Packet.read_version(pkt: self ref Packet): string
{
    BUFSIZE: con 64;
    bufcount := BUFSIZE;
    
    buf := array[bufcount] of byte;
    idx := 0;
    b: byte;
    
    do
    {
        b = pkt.data[idx];
        
        if (idx == bufcount)
        {
            bufcount = bufcount + BUFSIZE;
            tempbuf := buf;
            buf = array[bufcount] of byte;
            for (x:=0; x<len tempbuf; x++)
                buf[x] = tempbuf[x];
        }

        buf[idx] = b;
                    
        idx++; 
        
    } while (int b != 0);

    pkt.pos = pkt.pos + (idx-1);
    
    return string buf[1:idx-1];
}

Packet.read_salt(pkt: self ref Packet): string
{
    BUFSIZE: con 64;
    bufcount := BUFSIZE;
    
    buf := array[bufcount] of byte;
    idx := 0;
    b: byte;
    
    do
    {
        b = pkt.data[pkt.pos+idx];
        
        if (idx == bufcount)
        {
            bufcount = bufcount + BUFSIZE;
            tempbuf := buf;
            buf = array[bufcount] of byte;
            for (x:=0; x<len tempbuf; x++)
                buf[x] = tempbuf[x];
        }
        
        buf[idx] = b;
                    
        idx++; 
       
    } while (int b != 0);
    
    pkt.pos += idx;
    
    return string buf[:idx-1];
}

Packet.read_salt0(pkt: self ref Packet): string
{
    BUFSIZE: con 64;
    bufcount := BUFSIZE;
    
    buf := array[bufcount] of byte;
    idx := 0;
    b: byte;
    
    do
    {
        b = pkt.data[pkt.pos+idx];
        
        if (idx == bufcount)
        {
            bufcount = bufcount + BUFSIZE;
            tempbuf := buf;
            buf = array[bufcount] of byte;
            for (x:=0; x<len tempbuf; x++)
                buf[x] = tempbuf[x];
        }
        
        buf[idx] = b;
                    
        idx++; 
        
    } while (int b != 0);
    
    pkt.pos += idx;
    
    return string buf[:idx-1];
}

Packet.incr_pos(pkt: self ref Packet, c: int)
{
    pkt.pos =+ c;
}

Packet.rewind(pkt: self ref Packet)
{
    pkt.pos = 0;
}

Packet.allocate(io: ref IO): ref Packet
{
    load_modules();
    
    pkt0: ref Packet = ref Packet;

    b := io.readstream(4);
    bl := len b;
    
    pkt0.length      = (int b[0] & 16rff) + ((int b[1] & 16rff) << 8) + ((int b[2] & 16rff) << 16);
    pkt0.sequence    = int b[3];
    pkt0.data        = io.readstream(pkt0.length);
    pkt0.pos         = 0;
        
    return pkt0;
}

mysql_security.b

implement MySqlSec;

include "mysql_utils.m";
    utils: MySqlUtils;
    ModLoader:  import utils;
    FDTools:    import utils;
    Misc:       import utils;
    Msg:        import utils;
    Conv:       import utils;
    Dump:       import utils;

include "mysql_security.m";
include "mysql_constants.m";

load_modules() {
    utils = load MySqlUtils MySqlUtils->PATH;  
}

SecOps.allocate(): ref SecOps
{
    load_modules();
    secOps := ref SecOps;
    return secOps;
}

SecOps.crypt_password(m: self ref SecOps, from: ref RefArray, too: ref RefArray, password: ref RefArray, length: int)
{
    pos: int = 0;
    
    while ( pos < len(from.byteList) && pos < length ) {
        too.byteList[pos] = byte (from.byteList[pos] ^ password.byteList[pos]);
        pos++;
    }
}

SecOps.scramble_password( m: self ref SecOps, password: string ): string
{ 
    conv: ref Conv = Conv.allocate();
    
    passhash: array of big = m.hash_new( password );
    str := "";
    str += conv.big2hexstr( passhash[0] );    
    str += conv.big2hexstr( passhash[1] );
    return str;
}

SecOps.password_hash_stage1( m: self ref SecOps, password: string ): array of byte
{
    ml: ref ModLoader = ref ModLoader;
    
    kr: Keyring = ml.modload_keyring(Keyring->PATH);
    
    state: ref DigestState = nil;
    tmpByte := array[1] of byte;
    
    passwordLength := len( password );
    
    for ( x := 0; x < passwordLength; x++ ) {
        if ( password[x] == ' ' || password[x] == '\t' ) {
            continue;
        }
        tmpByte[0] = byte password[x];
        kr->sha1(tmpByte, 1, nil, state);
    }
    
    digest := array[kr->SHA1dlen] of byte;
    kr->sha1(tmpByte, 0, digest, state);
    return digest;
}

SecOps.password_hash_stage2( m: self ref SecOps, hashedPassword: array of byte, salt: array of byte ): array of byte
{
    ml: ref ModLoader = ref ModLoader;
    
    kr: Keyring = ml.modload_keyring(Keyring->PATH);
    
    state: ref DigestState = nil;

    kr->sha1(salt, 4, nil, state);
    kr->sha1(hashedPassword, kr->SHA1dlen, nil, state);
    digest := array[kr->SHA1dlen] of byte;
    kr->sha1(hashedPassword, 0, digest, state);
    return digest;
}

SecOps.sha1_hash_array( m: self ref SecOps, data: array of byte ): array of byte
{
    ml: ref ModLoader = ref ModLoader;
    
    kr: Keyring = ml.modload_keyring(Keyring->PATH);
    
    state: ref DigestState = nil;
    kr->sha1(data, len(data), nil, state);
    digest := array[kr->SHA1dlen] of byte;
    kr->sha1(data, 0, digest, state);
    return digest;
}

SecOps.scramble411( m: self ref SecOps, password: string, seed: string ): array of byte
{
    conv: ref Conv = Conv.allocate();
    
    passStage1: array of byte;
    passStage2: array of byte;
    seedAsBytes: array of byte;
    
    passStage1 = m.sha1_hash_array( conv.str2byteArray( password ) );
    passStage2 = m.sha1_hash_array( passStage1 );
    
    seedAsBytes = conv.str2byteArray( seed );
    
    ml: ref ModLoader = ref ModLoader;
    
    kr: Keyring = ml.modload_keyring(Keyring->PATH);
    
    state: ref DigestState = nil;
    
    kr->sha1(seedAsBytes, len(seedAsBytes), nil, state);
    kr->sha1(passStage2, len(passStage2), nil, state);
    
    digest := array[kr->SHA1dlen] of byte;
    kr->sha1(passStage2, 0, digest, state);
       
    for ( i := 0; i < len(digest); i++ ) {
        digest[i] = byte (digest[i] ^ passStage1[i]);
    }
    
    return digest;
}

SecOps.get_binary_password( m: self ref SecOps, salt: array of int, usingNewPasswords: int): array of byte
{
    ml: ref ModLoader = ref ModLoader;
    
    kr: Keyring = ml.modload_keyring(Keyring->PATH);
    
    state: ref DigestState = nil;

    val: int = 0;
    binaryPassword := array[kr->SHA1dlen] of byte;
    
    if (usingNewPasswords == 1) {
        pos: int = 0;
        
        for ( i := 0; i < 4; i++ ) {
            val = salt[i];
            
            for ( t := 3; t >= 0; t-- ) {
                binaryPassword[pos++] = byte (val & 255);
                val = val >> 8;
            }
        }
        return binaryPassword;
    }
    
    offset: int = 0;
    
    for ( i := 0; i < 2; i++ ) {
        val = salt[i];
        
        for ( t := 3; t >= 0; t-- ) {
            binaryPassword[t+offset] = byte (val % 255);
            val = val >> 8;
        }
        offset += 4;
    }
    
    kr->sha1(binaryPassword, 8, nil, state);
    
    digest := array[kr->SHA1dlen] of byte;
    
    kr->sha1(binaryPassword, 0, digest, state);
    
    return digest;
}

SecOps.create_key_from_old_pass( m: self ref SecOps, passwd: string ): array of byte
{
    newpass: string = m.scramble_password( passwd );
    salt: array of int = m.get_salt_from_pass( newpass );
    return m.get_binary_password( salt, 0 );
}

SecOps.get_salt_from_pass(m: self ref SecOps, password: string): array of int
{
    conv: ref Conv = Conv.allocate();
    
    result := array[6] of int;
    
    if ((password == nil) || (len(password) == 0)) {
        return result;
    }

    if (password[0] == PVERSION41_CHAR) {
        saltInHex := password[1:5];

        val := 0;

        for (i := 0; i < 4; i++) {
            val = (val << 4) + conv.char_hexval(saltInHex[i]);
        }

        return result;
    }

    resultPos := 0;
    pos := 0;
    length := len(password);

    while (pos < length) {
        val := 0;

        for (i := 0; i < 8; i++) {
            val = (val << 4) + conv.char_hexval(password[pos++]);
        }

        result[resultPos++] = val;
    }

    return result;
}
    
SecOps.crypt_new(m: self ref SecOps, password: string, seed: string): string
{
    conv: ref Conv = Conv.allocate();
    msgr: ref Msg = Msg.allocate();
         
    ml: ref ModLoader = ref ModLoader;    
    mth: Math = ml.modload_math(Math->PATH);
        
    b: byte;
    d: real;
    
    pw := m.hash_new(seed);
    msg := m.hash_new(password);
    
    max := big 16r3fffffff;
        
    seed1 := (pw[0] ^ msg[0]) % max;    
    seed2 := (pw[1] ^ msg[1]) % max;
    chars := array[len(seed)] of big;
    
    for (i:=0; i < len(seed); i++)
    {
        seed1 = ((seed1 * big 3) + seed2) % max;
        seed2 = (seed1 + seed2 + big 33) % max;
        d = real seed1 / real max;
        b = byte mth->floor((d * real 31) + real 64);
        chars[i] = big b;
    }

    seed1 = ((seed1 * big 3) + seed2) % max;
    seed2 = (seed1 + seed2 + big 33) % max;
    d = real seed1 / real max;
    b = byte mth->floor(d * real 31);

    for (i = 0; i < len(seed); i++) {
        chars[i] ^=  big b;
    }
    
    charInts := array[len(chars)] of int;
    
    for (idx := 0; idx < len(chars); idx++) {
        charInts[idx] = int chars[idx];
    }
    
    return conv.array2str( charInts );
}

SecOps.crypt_old(m: self ref SecOps, password: string, seed: string): string
{
    conv: ref Conv = Conv.allocate();
    
    ml: ref ModLoader = ref ModLoader;    
    mth: Math = ml.modload_math(Math->PATH);
    
    hp: big;
    hm: big;
    s1: big;
    s2: big;
    max: big = big 16r01ffffff;
    d: real;
    b: byte;

    hp = m.hash_old(seed);
    hm = m.hash_old(password);

    nr: big = hp ^ hm;
    nr %= max;
    s1 = nr;
    s2 = nr / big 2;

    chars := array[len(seed)] of big;

    for (i := 0; i < len(seed); i++) {
        s1 = ((s1 * big 3) + s2) % max;
        s2 = (s1 + s2 + big 33) % max;
        d = real s1 / real max;
        b = byte mth->floor((d * real 31) + real 64);
        chars[i] = big b;
    }

    charInts := array[len(chars)] of int;
    
    for (idx := 0; idx < len(chars); idx++) {
        charInts[idx] = int chars[idx];
    }
    
    return conv.array2str( charInts );
}

SecOps.hash_new(m: self ref SecOps, password: string): array of big
{
    
    nr: big = big 1345345333;
    add: big = big 7;
    nr2: big = big 16r12345671;
    tmp: big;
    
    for (x:=0; x < len(password); x++)
    {
        if (password[x] == ' ' || password[x] == '\t')
        {
            continue;
        }
        tmp = (big 16rff & big password[x]);
        nr ^= ((((nr & big 63) + add) * tmp) + (nr << 8));
        nr2 += ((nr2 << 8) ^ nr);
        add += tmp;
    }
    
    result := array[2] of big;
    result[0] = nr & big 16r7fffffff;
    result[1] = nr2 & big 16r7fffffff;
    return result;
}

SecOps.hash_old(m: self ref SecOps, password: string): big
{
    nr: big = big 1345345333;
    nr2: big = big 7;
    tmp: big;

    for (i := 0; i < len(password); i++) {
        if (password[i] == ' ' || password[i] == '\t') {
            continue;
        }

        tmp = big password[i];
        nr ^= ((((nr & big 63) + nr2) * tmp) + (nr << 8));
        nr2 += tmp;
    }

    return nr & ((big 1 << 31) - big 1);
}

SecOps.random_init(m: self ref SecOps, randStruct: ref RandData, seed1: big, seed2: big)
{
    #randStruct: RandData;
    randStruct.maxValue = big 16r3fffffff;
    randStruct.maxValueDbl = real randStruct.maxValue;
    randStruct.seed1 = seed1 % randStruct.maxValue;
    randStruct.seed2 = seed2 % randStruct.maxValue;
}

SecOps.scramble(m: self ref SecOps, message: string, password: string): string
{
    conv: ref Conv = Conv.allocate();

    ml: ref ModLoader = ref ModLoader;    
    mth: Math = ml.modload_math(Math->PATH);
    
    hashPass: array of big;
    hashMessage: array of big;
    too := array[8] of byte;
    val := ""; 
    randStruct: ref RandData;
    
    randStruct = ref RandData;
    
    newmessage := message[:8];
    
    if (password != nil && len(password) > 0) {
        hashPass = m.hash_new(password);
        hashMessage = m.hash_new(newmessage);

        m.random_init(randStruct, hashPass[0] ^ hashMessage[0], hashPass[1] ^ hashMessage[1]);

        msgPos: int = 0;
        msgLength: int = len(newmessage);
        toPos: int = 0;
        
        while (msgPos++ < msgLength) {
            too[toPos++] = byte mth->floor((m.rnd(randStruct) * real 31) + real 64);
        }

        extra := byte mth->floor((m.rnd(randStruct) * real 31));

        for (i := 0; i < len(too); i++) {
            too[i] ^= extra;
        }

        charInts := array[len(too)] of int;

        for (idx := 0; idx < len(too); idx++) {
            charInts[idx] = int too[idx];
        }
        
        val = conv.array2str( charInts );
    }

    return val;
}

SecOps.rnd( m: self ref SecOps, data: ref RandData ): real 
{
    data.seed1 = ((data.seed1 * big 3) + data.seed2) % data.maxValue;
    data.seed2 = (data.seed1 + data.seed2 + big 33) % data.maxValue;
    val: real = (real data.seed1 / data.maxValueDbl);
    return val;
}

mysql_test.b

implement MySqlTest;
    
include "mysql_utils.m";
    utils: MySqlUtils;
    ModLoader:  import utils;
    FDTools:    import utils;
    Misc:       import utils;
    Msg:        import utils;
    Conv:       import utils;
    Dump:       import utils;
    Net:        import utils;
    IO:         import utils;

include "mysql_client.m";
    mysql: MySql;
    Packet:     import mysql;
    
include "mysql_security.m";
    mysqlsec: MySqlSec;
    SecOps:     import mysqlsec;
    RefArray:   import mysqlsec;
    RandData:   import mysqlsec;
    
include "mysql_test.m";

load_modules()
{
    if (mysql == nil)       mysql       = load MySql MySql->PATH;
    if (utils == nil)       utils       = load MySqlUtils MySqlUtils->PATH;
    if (mysqlsec == nil)    mysqlsec    = load MySqlSec MySqlSec->PATH;
}

MySqlTestCases.test_hash_new(mt: self ref MySqlTestCases)
{
    
    
    s: ref SecOps = SecOps.allocate();
    m: ref Msg = Msg.allocate();
    
    m.msgstr( "test_hash_new" , "start" );
    
    teststring: string = "Tony Mendoza";
    result: array of big = s.hash_new(teststring);
    
    for (x:=0; x < len(result); x++) {
        m.msgbig("test_hash_new", result[x]);
    }
    
    m.msgstr( "test_hash_new" , "end" );
}

MySqlTestCases.test_hash_old(mt: self ref MySqlTestCases)
{
    
    
    s: ref SecOps = SecOps.allocate();
    m: ref Msg = Msg.allocate();
    
    m.msgstr( "test_hash_old" , "start" );
    
    teststring: string = "Tony Mendoza";
    result: big = s.hash_old(teststring);
    m.msgbig("test_hash_old", result);
    
    m.msgstr( "test_hash_old" , "end" );
}

MySqlTestCases.test_crypt_new(mt: self ref MySqlTestCases)
{
    
    
    s: ref SecOps = SecOps.allocate();
    m: ref Msg = Msg.allocate();
    
    m.msgstr( "test_crypt_new" , "start" );
    
    teststring: string = "Tony Mendoza";
    seed: string = "big freakazoid";
    res := s.crypt_new( teststring, seed );
    m.msgstr( "test_crypt_new", res );
    m.msgint( "test_crypt_new", len(res) );
    
    m.msgstr( "test_crypt_new" , "old" );
}

MySqlTestCases.test_crypt_old(mt: self ref MySqlTestCases)
{
    
    
    s: ref SecOps = SecOps.allocate();
    m: ref Msg = Msg.allocate();
    
    m.msgstr( "test_crypt_old" , "start" );
    
    teststring: string = "Tony Mendoza";
    seed: string = "big freakazoid";
    res := s.crypt_old( teststring, seed );
    m.msgstr( "test_crypt_old", res );
    m.msgint( "test_crypt_old", len(res) );
    
    m.msgstr( "test_crypt_old" , "end" );
}

MySqlTestCases.test_big_2_hexstr(mt: self ref MySqlTestCases) 
{
    
    
    s: ref SecOps = SecOps.allocate();
    m: ref Msg = Msg.allocate();
    c: ref Conv = Conv.allocate();
    
    m.msgstr("Hex String #42: ", c.big2hexstr(big 442368769));
}

MySqlTestCases.test_password_hash_stage1(mt: self ref MySqlTestCases)
{
    
    
    s: ref SecOps = SecOps.allocate();
    d: ref Dump = Dump.allocate();
    
    d.show_bytes_str( "test_password_hash_stage1", s.password_hash_stage1( "TonyMendoza" ) );
}

MySqlTestCases.test_scramble_password(mt: self ref MySqlTestCases)
{
    
    
    s: ref SecOps = SecOps.allocate();
    m: ref Msg = Msg.allocate();
    
    m.msgstr( "test_scramble_password", s.scramble_password( "t0ny8602" ) );
}

MySqlTestCases.test_rand_adt(mt: self ref MySqlTestCases) 
{
    
    
    s: ref SecOps = SecOps.allocate();
    m: ref Msg = Msg.allocate();
    
    seed1: big = big 123456789;
    seed2: big = big 987654321;
    
    data: ref RandData;
    data = ref RandData;
    
    s.random_init( data, seed1, seed2 );

    m.msgbig( "testRandStruct: maxValue = ", data.maxValue );
    m.msgreal( "testRandStruct: maxValueDbl = ", data.maxValueDbl );
    m.msgbig( "testRandStruct: seed1 = ", data.seed1 );
    m.msgbig( "testRandStruct: seed2 = ", data.seed2 );
}

MySqlTestCases.test_scramble(mt: self ref MySqlTestCases) 
{
    
    
    s: ref SecOps = SecOps.allocate();
    m: ref Msg = Msg.allocate();
    
    m.msgstr("testScramble: message = ", "Tony Mendoza");
    m.msgstr("testScramble: password = ", "t0ny8602!");
    m.msgstr("testScramble: ", s.scramble("Tony Mendoza", "t0ny8602!"));
}

MySqlTestCases.test_connect(mt: self ref MySqlTestCases)
{
    
    
    #mq:     ref MySqlOps    = MySqlOps.allocate();
    s:      ref SecOps      = SecOps.allocate();
    m:      ref Msg         = Msg.allocate();
    loader: ref ModLoader   = ref ModLoader;
    conv:   ref Conv        = Conv.allocate();
    net:    ref Net         = Net.allocate();
    misc:   ref Misc        = Misc.allocate();
    pkt:    ref Packet;
    
    sys   = loader.modload_sys(Sys->PATH);        
    S     = loader.modload_string(String->PATH);
    bufio = loader.modload_bufio(Bufio->PATH);
    math  = loader.modload_math(Math->PATH);
    key   = loader.modload_keyring(Keyring->PATH);
    
    conn: Connection;
    rv: int;
    err := "";
    
    m.msg("Connecting to 192.168.1.119...");
    
    (rv,conn) = net.connect("tcp", "192.168.1.119", "3306");
    
    if (rv < 0) {
        m.msgint("Connection Code", rv);
        syserr := sys->sprint("%r");
        if(S->prefix("cs: dialup", syserr))
            err = syserr[4:];
        else if(S->prefix("cs: dns: no translation found", syserr))
            err = "unknown host";
        else
            err = sys->sprint("couldn't connect: %s", syserr); 
        misc.error(err);
    } 
    
    io: ref IO = IO.allocate(conn.dfd); 
    
    m.msg("Connected to MySQL at 192.168.1.119.");
    m.msg("Sending handshake data...");
    
    pkt = Packet.allocate(io);

    # Now lets check to see if there was an error (Hex: FF)
    if (pkt.has_error())
    {
        m.msg( pkt.mysql_error() );
        return;
    }

    proto       := pkt.read_protocol();
    msgstr0     := pkt.read_version();
    threadid    := pkt.read_threadid();    
    saltstr     := pkt.read_salt();    
    caps        := pkt.read_caps();   
    charSet     := pkt.read_charset();
    status      := pkt.read_servstat();
    
    pkt.incr_pos(13);
    
    remsaltstr  := pkt.read_salt0();

    m.msgint("Data Buffer Length", pkt.length);
    m.msgint("Packet Sequence", pkt.sequence);    
    m.msgint("Protocol Version", proto);
    m.msgstr("MySQL Version", msgstr0);
    m.msgint("Thread ID", threadid);    
    m.msgstr("Salt String", saltstr);        
    m.msgint("Capabilities Flags", caps);
    m.msgint("Character Set", charSet);
    m.msgint("Server Status", status);
    m.msgstr("Remaining Salt String", remsaltstr);
    m.msgint("Final Packet Position",pkt.pos);    
}

MySqlTestCases.test_all(mt: self ref MySqlTestCases)
{
        #mt.test_hash_new();
        #mt.test_hash_old();
        #mt.test_crypt_new();
        #mt.test_crypt_old();
        #mt.test_big_2_hexstr();
        #mt.test_password_hash_stage1();
        #mt.test_scramble_password();
        #mt.test_rand_adt();
        #mt.test_scramble();
        mt.test_connect();
}

MySqlTestCases.allocate(): ref MySqlTestCases
{
    load_modules();

    mt: ref MySqlTestCases = ref MySqlTestCases;
    return mt;
}

mysql_utils.b

implement MySqlUtils;

include "mysql_utils.m";
include "mysql_constants.m";

ModLoader.modload_string(m: self ref ModLoader, path: string): String
{
    if (S != nil)
        return S;
        
    S = load String path;
    
    if (S == nil) 
        m.badmod(path);
        
    return S;
}

ModLoader.modload_bufio(m: self ref ModLoader, path: string): Bufio
{
    if (bufio != nil)
        return bufio;
    
    bufio = load Bufio path;
    
    if (bufio == nil) 
        m.badmod(path);
    
    return bufio;
}

ModLoader.modload_sys(m: self ref ModLoader, path: string): Sys
{
    if (sys != nil)
        return sys;
        
    sys = load Sys path;
    
    if (sys == nil) 
        m.badmod(path);
    
    return sys;
}


ModLoader.modload_math(l: self ref ModLoader, path: string): Math
{
    if (math != nil)
        return math;
        
    math = load Math path;
    
    if (math == nil) 
        l.badmod(path);
        
    return math;
}

ModLoader.modload_keyring(m: self ref ModLoader, path: string): Keyring
{
    if (key != nil)
        return key;
        
    key = load Keyring path;
    
    if (key == nil) 
        m.badmod(path);
    
    return key;
}

ModLoader.badmod(m: self ref ModLoader, path: string)
{
    ml: ref ModLoader = ref ModLoader;
    sys: Sys = ml.modload_sys(Sys->PATH);        
    sys->print("failed to load %s: %r\n",path);
    exit;
}

FDTools.fd_stderr(f: self ref FDTools): ref Sys->FD
{
    ml: ref ModLoader = ref ModLoader;
    s: Sys = ml.modload_sys(Sys->PATH);        
    return s->fildes(2);
}

FDTools.fd_stdout(f: self ref FDTools): ref Sys->FD
{
    ml: ref ModLoader = ref ModLoader;
    s: Sys = ml.modload_sys(Sys->PATH);        
    return s->fildes(1);
}

FDTools.fd_stdin(f: self ref FDTools): ref Sys->FD
{
    ml: ref ModLoader = ref ModLoader;
    s: Sys = ml.modload_sys(Sys->PATH);        
    return s->fildes(0);
}

FDTools.allocate(): ref FDTools
{
    fd := ref FDTools;
    return fd;
}

Msg.allocate(): ref Msg
{
    msg := ref Msg;
    return msg;
}

Msg.msg(m: self ref Msg, e: string)
{
    ml: ref ModLoader = ref ModLoader;
    s: Sys = ml.modload_sys(Sys->PATH);        
    s->print("%s\n", e);
}

Msg.msgint(m: self ref Msg, e: string, i: int)
{
    ml: ref ModLoader = ref ModLoader;
    s: Sys = ml.modload_sys(Sys->PATH);        
    s->print("%s: %d\n", e, i);
}

Msg.msgbig(m: self ref Msg, e: string, i: big)
{
    ml: ref ModLoader = ref ModLoader;
    s: Sys = ml.modload_sys(Sys->PATH);        
    s->print("%s: %bd\n", e, i);
}

Msg.msgreal(m: self ref Msg, e: string, i: real)
{
    ml: ref ModLoader = ref ModLoader;
    s: Sys = ml.modload_sys(Sys->PATH);        
    s->print("%s: %e\n", e, i);
}

Msg.msguint(m: self ref Msg, e: string, i: int)
{
    ml: ref ModLoader = ref ModLoader;
    s: Sys = ml.modload_sys(Sys->PATH);        
    s->print("%s: %ud\n", e, i);
}

Msg.msgstr(m: self ref Msg, e: string, i: string)
{
    ml: ref ModLoader = ref ModLoader;
    s: Sys = ml.modload_sys(Sys->PATH);        
    s->print("%s: %s\n", e, i);
}

Msg.msgxint(m: self ref Msg, e: string, i: int)
{
    ml: ref ModLoader = ref ModLoader;
    s: Sys = ml.modload_sys(Sys->PATH);        
    s->print("%s: %x\n", e, i);
}

Msg.msgxint0(m: self ref Msg, e: string, i: byte, b: int)
{
    ml: ref ModLoader = ref ModLoader;
    s: Sys = ml.modload_sys(Sys->PATH);        
    s->print("%s %d: Hex: %x | Dec: %d | String: %s\n", e, b, int i, int i, string i);
}

Conv.str2byteArray(c: self ref Conv,  str: string ): array of byte
{
    strlen: int = len(str);
    strb := array[strlen] of byte;
    
    for ( x := 0; x < len(strb); x++ ) {
        strb[x] = byte str[x];
    }
    
    return strb;
}

Conv.array2str(c: self ref Conv, chars: array of int): string
{
    str: string = "";
    for (x := 0; x < len(chars); x++) {
        str += c.int2char(chars[x]);
    }
    return str;
}

Conv.big2hexstr(c: self ref Conv, val: big ): string
{
    ml: ref ModLoader = ref ModLoader;
    s: Sys = ml.modload_sys(Sys->PATH);        
    return s->sprint( "%b.8X", val );
}

Conv.int2hexstr(c: self ref Conv, val: int): string
{
    ml: ref ModLoader = ref ModLoader;
    s: Sys = ml.modload_sys(Sys->PATH);        
    return s->sprint("%.8X",val);    
}

Conv.int2char(c: self ref Conv, val: int): string
{
    ml: ref ModLoader = ref ModLoader;
    s: Sys = ml.modload_sys(Sys->PATH);        
    return s->sprint("%c", val);
}

Conv.char_hexval(v: self ref Conv, c: int): int
{
    if ((c >= '0') && (c <= '9'))
    {
        return (c - '0');
    }
    
    if ((c >= 'A') && (c <= 'Z'))
    {
        return (c - 'A' + 10);
    } else {
        return (c - 'a' + 10);
    }
}

Conv.allocate(): ref Conv
{
    c := ref Conv;
    return c;
}

Dump.show_bytes_str(d: self ref Dump, msg: string, intBytes: array of byte)
{
  
    conv: ref Conv = Conv.allocate();
    m: ref Msg = Msg.allocate();
    
    for (x := 0; x < len(intBytes); x++)
    {
        m.msgstr( msg, conv.int2char(int intBytes[x]) );
    }
}

Dump.show_bytes(d: self ref Dump, intBytes: array of int)
{
    conv: ref Conv = Conv.allocate();
    m: ref Msg = Msg.allocate();
        
    for (x := 0; x < len(intBytes); x++)
    {
        m.msgstr( "Int Bytes: ", conv.int2char(intBytes[x]) );
    }
}

Dump.allocate(): ref Dump
{
    d := ref Dump;
    return d;
}

Misc.allocate(): ref Misc
{
    m := ref Misc;
    return m;
}

Misc.killg(m: self ref Misc, pid: int)
{
    ml: ref ModLoader = ref ModLoader;
    s: Sys = ml.modload_sys(Sys->PATH);        

    if ((fd := s->open("/prog/" + string pid + "/ctl", Sys->OWRITE)) != nil) {
        s->fprint(fd, "killgrp");
        fd = nil;
    }
}

Misc.error(m: self ref Misc, e: string)
{
    fd: ref FDTools = FDTools.allocate();
    ml: ref ModLoader = ref ModLoader;
    s: Sys = ml.modload_sys(Sys->PATH);        

    s->fprint(fd.fd_stderr(), "register: %s\n", e);
    raise "fail:error";
}

Misc.error2txt(m: self ref Misc, id: int): string
{
    name := "";
    case id {
        ER_ABORTING_CONNECTION => name = "ER_ABORTING_CONNECTION";
        ER_ACCESS_DENIED_ERROR => name = "ER_ACCESS_DENIED_ERROR";
        ER_ALTER_INFO => name = "ER_ALTER_INFO";
        ER_AUTO_CONVERT => name = "ER_AUTO_CONVERT";
        ER_BAD_DB_ERROR => name = "ER_BAD_DB_ERROR";
        ER_BAD_FIELD_ERROR => name = "ER_BAD_FIELD_ERROR";
        ER_BAD_FT_COLUMN => name = "ER_BAD_FT_COLUMN";
        ER_BAD_HOST_ERROR => name = "ER_BAD_HOST_ERROR";
        ER_BAD_NULL_ERROR => name = "ER_BAD_NULL_ERROR";
        ER_BAD_SLAVE => name = "ER_BAD_SLAVE";
        ER_BAD_SLAVE_UNTIL_COND => name = "ER_BAD_SLAVE_UNTIL_COND";
        ER_BAD_TABLE_ERROR => name = "ER_BAD_TABLE_ERROR";
        ER_BLOB_CANT_HAVE_DEFAULT => name = "ER_BLOB_CANT_HAVE_DEFAULT";
        ER_BLOB_KEY_WITHOUT_LENGTH => name = "ER_BLOB_KEY_WITHOUT_LENGTH";
        ER_BLOB_USED_AS_KEY => name = "ER_BLOB_USED_AS_KEY";
        ER_BLOBS_AND_NO_TERMINATED => name = "ER_BLOBS_AND_NO_TERMINATED";
        ER_CANNOT_ADD_FOREIGN => name = "ER_CANNOT_ADD_FOREIGN";
        ER_CANT_AGGREGATE_2COLLATIONS => name = "ER_CANT_AGGREGATE_2COLLATIONS";
        ER_CANT_AGGREGATE_3COLLATIONS => name = "ER_CANT_AGGREGATE_3COLLATIONS";
        ER_CANT_AGGREGATE_NCOLLATIONS => name = "ER_CANT_AGGREGATE_NCOLLATIONS";
        ER_CANT_CREATE_DB => name = "ER_CANT_CREATE_DB";
        ER_CANT_CREATE_FILE => name = "ER_CANT_CREATE_FILE";
        ER_CANT_CREATE_TABLE => name = "ER_CANT_CREATE_TABLE";
        ER_CANT_CREATE_THREAD => name = "ER_CANT_CREATE_THREAD";
        ER_CANT_DELETE_FILE => name = "ER_CANT_DELETE_FILE";
        ER_CANT_DO_THIS_DURING_AN_TRANSACTION => name = "ER_CANT_DO_THIS_DURING_AN_TRANSACTION";
        ER_CANT_DROP_FIELD_OR_KEY => name = "ER_CANT_DROP_FIELD_OR_KEY";
        ER_CANT_FIND_DL_ENTRY => name = "ER_CANT_FIND_DL_ENTRY";
        ER_CANT_FIND_SYSTEM_REC => name = "ER_CANT_FIND_SYSTEM_REC";
        ER_CANT_FIND_UDF => name = "ER_CANT_FIND_UDF";
        ER_CANT_GET_STAT => name = "ER_CANT_GET_STAT";
        ER_CANT_GET_WD => name = "ER_CANT_GET_WD";
        ER_CANT_INITIALIZE_UDF => name = "ER_CANT_INITIALIZE_UDF";
        ER_CANT_LOCK => name = "ER_CANT_LOCK";
        ER_CANT_OPEN_FILE => name = "ER_CANT_OPEN_FILE";
        ER_CANT_OPEN_LIBRARY => name = "ER_CANT_OPEN_LIBRARY";
        ER_CANT_READ_DIR => name = "ER_CANT_READ_DIR";
        ER_CANT_REMOVE_ALL_FIELDS => name = "ER_CANT_REMOVE_ALL_FIELDS";
        ER_CANT_REOPEN_TABLE => name = "ER_CANT_REOPEN_TABLE";
        ER_CANT_SET_WD => name = "ER_CANT_SET_WD";
        ER_CANT_UPDATE_WITH_READLOCK => name = "ER_CANT_UPDATE_WITH_READLOCK";
        ER_CANT_USE_OPTION_HERE => name = "ER_CANT_USE_OPTION_HERE";
        ER_CHECK_NO_SUCH_TABLE => name = "ER_CHECK_NO_SUCH_TABLE";
        ER_CHECK_NOT_IMPLEMENTED => name = "ER_CHECK_NOT_IMPLEMENTED";
        ER_CHECKREAD => name = "ER_CHECKREAD";
        ER_COLLATION_CHARSET_MISMATCH => name = "ER_COLLATION_CHARSET_MISMATCH";
        ER_COLUMNACCESS_DENIED_ERROR => name = "ER_COLUMNACCESS_DENIED_ERROR";
        ER_CON_COUNT_ERROR => name = "ER_CON_COUNT_ERROR";
        ER_CONNECT_TO_MASTER => name = "ER_CONNECT_TO_MASTER";
        ER_CORRUPT_HELP_DB => name = "ER_CORRUPT_HELP_DB";
        ER_CRASHED_ON_REPAIR => name = "ER_CRASHED_ON_REPAIR";
        ER_CRASHED_ON_USAGE => name = "ER_CRASHED_ON_USAGE";
        ER_CREATE_DB_WITH_READ_LOCK => name = "ER_CREATE_DB_WITH_READ_LOCK";
        ER_CUT_VALUE_GROUP_CONCAT => name = "ER_CUT_VALUE_GROUP_CONCAT";
        ER_CYCLIC_REFERENCE => name = "ER_CYCLIC_REFERENCE";
        ER_DB_CREATE_EXISTS => name = "ER_DB_CREATE_EXISTS";
        ER_DB_DROP_DELETE => name = "ER_DB_DROP_DELETE";
        ER_DB_DROP_EXISTS => name = "ER_DB_DROP_EXISTS";
        ER_DB_DROP_RMDIR => name = "ER_DB_DROP_RMDIR";
        ER_DBACCESS_DENIED_ERROR => name = "ER_DBACCESS_DENIED_ERROR";
        ER_DELAYED_CANT_CHANGE_LOCK => name = "ER_DELAYED_CANT_CHANGE_LOCK";
        ER_DELAYED_INSERT_TABLE_LOCKED => name = "ER_DELAYED_INSERT_TABLE_LOCKED";
        ER_DERIVED_MUST_HAVE_ALIAS => name = "ER_DERIVED_MUST_HAVE_ALIAS";
        ER_DISK_FULL => name = "ER_DISK_FULL";
        ER_DROP_DB_WITH_READ_LOCK => name = "ER_DROP_DB_WITH_READ_LOCK";
        ER_DROP_USER => name = "ER_DROP_USER";
        ER_DUMP_NOT_IMPLEMENTED => name = "ER_DUMP_NOT_IMPLEMENTED";
        ER_DUP_ARGUMENT => name = "ER_DUP_ARGUMENT";
        ER_DUP_ENTRY => name = "ER_DUP_ENTRY";
        ER_DUP_FIELDNAME => name = "ER_DUP_FIELDNAME";
        ER_DUP_KEY => name = "ER_DUP_KEY";
        ER_DUP_KEYNAME => name = "ER_DUP_KEYNAME";
        ER_DUP_UNIQUE => name = "ER_DUP_UNIQUE";
        ER_DUPLICATED_VALUE_IN_TYPE => name = "ER_DUPLICATED_VALUE_IN_TYPE";
        ER_EMPTY_QUERY => name = "ER_EMPTY_QUERY";
        ER_ERROR_DURING_CHECKPOINT => name = "ER_ERROR_DURING_CHECKPOINT";
        ER_ERROR_DURING_COMMIT => name = "ER_ERROR_DURING_COMMIT";
        ER_ERROR_DURING_FLUSH_LOGS => name = "ER_ERROR_DURING_FLUSH_LOGS";
        ER_ERROR_DURING_ROLLBACK => name = "ER_ERROR_DURING_ROLLBACK";
        ER_ERROR_MESSAGES => name = "ER_ERROR_MESSAGES";
        ER_ERROR_ON_CLOSE => name = "ER_ERROR_ON_CLOSE";
        ER_ERROR_ON_READ => name = "ER_ERROR_ON_READ";
        ER_ERROR_ON_RENAME => name = "ER_ERROR_ON_RENAME";
        ER_ERROR_ON_WRITE => name = "ER_ERROR_ON_WRITE";
        ER_ERROR_WHEN_EXECUTING_COMMAND => name = "ER_ERROR_WHEN_EXECUTING_COMMAND";
        ER_FEATURE_DISABLED => name = "ER_FEATURE_DISABLED";
        ER_FIELD_SPECIFIED_TWICE => name = "ER_FIELD_SPECIFIED_TWICE";
        ER_FILE_EXISTS_ERROR => name = "ER_FILE_EXISTS_ERROR";
        ER_FILE_NOT_FOUND => name = "ER_FILE_NOT_FOUND";
        ER_FILE_USED => name = "ER_FILE_USED";
        ER_FILSORT_ABORT => name = "ER_FILSORT_ABORT";
        ER_FLUSH_MASTER_BINLOG_CLOSED => name = "ER_FLUSH_MASTER_BINLOG_CLOSED";
        ER_FORCING_CLOSE => name = "ER_FORCING_CLOSE";
        ER_FORM_NOT_FOUND => name = "ER_FORM_NOT_FOUND";
        ER_FT_MATCHING_KEY_NOT_FOUND => name = "ER_FT_MATCHING_KEY_NOT_FOUND";
        ER_FUNCTION_NOT_DEFINED => name = "ER_FUNCTION_NOT_DEFINED";
        ER_GET_ERRMSG => name = "ER_GET_ERRMSG";
        ER_GET_ERRNO => name = "ER_GET_ERRNO";
        ER_GET_TEMPORARY_ERRMSG => name = "ER_GET_TEMPORARY_ERRMSG";
        ER_GLOBAL_VARIABLE => name = "ER_GLOBAL_VARIABLE";
        ER_GOT_SIGNAL => name = "ER_GOT_SIGNAL";
        ER_GRANT_WRONG_HOST_OR_USER => name = "ER_GRANT_WRONG_HOST_OR_USER";
        ER_HANDSHAKE_ERROR => name = "ER_HANDSHAKE_ERROR";
        ER_HASHCHK => name = "ER_HASHCHK";
        ER_HOST_IS_BLOCKED => name = "ER_HOST_IS_BLOCKED";
        ER_HOST_NOT_PRIVILEGED => name = "ER_HOST_NOT_PRIVILEGED";
        ER_ILLEGAL_GRANT_FOR_TABLE => name = "ER_ILLEGAL_GRANT_FOR_TABLE";
        ER_ILLEGAL_HA => name = "ER_ILLEGAL_HA";
        ER_ILLEGAL_REFERENCE => name = "ER_ILLEGAL_REFERENCE";
        ER_INCORRECT_GLOBAL_LOCAL_VAR => name = "ER_INCORRECT_GLOBAL_LOCAL_VAR";
        ER_INDEX_REBUILD => name = "ER_INDEX_REBUILD";
        ER_INSERT_INFO => name = "ER_INSERT_INFO";
        ER_INVALID_DEFAULT => name = "ER_INVALID_DEFAULT";
        ER_INVALID_GROUP_FUNC_USE => name = "ER_INVALID_GROUP_FUNC_USE";
        ER_INVALID_ON_UPDATE => name = "ER_INVALID_ON_UPDATE";
        ER_INVALID_USE_OF_NULL => name = "ER_INVALID_USE_OF_NULL";
        ER_IPSOCK_ERROR => name = "ER_IPSOCK_ERROR";
        ER_KEY_COLUMN_DOES_NOT_EXITS => name = "ER_KEY_COLUMN_DOES_NOT_EXITS";
        ER_KEY_DOES_NOT_EXITS => name = "ER_KEY_DOES_NOT_EXITS";
        ER_KEY_NOT_FOUND => name = "ER_KEY_NOT_FOUND";
        ER_KEY_REF_DO_NOT_MATCH_TABLE_REF => name = "ER_KEY_REF_DO_NOT_MATCH_TABLE_REF";
        ER_KILL_DENIED_ERROR => name = "ER_KILL_DENIED_ERROR";
        ER_LOAD_INFO => name = "ER_LOAD_INFO";
        ER_LOCAL_VARIABLE => name = "ER_LOCAL_VARIABLE";
        ER_LOCK_DEADLOCK => name = "ER_LOCK_DEADLOCK";
        ER_LOCK_OR_ACTIVE_TRANSACTION => name = "ER_LOCK_OR_ACTIVE_TRANSACTION";
        ER_LOCK_TABLE_FULL => name = "ER_LOCK_TABLE_FULL";
        ER_LOCK_WAIT_TIMEOUT => name = "ER_LOCK_WAIT_TIMEOUT";
        ER_MASTER => name = "ER_MASTER";
        ER_MASTER_FATAL_ERROR_READING_BINLOG => name = "ER_MASTER_FATAL_ERROR_READING_BINLOG";
        ER_MASTER_INFO => name = "ER_MASTER_INFO";
        ER_MASTER_NET_READ => name = "ER_MASTER_NET_READ";
        ER_MASTER_NET_WRITE => name = "ER_MASTER_NET_WRITE";
        ER_MISSING_SKIP_SLAVE => name = "ER_MISSING_SKIP_SLAVE";
        ER_MIX_OF_GROUP_FUNC_AND_FIELDS => name = "ER_MIX_OF_GROUP_FUNC_AND_FIELDS";
        ER_MIXING_NOT_ALLOWED => name = "ER_MIXING_NOT_ALLOWED";
        ER_MULTIPLE_PRI_KEY => name = "ER_MULTIPLE_PRI_KEY";
        ER_NET_ERROR_ON_WRITE => name = "ER_NET_ERROR_ON_WRITE";
        ER_NET_FCNTL_ERROR => name = "ER_NET_FCNTL_ERROR";
        ER_NET_PACKET_TOO_LARGE => name = "ER_NET_PACKET_TOO_LARGE";
        ER_NET_PACKETS_OUT_OF_ORDER => name = "ER_NET_PACKETS_OUT_OF_ORDER";
        ER_NET_READ_ERROR => name = "ER_NET_READ_ERROR";
        ER_NET_READ_ERROR_FROM_PIPE => name = "ER_NET_READ_ERROR_FROM_PIPE";
        ER_NET_READ_INTERRUPTED => name = "ER_NET_READ_INTERRUPTED";
        ER_NET_UNCOMPRESS_ERROR => name = "ER_NET_UNCOMPRESS_ERROR";
        ER_NET_WRITE_INTERRUPTED => name = "ER_NET_WRITE_INTERRUPTED";
        ER_NEW_ABORTING_CONNECTION => name = "ER_NEW_ABORTING_CONNECTION";
        ER_NISAMCHK => name = "ER_NISAMCHK";
        ER_NO => name = "ER_NO";
        ER_NO_DB_ERROR => name = "ER_NO_DB_ERROR";
        ER_NO_DEFAULT => name = "ER_NO_DEFAULT";
        ER_NO_PERMISSION_TO_CREATE_USER => name = "ER_NO_PERMISSION_TO_CREATE_USER";
        ER_NO_RAID_COMPILED => name = "ER_NO_RAID_COMPILED";
        ER_NO_REFERENCED_ROW => name = "ER_NO_REFERENCED_ROW";
        ER_NO_SUCH_INDEX => name = "ER_NO_SUCH_INDEX";
        ER_NO_SUCH_TABLE => name = "ER_NO_SUCH_TABLE";
        ER_NO_SUCH_THREAD => name = "ER_NO_SUCH_THREAD";
        ER_NO_TABLES_USED => name = "ER_NO_TABLES_USED";
        ER_NO_UNIQUE_LOGFILE => name = "ER_NO_UNIQUE_LOGFILE";
        ER_NON_UNIQ_ERROR => name = "ER_NON_UNIQ_ERROR";
        ER_NON_UPDATABLE_TABLE => name = "ER_NON_UPDATABLE_TABLE";
        ER_NONEXISTING_GRANT => name = "ER_NONEXISTING_GRANT";
        ER_NONEXISTING_TABLE_GRANT => name = "ER_NONEXISTING_TABLE_GRANT";
        ER_NONUNIQ_TABLE => name = "ER_NONUNIQ_TABLE";
        ER_NORMAL_SHUTDOWN => name = "ER_NORMAL_SHUTDOWN";
        ER_NOT_ALLOWED_COMMAND => name = "ER_NOT_ALLOWED_COMMAND";
        ER_NOT_FORM_FILE => name = "ER_NOT_FORM_FILE";
        ER_NOT_KEYFILE => name = "ER_NOT_KEYFILE";
        ER_NOT_SUPPORTED_AUTH_MODE => name = "ER_NOT_SUPPORTED_AUTH_MODE";
        ER_NOT_SUPPORTED_YET => name = "ER_NOT_SUPPORTED_YET";
        ER_NULL_COLUMN_IN_INDEX => name = "ER_NULL_COLUMN_IN_INDEX";
        ER_OLD_KEYFILE => name = "ER_OLD_KEYFILE";
        ER_OPEN_AS_READONLY => name = "ER_OPEN_AS_READONLY";
        ER_OPERAND_COLUMNS => name = "ER_OPERAND_COLUMNS";
        ER_OPTION_PREVENTS_STATEMENT => name = "ER_OPTION_PREVENTS_STATEMENT";
        ER_OUT_OF_RESOURCES => name = "ER_OUT_OF_RESOURCES";
        ER_OUT_OF_SORTMEMORY => name = "ER_OUT_OF_SORTMEMORY";
        ER_OUTOFMEMORY => name = "ER_OUTOFMEMORY";
        ER_PARSE_ERROR => name = "ER_PARSE_ERROR";
        ER_PASSWORD_ANONYMOUS_USER => name = "ER_PASSWORD_ANONYMOUS_USER";
        ER_PASSWORD_NO_MATCH => name = "ER_PASSWORD_NO_MATCH";
        ER_PASSWORD_NOT_ALLOWED => name = "ER_PASSWORD_NOT_ALLOWED";
        ER_PRIMARY_CANT_HAVE_NULL => name = "ER_PRIMARY_CANT_HAVE_NULL";
        ER_QUERY_ON_MASTER => name = "ER_QUERY_ON_MASTER";
        ER_READ_ONLY_TRANSACTION => name = "ER_READ_ONLY_TRANSACTION";
        ER_READY => name = "ER_READY";
        ER_RECORD_FILE_FULL => name = "ER_RECORD_FILE_FULL";
        ER_REGEXP_ERROR => name = "ER_REGEXP_ERROR";
        ER_REQUIRES_PRIMARY_KEY => name = "ER_REQUIRES_PRIMARY_KEY";
        ER_REVOKE_GRANTS => name = "ER_REVOKE_GRANTS";
        ER_ROW_IS_REFERENCED => name = "ER_ROW_IS_REFERENCED";
        ER_SELECT_REDUCED => name = "ER_SELECT_REDUCED";
        ER_SERVER_IS_IN_SECURE_AUTH_MODE => name = "ER_SERVER_IS_IN_SECURE_AUTH_MODE";
        ER_SERVER_SHUTDOWN => name = "ER_SERVER_SHUTDOWN";
        ER_SET_CONSTANTS_ONLY => name = "ER_SET_CONSTANTS_ONLY";
        ER_SHUTDOWN_COMPLETE => name = "ER_SHUTDOWN_COMPLETE";
        ER_SLAVE_IGNORED_SSL_PARAMS => name = "ER_SLAVE_IGNORED_SSL_PARAMS";
        ER_SLAVE_IGNORED_TABLE => name = "ER_SLAVE_IGNORED_TABLE";
        ER_SLAVE_MUST_STOP => name = "ER_SLAVE_MUST_STOP";
        ER_SLAVE_NOT_RUNNING => name = "ER_SLAVE_NOT_RUNNING";
        ER_SLAVE_THREAD => name = "ER_SLAVE_THREAD";
        ER_SLAVE_WAS_NOT_RUNNING => name = "ER_SLAVE_WAS_NOT_RUNNING";
        ER_SLAVE_WAS_RUNNING => name = "ER_SLAVE_WAS_RUNNING";
        ER_SPATIAL_CANT_HAVE_NULL => name = "ER_SPATIAL_CANT_HAVE_NULL";
        ER_SPECIFIC_ACCESS_DENIED_ERROR => name = "ER_SPECIFIC_ACCESS_DENIED_ERROR";
        ER_STACK_OVERRUN => name = "ER_STACK_OVERRUN";
        ER_SUBQUERY_NO_1_ROW => name = "ER_SUBQUERY_NO_1_ROW";
        ER_SYNTAX_ERROR => name = "ER_SYNTAX_ERROR";
        ER_TABLE_CANT_HANDLE_AUTO_INCREMENT => name = "ER_TABLE_CANT_HANDLE_AUTO_INCREMENT";
        ER_TABLE_CANT_HANDLE_BLOB => name = "ER_TABLE_CANT_HANDLE_BLOB";
        ER_TABLE_CANT_HANDLE_FT => name = "ER_TABLE_CANT_HANDLE_FT";
        ER_TABLE_EXISTS_ERROR => name = "ER_TABLE_EXISTS_ERROR";
        ER_TABLE_MUST_HAVE_COLUMNS => name = "ER_TABLE_MUST_HAVE_COLUMNS";
        ER_TABLE_NOT_LOCKED => name = "ER_TABLE_NOT_LOCKED";
        ER_TABLE_NOT_LOCKED_FOR_WRITE => name = "ER_TABLE_NOT_LOCKED_FOR_WRITE";
        ER_TABLEACCESS_DENIED_ERROR => name = "ER_TABLEACCESS_DENIED_ERROR";
        ER_TABLENAME_NOT_ALLOWED_HERE => name = "ER_TABLENAME_NOT_ALLOWED_HERE";
        ER_TEXTFILE_NOT_READABLE => name = "ER_TEXTFILE_NOT_READABLE";
        ER_TOO_BIG_FIELDLENGTH => name = "ER_TOO_BIG_FIELDLENGTH";
        ER_TOO_BIG_FOR_UNCOMPRESS => name = "ER_TOO_BIG_FOR_UNCOMPRESS";
        ER_TOO_BIG_ROWSIZE => name = "ER_TOO_BIG_ROWSIZE";
        ER_TOO_BIG_SELECT => name = "ER_TOO_BIG_SELECT";
        ER_TOO_BIG_SET => name = "ER_TOO_BIG_SET";
        ER_TOO_LONG_IDENT => name = "ER_TOO_LONG_IDENT";
        ER_TOO_LONG_KEY => name = "ER_TOO_LONG_KEY";
        ER_TOO_LONG_STRING => name = "ER_TOO_LONG_STRING";
        ER_TOO_MANY_DELAYED_THREADS => name = "ER_TOO_MANY_DELAYED_THREADS";
        ER_TOO_MANY_FIELDS => name = "ER_TOO_MANY_FIELDS";
        ER_TOO_MANY_KEY_PARTS => name = "ER_TOO_MANY_KEY_PARTS";
        ER_TOO_MANY_KEYS => name = "ER_TOO_MANY_KEYS";
        ER_TOO_MANY_ROWS => name = "ER_TOO_MANY_ROWS";
        ER_TOO_MANY_TABLES => name = "ER_TOO_MANY_TABLES";
        ER_TOO_MANY_USER_CONNECTIONS => name = "ER_TOO_MANY_USER_CONNECTIONS";
        ER_TOO_MUCH_AUTO_TIMESTAMP_COLS => name = "ER_TOO_MUCH_AUTO_TIMESTAMP_COLS";
        ER_TRANS_CACHE_FULL => name = "ER_TRANS_CACHE_FULL";
        ER_TRUNCATED_WRONG_VALUE => name = "ER_TRUNCATED_WRONG_VALUE";
        ER_UDF_EXISTS => name = "ER_UDF_EXISTS";
        ER_UDF_NO_PATHS => name = "ER_UDF_NO_PATHS";
        ER_UNEXPECTED_EOF => name = "ER_UNEXPECTED_EOF";
        ER_UNION_TABLES_IN_DIFFERENT_DIR => name = "ER_UNION_TABLES_IN_DIFFERENT_DIR";
        ER_UNKNOWN_CHARACTER_SET => name = "ER_UNKNOWN_CHARACTER_SET";
        ER_UNKNOWN_COLLATION => name = "ER_UNKNOWN_COLLATION";
        ER_UNKNOWN_COM_ERROR => name = "ER_UNKNOWN_COM_ERROR";
        ER_UNKNOWN_ERROR => name = "ER_UNKNOWN_ERROR";
        ER_UNKNOWN_KEY_CACHE => name = "ER_UNKNOWN_KEY_CACHE";
        ER_UNKNOWN_PROCEDURE => name = "ER_UNKNOWN_PROCEDURE";
        ER_UNKNOWN_STMT_HANDLER => name = "ER_UNKNOWN_STMT_HANDLER";
        ER_UNKNOWN_STORAGE_ENGINE => name = "ER_UNKNOWN_STORAGE_ENGINE";
        ER_UNKNOWN_SYSTEM_VARIABLE => name = "ER_UNKNOWN_SYSTEM_VARIABLE";
        ER_UNKNOWN_TABLE => name = "ER_UNKNOWN_TABLE";
        ER_UNSUPPORTED_EXTENSION => name = "ER_UNSUPPORTED_EXTENSION";
        ER_UNSUPPORTED_PS => name = "ER_UNSUPPORTED_PS";
        ER_UNTIL_COND_IGNORED => name = "ER_UNTIL_COND_IGNORED";
        ER_UPDATE_INFO => name = "ER_UPDATE_INFO";
        ER_UPDATE_TABLE_USED => name = "ER_UPDATE_TABLE_USED";
        ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE => name = "ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE";
        ER_USER_LIMIT_REACHED => name = "ER_USER_LIMIT_REACHED";
        ER_VAR_CANT_BE_READ => name = "ER_VAR_CANT_BE_READ";
        ER_VARIABLE_IS_NOT_STRUCT => name = "ER_VARIABLE_IS_NOT_STRUCT";
        ER_WARN_DATA_OUT_OF_RANGE => name = "ER_WARN_DATA_OUT_OF_RANGE";
        ER_WARN_DATA_TRUNCATED => name = "ER_WARN_DATA_TRUNCATED";
        ER_WARN_DEPRECATED_SYNTAX => name = "ER_WARN_DEPRECATED_SYNTAX";
        ER_WARN_FIELD_RESOLVED => name = "ER_WARN_FIELD_RESOLVED";
        ER_WARN_HOSTNAME_WONT_WORK => name = "ER_WARN_HOSTNAME_WONT_WORK";
        ER_WARN_NULL_TO_NOTNULL => name = "ER_WARN_NULL_TO_NOTNULL";
        ER_WARN_QC_RESIZE => name = "ER_WARN_QC_RESIZE";
        ER_WARN_TOO_FEW_RECORDS => name = "ER_WARN_TOO_FEW_RECORDS";
        ER_WARN_TOO_MANY_RECORDS => name = "ER_WARN_TOO_MANY_RECORDS";
        ER_WARN_USING_OTHER_HANDLER => name = "ER_WARN_USING_OTHER_HANDLER";
        ER_WARNING_NOT_COMPLETE_ROLLBACK => name = "ER_WARNING_NOT_COMPLETE_ROLLBACK";
        ER_WRONG_ARGUMENTS => name = "ER_WRONG_ARGUMENTS";
        ER_WRONG_AUTO_KEY => name = "ER_WRONG_AUTO_KEY";
        ER_WRONG_COLUMN_NAME => name = "ER_WRONG_COLUMN_NAME";
        ER_WRONG_DB_NAME => name = "ER_WRONG_DB_NAME";
        ER_WRONG_FIELD_SPEC => name = "ER_WRONG_FIELD_SPEC";
        ER_WRONG_FIELD_TERMINATORS => name = "ER_WRONG_FIELD_TERMINATORS";
        ER_WRONG_FIELD_WITH_GROUP => name = "ER_WRONG_FIELD_WITH_GROUP";
        ER_WRONG_FK_DEF => name = "ER_WRONG_FK_DEF";
        ER_WRONG_GROUP_FIELD => name = "ER_WRONG_GROUP_FIELD";
        ER_WRONG_KEY_COLUMN => name = "ER_WRONG_KEY_COLUMN";
        ER_WRONG_MRG_TABLE => name = "ER_WRONG_MRG_TABLE";
        ER_WRONG_NAME_FOR_CATALOG => name = "ER_WRONG_NAME_FOR_CATALOG";
        ER_WRONG_NAME_FOR_INDEX => name = "ER_WRONG_NAME_FOR_INDEX";
        ER_WRONG_NUMBER_OF_COLUMNS_IN_SELECT => name = "ER_WRONG_NUMBER_OF_COLUMNS_IN_SELECT";
        ER_WRONG_OUTER_JOIN => name = "ER_WRONG_OUTER_JOIN";
        ER_WRONG_PARAMCOUNT_TO_PROCEDURE => name = "ER_WRONG_PARAMCOUNT_TO_PROCEDURE";
        ER_WRONG_PARAMETERS_TO_PROCEDURE => name = "ER_WRONG_PARAMETERS_TO_PROCEDURE";
        ER_WRONG_SUB_KEY => name = "ER_WRONG_SUB_KEY";
        ER_WRONG_SUM_SELECT => name = "ER_WRONG_SUM_SELECT";
        ER_WRONG_TABLE_NAME => name = "ER_WRONG_TABLE_NAME";
        ER_WRONG_TYPE_FOR_VAR => name = "ER_WRONG_TYPE_FOR_VAR";
        ER_WRONG_USAGE => name = "ER_WRONG_USAGE";
        ER_WRONG_VALUE_COUNT => name = "ER_WRONG_VALUE_COUNT";
        ER_WRONG_VALUE_COUNT_ON_ROW => name = "ER_WRONG_VALUE_COUNT_ON_ROW";
        ER_WRONG_VALUE_FOR_VAR => name = "ER_WRONG_VALUE_FOR_VAR";
        ER_YES => name = "ER_YES";
        ER_ZLIB_Z_BUF_ERROR => name = "ER_ZLIB_Z_BUF_ERROR";
        ER_ZLIB_Z_DATA_ERROR => name = "ER_ZLIB_Z_DATA_ERROR";
        ER_ZLIB_Z_MEM_ERROR => name = "ER_ZLIB_Z_MEM_ERROR";
    }
    return name;
}

Misc.type2txt(m: self ref Misc, typeid: int): string
{
    name := "";
    case typeid {
        FIELD_TYPE_DECIMAL => name = "FIELD_TYPE_DECIMAL";
        FIELD_TYPE_TINY => name = "FIELD_TYPE_TINY";
        FIELD_TYPE_SHORT => name = "FIELD_TYPE_SHORT";
        FIELD_TYPE_LONG => name = "FIELD_TYPE_LONG";
        FIELD_TYPE_FLOAT => name = "FIELD_TYPE_FLOAT";
        FIELD_TYPE_DOUBLE => name = "FIELD_TYPE_DOUBLE";
        FIELD_TYPE_NULL => name = "FIELD_TYPE_NULL";
        FIELD_TYPE_TIMESTAMP => name = "FIELD_TYPE_TIMESTAMP";        
        FIELD_TYPE_LONGLONG => name = "FIELD_TYPE_LONGLONG";
        FIELD_TYPE_INT24 => name = "FIELD_TYPE_INT24";
        FIELD_TYPE_DATE => name = "FIELD_TYPE_DATE";
        FIELD_TYPE_TIME => name = "FIELD_TYPE_TIME";
        FIELD_TYPE_DATETIME => name = "FIELD_TYPE_DATETIME";
        FIELD_TYPE_YEAR => name = "FIELD_TYPE_YEAR";
        FIELD_TYPE_NEWDATE => name = "FIELD_TYPE_NEWDATE";
        FIELD_TYPE_ENUM => name = "FIELD_TYPE_ENUM";
        FIELD_TYPE_SET => name = "FIELD_TYPE_SET";
        FIELD_TYPE_TINY_BLOB => name = "FIELD_TYPE_TINY_BLOB";
        FIELD_TYPE_MEDIUM_BLOB => name = "FIELD_TYPE_MEDIUM_BLOB";
        FIELD_TYPE_LONG_BLOB => name = "FIELD_TYPE_LONG_BLOB";
        FIELD_TYPE_BLOB => name = "FIELD_TYPE_BLOB";
        FIELD_TYPE_VAR_STRING => name = "FIELD_TYPE_VAR_STRING";
        FIELD_TYPE_STRING => name = "FIELD_TYPE_STRING";
        FIELD_TYPE_VARCHAR => name = "FIELD_TYPE_VARCHAR";
        FIELD_TYPE_GEOMETRY => name = "FIELD_TYPE_GEOMETRY";          
    }
    return name;
}

IO.readstream(io: self ref IO, count: int): array of byte
{
    ml: ref ModLoader = ref ModLoader;
    s: Sys = ml.modload_sys(Sys->PATH);        

    if(io.fd == nil)
        return nil;

    buf := array[count] of byte;
    
    n := s->read(io.fd, buf, len buf);
    
    if(n < 0)
        return nil;

    return buf[0:n]; 
}

IO.writestream(io: self ref IO, data: array of byte): int
{
    ml: ref ModLoader = ref ModLoader;
    s: Sys = ml.modload_sys(Sys->PATH); 
    
    if(io.fd == nil)
        return -111;

    n := s->write(io.fd, data, len data);
    
    return n; 
}

IO.allocate(fd: ref FD): ref IO
{
    io: ref IO = ref IO;
    io.fd = fd;
    return io;
}

Net.connect(n: self ref Net, network: string, host: string, port: string): (int, Connection)
{
    ml: ref ModLoader = ref ModLoader;
    s: Sys = ml.modload_sys(Sys->PATH);        

    if (network == nil || host == nil || s == nil)
        raise "Invalid connection string.";
        
    connstr := network + "!" + host + "!" + port;
    
    return s->dial(connstr, nil);        
}

Net.allocate(): ref Net
{
    n := ref Net;
    return n;
}

mysqlcli.b

implement MySqlCli;
    
include "sys.m";
    sys: Sys;

include "draw.m";
    draw: Draw;

include "mysql_test.m";
    mysqlTest: MySqlTest;
    MySqlTestCases: import mysqlTest;

    
MySqlCli: module {
    init:                       fn(ctx: ref Draw->Context, argv: list of string);
};

load_modules()
{

    mysqlTest = load MySqlTest MySqlTest->PATH;    
}

init(ctx: ref Draw->Context, argv: list of string)
{
    load_modules();
    
    t: ref MySqlTestCases = MySqlTestCases.allocate();
    t.test_all();
    
    exit;
}

Author

Tony A. Mendoza


Sign in to add a comment
Powered by Google Project Hosting