*** empty log message ***
[csql.git] / src / sql / DdlStatement.cxx
blob29f279da448e4d87958da4a9373f57a343d70af3
1 /***************************************************************************
2 * Copyright (C) 2007 by Prabakaran Thirumalai *
3 * praba_tuty@yahoo.com *
4 * *
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. *
9 * *
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. *
14 * *
15 ***************************************************************************/
16 #include <os.h>
17 #include <Statement.h>
18 #include <Info.h>
19 #ifndef MMDB
20 #include <TableConfig.h>
21 #endif
22 CreateTblStatement::CreateTblStatement()
24 parsedData = NULL;
25 dbMgr = NULL;
28 CreateTblStatement::~CreateTblStatement()
30 tblDef.reset();
32 DbRetVal CreateTblStatement::execute(int &rowsAffected)
34 DbRetVal rv = OK;
35 rv = dbMgr->createTable(tblName, tblDef);
36 if (rv != OK) return rv;
37 if (parsedData->getFieldNameList().size() > 0)
39 HashIndexInitInfo *idxInfo = new HashIndexInitInfo();
40 strcpy(idxInfo->tableName, tblName);
41 ListIterator iter = parsedData->getFieldNameList().getIterator();
42 FieldName *name = NULL;
43 while (iter.hasElement())
45 name = (FieldName*)iter.nextElement();
46 idxInfo->list.append(name->fldName);
48 idxInfo->indType = hashIndex;
49 idxInfo->isPrimary = true;
50 idxInfo->isUnique = true;
51 int bucket = parsedData->getBucketSize();
52 if(bucket!=0)
53 idxInfo->bucketSize = bucket;
54 char indName[IDENTIFIER_LENGTH];
55 sprintf(indName, "%s_idx1_Primary", tblName);
56 rv = dbMgr->createIndex(indName, idxInfo);
57 if (rv != OK)
59 dbMgr->dropTable(tblName);
60 delete idxInfo;
61 return rv;
63 delete idxInfo;
65 if(parsedData->getSecondaryIndexFieldList().size() > 0)
67 HashIndexInitInfo *idxInfo = new HashIndexInitInfo();
68 strcpy(idxInfo->tableName, tblName);
69 ListIterator iter = parsedData->getSecondaryIndexFieldList().getIterator();
70 FieldInfo *name = NULL;
71 while (iter.hasElement())
73 name = (FieldInfo*)iter.nextElement();
74 idxInfo->list.append(name->fldName);
76 idxInfo->indType = treeIndex;
77 idxInfo->isPrimary = true;
78 idxInfo->isUnique = true;
79 char indName[IDENTIFIER_LENGTH];
80 sprintf(indName, "%s_idx_Auto_increment", tblName);
81 rv = dbMgr->createIndex(indName, idxInfo);
82 if (rv != OK)
84 dbMgr->dropTable(tblName);
85 delete idxInfo;
86 return rv;
88 delete idxInfo;
90 if(parsedData->getForeignKeyList().size() > 0)
92 ForeignKeyInfo *fkInfo=NULL;
93 int i=0;
94 ListIterator iter = parsedData->getForeignKeyList().getIterator();
95 while (iter.hasElement())
97 fkInfo = (ForeignKeyInfo *)iter.nextElement();
98 strcpy(fkInfo->fkTableName,tblName);
99 char fkName[IDENTIFIER_LENGTH];
100 sprintf(fkName, "%s_FKEY_%d", tblName,++i);
101 rv = dbMgr->createForeignKey(fkName,fkInfo);
102 if (rv != OK)
104 dbMgr->dropTable(tblName);
105 return rv;
110 return rv;
112 DbRetVal CreateTblStatement::checkForDot(char *name)
114 int i=0;
115 while ( name[i] != '\0')
117 if (name[i++] == '.') { return ErrSyntaxError; }
119 return OK;
122 DbRetVal CreateTblStatement::resolve()
124 DbRetVal rv = OK;
125 strcpy(tblName, parsedData->getTableName());
126 rv = checkForDot(tblName);
127 if ( rv!=OK )
129 printf("Check SQL Syntax: .\n");
130 return rv;
132 FieldIterator iter = parsedData->getCreFldList().getIterator();
134 int i = 0;
135 FieldName *name = NULL;
136 ListIterator nIter = parsedData->getFieldNameList().getIterator();
137 while (iter.hasElement())
139 FieldDef *fDef = iter.nextElement();
140 nIter.reset();
141 while (nIter.hasElement())
143 name = (FieldName*)nIter.nextElement();
144 if (strcmp(name->fldName, fDef->fldName_) == 0) fDef->isNull_ = true;
146 rv = checkForDot(fDef->fldName_);
147 if ( rv!=OK )
149 printf("Check SQL Syntax: .\n");
150 return rv;
152 if (fDef->type_ == typeVarchar || fDef->type_ == typeString) {
153 fDef->length_++;
154 //varchar and char require \0 to be stored at the end
156 /* To check char field and restrict it for the max length 8kb(8000) */
157 if( (fDef->type_ == typeString) && (fDef->length_ > 8000) ){
158 printError(ErrBadRange,"Char data type length should be less than 8kb(8000).");
159 return ErrBadRange;
161 //TODO : need a new addField function which can take FieldDef as parameter.
162 if (!fDef->isDefault_ || fDef->isDefault_ && fDef->defaultValueBuf_[0] == '\0') {
163 i = tblDef.addField(fDef->fldName_, fDef->type_, fDef->length_,
164 NULL,fDef->isNull_,fDef->isAutoIncrement_);
165 } else {
166 i = tblDef.addField(fDef->fldName_, fDef->type_, fDef->length_,
167 fDef->defaultValueBuf_,fDef->isNull_,fDef->isAutoIncrement_);
169 if( 0 != i )
171 printError(ErrUnknown, "Error while adding field");
172 rv = ErrUnknown;
173 break;
176 return rv;
178 /////////////////////////////////////
179 DbRetVal CacheTblStatement::resolve()
181 DbRetVal rv = OK;
182 #ifndef MMDB
183 TableConf::config.init();
184 cacheLoader.setConnParam(I_USER, I_PASS);
185 cacheLoader.setTable(parsedData->getTableName());
186 TableConf::config.setTable(parsedData->getTableName());
187 if(parsedData->getHCondFld()){
188 cacheLoader.setCondition(parsedData->getHCondition());// new one
189 TableConf::config.setCondition(parsedData->getHCondition());
191 if(parsedData->getVCondFld()) {
192 cacheLoader.setFieldListVal(parsedData->getVCondition());
193 TableConf::config.setFieldListVal(parsedData->getVCondition());
195 if(parsedData->getPkFld()){
196 cacheLoader.setFieldName(parsedData->getIndexName());
197 TableConf::config.setFieldName(parsedData->getIndexName());
199 if(parsedData->getDSN()){
200 cacheLoader.setDsnName(parsedData->getPKTableName());
201 TableConf::config.setDsnName(parsedData->getPKTableName());
203 if( !(parsedData->getUnCache()))
205 rv = TableConf::config.isTableCached(parsedData->getTableName());
206 if(rv == OK){
207 printError(ErrAlready, "Table is already cached,unload table then try");
208 return ErrAlready;
211 #endif
212 return OK;
214 DbRetVal CacheTblStatement::execute(int &rowsAffected)
216 DbRetVal rv = OK;
217 #ifndef MMDB
218 if( parsedData->getUnCache())
220 unsigned int mode =
221 TableConf::config.getTableMode(parsedData->getTableName());
222 bool isCached = TableConf::config.isTableCached(mode);
223 if (!isCached) {
224 printError(ErrNotCached, "Table is not Cached");
225 return ErrNotCached;
227 TableConf::config.removeFromCacheTableFile();
228 } else {
229 rv = cacheLoader.load(!(parsedData->getNoSchema()));
230 if(rv == OK){
231 TableConf::config.addToCacheTableFile(parsedData->getDirect());
232 } else return rv;
234 #endif
235 return OK;
237 ///////////////////////////////////////
238 CreateIdxStatement::CreateIdxStatement()
240 parsedData = NULL;
241 dbMgr = NULL;
244 CreateIdxStatement::~CreateIdxStatement()
249 DbRetVal CreateIdxStatement::execute(int &rowsAffected)
251 DbRetVal rv = OK;
252 if (parsedData->getFieldNameList().size() > 0)
254 HashIndexInitInfo *idxInfo = new HashIndexInitInfo();
255 strcpy(idxInfo->tableName, parsedData->getTableName());
256 ListIterator iter = parsedData->getFieldNameList().getIterator();
257 FieldName *name = NULL;
258 while (iter.hasElement())
260 name = (FieldName*)iter.nextElement();
261 idxInfo->list.append(name->fldName);
263 idxInfo->indType = parsedData->getIndexType();
264 idxInfo->isPrimary = parsedData->getPrimary();
265 idxInfo->isUnique = parsedData->getUnique();
266 int bucket = parsedData->getBucketSize();
267 if(bucket!=0)
268 idxInfo->bucketSize = bucket;
269 rv = dbMgr->createIndex(parsedData->getIndexName(), idxInfo);
270 delete idxInfo;
272 if (rv == OK) dbMgr->sendSignal(SIGCSQL1);
273 return rv;
276 // function for not to drop cached table
277 DbRetVal isTableCached(char *tabName) // function added by :Jitendra
280 DbRetVal rv =OK;
281 FILE *fp;
282 if (!Conf::config.useCache()) return OK;
283 fp = fopen(Conf::config.getTableConfigFile(),"r");
284 if(fp==NULL) return OK;
285 char tablename[IDENTIFIER_LENGTH]; tablename[0] = '\0';
286 char condition[IDENTIFIER_LENGTH]; condition[0]='\0';
287 char fieldname[IDENTIFIER_LENGTH]; fieldname[0]='\0';
288 char field[IDENTIFIER_LENGTH]; field[0]='\0';
289 char dsnName[IDENTIFIER_LENGTH]; dsnName[0]='\0';
290 int mode;
291 while(!feof(fp))
293 fscanf(fp,"%d %s %s %s %s %s\n",&mode,tablename,fieldname,condition,field,dsnName);
294 if(strcmp(tablename,tabName) ==0){
295 fclose(fp);
296 return ErrNoPrivilege;}
298 fclose(fp);
299 return rv;
302 DbRetVal DropTblStatement::execute(int &rowsAffected)
304 DbRetVal rv = OK; // newly added
305 char *tab;
306 tab = parsedData->getTableName();
308 DatabaseManagerImpl *dmgr = (DatabaseManagerImpl *)dbMgr;
309 IsolationLevel iso = dmgr->txnMgr()->getIsoLevel();
310 rv = dmgr->txnMgr()->rollback(dmgr->lockMgr());
311 rv = dmgr->txnMgr()->startTransaction(dmgr->lockMgr(),iso);
312 #ifndef MMDB
313 int mode = TableConf::config.getTableMode(tab);
314 // rv = isTableCached(tab);
315 if (mode != 0 && mode < 8) {
316 printf("Cached table '%s' cannot be dropped.\n", tab);
317 printf("uncache the table by 'cachetable -t %s -u' and drop.\n", tab);
318 printError(ErrNoPrivilege, "Cached table '%s' cannot be dropped.", tab);
319 return ErrNoPrivilege;
321 else if (mode == 8) {
322 printf("Replicated table '%s' cannot be dropped.\n", tab);
323 printf("Unreplicate the table by 'repltable -t %s -u' and drop.\n", tab);
324 printError(ErrNoPrivilege, "Replicated table '%s' cannot be dropped.", tab);
325 return ErrNoPrivilege;
327 else if (mode > 8) {
328 printf("Table %s is cached and replicated. Cannot be dropped.\n", tab);
329 printf("Uncache the table by 'cachetable -t %s -u'.\n", tab);
330 printf("Unreplicated the table by 'repltable -t %s -u' and drop.\n", tab);
331 printError(ErrNoPrivilege, "Table %s is cached and replicated. Cannot be dropped.", tab);
332 return ErrNoPrivilege;
334 #endif
335 rv = dbMgr->dropTable(parsedData->getTableName());
336 if (rv == OK) dbMgr->sendSignal(SIGCSQL1);
337 return rv;
340 DbRetVal DropIdxStatement::execute(int &rowsAffected)
342 DbRetVal rv = OK;
343 DatabaseManagerImpl *dmgr = (DatabaseManagerImpl *)dbMgr;
344 IsolationLevel iso = dmgr->txnMgr()->getIsoLevel();
345 rv = dmgr->txnMgr()->rollback(dmgr->lockMgr());
346 rv = dmgr->txnMgr()->startTransaction(dmgr->lockMgr(),iso);
347 rv = dmgr->dropIndex(parsedData->getIndexName());
348 if (rv == OK) dbMgr->sendSignal(SIGCSQL1);
349 return rv;
352 //================== Truncate Table Statement ===============
355 DbRetVal TruncateTblStatement::execute(int &rowsAffected)
357 DbRetVal rv = OK;
358 table->setCondition(NULL);
359 IsolationLevel level = ((DatabaseManagerImpl*)dbMgr)->txnMgr()->getIsoLevel();
360 rv=((DatabaseManagerImpl*)dbMgr)->txnMgr()->commit(((DatabaseManagerImpl*)dbMgr)->lockMgr());
361 if (rv != OK) return rv;
362 rv=((DatabaseManagerImpl*)dbMgr)->txnMgr()->startTransaction(((DatabaseManagerImpl*)dbMgr)->lockMgr(),level);
363 if (rv != OK) return rv;
365 rv = table->execute();
366 if (rv != OK) return rv;
367 rowsAffected = 0;
368 table->setLoading(true);
369 void *tuple;
370 while(true)
372 tuple = (char*)table->fetchNoBind(rv);
373 if (rv != OK) break;
374 if (tuple == NULL) {break;}
375 rv = table->deleteTuple();
376 if (rv != OK) break;
377 rowsAffected++;
379 table->closeScan();
380 return rv;
382 DbRetVal TruncateTblStatement::resolve()
384 DbRetVal rv = OK;
385 table = dbMgr->openTable(parsedData->getTableName());
386 if (table == NULL)
388 printError(ErrNotExists, "Unable to open the table:Table not exists");
389 return ErrNotExists;
391 return rv;
398 //================== Compact Table Statement===================
399 DbRetVal CompactTblStatement::resolve()
401 DbRetVal rv = OK;
402 table = dbMgr->openTable(parsedData->getTableName());
403 if (table == NULL)
405 printError(ErrNotExists, "Unable to open the table:Table not exists");
406 return ErrNotExists;
408 return OK;
410 DbRetVal CompactTblStatement::execute(int &rowsAffected)
412 DbRetVal rv = OK;
413 rv = table->compact();
414 dbMgr->closeTable(table);
415 return rv;
417 DbRetVal UserTblStatement::resolve()
419 uType = parsedData->getUserType();
420 if( uType == CREATEUSER || uType == DROPUSER || (uType == ALTERUSER && strcmp(userName,parsedData->getUserName())!=0))
422 if(strcmp(userName,"root")!=0)
424 printError(ErrNoPrivilege,"Permission Denied. Login as root");
425 return ErrNoPrivilege;
426 }else if(uType == DROPUSER && strcmp(parsedData->getUserName(),"root")==0)
428 printError(ErrNoPrivilege,"Permission Denied. root user cannot be deleted");
429 return ErrNoPrivilege;
432 return OK;
434 DbRetVal UserTblStatement::execute(int &rowsAffected)
436 DbRetVal rv = OK;
437 if( uType == CREATEUSER){
438 rv =(DbRetVal) usrMgr->createUser(parsedData->getUserName(), parsedData->getPassWord());
439 }else if(uType == DROPUSER){
440 rv =(DbRetVal) usrMgr->deleteUser(parsedData->getUserName());
441 }else{
442 rv =(DbRetVal) usrMgr->changePassword(parsedData->getUserName(), parsedData->getPassWord());
444 return rv;