00001 /* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB 00002 00003 This program is free software; you can redistribute it and/or modify 00004 it under the terms of the GNU General Public License as published by 00005 the Free Software Foundation; either version 2 of the License, or 00006 (at your option) any later version. 00007 00008 This program is distributed in the hope that it will be useful, 00009 but WITHOUT ANY WARRANTY; without even the implied warranty of 00010 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00011 GNU General Public License for more details. 00012 00013 You should have received a copy of the GNU General Public License 00014 along with this program; if not, write to the Free Software 00015 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ 00016 00017 #include <mysql.h> 00018 #include <stdio.h> 00019 #include <stdarg.h> 00020 #include <stdio.h> 00021 #include <string.h> 00022 #include <stdlib.h> 00023 00024 typedef unsigned char uchar; 00025 static void die(char* fmt, ...); 00026 static void safe_query(MYSQL* mysql, char* query, int read_ok); 00027 static void run_query_batch(int* order, int num_queries); 00028 static void permute(int *order, int num_queries); 00029 static void permute_aux(int *order, int num_queries, int* fixed); 00030 static void dump_result(MYSQL* mysql, char* query); 00031 00032 int count = 0; 00033 00034 00035 struct query 00036 { 00037 MYSQL* mysql; 00038 char* query; 00039 int read_ok; 00040 int pri; 00041 int dump_result; 00042 }; 00043 00044 MYSQL lock, sel, del_ins; 00045 00046 struct query queries[] = 00047 { 00048 {&del_ins, "insert delayed into foo values(1)", 1, 0, 0}, 00049 {&del_ins, "insert delayed into foo values(1)", 1, 0, 0}, 00050 {&lock, "lock tables foo write", 1, 1, 0}, 00051 {&lock, "unlock tables", 1,2, 0}, 00052 {&sel, "select * from foo", 0,0, 0}, 00053 {&del_ins, "insert into foo values(4)", 0,3, 0}, 00054 {0,0,0} 00055 }; 00056 00057 static void die(char* fmt, ...) 00058 { 00059 va_list args; 00060 va_start(args, fmt); 00061 fprintf(stderr, "ERROR: "); 00062 vfprintf(stderr, fmt, args); 00063 fprintf(stderr, "\n"); 00064 va_end(args); 00065 exit(1); 00066 } 00067 00068 static void permute(int *order, int num_queries) 00069 { 00070 int *fixed; 00071 if(num_queries < 2) return; 00072 if(!(fixed = (int*)malloc(num_queries * sizeof(int)))) 00073 die("malloc() failed"); 00074 00075 memset(fixed, 0, num_queries * sizeof(int)); 00076 permute_aux(order, num_queries, fixed); 00077 00078 free(fixed); 00079 } 00080 00081 static order_ok(int *order, int num_queries) 00082 { 00083 int i,j, pri_i, pri_j; 00084 for(i = 0; i < num_queries; i++) 00085 { 00086 if((pri_i = queries[order[i]].pri)) 00087 for(j = i + 1; j < num_queries; j++) 00088 { 00089 pri_j = queries[order[j]].pri; 00090 if(pri_j && pri_i > pri_j) 00091 return 0; 00092 } 00093 } 00094 00095 return 1; 00096 } 00097 00098 static void permute_aux(int *order, int num_queries, int* fixed) 00099 { 00100 int *p,*p1,j,i,tmp, num_free = 0; 00101 p = fixed; 00102 for(i = 0; i < num_queries; i++, p++) 00103 { 00104 if(!*p) 00105 { 00106 num_free++; 00107 *p = 1; 00108 for(j = 0, p1 = fixed ; 00109 j < num_queries; j++,p1++) 00110 { 00111 if(!*p1) 00112 { 00113 tmp = order[i]; 00114 order[i] = order[j]; 00115 order[j] = tmp; 00116 *p1 = 1; 00117 permute_aux(order, num_queries, fixed); 00118 tmp = order[i]; 00119 order[i] = order[j]; 00120 order[j] = tmp; 00121 *p1 = 0; 00122 } 00123 } 00124 *p = 0; 00125 } 00126 } 00127 00128 /*printf("num_free = %d\n", num_free); */ 00129 00130 if(num_free <= 1) 00131 { 00132 count++; 00133 if(order_ok(order, num_queries)) 00134 run_query_batch(order, num_queries); 00135 } 00136 } 00137 00138 static void run_query_batch(int* order, int num_queries) 00139 { 00140 int i; 00141 struct query* q; 00142 int *save_order; 00143 safe_query(&lock, "delete from foo", 1); 00144 save_order = order; 00145 for(i = 0; i < num_queries; i++,order++) 00146 { 00147 q = queries + *order; 00148 printf("query='%s'\n", q->query); 00149 safe_query(q->mysql, q->query, q->read_ok); 00150 } 00151 order = save_order; 00152 for(i = 0; i < num_queries; i++,order++) 00153 { 00154 q = queries + *order; 00155 if(q->dump_result) 00156 dump_result(q->mysql, q->query); 00157 } 00158 printf("\n"); 00159 00160 } 00161 00162 static void safe_net_read(NET* net, char* query) 00163 { 00164 int len; 00165 len = my_net_read(net); 00166 if(len == packet_error || !len) 00167 die("Error running query '%s'", query); 00168 if(net->read_pos[0] == 255) 00169 die("Error running query '%s'", query); 00170 } 00171 00172 00173 static void safe_query(MYSQL* mysql, char* query, int read_ok) 00174 { 00175 int len; 00176 NET* net = &mysql->net; 00177 net_clear(net); 00178 if(net_write_command(net,(uchar)COM_QUERY, query,strlen(query))) 00179 die("Error running query '%s': %s", query, mysql_error(mysql)); 00180 if(read_ok) 00181 { 00182 safe_net_read(net, query); 00183 } 00184 } 00185 00186 static void dump_result(MYSQL* mysql, char* query) 00187 { 00188 MYSQL_RES* res; 00189 safe_net_read(&mysql->net, query); 00190 res = mysql_store_result(mysql); 00191 if(res) 00192 mysql_free_result(res); 00193 } 00194 00195 static int* init_order(int* num_queries) 00196 { 00197 struct query* q; 00198 int *order, *order_end, *p; 00199 int n,i; 00200 00201 for(q = queries; q->mysql; q++) 00202 ; 00203 00204 n = q - queries; 00205 if(!(order = (int*) malloc(n * sizeof(int)))) 00206 die("malloc() failed"); 00207 order_end = order + n; 00208 for(p = order,i = 0; p < order_end; p++,i++) 00209 *p = i; 00210 *num_queries = n; 00211 return order; 00212 } 00213 00214 int main() 00215 { 00216 char* user = "root", *pass = "", *host = "localhost", *db = "test"; 00217 int *order, num_queries; 00218 order = init_order(&num_queries); 00219 if(!mysql_init(&lock) || !mysql_init(&sel) || !mysql_init(&del_ins)) 00220 die("error in mysql_init()"); 00221 00222 mysql_options(&lock, MYSQL_READ_DEFAULT_GROUP, "mysql"); 00223 mysql_options(&sel, MYSQL_READ_DEFAULT_GROUP, "mysql"); 00224 mysql_options(&del_ins, MYSQL_READ_DEFAULT_GROUP, "mysql"); 00225 00226 if(!mysql_real_connect(&lock, host, user, pass, db, 0,0,0 ) || 00227 !mysql_real_connect(&sel, host, user, pass, db, 0,0,0 ) || 00228 !mysql_real_connect(&del_ins, host, user, pass, db, 0,0,0 )) 00229 die("Error in mysql_real_connect(): %s", mysql_error(&lock)); 00230 lock.reconnect= sel.reconnect= del_ins.reconnect= 1; 00231 00232 permute(order, num_queries); 00233 printf("count = %d\n", count); 00234 00235 mysql_close(&lock); 00236 mysql_close(&sel); 00237 mysql_close(&del_ins); 00238 free(order); 00239 }
1.4.7

