📄 mysqltest.c
字号:
if (con->util_mysql) mysql_close(con->util_mysql); con->util_mysql= 0; my_free(con->name, MYF(0)); /* When the connection is closed set name to "closed_connection" to make it possible to reuse the connection name. The connection slot will not be reused */ if (!(con->name = my_strdup("closed_connection", MYF(MY_WME)))) die("Out of memory"); DBUG_RETURN(0); } } die("connection '%s' not found in connection pool", name); DBUG_RETURN(1); /* Never reached */}/* This one now is a hack - we may want to improve in in the future to handle quotes. For now we assume that anything that is not a comma, a space or ) belongs to the argument. space is a chopper, comma or ) are delimiters/terminators SYNOPSIS safe_get_param str - string to get param from arg - pointer to string where result will be stored msg - Message to display if param is not found if msg is 0 this param is not required and param may be empty RETURNS pointer to str after param*/char* safe_get_param(char *str, char** arg, const char *msg){ DBUG_ENTER("safe_get_param"); if(!*str) { if (msg) die(msg); *arg= str; DBUG_RETURN(str); } while (*str && my_isspace(charset_info,*str)) str++; *arg= str; while (*str && *str != ',' && *str != ')') str++; if (msg && !*arg) die(msg); *str++= 0; DBUG_RETURN(str);}#ifndef EMBEDDED_LIBRARYvoid init_manager(){ if (!(manager=mysql_manager_init(0))) die("Failed in mysql_manager_init()"); if (!mysql_manager_connect(manager,manager_host,manager_user, manager_pass,manager_port)) die("Could not connect to MySQL manager: %s(%d)",manager->last_error, manager->last_errno);}#endif/* Connect to a server doing several retries if needed. SYNOPSIS safe_connect() con - connection structure to be used host, user, pass, - connection parameters db, port, sock NOTE This function will try to connect to the given server MAX_CON_TRIES times and sleep CON_RETRY_SLEEP seconds between attempts before finally giving up. This helps in situation when the client starts before the server (which happens sometimes). It will ignore any errors during these retries. One should use connect_n_handle_errors() if he expects a connection error and wants handle as if it was an error from a usual statement. RETURN VALUE 0 - success, non-0 - failure*/int safe_connect(MYSQL* mysql, const char *host, const char *user, const char *pass, const char *db, int port, const char *sock){ int con_error= 1; my_bool reconnect= 1; int i; for (i= 0; i < MAX_CON_TRIES; ++i) { if (mysql_real_connect(mysql, host,user, pass, db, port, sock, CLIENT_MULTI_STATEMENTS | CLIENT_REMEMBER_OPTIONS)) { con_error= 0; break; } sleep(CON_RETRY_SLEEP); } /* TODO: change this to 0 in future versions, but the 'kill' test relies on existing behavior */ mysql_options(mysql, MYSQL_OPT_RECONNECT, (char *)&reconnect); return con_error;}/* Connect to a server and handle connection errors in case they occur. SYNOPSIS connect_n_handle_errors() q - context of connect "query" (command) con - connection structure to be used host, user, pass, - connection parameters db, port, sock create_conn - out parameter, set to zero if connection was not established and is not touched otherwise DESCRIPTION This function will try to establish a connection to server and handle possible errors in the same manner as if "connect" was usual SQL-statement (If error is expected it will ignore it once it occurs and log the "statement" to the query log). Unlike safe_connect() it won't do several attempts. RETURN VALUE 0 - success, non-0 - failure*/int connect_n_handle_errors(struct st_query *q, MYSQL* con, const char* host, const char* user, const char* pass, const char* db, int port, const char* sock, int* create_conn){ DYNAMIC_STRING *ds; my_bool reconnect= 1; int error= 0; ds= &ds_res; if (!disable_query_log) { /* It is nice to have connect() statement logged in result file in this case. QQ: Should we do this only if we are expecting an error ? */ char port_buff[22]; /* This should be enough for any int */ char *port_end; dynstr_append_mem(ds, "connect(", 8); replace_dynstr_append(ds, host); dynstr_append_mem(ds, ",", 1); replace_dynstr_append(ds, user); dynstr_append_mem(ds, ",", 1); replace_dynstr_append(ds, pass); dynstr_append_mem(ds, ",", 1); if (db) replace_dynstr_append(ds, db); dynstr_append_mem(ds, ",", 1); port_end= int10_to_str(port, port_buff, 10); replace_dynstr_append_mem(ds, port_buff, port_end - port_buff); dynstr_append_mem(ds, ",", 1); if (sock) replace_dynstr_append(ds, sock); dynstr_append_mem(ds, ")", 1); dynstr_append_mem(ds, delimiter, delimiter_length); dynstr_append_mem(ds, "\n", 1); } if (!mysql_real_connect(con, host, user, pass, db, port, sock ? sock: 0, CLIENT_MULTI_STATEMENTS)) { handle_error("connect", q, mysql_errno(con), mysql_error(con), mysql_sqlstate(con), ds); *create_conn= 0; goto err; } handle_no_error(q); /* TODO: change this to 0 in future versions, but the 'kill' test relies on existing behavior */ mysql_options(con, MYSQL_OPT_RECONNECT, (char *)&reconnect);err: free_replace(); return error;}/* Open a new connection to MySQL Server with the parameters specified SYNOPSIS do_connect() q called command DESCRIPTION connect(<name>,<host>,<user>,<pass>,<db>,[<port>,<sock>[<opts>]]); <name> - name of the new connection <host> - hostname of server <user> - user to connect as <pass> - password used when connecting <db> - initial db when connected <port> - server port <sock> - server socket <opts> - options to use for the connection SSL - use SSL if available COMPRESS - use compression if available */int do_connect(struct st_query *q){ char *con_name, *con_user,*con_pass, *con_host, *con_port_str, *con_db, *con_sock, *con_options; char *con_buf, *p; char buff[FN_REFLEN]; int con_port; bool con_ssl= 0; bool con_compress= 0; int free_con_sock= 0; int error= 0; int create_conn= 1; VAR *var_port, *var_sock; DBUG_ENTER("do_connect"); DBUG_PRINT("enter",("connect: %s", q->first_argument)); /* Make a copy of query before parsing, safe_get_param will modify */ if (!(con_buf= my_strdup(q->first_argument, MYF(MY_WME)))) die("Could not allocate con_buf"); p= con_buf; if (*p != '(') die("Syntax error in connect - expected '(' found '%c'", *p); p++; p= safe_get_param(p, &con_name, "Missing connection name"); p= safe_get_param(p, &con_host, "Missing connection host"); p= safe_get_param(p, &con_user, "Missing connection user"); p= safe_get_param(p, &con_pass, "Missing connection password"); p= safe_get_param(p, &con_db, "Missing connection db"); /* Port */ p= safe_get_param(p, &con_port_str, 0); if (*con_port_str) { if (*con_port_str == '$') { if (!(var_port= var_get(con_port_str, 0, 0, 0))) die("Unknown variable '%s'", con_port_str+1); con_port= var_port->int_val; } else { con_port= atoi(con_port_str); if (con_port == 0) die("Illegal argument for port: '%s'", con_port_str); } } else { con_port= port; } /* Sock */ p= safe_get_param(p, &con_sock, 0); if (*con_sock) { if (*con_sock == '$') { if (!(var_sock= var_get(con_sock, 0, 0, 0))) die("Unknown variable '%s'", con_sock+1); if (!(con_sock= (char*)my_malloc(var_sock->str_val_len+1, MYF(0)))) die("Out of memory"); free_con_sock= 1; memcpy(con_sock, var_sock->str_val, var_sock->str_val_len); con_sock[var_sock->str_val_len]= 0; } } else { con_sock= (char*) unix_sock; } /* Options */ p= safe_get_param(p, &con_options, 0); while (*con_options) { char* str= con_options; while (*str && !my_isspace(charset_info, *str)) str++; *str++= 0; if (!strcmp(con_options, "SSL")) con_ssl= 1; else if (!strcmp(con_options, "COMPRESS")) con_compress= 1; else die("Illegal option to connect: %s", con_options); con_options= str; } /* Note: 'p' is pointing into the copy 'con_buf' */ q->last_argument= q->first_argument + (p - con_buf); if (next_con == cons_end) die("Connection limit exhausted - increase MAX_CONS in mysqltest.c"); if (find_connection_by_name(con_name)) die("Connection %s already exists", con_name); if (!mysql_init(&next_con->mysql)) die("Failed on mysql_init()"); if (opt_compress || con_compress) mysql_options(&next_con->mysql, MYSQL_OPT_COMPRESS, NullS); mysql_options(&next_con->mysql, MYSQL_OPT_LOCAL_INFILE, 0); mysql_options(&next_con->mysql, MYSQL_SET_CHARSET_NAME, charset_name);#ifdef HAVE_OPENSSL if (opt_use_ssl || con_ssl) mysql_ssl_set(&next_con->mysql, opt_ssl_key, opt_ssl_cert, opt_ssl_ca, opt_ssl_capath, opt_ssl_cipher);#endif if (con_sock && !free_con_sock && *con_sock && *con_sock != FN_LIBCHAR) con_sock=fn_format(buff, con_sock, TMPDIR, "",0); if (!con_db[0]) con_db= db; /* Special database to allow one to connect without a database name */ if (con_db && !strcmp(con_db,"*NO-ONE*")) con_db= 0; if (q->abort_on_error) { if (safe_connect(&next_con->mysql, con_host, con_user, con_pass, con_db, con_port, con_sock ? con_sock: 0)) die("Could not open connection '%s': %d %s", con_name, mysql_errno(&next_con->mysql), mysql_error(&next_con->mysql)); } else error= connect_n_handle_errors(q, &next_con->mysql, con_host, con_user, con_pass, con_db, con_port, con_sock, &create_conn); if (create_conn) { if (!(next_con->name= my_strdup(con_name, MYF(MY_WME)))) die(NullS); cur_con= next_con++; } if (free_con_sock) my_free(con_sock, MYF(MY_WME)); my_free(con_buf, MYF(MY_WME)); DBUG_RETURN(error);}int do_done(struct st_query *q){ /* Check if empty block stack */ if (cur_block == block_stack) { if (*q->query != '}') die("Stray 'end' command - end of block before beginning"); die("Stray '}' - end of block before beginning"); } /* Test if inner block has been executed */ if (cur_block->ok && cur_block->cmd == cmd_while) { /* Pop block from stack, re-execute outer block */ cur_block--; parser.current_line = cur_block->line; } else { /* Pop block from stack, goto next line */ cur_block--; parser.current_line++; } return 0;}/* Process start of a "if" or "while" statement SYNOPSIS do_block() cmd Type of block q called command DESCRIPTION if ([!]<expr>) { <block statements> } while ([!]<expr>) { <block statements> } Evaluates the <expr> and if it evaluates to greater than zero executes the following code block. A '!' can be used before the <expr> to indicate it should be executed if it evaluates to zero. */void do_block(enum block_cmd cmd, struct st_query* q){ char *p= q->first_argument; const char *expr_start, *expr_end; VAR v; const char *cmd_name= (cmd == cmd_while ? "while" : "if"); my_bool not_expr= FALSE; DBUG_ENTER("do_block"); DBUG_PRINT("enter", ("%s", cmd_name)); /* Check stack overflow */ if (cur_block == block_stack_end) die("Nesting too deeply"); /* Set way to find outer block again, increase line counter */ cur_block->line= parser.current_line++; /* If this block is ignored */ if (!cur_block->ok) { /* Inner block should be ignored too */ cur_block++; cur_block->cmd= cmd; cur_block->ok= FALSE; DBUG_VOID_RETURN; } /* Parse and evaluate test expression */ expr_start= strchr(p, '('); if (!expr_start++) die("missing '(' in %s", cmd_name); /* Check for !<expr> */ if (*expr_start == '!') { not_expr= TRUE; expr_start++; /* Step past the '!' */ } /* Find ending ')' */ expr_end= strrchr(expr_start, ')'); if (!expr_end) die("missing ')' in %s", cmd_name); p= (char*)expr_end+1; while (*p && my_isspace(charset_info, *p)) p++; if (*p == '{') die("Missing newline between %s and '{'", cmd_name); if (*p) die("Missing '{' after %s. Found \"%s\"", cmd_name, p); var_init(&v,0,0,0,0); eval_expr(&v, expr_start, &expr_end); /* Define inner block */ cur_block++; cur_block->cmd= cmd; cur_block->ok= (v.int_val ? TRUE : FALSE); if (not_expr) cur_block->ok = !cur_block->ok; DBUG_PRINT("info", ("OK: %d", cur_block->ok)); var_free(&v); DBUG_VOID_RETURN;}/* Read characters from line buffer or file. This is needed to allow my_ungetc() to buffer MAX_DELIMITER characters for a file NOTE: This works as long as one doesn't change files (with 'source file_name') when there is things pushed into the buffer. This should however not happen for any tests in the test suite.*/int my_getc(FILE *file){ if (line_buffer_pos == line_buffer) return fgetc(file); return *--line_b
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -