1 /***************************************************************************
2 * Copyright (C) 2007 by Prabakaran Thirumalai *
3 * praba_tuty@yahoo.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 ***************************************************************************/
17 #include <Statement.h>
18 #include <TableImpl.h>
20 AlterTblStatement::AlterTblStatement()
22 bindFieldValues
= NULL
;
27 AlterTblStatement::~AlterTblStatement()
29 if (table
) { table
->close(); table
= NULL
; }
31 for(int i
=0;i
<totalFields
;i
++)
33 free(bindFieldValues
[i
]);
35 free(bindFieldValues
); bindFieldValues
= NULL
;
39 DbRetVal
AlterTblStatement::resolve()
42 table
= dbMgr
->openTable(parsedData
->getTableName());
45 printError(ErrNotExists
, "Unable to open the table:Table not exists");
48 altType
= parsedData
->getAlterType();
49 if(altType
== ALTERMODIFY
)
51 printError(ErrUnknown
, " NOT Done \n");
54 rv
= resolveForAddDropColumn();
58 DbRetVal
AlterTblStatement::execute(int &rowsAffected
)
61 if( altType
== ALTERTABLERENAME
)
63 rv
= dbMgr
->renameTable(parsedData
->getTableName(), parsedData
->getIndexName());
65 }else if( altType
== ALTERFIELDRENAME
)
67 if (strcmp(parsedData
->getIndexName(),parsedData
->getPKTableName())==0)
69 rv
= dbMgr
->renameField(parsedData
->getTableName(), parsedData
->getIndexName(),parsedData
->getPKTableName());
72 rv
= executeForAddDropColumn(rowsAffected
);
76 DbRetVal
AlterTblStatement::resolveForAddDropColumn()
79 if( altType
== ALTERTABLERENAME
|| altType
== ALTERFIELDRENAME
) return OK
;
80 List fNameList
= table
->getFieldNameList();
81 FieldList extraFldList
= parsedData
->getCreFldList() ;
82 ListIterator fNameIter
= fNameList
.getIterator();
83 FieldInfo
*info
= new FieldInfo();
84 int fcount
= 1; void *valBuf
; int ret
=0;
85 Identifier
*elem
= NULL
;
86 noOfOldTabFld
= fNameList
.size();
87 totalFields
= noOfOldTabFld
+ extraFldList
.size();
88 bindFieldValues
= (void**) malloc( totalFields
* sizeof(char*));
89 memset(bindFieldValues
, 0, totalFields
* sizeof(char*));
90 char fldName
[IDENTIFIER_LENGTH
];
92 while (fNameIter
.hasElement())
94 elem
= (Identifier
*) fNameIter
.nextElement();
95 table
->getFieldInfo((const char*)elem
->name
, info
);
96 Table::getFieldNameAlone(elem
->name
,fldName
);
98 valBuf
= AllDataType::alloc(info
->type
, info
->length
);
99 table
->bindFld(elem
->name
, valBuf
);
100 if(altType
== ALTERDROP
&& 0 == strcmp(parsedData
->getIndexName(),fldName
)){
101 bindFieldValues
[totalFields
-i
] = valBuf
; //Store Last
105 bindFieldValues
[fcount
-1] = valBuf
;
106 ret
= tblDef
.addField(fldName
,info
->type
, info
->length
, info
->defaultValueBuf
, info
->isNull
, info
->isAutoIncrement
);
109 printError(ErrUnknown
, "Error while adding field");
117 while (fNameIter
.hasElement())
119 delete (Identifier
*) fNameIter
.nextElement();
122 if(altType
== ALTERDROP
)
127 FieldIterator iter
= extraFldList
.getIterator();
128 FieldName
*name
= NULL
;
129 ListIterator nIter
= parsedData
->getFieldNameList().getIterator();
130 while (iter
.hasElement())
132 FieldDef
*fDef
= iter
.nextElement();
134 while (nIter
.hasElement())
136 name
= (FieldName
*)nIter
.nextElement();
137 if (strcmp(name
->fldName
, fDef
->fldName_
) == 0) fDef
->isNull_
= true;
139 if (!fDef
->isDefault_
|| fDef
->isDefault_
&& fDef
->defaultValueBuf_
[0] == '\0') {
140 ret
= tblDef
.addField(fDef
->fldName_
, fDef
->type_
, fDef
->length_
,
141 NULL
,fDef
->isNull_
,fDef
->isAutoIncrement_
);
143 ret
= tblDef
.addField(fDef
->fldName_
, fDef
->type_
, fDef
->length_
,
144 fDef
->defaultValueBuf_
,fDef
->isNull_
,fDef
->isAutoIncrement_
);
148 printError(ErrUnknown
, "Error while adding field");
152 valBuf
= AllDataType::alloc(fDef
->type_
, fDef
->length_
);
153 bindFieldValues
[fcount
-1] = valBuf
;
159 DbRetVal
AlterTblStatement::executeForAddDropColumn(int &rowsAffected
)
162 char tblName
[IDENTIFIER_LENGTH
];
163 sprintf(tblName
,"%s_temp",parsedData
->getTableName());
164 rv
= dbMgr
->createTable(tblName
, tblDef
);
165 if (rv
!= OK
) return rv
;
166 rv
= createIndex(parsedData
->getTableName(),tblName
);
168 dbMgr
->dropTable(tblName
);
171 //TODO:Create Foreign Key Info
172 Table
*tempTable
= dbMgr
->openTable(tblName
);
173 List fNameList
= tempTable
->getFieldNameList();
174 ListIterator fNameIter
= fNameList
.getIterator();
175 FieldInfo
*info
= new FieldInfo();
176 int fcount
= 1; void *valBuf
;
177 Identifier
*elem
= NULL
;
178 while (fNameIter
.hasElement())
180 elem
= (Identifier
*) fNameIter
.nextElement();
181 tempTable
->getFieldInfo((const char*)elem
->name
, info
);
182 valBuf
= bindFieldValues
[fcount
-1];
183 tempTable
->bindFld(elem
->name
, valBuf
);
186 table
->setCondition(NULL
);
187 rv
= table
->execute();
190 dbMgr
->closeTable(tempTable
);
191 dbMgr
->dropTable(tblName
);
197 int extraField
= totalFields
- noOfOldTabFld
;
198 tuple
= (char*)table
->fetch();
199 if (tuple
== NULL
) {break;}
203 tempTable
->markFldNull(noOfOldTabFld
+i
);
206 rv
= tempTable
->insertTuple();
210 dbMgr
->closeTable(tempTable
);
211 dbMgr
->dropTable(tblName
);
214 char tblName1
[IDENTIFIER_LENGTH
];
215 sprintf(tblName1
,"%s_temp2",parsedData
->getTableName());
216 rv
= dbMgr
->renameTable(parsedData
->getTableName(),tblName1
);
218 dbMgr
->closeTable(tempTable
);
219 dbMgr
->dropTable(tblName
);
222 rv
= dbMgr
->renameTable(tblName
,parsedData
->getTableName());
224 dbMgr
->renameTable(tblName1
,parsedData
->getTableName());
225 dbMgr
->closeTable(tempTable
);
226 dbMgr
->dropTable(tblName
);
229 rv
= dbMgr
->dropTable(tblName1
);
231 dbMgr
->renameTable(tblName1
,parsedData
->getTableName());
232 dbMgr
->closeTable(tempTable
);
233 dbMgr
->dropTable(tblName
);
238 DbRetVal
AlterTblStatement::createIndex(const char *oldName
,const char *newName
)
241 CatalogTableINDEXFIELD
cIndexField(((DatabaseManagerImpl
*)dbMgr
)->sysDb());
242 ListIterator iter
= cIndexField
.getIndexListIterater((char*)oldName
);
243 IndexInfoForDriver
*info
=NULL
;
244 char name
[IDENTIFIER_LENGTH
]="";
245 char indName
[IDENTIFIER_LENGTH
]="";
246 char tempIndexName
[IDENTIFIER_LENGTH
] ="";
247 sprintf(tempIndexName
, "%s_idx1_Primary", oldName
);
248 bool shouldCreateIndex
= false;
249 bool isFirstEntry
=true;
250 HashIndexInitInfo
*idxInfo
= NULL
, *indexInfo2
= NULL
;
251 while(iter
.hasElement())
253 if(shouldCreateIndex
)
255 if(idxInfo
->isPrimary
&& 0 == strcmp(info
->indexName
,tempIndexName
))
256 sprintf(indName
, "%s_idx1_Primary", newName
);
257 rv
= dbMgr
->createIndex(indName
, idxInfo
);
264 shouldCreateIndex
= false;
267 info
= (IndexInfoForDriver
*) iter
.nextElement();
268 if((0 == strcmp(info
->indexName
,indName
)))
270 if(idxInfo
) idxInfo
->list
.append(info
->fieldName
);
271 else printf("should not happen\n");
273 idxInfo
= new HashIndexInitInfo();
274 strcpy(idxInfo
->tableName
, newName
);
275 strcpy(indName
,info
->indexName
);
276 if(!isFirstEntry
)shouldCreateIndex
=true;
277 isFirstEntry
= false;
278 idxInfo
->indType
=(IndexType
) info
->type
;
279 idxInfo
->isPrimary
= info
->isPrimary
;
280 idxInfo
->isUnique
= info
->isUnique
;
281 idxInfo
->list
.append(info
->fieldName
);
284 if (idxInfo
== NULL
) return OK
;
285 if(idxInfo
->isPrimary
&& 0 == strcmp(info
->indexName
,tempIndexName
))
286 sprintf(indName
, "%s_idx1_Primary", newName
);
287 rv
= dbMgr
->createIndex(indName
, idxInfo
);
298 DbRetVal
AlterTblStatement::resolveForModifyColumn()