/**
Copyright 2000 - 2003 LogicMatrix. All rights reserved.
This software is distributed under the LogicMatrix Free Software License. This software may be used for any purpose, personal or commercial. Redistributions in binary /source code form are permitted. Commercial redistribution of larger works derived from, or works which bundle this software requires a "Commercial Redistribution License" which can be purchased from LogicMatrix. Contact LogicMatrix for details
Redistributions qualify as Free and non-commercial under one of the following terms:
1) Redistributions are made at no charge beyond the reasonable cost of materials and delivery.
2) Redistributions in binary/source code form must reproduce this Copyright Notice,these license terms, and the disclaimer/limitation of liability set forth as below, in the documentation and/or other materials
provided with the distribution.
Disclaimer
==========
The Software is provided on an "AS IS" basis. No warranty is
provided that the Software is free of defects, or fit for a
particular purpose.
Limitation of Liability
=======================
LogicMatrix shall not be liable for any damages suffered by the Licensee or any third party resulting from use of the Software.
**/
/**
dsql_m_structs.cpp
Purpose: Defines the metadata objects of
a dsql_mini database
Author: Vijay Mathew Pandyalakal
Date: 14/11/2003
Copyright: logicmatrix
**/
#include <string>
#include <vector>
using namespace std;
#include "mydate.h"
using namespace openutils;
#include "dsql_m_structs.h"
#include "bridge.h"
#include "sql_utils.h"
#include "rec.h"
using namespace dsqlm;
#include "datastore.h"
/**
Column class defenition
**/
Column::Column() {
this->id = 0;
this->in_active = FALSE;
this->decim_size = 0;
this->indexed = FALSE;
this->nullable = TRUE;
this->size = 0;
strcpy(this->title,"");
this->type = INT;
this->unique = FALSE;
}
Column::Column(const char* title,DsqlType type,int size,int decim_size,
enum boolean unique,enum boolean indexed,enum boolean nullable) {
if(strlen(title) > 32) {
throw DsqlMException("Column name too long");
}
this->decim_size = decim_size;
this->indexed = indexed;
this->nullable = nullable;
this->size = size;
strcpy(this->title,title);
this->type = type;
this->unique = unique;
}
void Column::refresh() {
this->id = 0;
this->in_active = FALSE;
this->decim_size = 0;
this->indexed = FALSE;
this->nullable = TRUE;
this->size = 0;
strcpy(this->title,"");
this->type = INT;
this->unique = FALSE;
}
void Column::setId(int id) {
this->id = id;
}
void Column::setDecimSize(int decim_size) {
this->decim_size = decim_size;
}
void Column::setIndexed(boolean indexed) {
this->indexed = indexed;
}
void Column::setNullable(enum boolean nullable) {
this->nullable = nullable;
}
void Column::setUnique(enum boolean unique) {
this->unique = unique;
}
void Column::setSize(int size) {
this->size = size;
}
void Column::setTitle(const char* title) {
if(strlen(title) > 32) {
throw DsqlMException("Column name too long");
}
strcpy(this->title,title);
}
void Column::setType(enum DsqlType type) {
this->type = type;
}
boolean Column::isIndexed() {
return indexed;
}
boolean Column::isNullable() {
return nullable;
}
boolean Column::isUnique() {
return unique;
}
int Column::getId() {
return id;
}
int Column::getDecimSize() {
return decim_size;
}
int Column::getSize() {
return size;
}
string Column::getTitle() {
return title;
}
DsqlType Column::getType() {
return type;
}
string Column::toString() {
char buff[100];
char null[4];
strcpy(null,"No");
if(isNullable() == TRUE) {
strcpy(null,"Yes");
}
char uk[4];
strcpy(uk,"No");
if(isUnique() == TRUE) {
strcpy(uk,"Yes");
}
char idx[4];
strcpy(idx,"No");
if(isIndexed() == TRUE) {
strcpy(idx,"Yes");
}
char tp[12];
SQLUtils utils;
strcpy(tp,utils.getTypeName(type).c_str());
sprintf(buff,"<<%s>>,size: %d.%d,type: %s,null: %s,"
"unique: %s,indexed %s",title,size,decim_size,tp,null,
uk,idx);
string s = buff;
return s;
}
/**
Table class defenition
**/
/*
Table::Table() {
strcpy(this->name,"");
}
*/
Table::Table(const char* name,Database* db) {
if(strlen(name) > 32) {
throw DsqlMException("Table name too long");
}
strcpy(this->name,name);
if(db == 0) {
throw DsqlMException("Database not inited");
}
this->db = db;
}
void Table::setName(const char* name) {
if(strlen(name) > 32) {
throw DsqlMException("Table name too long");
}
strcpy(this->name,name);
}
string Table::getName() {
return name;
}
openutils::MyDate Table::getCreated() {
return created;
}
openutils::MyDate Table::getLastAccess() {
return last_access;
}
void Table::create() {
if(strlen(name) <= 1) {
throw DsqlMException("Table name not set");
}
DataStore<Table> ds(this->name,db->getDBName().c_str());
if(!ds.Open(false)) {
throw DsqlMException("Table creation failed");
}
ds.AddRecord(*this);
ds.Close();
}
void Table::open() {
if(strlen(name) <= 1) {
throw DsqlMException("Table name not set");
}
DataStore<Table> ds(this->name,db->getDBName().c_str());
if(!ds.Open(true)) {
throw DsqlMException("Table not found");
}
Table t = ds.FindRecord(0);
this->created = t.created;
this->last_access = t.last_access;
strcpy(this->name,t.name);
ds.Close();
}
void Table::drop() {
char filnm[101];
sprintf(filnm,"%s\\%s_data",db->getDBName().c_str(),
getName().c_str());
unlink(filnm);
int cols = getNumberOfColumns();
for(int i=0;i<cols;i++) {
Column col = getCol(i+1);
if(col.isIndexed() == TRUE || col.isUnique() == TRUE) {
sprintf(filnm,"%s\\%s_%s_x",db->getDBName().c_str(),
getName().c_str(),
col.getTitle().c_str());
unlink(filnm);
}
if(col.getType() == AUTOID) {
sprintf(filnm,"%s\\%s_%s_aid",db->getDBName().c_str(),
getName().c_str(),
col.getTitle().c_str());
unlink(filnm);
}
}
sprintf(filnm,"%s\\%s_col",db->getDBName().c_str(),
getName().c_str());
unlink(filnm);
sprintf(filnm,"%s\\%s",db->getDBName().c_str(),
getName().c_str());
unlink(filnm);
}
void Table::addColumn(Column col) {
if(isDuplicateColumn(col.getTitle().c_str()) >= 0) {
throw DsqlMException("Duplicate column");
}
char col_fil[55];
sprintf(col_fil,"%s_col",name);
DataStore<Column> ds(col_fil,db->getDBName().c_str());
if(!ds.Open(true)) {
throw DsqlMException("Failed to open meta file");
}
col.setId(ds.GetRecordCount()+1);
ds.AddRecord(col);
ds.Close();
}
void Table::dropColumn(const char* col_name) {
int i = isDuplicateColumn(col_name);
if(i < 0) {
string str = col_name;
char *err_buff = new char[str.size() + 30];
sprintf(err_buff,"Column %s not found",str.c_str());
str = err_buff;
delete[] err_buff;
throw DsqlMException(str.c_str());
}
char col_fil[55];
sprintf(col_fil,"%s_col",name);
DataStore<Column> ds(col_fil,db->getDBName().c_str());
if(!ds.Open(true)) {
throw DsqlMException("Failed to open meta file");
}
ds.DeleteRecord(i);
ds.Close();
}
void Table::modifyColumn(const char* col_name,Column new_col) {
int i = isDuplicateColumn(col_name);
if(i < 0) {
string str = col_name;
char *err_buff = new char[str.size() + 30];
sprintf(err_buff,"Column %s not found",str.c_str());
str = err_buff;
delete[] err_buff;
throw DsqlMException(str.c_str());
}
char col_fil[55];
sprintf(col_fil,"%s_col",name);
DataStore<Column> ds(col_fil,db->getDBName().c_str());
if(!ds.Open(true)) {
throw DsqlMException("Failed to open meta file");
}
ds.ModifyRecord(new_col,i);
ds.Close();
}
int Table::getNumberOfColumns() {
char col_fil[80];
sprintf(col_fil,"%s_col",name);
string db_nm = "";
//try {
db_nm = db->getDBName();
/*}catch(...) {
throw DsqlMException("Data size error");
}*/
DataStore<Column> ds(col_fil,db_nm.c_str());
if(!ds.Open(true)) {
throw DsqlMException("Failed to open meta file");
}
int recs = ds.GetRecordCount();
ds.Close();
return recs;
}
int Table::getColumnNumber(Column col) {
char col_fil[80];
sprintf(col_fil,"%s_col",name);
DataStore<Column> ds(col_fil,db->getDBName().c_str());
if(!ds.Open(true)) {
throw DsqlMException("Failed to open meta file");
}
int recs = ds.GetRecordCount();
for(int i=0;i<recs;i++) {
Column c = ds.FindRecord(i);
if(strcmpi(col.getTitle().c_str(),c.getTitle().c_str()) == 0) {
ds.Close();
return (i+1);
}
}
ds.Close();
throw DsqlMException("Column not found");
}
Column Table::getCol(const char* col_name) {
int i = isDuplicateColumn(col_name);
if(i < 0) {
string str = col_name;
char *err_buff = new char[str.size() + 30];
sprintf(err_buff,"Column %s not found",str.c_str());
str = err_buff;
delete[] err_buff;
throw DsqlMException(str.c_str());
}
char col_fil[55];
sprintf(col_fil,"%s_col",name);
DataStore<Column> ds(col_fil,db->getDBName().c_str());
if(!ds.Open(true)) {
throw DsqlMException("Failed to open meta file");
}
Column c = ds.FindRecord(i);
ds.Close();
return c;
}
Column Table::getCol(int col_no) {
if(col_no <= 0) {
throw DsqlMException("Invalid column number");
}
char col_fil[55];
sprintf(col_fil,"%s_col",name);
DataStore<Column> ds(col_fil,db->getDBName().c_str());
if(!ds.Open(true)) {
throw DsqlMException("Failed to open meta file");
}
int recs = ds.GetRecordCount();
if(col_no > recs) {
ds.Close();
throw DsqlMException("Invalid column number");
}
for(int i=0;i<recs;i++) {
Column c = ds.FindRecord(i);
if(col_no == (i+1)) {
ds.Close();
return c;
}
}
ds.Close();
throw DsqlMException("Invalid column number");
}
int Table::isDuplicateColumn(const char* col_name) {
char col_fil[55];
sprintf(col_fil,"%s_col",name);
DataStore<Column> ds(col_fil,db->getDBName().c_str());
if(!ds.Open(true)) {
throw DsqlMException("Failed to open meta file");
}
int recs = ds.GetRecordCount();
for(int i=0;i<recs;i++) {
Column c = ds.FindRecord(i);
if(strcmpi(c.getTitle().c_str(),col_name) == 0) {
ds.Close();
return i;
}
}
ds.Close();
return -1;
}
long Table::optimize() {
Rec rec(this,db);
return rec.optimize();
}
string Table::toString() {
char buff[100];
sprintf(buff,"<<%s>>,created: %s,last_access: %s",
name,created.getDate().c_str(),last_access.getDate().c_str());
return buff;
}
/**
Identifier class defenition
**/
void Identifier::check(const char* idn) {
char c = idn[0];
if(c == '0' || c == '1' || c == '2' || c == '3' || c == '4'
|| c == '5' || c == '6' || c == '7' || c == '8' || c == '9'
|| c == '+' || c == '-' || c == '=' || c == '|' || c == '\\'
|| c == '(' || c == ')' || c == '*' || c == '&' || c == '^'
|| c == '%' || c == '$' || c == '#' || c== '@' || c == '!'
|| c == '~' || c == '`' || c == '\'' || c == '\"' || c == ':'
|| c == ';' || c == '<' || c == '>' || c == '.' || c == '?'
|| c == '/') {
char buff[51];
sprintf(buff,"Cannot begin an identifier with %c",c);
throw DsqlMException(buff);
}
if((strcmpi(idn,"CREATE") == 0)||(strcmpi(idn,"TABLE") == 0)||
(strcmpi(idn,"DROP") == 0)||(strcmpi(idn,"INSERT") == 0)||
(strcmpi(idn,"SELECT") == 0)||(strcmpi(idn,"DELETE") == 0)||
(strcmpi(idn,"FROM") == 0)||(strcmpi(idn,"INTO") == 0)||
(strcmpi(idn,"VALUES") == 0)) {
throw DsqlMException("An identifier cannot be a reserverd word");
}
}