📄 importodbc.cpp
字号:
//////////////////////////////////////////////////////
//
// NRDB Pro - Spatial database and mapping application
//
// Copyright (c) 1989-2004 Richard D. Alexander
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
// NRDB Pro is part of the Natural Resources Database Project
//
// Homepage: http://www.nrdb.co.uk/
// Users' Forum: http://nrdb.mypalawan.info/
//
#include "stdafx.h"
#include <io.h>
#include <fcntl.h>
#include <odbcinst.h>
#include "nrdb.h"
#include "importodbc.h"
#include "dlgimportodbc.h"
#include "dlgimportfeature.h"
#include "bdimportexport.h"
#include "dlgimportstatus.h"
#include "utils.h"
#include "dlgprogress.h"
#include "dlgeditfeature.h"
#include "dlgimportdate.h"
#include "importmaplines.h"
#include "shapefile.h"
#include "importftype.h"
#include "mainfrm.h"
#include "dlgimportrename.h"
#include "dlgimportprimarykey.h"
#include "dlgprotect.h"
///////////////////////////////////////////////////////////////////////////////
CImportColumn::CImportColumn()
{
m_bAttr = FALSE;
m_bShapeFile = FALSE;
m_sText[0] = '\0';
m_lItemData = 0;
}
CImportColumn::CImportColumn(CImportColumn& rSrc)
{
m_sNameImport = rSrc.m_sNameImport;
m_sNameAttr = rSrc.m_sNameAttr;
m_bAttr = rSrc.m_bAttr;
m_bShapeFile = rSrc.m_bShapeFile;
m_lItemData = rSrc.m_lItemData;
strncpy(m_sText, rSrc.m_sText, BD_SHORTSTR);
}
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
CImportFeature::CImportFeature()
{
m_lFeature = 0;
m_lFType = 0;
}
///////////////////////////////////////////////////////////////////////////////
CImportDB& CImportDB::operator=(CImportDB& rSrc)
{
RemoveAll();
for (int i = 0; i < rSrc.GetSize(); i++) Add(rSrc[i]);
return *this;
}
///////////////////////////////////////////////////////////////////////////////
CImportDB::CImportDB()
{
m_pDlgProgress = NULL;
}
///////////////////////////////////////////////////////////////////////////////
//
// Retrieve the data source and open it and the municipality that the ODBC
// data is to be imported for
//
void CImportDB::ImportODBC(LPCSTR sDataSource, LPCSTR sTable, BOOL bSysTables, int nFileType)
{
CDatabase database;
BOOL bCancel = FALSE;
BOOL bNRDB = FALSE;
// Initialise variables
m_nImported = 0;
// Open the log file
m_sLogFile = GetTempFileName();
m_pLogFile = fopen(m_sLogFile,"w");
fprintf(m_pLogFile, BDString(IDS_IMPORTING) + "...\r\n");
// Start the transaction here so that OnCreate can also be cancelled
if (BDGetTransLevel(BDHandle()) > 0) BDCommit(BDHandle());
BDBeginTrans(BDHandle());
// Open dialog to select data source and format
CDlgImportODBC dlg(sDataSource, sTable, bSysTables, nFileType);
int nRet = dlg.DoModal();
// Begin the transaction
BDOnError(BDHandle(), ThrowException);
if (nRet == IDOK)
{
*this = dlg.GetImportDB();
// Retrieve the format
bNRDB = dlg.IsNRDB();
if (bNRDB)
{
CImportFType importftype(this, sDataSource);
m_nImported = importftype.Import();
if (m_nImported < 0)
{
bCancel = TRUE;
}
}
// Connect to the database
else if (database.Open(dlg.GetDatabase()))
{
m_pDlgProgress = new CDlgProgress;
for (int i = 0; i < GetSize(); i++)
{
if (GetAt(i).m_bImport)
{
GetAt(i).Import(database, *this, nFileType);
};
if (!m_pDlgProgress->SetPercent((100*i)/GetSize()))
{
bCancel = TRUE;
}
};
// Close the database
database.Close();
delete m_pDlgProgress;
m_pDlgProgress = NULL;
};
} else
{
bCancel = TRUE;
}
// Output the log file
// Report number of records imported
if (bCancel)
{
fprintf(m_pLogFile, BDString(IDS_IMPORTCANCEL) + "\r\n");
}
else
{
fprintf(m_pLogFile, BDString(IDS_NUMRECORDS) + ": %i\r\n", m_nImported);
if (m_nImported == 0 && !bNRDB)
{
fprintf(m_pLogFile,"\r\n" + BDString(IDS_IMPORTTIP) + "\r\n");
}
};
if (m_pLogFile != NULL) fclose(m_pLogFile);
CDlgImportStatus dlgStatus(m_sLogFile, !bCancel && m_nImported != 0);
if (dlgStatus.DoModal() == IDOK)
{
BDCommit(BDHandle());
} else
{
bCancel = TRUE;
BDRollBack(BDHandle());
}
remove(m_sLogFile);
BDOnError(BDHandle(), DisplayMessage);
// Compact database
if (m_nImported != 0 && !bCancel)
{
CompactDatabase();
}
};
///////////////////////////////////////////////////////////////////////////////
CImportTable::CImportTable()
{
m_bImport = FALSE;
m_lId = 0;
m_pImportDB = NULL;
m_lAttrIdShapefile = 0;
m_bAutoCreate = FALSE;
};
CImportTable::CImportTable(CImportTable& rSrc)
{
*this = rSrc;
}
CImportTable& CImportTable::operator=(CImportTable& rSrc)
{
m_sTableImport = rSrc.m_sTableImport;
m_sFType = rSrc.m_sFType;
m_bImport = rSrc.m_bImport;
m_lId = rSrc.m_lId;
m_sFeature = rSrc.m_sFeature;
m_sParentFeature = rSrc.m_sParentFeature;
m_sGrandParentFeature = rSrc.m_sGrandParentFeature;
m_sGreatGrandParentFeature = rSrc.m_sGreatGrandParentFeature;
m_sShapeFile = rSrc.m_sShapeFile;
m_bAutoCreate = rSrc.m_bAutoCreate;
m_aColumn.RemoveAll();
for (int i = 0; i < rSrc.m_aColumn.GetSize(); i++) m_aColumn.Add(rSrc.m_aColumn[i]);
return *this;
}
///////////////////////////////////////////////////////////////////////////////
BOOL CImportTable::Import(CDatabase& database, CImportDB& importDB, int nFileType)
{
SDWORD dwLength;
BOOL bOK = TRUE;
CString sSQL;
HSTMT hstmt;
int nRet;
CFeatureType ftype;
CAttrArray aAttr;
char sFeature[BD_SHORTSTR] = "";
char sParentFeature[BD_SHORTSTR] = "";
char sGrandParentFeature[BD_SHORTSTR] = "";
char sGreatGrandParentFeature[BD_SHORTSTR] = "";
char sDate[32] = "";
char sID[32] = "";
CDateTime date, dateDefault;
CString sError;
CString sProgress;
m_nRecord = 1;
BOOL bCancel = FALSE;
CMapLayer maplayer;
int nShape = 0;
m_nPrimaryKey = -1;
m_pImportDB = &importDB;
// Retrieve attribute defintion for feature type from BEMO database
ftype.m_sDesc = m_sFType;
bOK = BDFeatureType(BDHandle(), &ftype, BDSELECT2);
if (bOK)
{
bOK = BDFTypeAttrInit(BDHandle(), ftype.m_lId, &aAttr);
};
// For DBase files construct a short file name
CString sTable = m_sTableImport;
if (nFileType == CImportDB::shapefile || nFileType == CImportDB::dbase)
{
sTable = GetShortFileTitle(database);
}
// Count the number of records
long lRecords = GetCountRecords(database.m_hdbc, sTable);
// Determine if shapefile data is to be loaded
if (bOK) bOK = LoadShapefile(importDB, maplayer);
// Open statement
if (SQLAllocStmt(database.m_hdbc, &hstmt) == SQL_SUCCESS)
{
TRY
{
// Construct SQL
BOOL bFirst = TRUE;
sSQL = "select ";
for (int i = 0; i < m_aColumn.GetSize(); i++)
{
if (!m_aColumn[i].m_bShapeFile)
{
if (!bFirst) sSQL += ", ";
sSQL += "`" + m_aColumn[i].m_sNameImport + "`";
bFirst = FALSE;
};
}
if (sSQL == "select ") sSQL += "*";
sSQL += " from `" + CString(sTable) + "`";
// Execute statement
nRet = SQLExecDirect(hstmt, (UCHAR*)sSQL.GetBuffer(0), sSQL.GetLength());
// Bind values to variables
int iCol = 1;
for (i = 0; i < m_aColumn.GetSize() && nRet == SQL_SUCCESS; i++)
{
// Handle date
if (m_aColumn[i].m_sNameAttr == IMPORT_DATE)
{
nRet = SQLBindCol(hstmt, iCol, SQL_C_CHAR, sDate, sizeof(sDate), &dwLength);
}
// Handle id
else if (m_aColumn[i].m_sNameAttr == IMPORT_ID)
{
nRet = SQLBindCol(hstmt, iCol, SQL_C_CHAR, sID, sizeof(sID), &dwLength);
}
// Retrieve feature name (if any)
else if (m_aColumn[i].m_sNameAttr == m_sFeature + IMPORT_NAME)
{
nRet = SQLBindCol(hstmt, iCol, SQL_C_CHAR, sFeature, BD_SHORTSTR, &dwLength);
}
else if (m_aColumn[i].m_sNameAttr == m_sParentFeature + IMPORT_NAME)
{
nRet = SQLBindCol(hstmt, iCol, SQL_C_CHAR, sParentFeature, BD_SHORTSTR, &dwLength);
}
else if (m_aColumn[i].m_sNameAttr == m_sGrandParentFeature + IMPORT_NAME)
{
nRet = SQLBindCol(hstmt, iCol, SQL_C_CHAR, sGrandParentFeature, BD_SHORTSTR, &dwLength);
}
else if (m_aColumn[i].m_sNameAttr == m_sGreatGrandParentFeature + IMPORT_NAME)
{
nRet = SQLBindCol(hstmt, iCol, SQL_C_CHAR, sGreatGrandParentFeature, BD_SHORTSTR, &dwLength);
}
// Import the corresponding shapefile data
else if ((m_aColumn[i].m_sNameImport == SHAPEFILE_POINTS ||
m_aColumn[i].m_sNameImport == SHAPEFILE_POLYLINES) &&
m_aColumn[i].m_sNameAttr != IMPORT_SKIP)
{
m_aColumn[i].m_bAttr = TRUE;
}
// Skip columns not to be imported
else if (m_aColumn[i].m_sNameAttr == IMPORT_SKIP)
{
}
// Bind columns
else
{
m_aColumn[i].m_bAttr = TRUE;
CAttribute* pAttr = NULL;
int iAttr = GetAttr(aAttr, m_aColumn[i].m_sNameAttr);
if (iAttr == Undefined)
{
ASSERT(FALSE);
AfxThrowDBException(0,&database, hstmt);
}
for (int j = 0; j < aAttr.GetSize(); j++)
{
if (aAttr.GetAt(j)->GetAttrId() == LOWORD(iAttr))
{
pAttr = aAttr.GetAt(j);
}
}
ASSERT(pAttr != NULL);
if (pAttr == NULL) AfxThrowDBException(0,&database, hstmt);
WORD wFlag = HIWORD(iAttr);
switch (pAttr->GetDataType())
{
case BDNUMBER :
nRet = SQLBindCol(hstmt, iCol, SQL_C_CHAR, m_aColumn[i].m_sText, BD_SHORTSTR, &dwLength);
break;
case BDTEXT :
nRet = SQLBindCol(hstmt, iCol, SQL_C_CHAR, pAttr->GetString(), BD_SHORTSTR, &dwLength);
break;
// For long text, use SQLGetData to retrieve values
case BDLONGTEXT :
nRet = SQLBindCol(hstmt, iCol, SQL_C_CHAR, NULL, 0, &dwLength);
break;
case BDCOORD :
if (wFlag == X_COORD)
{
nRet = SQLBindCol(hstmt, iCol, SQL_C_DOUBLE, &pAttr->GetCoord()->x, sizeof(double), &dwLength);
} else if (wFlag == Y_COORD)
{
nRet = SQLBindCol(hstmt, iCol, SQL_C_DOUBLE, &pAttr->GetCoord()->y, sizeof(double), &dwLength);
} else if (wFlag == LAT_COORD)
{
nRet = SQLBindCol(hstmt, iCol, SQL_C_CHAR, m_aColumn[i].m_sText, BD_SHORTSTR, &dwLength);
} else if (wFlag == LON_COORD)
{
nRet = SQLBindCol(hstmt, iCol, SQL_C_CHAR, m_aColumn[i].m_sText, BD_SHORTSTR, &dwLength);
} else if (wFlag == IMP_COORD)
{
nRet = SQLBindCol(hstmt, iCol, SQL_C_CHAR, m_aColumn[i].m_sText, BD_SHORTSTR, &dwLength);
}
break;
case BDLINK:
nRet = SQLBindCol(hstmt, iCol, SQL_C_CHAR, m_aColumn[i].m_sText, BD_SHORTSTR, &dwLength);
break;
case BDBOOLEAN:
nRet = SQLBindCol(hstmt, iCol, SQL_C_CHAR, m_aColumn[i].m_sText, BD_SHORTSTR, &dwLength);
break;
};
};
if (!m_aColumn[i].m_bShapeFile) iCol++;
}
} CATCH (CDBException, pEx)
{
bOK = FALSE;
} END_CATCH
// Set progress bar for shapefiles
BDProgressRange(0, lRecords);
// Retrieve the data and save it to the database
int nRet;
while (!bCancel && bOK && SQL_SUCCEEDED(nRet = SQLFetch(hstmt)))
{
// For longtext, retrieve data now
RetrieveLongText(hstmt, aAttr);
try
{
// Determine feature
long lFeature = 0;
if (sID[0] == '\0')
{
lFeature = DetermineFeature(ftype.m_lId, sFeature, sParentFeature,
sGrandParentFeature, sGreatGrandParentFeature);
}
else
{
lFeature = DetermineFeature(ftype.m_lId, sID, m_aColumn);
}
if (lFeature == -1) bOK = FALSE;
// Convert the date to a long
if (sDate[0] != '\0')
{
if (!date.StringAsDate(sDate))
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -