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 rv
= dbMgr
->renameField(parsedData
->getTableName(), parsedData
->getIndexName(),parsedData
->getPKTableName());
70 rv
= executeForAddDropColumn(rowsAffected
);
74 DbRetVal
AlterTblStatement::resolveForAddDropColumn()
77 if( altType
== ALTERTABLERENAME
|| altType
== ALTERFIELDRENAME
) return OK
;
78 List fNameList
= table
->getFieldNameList();
79 FieldList extraFldList
= parsedData
->getCreFldList() ;
80 ListIterator fNameIter
= fNameList
.getIterator();
81 FieldInfo
*info
= new FieldInfo();
82 int fcount
= 1; void *valBuf
; int ret
=0;
83 Identifier
*elem
= NULL
;
84 noOfOldTabFld
= fNameList
.size();
85 totalFields
= noOfOldTabFld
+ extraFldList
.size();
86 bindFieldValues
= (void**) malloc( totalFields
* sizeof(char*));
87 memset(bindFieldValues
, 0, totalFields
* sizeof(char*));
88 char fldName
[IDENTIFIER_LENGTH
];
90 while (fNameIter
.hasElement())
92 elem
= (Identifier
*) fNameIter
.nextElement();
93 table
->getFieldInfo((const char*)elem
->name
, info
);
94 Table::getFieldNameAlone(elem
->name
,fldName
);
96 valBuf
= AllDataType::alloc(info
->type
, info
->length
);
97 table
->bindFld(elem
->name
, valBuf
);
98 if(altType
== ALTERDROP
&& 0 == strcmp(parsedData
->getIndexName(),fldName
)){
99 bindFieldValues
[totalFields
-i
] = valBuf
; //Store Last
103 bindFieldValues
[fcount
-1] = valBuf
;
104 ret
= tblDef
.addField(fldName
,info
->type
, info
->length
, info
->defaultValueBuf
, info
->isNull
, info
->isAutoIncrement
);
107 printError(ErrUnknown
, "Error while adding field");
115 while (fNameIter
.hasElement())
117 delete (Identifier
*) fNameIter
.nextElement();
120 if(altType
== ALTERDROP
)
125 FieldIterator iter
= extraFldList
.getIterator();
126 FieldName
*name
= NULL
;
127 ListIterator nIter
= parsedData
->getFieldNameList().getIterator();
128 while (iter
.hasElement())
130 FieldDef
*fDef
= iter
.nextElement();
132 while (nIter
.hasElement())
134 name
= (FieldName
*)nIter
.nextElement();
135 if (strcmp(name
->fldName
, fDef
->fldName_
) == 0) fDef
->isNull_
= true;
137 if (!fDef
->isDefault_
|| fDef
->isDefault_
&& fDef
->defaultValueBuf_
[0] == '\0') {
138 ret
= tblDef
.addField(fDef
->fldName_
, fDef
->type_
, fDef
->length_
,
139 NULL
,fDef
->isNull_
,fDef
->isAutoIncrement_
);
141 ret
= tblDef
.addField(fDef
->fldName_
, fDef
->type_
, fDef
->length_
,
142 fDef
->defaultValueBuf_
,fDef
->isNull_
,fDef
->isAutoIncrement_
);
146 printError(ErrUnknown
, "Error while adding field");
150 valBuf
= AllDataType::alloc(fDef
->type_
, fDef
->length_
);
151 bindFieldValues
[fcount
-1] = valBuf
;
157 DbRetVal
AlterTblStatement::executeForAddDropColumn(int &rowsAffected
)
160 char tblName
[IDENTIFIER_LENGTH
];
161 sprintf(tblName
,"%s_temp",parsedData
->getTableName());
162 rv
= dbMgr
->createTable(tblName
, tblDef
);
163 if (rv
!= OK
) return rv
;
164 rv
= createIndex(parsedData
->getTableName(),tblName
);
166 dbMgr
->dropTable(tblName
);
169 //TODO:Create Foreign Key Info
170 Table
*tempTable
= dbMgr
->openTable(tblName
);
171 List fNameList
= tempTable
->getFieldNameList();
172 ListIterator fNameIter
= fNameList
.getIterator();
173 FieldInfo
*info
= new FieldInfo();
174 int fcount
= 1; void *valBuf
;
175 Identifier
*elem
= NULL
;
176 while (fNameIter
.hasElement())
178 elem
= (Identifier
*) fNameIter
.nextElement();
179 tempTable
->getFieldInfo((const char*)elem
->name
, info
);
180 valBuf
= bindFieldValues
[fcount
-1];
181 tempTable
->bindFld(elem
->name
, valBuf
);
184 table
->setCondition(NULL
);
185 rv
= table
->execute();
188 dbMgr
->closeTable(tempTable
);
189 dbMgr
->dropTable(tblName
);
195 int extraField
= totalFields
- noOfOldTabFld
;
196 tuple
= (char*)table
->fetch();
197 if (tuple
== NULL
) {break;}
201 tempTable
->markFldNull(noOfOldTabFld
+i
);
204 rv
= tempTable
->insertTuple();
208 dbMgr
->closeTable(tempTable
);
209 dbMgr
->dropTable(tblName
);
212 char tblName1
[IDENTIFIER_LENGTH
];
213 sprintf(tblName1
,"%s_temp2",parsedData
->getTableName());
214 rv
= dbMgr
->renameTable(parsedData
->getTableName(),tblName1
);
216 dbMgr
->closeTable(tempTable
);
217 dbMgr
->dropTable(tblName
);
220 rv
= dbMgr
->renameTable(tblName
,parsedData
->getTableName());
222 dbMgr
->renameTable(tblName1
,parsedData
->getTableName());
223 dbMgr
->closeTable(tempTable
);
224 dbMgr
->dropTable(tblName
);
227 rv
= dbMgr
->dropTable(tblName1
);
229 dbMgr
->renameTable(tblName1
,parsedData
->getTableName());
230 dbMgr
->closeTable(tempTable
);
231 dbMgr
->dropTable(tblName
);
236 DbRetVal
AlterTblStatement::createIndex(const char *oldName
,const char *newName
)
239 CatalogTableINDEXFIELD
cIndexField(((DatabaseManagerImpl
*)dbMgr
)->sysDb());
240 ListIterator iter
= cIndexField
.getIndexListIterater((char*)oldName
);
241 IndexInfoForDriver
*info
=NULL
;
242 char name
[IDENTIFIER_LENGTH
]="";
243 char indName
[IDENTIFIER_LENGTH
]="";
244 char tempIndexName
[IDENTIFIER_LENGTH
] ="";
245 sprintf(tempIndexName
, "%s_idx1_Primary", oldName
);
246 bool shouldCreateIndex
= false;
247 bool isFirstEntry
=true;
248 HashIndexInitInfo
*idxInfo
= NULL
, *indexInfo2
= NULL
;
249 while(iter
.hasElement())
251 if(shouldCreateIndex
)
253 if(idxInfo
->isPrimary
&& 0 == strcmp(info
->indexName
,tempIndexName
))
254 sprintf(indName
, "%s_idx1_Primary", newName
);
255 rv
= dbMgr
->createIndex(indName
, idxInfo
);
262 shouldCreateIndex
= false;
265 info
= (IndexInfoForDriver
*) iter
.nextElement();
266 if((0 == strcmp(info
->indexName
,indName
)))
268 if(idxInfo
) idxInfo
->list
.append(info
->fieldName
);
269 else printf("should not happen\n");
271 idxInfo
= new HashIndexInitInfo();
272 strcpy(idxInfo
->tableName
, newName
);
273 strcpy(indName
,info
->indexName
);
274 if(!isFirstEntry
)shouldCreateIndex
=true;
275 isFirstEntry
= false;
276 idxInfo
->indType
=(IndexType
) info
->type
;
277 idxInfo
->isPrimary
= info
->isPrimary
;
278 idxInfo
->isUnique
= info
->isUnique
;
279 idxInfo
->list
.append(info
->fieldName
);
282 if(idxInfo
->isPrimary
&& 0 == strcmp(info
->indexName
,tempIndexName
))
283 sprintf(indName
, "%s_idx1_Primary", newName
);
284 rv
= dbMgr
->createIndex(indName
, idxInfo
);
295 DbRetVal
AlterTblStatement::resolveForModifyColumn()