1 /***************************************************************************
2 * Copyright (C) 2007 by www.databasecache.com *
3 * Contact: praba_tuty@databasecache.com *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
15 ***************************************************************************/
18 #include<DatabaseManagerImpl.h>
19 #include <Statement.h>
20 #include <SqlFactory.h>
21 #include <SqlStatement.h>
22 #include <SqlNwConnection.h>
23 #include <SqlNwStatement.h>
24 #include <readline/readline.h>
25 #include <readline/history.h>
26 #define SQL_STMT_LEN 1024
33 STMT_TYPE stmtType
= SELECT
;
35 AbsSqlConnection
*conn
;
36 AbsSqlStatement
*stmt
;
37 AbsSqlStatement
*aconStmt
; //stmt object when autocommit is on
39 SqlApiImplType type
= CSqlUnknown
;
40 bool gateway
=false, silent
=false;
41 bool autocommitmode
= true;
43 bool firstPrepare
= false;
44 IsolationLevel isoLevel
= READ_COMMITTED
;
49 printf("Usage: csql [ [-u username] [-p passwd] ] [ [-H hostname] [-P port] ]\n");
50 printf(" [-s sqlfile] \n");
51 printf(" username -> username to connect to database\n");
52 printf(" password -> password to connect to database\n");
53 printf(" hostname -> hostname to connect to database through network\n");
54 printf(" port -> port no\n");
55 printf(" sqlfile -> filename containing sql statements\n");
60 int getConnType(int opt
);
62 int main(int argc
, char **argv
)
64 char username
[IDENTIFIER_LENGTH
];
66 char password
[IDENTIFIER_LENGTH
];
68 char hostname
[IDENTIFIER_LENGTH
];
77 while ((c
= getopt(argc
, argv
, "u:p:s:o:H:P:gXS?")) != EOF
)
81 case 'u' : strcpy(username
, argv
[optind
- 1]); break;
82 case 'p' : strcpy(password
, argv
[optind
- 1]); break;
83 case 's' : strcpy(filename
, argv
[optind
- 1]); break;
84 case 'o' : { connOpt
= atoi(argv
[optind
- 1]); break; }
85 case '?' : { opt
= 1; break; } //print help
86 case 'S' : { silent
= true; break; } //silent
87 case 'X' : { silent
= true; exclusive
= true; break; } //silent
88 case 'g' : { gateway
= true; break; } //print help
89 case 'H' : { strcpy (hostname
, argv
[optind
- 1]);
90 network
= true; break; }
91 case 'P' : { strcpy (port
, argv
[optind
- 1]);
92 network
= true; break; }
93 default: printf("Wrong args\n"); exit(1);
97 //printf("%s %s %s", username, password, filename);
103 if (username
[0] == '\0' )
105 strcpy(username
, "root");
106 strcpy(password
, "manager");
109 if (hostname
[0] == '\0') { printUsage(); return 0; }
110 if (port
[0] == '\0') { printUsage(); return 0; }
112 bool fileFlag
= false;
113 if (filename
[0] !='\0')
115 fp
= fopen(filename
,"r");
118 printf("Unable to open the file %s\n", filename
);
126 type
= (SqlApiImplType
) getConnType(connOpt
);
127 conn
= SqlFactory::createConnection((SqlApiImplType
)type
);
128 if(connOpt
== 4 || connOpt
== 5 || connOpt
== 6) {
129 SqlNwConnection
*con
= (SqlNwConnection
*)conn
;
130 con
->setHost("localhost", 5678);
132 else if (connOpt
== 7)
133 conn
= SqlFactory::createConnection((SqlApiImplType
)type
);
136 if (gateway
) type
= CSqlNetworkGateway
;
137 else type
= CSqlNetwork
;
138 conn
= SqlFactory::createConnection(type
);
139 SqlNwConnection
*con
= (SqlNwConnection
*)conn
;
140 con
->setHost(hostname
, atoi(port
));
143 if (gateway
) type
= CSqlGateway
;
145 if (exclusive
) type
=CSqlDirect
;
148 conn
= SqlFactory::createConnection(type
);
151 rv
= conn
->connect(username
,password
);
152 if (rv
!= OK
) return 1;
154 SqlConnection
*sCon
= (SqlConnection
*) conn
;
155 rv
= sCon
->getExclusiveLock();
162 aconStmt
= SqlFactory::createStatement(type
);
164 SqlStatement
*sqlStmt
= (SqlStatement
*)aconStmt
;
165 sqlStmt
->setLoading(true);
167 aconStmt
->setConnection(conn
);
168 //rv = conn->beginTrans(READ_COMMITTED, TSYNC);
169 rv
= conn
->beginTrans();
170 if (rv
!= OK
) return 2;
171 while (getInput(fileFlag
) == true) continue;
173 //TODO::conn should provide method telling status of the transaction.
174 //if running, then abort it
176 if (filename
[0] !='\0')
185 bool handleTransaction(char *st
)
187 while (isspace (*st
)|| *st
== '(' ) st
++; // Skip white spaces
188 if (strcasecmp (st
, "COMMIT;") == 0 ||
189 strcasecmp (st
, "commit;") == 0 )
192 ListIterator it
= sqlStmtList
.getIterator();
193 while(it
.hasElement()) {
194 stmt
= (AbsSqlStatement
*) it
.nextElement();
199 //conn->beginTrans(isoLevel, TSYNC);
200 conn
->beginTrans(isoLevel
);
203 else if (strcasecmp (st
, "ROLLBACK;") == 0||
204 strcasecmp (st
, "rollback;") == 0)
207 ListIterator it
= sqlStmtList
.getIterator();
208 while(it
.hasElement()) {
209 stmt
= (AbsSqlStatement
*)it
.nextElement();
214 //conn->beginTrans(isoLevel, TSYNC);
215 conn
->beginTrans(isoLevel
);
218 else if (strcasecmp (st
, "SET AUTOCOMMIT ON;") == 0)
220 autocommitmode
= true;
221 if (!silent
) printf("AUTOCOMMIT Mode is set to ON\n");
224 else if (strcasecmp (st
, "SET AUTOCOMMIT OFF;") == 0)
226 autocommitmode
= false;
227 if (!silent
) printf("AUTOCOMMIT Mode is set to OFF\n");
230 else if (strcasecmp (st
, "SET ISOLATION LEVEL UNCOMMITTED;") == 0)
232 isoLevel
= READ_UNCOMMITTED
;
233 printf("Isolation Level is set to READ_UNCOMMITTED\n");
236 else if (strcasecmp (st
, "SET ISOLATION LEVEL COMMITTED;") == 0)
238 isoLevel
= READ_COMMITTED
;
239 printf("Isolation Level is set to READ_COMMITTED\n");
242 else if (strcasecmp (st
, "SET ISOLATION LEVEL REPEATABLE;") == 0)
244 isoLevel
= READ_REPEATABLE
;
245 printf("Isolation Level is set to READ_REPEATABLE\n");
250 bool handleEchoAndComment(char *st
)
252 while (isspace (*st
)|| *st
== '(' ) st
++; // Skip white spaces
253 if (strncasecmp (st
, "ECHO", 4) == 0)
257 }else if (strncmp(st
, "--", 2) == 0)
260 }else if (strncasecmp(st
, "help", 2) == 0)
264 }else if (strcasecmp(st
, "show tables;") == 0) {
266 List tableList
= aconStmt
->getAllTableNames(rv
);
267 ListIterator iter
= tableList
.getIterator();
268 Identifier
*elem
= NULL
;
270 printf("=============TableNames===================\n");
272 while (iter
.hasElement())
274 elem
= (Identifier
*) iter
.nextElement();
276 printf(" %s \n", elem
->name
);
278 if (count
==0) printf(" No tables exist\n");
279 printf("==========================================\n");
287 printf("CSQL Command List\n");
288 printf("======================================================\n");
289 printf("SHOW TABLES\n");
290 printf("SET AUTOCOMMIT ON | OFF\n");
291 printf("COMMIT | ROLLBACK\n");
292 printf("SET ISOLATION LEVEL UNCOMMITTED | COMMITTED | REPEATABLE\n");
293 printf("CREATE TABLE | INDEX ...\n");
294 printf("DROP TABLE | INDEX ...\n");
295 printf("INSERT ...\n");
296 printf("UPDATE ...\n");
297 printf("DELETE ...\n");
298 printf("SELECT ...\n");
300 printf("======================================================\n");
302 void setStmtType(char *st
)
304 if (strncasecmp (st
, "SELECT", 6) == 0) {stmtType
=SELECT
; return; }
305 else if (strncasecmp (st
, "CREATE", 6) == 0) {stmtType
=DDL
; return; }
306 else if (strncasecmp (st
, "DROP", 4) == 0) { stmtType
=DDL
; return; }
311 char getQueryFromStdIn(char *buf
)
313 char c
, *bufBegin
=buf
;
317 while( (c=(char ) getchar()) != EOF && c != ';')
319 *buf++ = c; charCnt++;
320 if(c=='\n') //printf("%1d>",ln++);
322 if( charCnt == SQL_STMT_LEN ) {
323 printf("SQL Statement length is greater than %d. "
324 "Ignoring the statement.\n", SQL_STMT_LEN );
335 char *line
= readline("CSQL>");
336 if (line
) {strcpy(buf
, line
); add_history(line
); }
340 char getQueryFromFile(char *buf
)
342 char c
, *bufBegin
=buf
;
344 while( (c
=(char ) fgetc(fp
)) != EOF
&& c
!= ';')
346 *buf
++ = c
; charCnt
++;
347 if( charCnt
== SQL_STMT_LEN
) {
348 printf("SQL Statement length is greater than %d. "
349 "Ignoring the statement.\n", SQL_STMT_LEN
);
360 bool getInput(bool fromFile
)
362 char buffer
[SQL_STMT_LEN
+ 1];
365 if (fromFile
== false)
366 eof
= getQueryFromStdIn(buffer
);
368 eof
= getQueryFromFile(buffer
);
371 while(*buf
== ' ' || *buf
== '\t' || *buf
== '\n') buf
++;
372 if (eof
== EOF
|| strncasecmp (buf
, "quit", 4) == 0)
374 if (handleTransaction(buf
)) return true;
375 if (handleEchoAndComment(buf
)) return true;
376 if ( *buf
== ';' ) return true; // Null statement.
381 if (autocommitmode
) {
382 if (firstPrepare
) aconStmt
->free();
383 rv
= aconStmt
->prepare(buf
);
385 printf("Statement prepare failed with error %d\n", rv
);
392 stmt
= SqlFactory::createStatement(type
);
393 stmt
->setConnection(conn
);
394 rv
= stmt
->prepare(buf
);
396 printf("Statement prepare failed with error %d\n", rv
);
399 sqlStmtList
.append(stmt
);
402 rv
= stmt
->execute(rows
);
405 printf("Statement execute failed with error %d\n", rv
);
406 if (autocommitmode
) {
409 firstPrepare
= false; //set this so that it does not free again
410 conn
->beginTrans(isoLevel
);
414 sqlStmtList
.remove(stmt
);
415 delete stmt
; stmt
= NULL
;
419 if (stmtType
== OTHER
)
421 if (!silent
) printf("Statement Executed: Rows Affected = %d\n", rows
);
423 else if (stmtType
== DDL
)
425 if (!silent
) printf("Statement Executed\n");
429 FieldInfo
*info
= new FieldInfo();
430 printf("---------------------------------------------------------\n");
432 for (int i
= 0 ; i
< stmt
->noOfProjFields() ; i
++)
434 stmt
->getProjFldInfo(i
+1, info
);
435 printf("%s\t", info
->fldName
);
437 printf("\n---------------------------------------------------------\n");
443 tuple
= (char*)stmt
->fetchAndPrint(false);
445 if (tuple
== NULL
) { break; }
452 //conn->beginTrans(isoLevel, TSYNC);
454 firstPrepare
= false; //set this so that it does not free again
455 conn
->beginTrans(isoLevel
);
461 int getConnType(int opt
)
464 case 1: { printf("Local CSql\n"); return (int) CSql
; }
465 case 2: { printf("Local Adapter\n"); return (int) CSqlAdapter
; }
466 case 3: { printf("Local Gateway\n"); return (int) CSqlGateway
; }
467 case 4: { printf("Network CSql\n"); return (int) CSqlNetwork
; }
468 case 5: { printf("Network Adapter\n"); return (int) CSqlNetworkAdapter
;}
469 case 6: { printf("Netwrok Gateway\n"); return (int) CSqlNetworkGateway
;}