|
|
#pragma once
#ifndef BASEINFO_H
#define BASEINFO_H
//--------------------------------------------------------------
class BaseInfo
{
public:
BaseInfo()
{}
BaseInfo(const string& n)
: m_name(n)
{}
BaseInfo(const UCHAR* const n)
: m_name((char*)n)
{}
BaseInfo(const BaseInfo& d)
: m_name(d.m_name)
{}
const string& name() const
{
return m_name;
}
bool operator == (const BaseInfo& rhs) const
{
return m_name == rhs.m_name;
}
bool operator != (const BaseInfo& rhs) const
{
return m_name != rhs.m_name;
}
bool operator < (const BaseInfo& rhs) const
{
return m_name < rhs.m_name;
}
bool operator > (const BaseInfo& rhs) const
{
return m_name > rhs.m_name;
}
private:
string m_name;
} ;
#endif
|
|
|
#pragma once
#ifndef CHECKATTR_H
#define CHECKATTR_H
//--------------------------------------------------------------
#include "Header.h"
template < class T >
bool CheckAttr(Header& hdr, const string& colname, const string& attr, const T& lhs, const T& rhs)
{
if (lhs == rhs)
return true;
hdr.Print();
cout << "Changed : column " << colname
<< " : '" << attr << "' changed from " << lhs
<< " to " << rhs
<< endl;
return false;
}
#endif
|
|
|
#include "Common.h"
#include "DSNInfo.h"
#include "CSqlImpl.h"
#include "SqlColumn.h"
#include "ColumnRS.h"
#include "dbgdefines.h"
const int STR_LEN = 128 + 1;
const int REM_LEN = 254 + 1;
struct ColumnRSPrivate
{
UCHAR szQualifier[STR_LEN];
UCHAR szOwner[STR_LEN];
UCHAR szTableName[STR_LEN];
UCHAR szColName[STR_LEN];
UCHAR szTypeName[STR_LEN];
UCHAR szRemarks[REM_LEN];
SDWORD Precision;
SDWORD Length;
SWORD DataType;
SWORD Scale;
SWORD Radix;
SWORD Nullable;
SDWORD cbQualifier;
SDWORD cbOwner;
SDWORD cbTableName;
SDWORD cbColName;
SDWORD cbTypeName;
SDWORD cbRemarks;
SDWORD cbDataType;
SDWORD cbPrecision;
SDWORD cbLength;
SDWORD cbScale;
SDWORD cbRadix;
SDWORD cbNullable;
} ;
//--------------------------------------------------------------------------------
ColumnRS::ColumnRS()
{
m_priv = new ColumnRSPrivate;
Clear();
}
//--------------------------------------------------------------------------------
void ColumnRS::Bind(CSqlImpl& pimpl)
{
USHORT i = 1;
pimpl.CheckRC(SQLBindCol(pimpl.hstmt(), i++, SQL_C_CHAR, m_priv->szQualifier, STR_LEN, &m_priv->cbQualifier));
pimpl.CheckRC(SQLBindCol(pimpl.hstmt(), i++, SQL_C_CHAR, m_priv->szOwner, STR_LEN, &m_priv->cbOwner));
pimpl.CheckRC(SQLBindCol(pimpl.hstmt(), i++, SQL_C_CHAR, m_priv->szTableName, STR_LEN, &m_priv->cbTableName));
pimpl.CheckRC(SQLBindCol(pimpl.hstmt(), i++, SQL_C_CHAR, m_priv->szColName, STR_LEN, &m_priv->cbColName));
pimpl.CheckRC(SQLBindCol(pimpl.hstmt(), i++, SQL_C_SSHORT, &m_priv->DataType, 0, &m_priv->cbDataType));
pimpl.CheckRC(SQLBindCol(pimpl.hstmt(), i++, SQL_C_CHAR, m_priv->szTypeName, STR_LEN, &m_priv->cbTypeName));
pimpl.CheckRC(SQLBindCol(pimpl.hstmt(), i++, SQL_C_SLONG, &m_priv->Precision, 0, &m_priv->cbPrecision));
pimpl.CheckRC(SQLBindCol(pimpl.hstmt(), i++, SQL_C_SLONG, &m_priv->Length, 0, &m_priv->cbLength));
pimpl.CheckRC(SQLBindCol(pimpl.hstmt(), i++, SQL_C_SSHORT, &m_priv->Scale, 0, &m_priv->cbScale));
pimpl.CheckRC(SQLBindCol(pimpl.hstmt(), i++, SQL_C_SSHORT, &m_priv->Radix, 0, &m_priv->cbRadix));
pimpl.CheckRC(SQLBindCol(pimpl.hstmt(), i++, SQL_C_SSHORT, &m_priv->Nullable, 0, &m_priv->cbNullable));
pimpl.CheckRC(SQLBindCol(pimpl.hstmt(), i++, SQL_C_CHAR, m_priv->szRemarks, REM_LEN, &m_priv->cbRemarks));
}
//--------------------------------------------------------------------------------
void ColumnRS::Clear()
{
m_priv->szQualifier[0] = 0;
m_priv->szQualifier[0] = 0;
m_priv->szOwner[0] = 0;
m_priv->szTableName[0] = 0;
m_priv->szColName[0] = 0;
m_priv->szTypeName[0] = 0;
m_priv->szRemarks[0] = 0;
m_priv->Precision = 0;
m_priv->Length = 0;
m_priv->DataType = 0;
m_priv->Scale = 0;
m_priv->Radix = 0;
m_priv->Nullable = 0;
}
//--------------------------------------------------------------------------------
SqlColumn ColumnRS::GetData()
{
return SqlColumn(m_priv->szColName,
m_priv->DataType,
m_priv->szTypeName,
m_priv->Precision,
m_priv->Length,
m_priv->Scale,
m_priv->Radix,
m_priv->Nullable);
}
|
|
|
#pragma once
#ifndef COLUMNRS_H
#define COLUMNRS_H
//--------------------------------------------------------------
class ColumnRS
{
public:
ColumnRS();
void Bind(CSqlImpl& pimpl);
void Clear();
SqlColumn GetData();
private:
struct ColumnRSPrivate* m_priv;
} ;
#endif
|
|
|
#pragma once
#ifndef COMMON_H
#define COMMON_H
#include <windows.h>
#include <sqlext.h>
#include <iostream>
#include <string>
using namespace std;
#endif
|
|
|
#pragma once
#ifndef COMPARER_H
#define COMPARER_H
//--------------------------------------------------------------
class Comparer
{
public:
template < class T >
void Lists(const string& str, const T& l1, const T& l2, T& result)
{
Header header(str);
typename T::const_iterator it1 = l1.begin();
typename T::const_iterator it2 = l2.begin();
while (it1 != l1.end() || it2 != l2.end())
{
if (it1 == l1.end())
{
header.Print();
cout << "Added : " << (*it2).name() << endl;
it2++;
continue;
}
if (it2 == l2.end())
{
header.Print();
cout << "Deleted: " << (*it1).name() << endl;
it1++;
continue;
}
if (*it1 > *it2)
{
header.Print();
cout << "Added : " << (*it2).name() << endl;
it2++;
continue;
}
if (*it1 < *it2)
{
header.Print();
cout << "Deleted: " << (*it1).name() << endl;
it1++;
continue;
}
if (verbosity > 0)
{
header.Print();
cout << "Common : " << (*it1).name() << endl;
}
if ((*it1).matches(header, *it2))
result.push_back(*it1);
it1++;
it2++;
}
}
//--------------------------------------------------------------
void Content(const string& str, CSql& s1, CSql& s2, const string& table, SqlColumnsList& cols1)
{
SqlColumnsList cols2 = cols1;
// _ASSERTE(cols1.size() == cols2.size());
SqlColumnsList::iterator it2;
SqlColumnsList::iterator it1;
//creaet SQL statement:
// select col1,col2,col3 from table
string query = "select ";
for (it1 = cols1.begin(); it1 != cols1.end(); ++it1)
{
if (it1 != cols1.begin())
query += ", ";
query += (*it1).name();
}
query += " from ";
query += table;
SqlQuery sq1 = s1.Query();
SqlQuery sq2 = s2.Query();
SQPair sqpair(sq1, sq2);
sqpair.BindColumns(cols1, cols2);
sqpair.Exec(query);
sqpair.Fetch();
while (!sqpair.isEOF())
{
if (sqpair.CheckOneEOF("new entry in sq2: ", "new entry in sq1: "))
continue;
for (it1 = cols1.begin(), it2 = cols2.begin(); it1 != cols1.end() && it2 != cols1.end(); ++it1, ++it2)
{
if ((*it1) != (*it2))
{
cout << "column '" << (*it1).name() << "' : " << endl;
sqpair.Print(it1, it2);
}
}
sqpair.Fetch();
}
sqpair.CloseCursor();
}
} ;
#endif
|
|
|
#include "Common.h"
#include "SqlTable.h"
#include "SqlColumn.h"
#include "CSqlENV.h"
#include "CSqlImpl.h"
#include "TableRS.h"
#include "ColumnRS.h"
#include "DSNInfo.h"
#include "CSql.h"
#include "dbgdefines.h"
//--------------------------------------------------------------
CSql::CSql()
: m_private(*(new CSqlImpl))
{ }
//--------------------------------------------------------------
CSql::~CSql()
{
delete &m_private;
}
//--------------------------------------------------------------
const DSNInfoList& CSql::GetAllDSNs()
{
DSNInfo di;
for (m_private.GetFirstDSN(di); m_private.IsSuccess(); m_private.GetNextDSN(di))
m_dsns.push_back(di);
m_dsns.sort();
return m_dsns;
}
//--------------------------------------------------------------
SqlQuery CSql::Query()
{
return SqlQuery(m_private);
}
//--------------------------------------------------------------
void CSql::Connect(const string& dsn)
{
m_private.Connect(dsn, "sa", "");
}
//--------------------------------------------------------------
const SqlTablesList& CSql::GetTables()
{
m_tables.clear();
m_private.FetchTables();
TableRS row;
row.Bind(m_private);
for (; ; )
{
row.Clear();
if (m_private.Fetch())
break;
if (row.Skip())
continue;
m_tables.push_back(row.GetData());
}
m_private.CloseCursor();
m_tables.sort();
return m_tables;
}
//--------------------------------------------------------------
const SqlColumnsList& CSql::GetColumns(const string& table)
{
m_columns.clear();
m_private.FetchColumns(table);
ColumnRS row;
row.Bind(m_private);
for (; ; )
{
row.Clear();
if (m_private.Fetch())
break;
m_columns.push_back(row.GetData());
}
m_private.CloseCursor();
m_columns.sort();
return m_columns;
}
|
|
|
#pragma once
#ifndef CSQL_H
#define CSQL_H
//--------------------------------------------------------------
#include "SqlQuery.h"
class CSql
{
public:
CSql();
~CSql();
const DSNInfoList& GetAllDSNs();
void Connect(const string& dsn);
const SqlTablesList& GetTables();
const SqlColumnsList& GetColumns(const string& table);
SqlQuery Query();
private:
const CSql& operator= (const CSql&);
CSqlImpl& m_private;
DSNInfoList m_dsns;
SqlTablesList m_tables;
SqlColumnsList m_columns;
} ;
#endif
|
|
|
#include "Common.h"
#include "CSqlDBC.h"
#include "CSqlENV.h"
#include "CSqlImpl.h"
#include "dbgdefines.h"
//--------------------------------------------------------------
CSqlDBC::CSqlDBC(CSqlImpl& pimpl)
: m_private(pimpl), m_hdbc(0), m_connected(false)
{}
//--------------------------------------------------------------
void CSqlDBC::Alloc()
{
m_private.CheckRC(SQLAllocConnect(m_private.henv(), &m_hdbc));
}
//--------------------------------------------------------------
void CSqlDBC::Connect(const string& dsn, const string& userid, const string& password)
{
m_private.CheckRC(SQLConnect(m_hdbc,
(UCHAR*)dsn.c_str(), SQL_NTS,
(UCHAR*)userid.c_str(), SQL_NTS,
(UCHAR*)password.c_str(), SQL_NTS));
m_connected = true;
}
//--------------------------------------------------------------
void CSqlDBC::GetTableLimits(SWORD& MaxQualLen, SWORD& MaxOwnerLen, SWORD& MaxNameLen)
{
SWORD s;
m_private.CheckRC(SQLGetInfo(m_hdbc, SQL_MAX_QUALIFIER_NAME_LEN, &MaxQualLen, sizeof(SWORD), &s));
m_private.CheckRC(SQLGetInfo(m_hdbc, SQL_MAX_OWNER_NAME_LEN, &MaxOwnerLen, sizeof(SWORD), &s));
m_private.CheckRC(SQLGetInfo(m_hdbc, SQL_MAX_TABLE_NAME_LEN, &MaxNameLen, sizeof(SWORD), &s));
}
//--------------------------------------------------------------
CSqlDBC::~CSqlDBC()
{
if (m_connected && m_hdbc)
{
m_private.CheckRC(SQLDisconnect(m_hdbc));
m_connected = false;
}
if (m_hdbc)
{
m_private.CheckRC(SQLFreeConnect(m_hdbc));
}
}
//--------------------------------------------------------------
HDBC CSqlDBC::h()
{
return m_hdbc;
}
|
|
|
#pragma once
#ifndef CSQLDBC_H
#define CSQLDBC_H
//--------------------------------------------------------------
class CSqlImpl;
class CSqlDBC
{
public:
explicit CSqlDBC(CSqlImpl& pimpl);
~CSqlDBC();
HDBC h();
void Alloc();
void Connect(const string& dsn, const string& userid, const string& password);
void GetTableLimits(SWORD& MaxQualLen, SWORD& MaxOwnerLen, SWORD& MaxNameLen);
private:
CSqlDBC(); //unused
const CSqlDBC& operator= (const CSqlDBC&);
CSqlImpl& m_private;
HDBC m_hdbc;
bool m_connected;
} ;
#endif
|
|
|
#include "Common.h"
#include "CSqlENV.h"
#include "CSqlImpl.h"
#include "DSNInfo.h"
#include "dbgdefines.h"
//--------------------------------------------------------------
CSqlENV::CSqlENV(CSqlImpl& pimpl)
: m_private(pimpl), m_henv(0)
{
m_private.CheckRC(SQLAllocEnv(&m_henv));
}
//--------------------------------------------------------------
CSqlENV::~CSqlENV()
{
m_private.CheckRC(SQLFreeEnv(m_henv));
}
//--------------------------------------------------------------
HENV CSqlENV::h()
{
return m_henv;
}
//--------------------------------------------------------------
void CSqlENV::GetFirstDSN(DSNInfo& di)
{
SWORD dsnlen;
SWORD desclen;
const SWORD descmax = 1024;
UCHAR dsn[SQL_MAX_DSN_LENGTH];
UCHAR desc[descmax];
m_private.SetRC(SQLDataSources(
m_henv,
SQL_FETCH_FIRST,
dsn, SQL_MAX_DSN_LENGTH, &dsnlen,
desc, descmax, &desclen));
di = DSNInfo(dsn, desc);
}
//--------------------------------------------------------------
void CSqlENV::GetNextDSN(DSNInfo& di)
{
SWORD dsnlen;
SWORD desclen;
const SWORD descmax = 1024;
UCHAR dsn[SQL_MAX_DSN_LENGTH];
UCHAR desc[descmax];
m_private.SetRC(SQLDataSources(
m_henv,
SQL_FETCH_NEXT,
dsn, SQL_MAX_DSN_LENGTH, &dsnlen,
desc, descmax, &desclen));
di = DSNInfo(dsn, desc);
}
|
|
|
#pragma once
#ifndef CSQLENV_H
#define CSQLENV_H
//--------------------------------------------------------------
class CSqlImpl;
class DSNInfo;
class CSqlENV
{
public:
explicit CSqlENV(CSqlImpl& pimpl);
~CSqlENV();
HENV h();
void GetFirstDSN(DSNInfo& di);
void GetNextDSN(DSNInfo& di);
private:
CSqlENV(); //unused
const CSqlENV& operator= (const CSqlENV&);
CSqlImpl& m_private;
HENV m_henv;
} ;
#endif
|
|
|
#include "Common.h"
#include "CSqlDBC.h"
#include "CSqlSTMT.h"
#include "CSqlENV.h"
#include "CSqlImpl.h"
#include "DSNInfo.h"
#include "dbgdefines.h"
//--------------------------------------------------------------
CSqlImpl::CSqlImpl()
: m_rc(SQL_SUCCESS)
{
m_env = new CSqlENV(*this);
m_dbc = new CSqlDBC(*this);
m_stmt = new CSqlSTMT(*this);
}
//--------------------------------------------------------------
CSqlImpl::~CSqlImpl()
{
delete m_stmt;
delete m_dbc;
delete m_env;
}
//--------------------------------------------------------------
void CSqlImpl::SetRC(RETCODE rc)
{
m_rc = rc;
}
//--------------------------------------------------------------
void CSqlImpl::CheckRC(RETCODE rc)
{
m_rc = rc;
CheckRC();
}
//--------------------------------------------------------------
bool CSqlImpl::IsSuccess()
{
return m_rc == SQL_SUCCESS;
}
//--------------------------------------------------------------
bool CSqlImpl::IsEndOfData()
{
return m_rc == SQL_NO_DATA_FOUND;
}
//--------------------------------------------------------------
void CSqlImpl::Connect(const string& dsn, const string& userid, const string& password)
{
m_dbc->Alloc();
m_dbc->Connect(dsn, userid, password);
m_stmt->Alloc();
}
//--------------------------------------------------------------
void CSqlImpl::GetTableLimits(SWORD& MaxQualLen, SWORD& MaxOwnerLen, SWORD& MaxNameLen)
{
m_dbc->GetTableLimits(MaxQualLen, MaxOwnerLen, MaxNameLen);
}
//--------------------------------------------------------------
void CSqlImpl::GetFirstDSN(DSNInfo& di)
{
m_env->GetFirstDSN(di);
}
//--------------------------------------------------------------
void CSqlImpl::GetNextDSN(DSNInfo& di)
{
m_env->GetNextDSN(di);
}
//--------------------------------------------------------------
void CSqlImpl::CloseCursor()
{
m_stmt->CloseCursor();
}
//--------------------------------------------------------------
void CSqlImpl::FetchTables()
{
m_stmt->FetchTables();
}
//--------------------------------------------------------------
void CSqlImpl::FetchColumns(const string& table)
{
m_stmt->FetchColumns(table);
}
//--------------------------------------------------------------
void CSqlImpl::ExecQuery(const string& sql)
{
m_stmt->ExecQuery(sql);
}
//--------------------------------------------------------------
bool CSqlImpl::Fetch()
{
return m_stmt->Fetch();
}
//--------------------------------------------------------------
HSTMT CSqlImpl::hstmt()
{
return m_stmt->h();
}
//--------------------------------------------------------------
HENV CSqlImpl::henv()
{
return m_env->h();
}
//--------------------------------------------------------------
HDBC CSqlImpl::hdbc()
{
return m_dbc->h();
}
//--------------------------------------------------------------
void CSqlImpl::CheckRC()
{
if (IsSuccess())
return ;
SWORD pcbErrorMsg;
SDWORD NativeErr;
UCHAR szErrorMsg[SQL_MAX_MESSAGE_LENGTH];
UCHAR szSqlState[SQL_MAX_MESSAGE_LENGTH];
m_rc = SQLError(m_env->h(), m_dbc->h(), m_stmt->h(),
szSqlState, &NativeErr,
szErrorMsg, SQL_MAX_MESSAGE_LENGTH - 1, &pcbErrorMsg);
if (m_rc == SQL_SUCCESS_WITH_INFO)
cout << "Info : rc=" << m_rc;
else
cout << "Error: rc=" << m_rc;
cout << " nativederr=" << NativeErr
<< " sqlstate=" << szSqlState << endl
<< " msg=" << szErrorMsg
<< endl;
if (m_rc != SQL_SUCCESS && m_rc != SQL_SUCCESS_WITH_INFO)
throw m_rc;
}
|
|
|
#pragma once
#ifndef CSQLIMPL_H
#define CSQLIMPL_H
//--------------------------------------------------------------
class CSqlSTMT;
class CSqlENV;
class CSqlDBC;
class CSqlImpl
{
public:
CSqlImpl();
~CSqlImpl();
void SetRC(RETCODE rc);
void CheckRC(RETCODE rc);
bool IsSuccess();
bool IsEndOfData();
void Connect(const string& dsn, const string& userid, const string& password);
void GetTableLimits(SWORD& MaxQualLen, SWORD& MaxOwnerLen, SWORD& MaxNameLen);
void GetFirstDSN(DSNInfo& di);
void GetNextDSN(DSNInfo& di);
void CloseCursor();
void FetchTables();
void FetchColumns(const string& table);
void ExecQuery(const string& sql);
bool Fetch();
HSTMT hstmt();
HENV henv();
HDBC hdbc();
void CheckRC();
private:
RETCODE m_rc;
CSqlSTMT* m_stmt;
CSqlENV* m_env;
CSqlDBC* m_dbc;
} ;
#endif
|
|
|
#include "Common.h"
#include "CSqlSTMT.h"
#include "CSqlENV.h"
#include "CSqlImpl.h"
#include "dbgdefines.h"
//--------------------------------------------------------------
CSqlSTMT::CSqlSTMT(CSqlImpl& pimpl)
: m_private(pimpl), m_hstmt(0)
{}
//--------------------------------------------------------------
CSqlSTMT::~CSqlSTMT()
{
if (m_hstmt)
{
m_private.CheckRC(SQLFreeStmt(m_hstmt, SQL_DROP));
m_hstmt = 0;
}
}
//--------------------------------------------------------------
HSTMT CSqlSTMT::h()
{
return m_hstmt;
}
//--------------------------------------------------------------
void CSqlSTMT::Alloc()
{
m_private.CheckRC(SQLAllocStmt(m_private.hdbc(), &m_hstmt));
}
//--------------------------------------------------------------
void CSqlSTMT::CloseCursor()
{
m_private.CheckRC(SQLFreeStmt(m_private.hstmt(), SQL_CLOSE));
}
//--------------------------------------------------------------
void CSqlSTMT::FetchTables()
{
m_private.CheckRC(SQLTables(m_hstmt,
0, SQL_NTS,
0, SQL_NTS,
0, SQL_NTS,
0, SQL_NTS));
}
//--------------------------------------------------------------
void CSqlSTMT::FetchColumns(const string& table)
{
m_private.CheckRC(SQLColumns(m_hstmt,
NULL, 0,
NULL, 0,
(UCHAR*) table.c_str(), SQL_NTS,
NULL, 0));
}
//--------------------------------------------------------------
bool CSqlSTMT::Fetch()
{
m_private.SetRC(SQLFetch(m_hstmt));
if (m_private.IsEndOfData())
return true;
m_private.CheckRC();
return false;
}
//--------------------------------------------------------------
void CSqlSTMT::ExecQuery(const string& sql)
{
m_private.CheckRC(SQLPrepare(m_hstmt, (UCHAR*)sql.c_str(), sql.length()+1));
m_private.CheckRC(SQLExecute(m_hstmt));
}
|
|
|
#pragma once
#ifndef CSQLSTMT_H
#define CSQLSTMT_H
//--------------------------------------------------------------
class CSqlImpl;
class CSqlSTMT
{
public:
explicit CSqlSTMT(CSqlImpl& pimpl);
~CSqlSTMT();
HSTMT h();
void Alloc();
void CloseCursor();
void ExecQuery(const string& sql);
bool Fetch(); //returns true when done
void FetchTables();
void FetchColumns(const string& table);
private:
CSqlSTMT(); //unused
const CSqlSTMT& operator= (const CSqlSTMT&);
CSqlImpl& m_private;
HSTMT m_hstmt;
} ;
#endif
|
|
|
#include "Common.h"
#include <list>
#include <iomanip>
#include <time.h>
#include "dbgdefines.h"
int verbosity = 0;
#include "DSNInfo.h"
#include "SqlTable.h"
#include "CheckAttr.h"
#include "SqlColumn.h"
#include "SqlQuery.h"
#include "CSql.h"
#include "SQPair.h"
#include "Dumper.h"
#include "Comparer.h"
//--------------------------------------------------------------
int main()
{
//int dbgf = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
//_CrtSetDbgFlag(dbgf | _CRTDBG_LEAK_CHECK_DF);
clock_t start = clock();
try
{
Dumper d;
Comparer c;
CSql s1;
#if 1
//mdb
const string dsn1 = "DBDIFFA";
const string dsn2 = "DBDIFFB";
#endif
#if 0
//globalstore mine vs jeff's
const string dsn1 = "DBDIFF1";
const string dsn2 = "DBDIFF2";
#endif
#if 0
//gstr v42 vs v43
const string dsn1 = "DBDIFFX";
const string dsn2 = "DBDIFFY";
#endif
d.Dsns(s1.GetAllDSNs());
s1.Connect(dsn1);
SqlTablesList t1 = s1.GetTables();
d.Tables(t1, string("Tables for " + dsn1));
CSql s2;
s2.Connect(dsn2);
SqlTablesList t2 = s2.GetTables();
d.Tables(t2, string("Tables for " + dsn2));
SqlTablesList commontables;
c.Lists("Comparing table lists", t1, t2, commontables);
d.Tables(commontables, "Common Tables");
SqlColumnsList commoncolumns;
for (SqlTablesIterator it = commontables.begin(); it != commontables.end(); ++it)
{
string name = (*it).name();
SqlColumnsList c1 = s1.GetColumns(name);
SqlColumnsList c2 = s2.GetColumns(name);
c.Lists(string("Comparing column lists for table: " + name), c1, c2, commoncolumns);
d.Columns(commoncolumns, string("Common columns for table " + name));
if (commoncolumns.size() > 0)
c.Content(string("Comparing content for table: " + name), s1, s2, name, commoncolumns);
commoncolumns.clear();
}
}
catch (RETCODE rc)
{
cout << "An SQL operation failed: rc=" << rc << endl;
}
catch (...)
{
cout << "An exception occurred" << endl;
}
cout << "That took: " << (clock() - start) / CLOCKS_PER_SEC << " seconds" << endl;
cout << "Done. Press enter to continue..." << endl;
cin.get();
return 0;
}
|
|
|
#pragma once
#ifndef DBGDEFINES_H
#define DBGDEFINES_H
//#include <crtdbg.h>
//_CRTIMP void * __cdecl operator new( unsigned int, int, const char *, int);
//#define new CRT_NEW
//#define CRT_NEW new(_NORMAL_BLOCK, __FILE__, __LINE__)
#endif
|
|
|
#pragma once
#ifndef DSNINFO_H
#define DSNINFO_H
#include "BaseInfo.h"
#include <list>
//--------------------------------------------------------------
class DSNInfo : public BaseInfo
{
public:
DSNInfo()
{}
DSNInfo(const string& n, const string& d)
: BaseInfo(n), m_desc(d)
{}
DSNInfo(const UCHAR* const n, const UCHAR* const d)
: BaseInfo(n), m_desc((char*)d)
{}
DSNInfo(const DSNInfo& d)
: BaseInfo(d.name()), m_desc(d.m_desc)
{}
const string& desc() const
{
return m_desc;
}
private:
string m_desc;
} ;
typedef list < DSNInfo > DSNInfoList;
typedef DSNInfoList::const_iterator DSNInfoIterator;
#endif
|
|
|
#pragma once
#ifndef DUMPER_H
#define DUMPER_H
//--------------------------------------------------------------
class Dumper
{
public:
void Dsns(const DSNInfoList& l)
{
if (verbosity < 2)
return ;
cout << setw(25) << "Name" << " " << "Description" << endl;
cout << setw(25) << setfill('-') << "-" << " " << setw(50) << "-" << setfill(' ') << endl;
for (DSNInfoIterator it = l.begin(); it != l.end(); it++)
{
cout << setw(25) << (*it).name() << " " << (*it).desc() << endl;
}
cout << endl << endl;
}
//--------------------------------------------------------------
void Tables(const SqlTablesList& t, const string& prefix)
{
if (verbosity < 2)
return ;
cout << prefix << endl;
cout << setw(25) << "Name" << endl;
cout << setw(25) << setfill('-') << "-" << setfill(' ') << endl;
for (SqlTablesIterator it = t.begin(); it != t.end(); it++)
{
cout << (*it).name() << endl;
}
cout << endl << endl;
}
//--------------------------------------------------------------
void Columns(const SqlColumnsList& c, const string& prefix)
{
if (verbosity < 2)
return ;
cout << prefix << endl;
cout << setw(25) << "Name" << endl;
cout << setw(25) << setfill('-') << "-" << setfill(' ') << endl;
for (SqlColumnsIterator it = c.begin(); it != c.end(); it++)
{
cout << (*it).name() << endl;
}
cout << endl << endl;
}
} ;
#endif
|
|
|
#pragma once
#ifndef HEADER_H
#define HEADER_H
//--------------------------------------------------------------
class Header
{
public:
explicit Header(const string& h)
: m_printed(false), m_header(h)
{ }
void Print()
{
if (m_printed)
return ;
cout << m_header << endl;
m_printed = true;
}
~Header()
{
if (m_printed)
cout << "--- done" << endl << endl;
}
private:
Header();
bool m_printed;
const Header& operator=(const Header&);
const string m_header;
} ;
#endif
|
|
|
#include "Common.h"
#include "SqlColumn.h"
#include "CheckAttr.h"
#include "BaseInfo.h"
#include "dbgdefines.h"
ostream& operator << (ostream& os, const SqlColumn& sc)
{
switch (sc.datatype())
{
case SQL_DECIMAL:
case SQL_NUMERIC:
case SQL_VARCHAR:
case SQL_CHAR:
os << (char*) sc.databuf();
break;
case SQL_SMALLINT:
os << *((short*) sc.databuf());
break;
case SQL_INTEGER:
os << *((long*) sc.databuf());
break;
case SQL_REAL:
os << *((float*) sc.databuf());
break;
case SQL_FLOAT:
case SQL_DOUBLE:
os << *((double*) sc.databuf());
break;
}
return os;
}
SqlColumn::SqlColumn()
{}
SqlColumn::SqlColumn(const string& n)
: BaseInfo(n)
{}
SqlColumn::SqlColumn(const UCHAR* const name,
short datatype,
const UCHAR* const typname,
long precision,
long length,
short scale,
short radix,
short nullable)
: BaseInfo(name),
m_datatype(datatype),
m_typename((char*)typname),
m_precision(precision),
m_length(length),
m_scale(scale),
m_radix(radix),
m_nullable(nullable) //,
//m_data(0)
{}
SqlColumn::SqlColumn(const SqlColumn& t)
: BaseInfo(t.name()),
m_datatype(t.m_datatype),
m_typename(t.m_typename),
m_precision(t.m_precision),
m_length(t.m_length),
m_scale(t.m_scale),
m_radix(t.m_radix),
m_nullable(t.m_nullable) //,
//m_data(0)
{}
SqlColumn::~SqlColumn()
{
// delete [] m_data;
}
bool SqlColumn::matches(Header& hdr, const SqlColumn& rhs) const
{
//these have to be a series of assignments
//to ensure that all of the CheckAttr() get called!
bool eq = true;
eq = CheckAttr(hdr, name(), "TypeName", m_typename, rhs.m_typename) && eq;
eq = CheckAttr(hdr, name(), "Precision", m_precision, rhs.m_precision) && eq;
eq = CheckAttr(hdr, name(), "Length", m_length, rhs.m_length) && eq;
eq = CheckAttr(hdr, name(), "Scale", m_scale, rhs.m_scale) && eq;
eq = CheckAttr(hdr, name(), "Radix", m_radix, rhs.m_radix) && eq;
eq = CheckAttr(hdr, name(), "Nullable", m_nullable, rhs.m_nullable) && eq;
return eq;
}
short SqlColumn::datatype() const
{
return m_datatype;
}
long SqlColumn::datalen() const
{
return m_length;
}
void* SqlColumn::databuf() const
{
return (void*)(char*)m_data;
}
void SqlColumn::AllocBuffer()
{
// delete [] m_data;
// m_data = new char[m_length];
// memset(m_data, 0x00, m_length);
}
bool SqlColumn::operator != (const SqlColumn& rhs) const
{
//_ASSERTE(m_data);
//_ASSERTE(m_data != (char*)0xcdcdcdcd);
//_ASSERTE(rhs.m_data);
//_ASSERTE(rhs.m_data != (char*)0xcdcdcdcd);
if (m_datatype == SQL_VARCHAR)
return strcmp(m_data, rhs.m_data) != 0;
return memcmp(m_data, rhs.m_data, m_length) != 0;
}
|
|
|
#pragma once
#ifndef SQLCOLUMN_H
#define SQLCOLUMN_H
//--------------------------------------------------------------
#include "Header.h"
#include "BaseInfo.h"
#include <list>
class SqlColumn : public BaseInfo
{
public:
SqlColumn();
SqlColumn(const string& n);
SqlColumn(const UCHAR* const name,
short datatype,
const UCHAR* const typname,
long precision,
long length,
short scale,
short radix,
short nullable);
SqlColumn(const SqlColumn& t);
~SqlColumn();
bool matches(Header& hdr, const SqlColumn& rhs) const;
short datatype() const;
long datalen() const;
void* databuf() const;
void AllocBuffer();
bool operator != (const SqlColumn& rhs) const;
private:
short m_datatype;
string m_typename;
long m_precision;
long m_length;
short m_scale;
short m_radix;
short m_nullable;
char m_data[1024];
} ;
ostream& operator << (ostream& os, const SqlColumn& sc);
typedef list < SqlColumn > SqlColumnsList;
typedef SqlColumnsList::const_iterator SqlColumnsIterator;
#endif
|
|
|
#include "Common.h"
#include "CSqlENV.h"
#include "CSqlImpl.h"
#include "SqlQuery.h"
#include "dbgdefines.h"
//--------------------------------------------------------------
SqlQuery::SqlQuery(CSqlImpl& pimpl)
: m_private(pimpl), m_row(0)
{}
//--------------------------------------------------------------
SqlQuery::SqlQuery(const SqlQuery& sq)
: m_private(sq.m_private), m_row(0)
{}
//--------------------------------------------------------------
void SqlQuery::Exec(const string& sql) const
{
m_private.ExecQuery(sql);
}
//--------------------------------------------------------------
void SqlQuery::CloseCursor() const
{
m_private.CloseCursor();
}
//--------------------------------------------------------------
bool SqlQuery::isEOF() const
{
return m_private.IsEndOfData();
}
//--------------------------------------------------------------
void SqlQuery::Fetch()
{
m_private.Fetch();
++m_row;
}
//--------------------------------------------------------------
void SqlQuery::Bind()
{
//col.AllocBuffer();
//#define SQL_C_CHAR SQL_CHAR /* CHAR, VARCHAR, DECIMAL, NUMERIC */
//#define SQL_C_LONG SQL_INTEGER /* INTEGER */
//#define SQL_C_SHORT SQL_SMALLINT /* SMALLINT */
//#define SQL_C_FLOAT SQL_REAL /* REAL */
//#define SQL_C_DOUBLE SQL_DOUBLE /* FLOAT, DOUBLE */
//#if (ODBCVER >= 0x0300)
//#define SQL_C_NUMERIC SQL_NUMERIC
//#endif /* ODBCVER >= 0x0300 */
//#define SQL_C_DEFAULT 99
short datatype = SQL_C_DEFAULT;
switch (m_col->datatype())
{
case SQL_VARCHAR:
case SQL_DECIMAL:
case SQL_NUMERIC:
case SQL_CHAR:
datatype = SQL_C_CHAR;
break;
default:
datatype = m_col->datatype();
}
SDWORD s = 0;
m_private.CheckRC(SQLBindCol(m_private.hstmt(),
m_colno,
datatype,
m_col->databuf(),
m_col->datalen(),
&s));
}
//--------------------------------------------------------------
void SqlQuery::Dump() const
{
cout << "sqlquery::dump='" << (char*)(m_col->databuf()) << "'" << endl;
}
//--------------------------------------------------------------
void SqlQuery::BindColumns(SqlColumnsList& cols)
{
USHORT colno = 0;
for (SqlColumnsList::iterator it = cols.begin(); it != cols.end(); ++it)
{
m_col = &(*it);
m_colno = ++colno;
Bind();
}
}
//--------------------------------------------------------------
long SqlQuery::Row() const
{
return m_row;
}
|
|
|
#pragma once
#ifndef SQLQUERY_H
#define SQLQUERY_H
//--------------------------------------------------------------
class CSqlImpl;
#include "SqlColumn.h"
class SqlQuery
{
public:
explicit SqlQuery(CSqlImpl& pimpl);
SqlQuery(const SqlQuery& sq);
void Exec(const string& sql) const;
void CloseCursor() const;
void BindColumns(SqlColumnsList& cols);
void Bind();
long Row() const;
bool isEOF() const;
void Fetch();
void Dump() const;
private:
SqlQuery();
const SqlQuery& operator=(const SqlQuery&);
SqlColumn* m_col;
USHORT m_colno;
CSqlImpl& m_private;
long m_row;
} ;
#endif
|
|
|
#pragma once
#ifndef SQLTABLE_H
#define SQLTABLE_H
#include "Header.h"
#include "BaseInfo.h"
#include <string>
#include <list>
//--------------------------------------------------------------
class SqlTable : public BaseInfo
{
public:
SqlTable()
{}
SqlTable(const string& n)
: BaseInfo(n)
{}
SqlTable(const UCHAR* const n)
: BaseInfo(n)
{}
SqlTable(const SqlTable& t)
: BaseInfo(t.name())
{}
bool matches(Header& /*hdr*/, const SqlTable& /*rhs*/) const
{
return true;
}
private:
//none
}
;
typedef list < SqlTable > SqlTablesList;
typedef SqlTablesList::const_iterator SqlTablesIterator;
#endif
|
|
|
#pragma once
#ifndef SQPAIR_H
#define SQPAIR_H
//--------------------------------------------------------------
class SQPair
{
public:
SQPair(SqlQuery& q1, SqlQuery& q2)
: m_sq1(q1), m_sq2(q2)
{ }
void BindColumns(SqlColumnsList& cols1, SqlColumnsList& cols2)
{
m_sq1.BindColumns(cols1);
m_sq2.BindColumns(cols2);
}
void Exec(const string& query) const
{
m_sq1.Exec(query);
m_sq2.Exec(query);
}
void Fetch()
{
m_sq1.Fetch();
m_sq2.Fetch();
}
void CloseCursor() const
{
m_sq1.CloseCursor();
m_sq2.CloseCursor();
}
bool isEOF() const
{
return m_sq1.isEOF() && m_sq2.isEOF();
}
bool CheckOneEOF(const string& str1, const string& str2)
{
if (m_sq1.isEOF())
{
cout << str1;
m_sq2.Dump();
m_sq2.Fetch();
return true;
}
if (m_sq2.isEOF())
{
cout << str2;
m_sq1.Dump();
m_sq1.Fetch();
return true;
}
return false;
}
void Print(const SqlColumnsList::iterator& it1, const SqlColumnsList::iterator& it2) const
{
cout << " sq1(" << m_sq1.Row() << "): " << (*it1) << endl;
cout << " sq2(" << m_sq2.Row() << "): " << (*it2) << endl;
}
private:
SqlQuery& m_sq1;
SqlQuery& m_sq2;
} ;
#endif
|
|
|
#include "Common.h"
#include "DSNInfo.h"
#include "CSqlImpl.h"
#include "SqlTable.h"
#include "TableRS.h"
#include "dbgdefines.h"
const int STR_LEN = 255;
//-------------------------------------------------------------------
struct TableRSPrivate
{
TableRSPrivate()
{
szQualifier = 0;
szOwner = 0;
szName = 0;
szType = 0;
szRemarks = 0;
MaxQualLen = -1;
MaxOwnerLen = -1;
MaxNameLen = -1;
}
void AllocBuffers()
{
//_ASSERTE(MaxQualLen >= 0);
//_ASSERTE(MaxOwnerLen >= 0);
//_ASSERTE(MaxNameLen >= 0);
szQualifier = new char [MaxQualLen + 1];
szOwner = new char [MaxOwnerLen + 50];
szName = new char [MaxNameLen + 1];
szType = new char [STR_LEN + 1];
szRemarks = new char [STR_LEN + 1];
}
~TableRSPrivate()
{
delete [] szQualifier;
delete [] szOwner;
delete [] szName;
delete [] szType;
delete [] szRemarks;
}
void Clear()
{
//_ASSERTE(szQualifier);
//_ASSERTE(szOwner);
//_ASSERTE(szName);
//_ASSERTE(szType);
//_ASSERTE(szRemarks);
szQualifier[0] = 0;
szOwner[0] = 0;
szName[0] = 0;
szType[0] = 0;
szRemarks[0] = 0;
}
SWORD MaxQualLen;
SWORD MaxOwnerLen;
SWORD MaxNameLen;
char* szQualifier;
char* szOwner;
char* szName;
char* szType;
char* szRemarks;
};
//-------------------------------------------------------------------
TableRS::TableRS()
{
m_priv = new TableRSPrivate;
}
//-------------------------------------------------------------------
TableRS::~TableRS()
{
delete m_priv;
}
//-------------------------------------------------------------------
void TableRS::Bind(CSqlImpl& pimpl)
{
pimpl.GetTableLimits(m_priv->MaxQualLen, m_priv->MaxOwnerLen, m_priv->MaxNameLen);
m_priv->AllocBuffers();
SDWORD s;
USHORT i = 1;
pimpl.CheckRC(SQLBindCol(pimpl.hstmt(), i++, SQL_C_CHAR, m_priv->szQualifier, m_priv->MaxQualLen, &s));
pimpl.CheckRC(SQLBindCol(pimpl.hstmt(), i++, SQL_C_CHAR, m_priv->szOwner, m_priv->MaxOwnerLen, &s));
pimpl.CheckRC(SQLBindCol(pimpl.hstmt(), i++, SQL_C_CHAR, m_priv->szName, m_priv->MaxNameLen, &s));
pimpl.CheckRC(SQLBindCol(pimpl.hstmt(), i++, SQL_C_CHAR, m_priv->szType, STR_LEN, &s));
pimpl.CheckRC(SQLBindCol(pimpl.hstmt(), i++, SQL_C_CHAR, m_priv->szRemarks, STR_LEN, &s));
}
//-------------------------------------------------------------------
void TableRS::Clear()
{
m_priv->Clear();
}
//-------------------------------------------------------------------
SqlTable TableRS::GetData()
{
return SqlTable(m_priv->szName);
}
//-------------------------------------------------------------------
bool TableRS::Skip()
{
if (stricmp(m_priv->szType, "SYSTEM TABLE") == 0)
return true;
if (stricmp(m_priv->szType, "VIEW") == 0)
return true;
return false;
}
|
|
|
#pragma once
#ifndef TABLERS_H
#define TABLERS_H
//#include <crtdbg.h>
//--------------------------------------------------------------
class TableRS
{
public:
TableRS();
~TableRS();
void Bind(CSqlImpl& pimpl);
void Clear();
SqlTable GetData();
bool Skip();
private:
struct TableRSPrivate* m_priv;
};
#endif
|