Character group database support added
This commit is contained in:
@@ -27,6 +27,12 @@ ZRCola::DBSource::DBSource()
|
||||
|
||||
ZRCola::DBSource::~DBSource()
|
||||
{
|
||||
if (m_pCharacterGroup1)
|
||||
m_pCharacterGroup1.Release();
|
||||
|
||||
if (m_comCharacterGroup)
|
||||
m_comCharacterGroup.Release();
|
||||
|
||||
if (m_db)
|
||||
m_db->Close();
|
||||
|
||||
@@ -53,6 +59,23 @@ bool ZRCola::DBSource::Open(LPCTSTR filename)
|
||||
// Database open and ready.
|
||||
m_filename = filename;
|
||||
m_locale = _create_locale(LC_ALL, "Slovenian_Slovenia.1250");
|
||||
|
||||
wxASSERT_MSG(!m_comCharacterGroup, wxT("ADO command already created"));
|
||||
|
||||
// Create ADO command(s).
|
||||
wxVERIFY(SUCCEEDED(::CoCreateInstance(CLSID_CADOCommand, NULL, CLSCTX_ALL, IID_IADOCommand, (LPVOID*)&m_comCharacterGroup)));
|
||||
wxVERIFY(SUCCEEDED(m_comCharacterGroup->put_ActiveConnection(ATL::CComVariant(m_db))));
|
||||
wxVERIFY(SUCCEEDED(m_comCharacterGroup->put_CommandType(adCmdText)));
|
||||
wxVERIFY(SUCCEEDED(m_comCharacterGroup->put_CommandText(ATL::CComBSTR(L"SELECT [Znak] FROM [VRS_SkupineZnakov] WHERE [Skupina]=? ORDER BY [Rang] ASC, [Znak] ASC"))));
|
||||
{
|
||||
// Create and add command parameters.
|
||||
ATL::CComPtr<ADOParameters> params;
|
||||
wxVERIFY(SUCCEEDED(m_comCharacterGroup->get_Parameters(¶ms)));
|
||||
wxASSERT_MSG(!m_pCharacterGroup1, wxT("ADO command parameter already created"));
|
||||
wxVERIFY(SUCCEEDED(m_comCharacterGroup->CreateParameter(ATL::CComBSTR(L"@Skupina"), adVarWChar, adParamInput, 50, ATL::CComVariant(DISP_E_PARAMNOTFOUND, VT_ERROR), &m_pCharacterGroup1)));
|
||||
wxVERIFY(SUCCEEDED(params->Append(m_pCharacterGroup1)));
|
||||
}
|
||||
|
||||
return true;
|
||||
} else {
|
||||
_ftprintf(stderr, wxT("%s: error ZCC0011: Could not open database (0x%x).\n"), (LPCTSTR)filename, hr);
|
||||
@@ -504,3 +527,92 @@ bool ZRCola::DBSource::GetLanguageCharacter(const ATL::CComPtr<ADORecordset>& rs
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool ZRCola::DBSource::SelectCharacterGroups(ATL::CComPtr<ADORecordset>& rs) const
|
||||
{
|
||||
// Create a new recordset.
|
||||
if (rs) rs.Release();
|
||||
wxCHECK(SUCCEEDED(::CoCreateInstance(CLSID_CADORecordset, NULL, CLSCTX_ALL, IID_IADORecordset, (LPVOID*)&rs)), false);
|
||||
|
||||
// Open it.
|
||||
if (FAILED(rs->Open(ATL::CComVariant(
|
||||
L"SELECT DISTINCT [id], [Skupina], [opis_en], [Rang], [prikazano] "
|
||||
L"FROM [VRS_SkupinaZnakov] "
|
||||
L"ORDER BY [Rang], [opis_en]"), ATL::CComVariant(m_db), adOpenStatic, adLockReadOnly, adCmdText)))
|
||||
{
|
||||
_ftprintf(stderr, wxT("%s: error ZCC0090: Error loading character groups from database. Please make sure the file is ZRCola.zrc compatible.\n"), m_filename.c_str());
|
||||
LogErrors();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool ZRCola::DBSource::GetCharacterGroup(const ATL::CComPtr<ADORecordset>& rs, chrgrp& cg) const
|
||||
{
|
||||
wxASSERT_MSG(rs, wxT("recordset is empty"));
|
||||
|
||||
ATL::CComPtr<ADOFields> flds;
|
||||
wxVERIFY(SUCCEEDED(rs->get_Fields(&flds)));
|
||||
std::wstring id;
|
||||
|
||||
{
|
||||
ATL::CComPtr<ADOField> f;
|
||||
wxVERIFY(SUCCEEDED(flds->get_Item(ATL::CComVariant(L"id"), &f)));
|
||||
wxCHECK(GetValue(f, cg.id), false);
|
||||
}
|
||||
|
||||
{
|
||||
ATL::CComPtr<ADOField> f;
|
||||
wxVERIFY(SUCCEEDED(flds->get_Item(ATL::CComVariant(L"Skupina"), &f)));
|
||||
wxCHECK(GetValue(f, id), false);
|
||||
}
|
||||
|
||||
{
|
||||
ATL::CComPtr<ADOField> f;
|
||||
wxVERIFY(SUCCEEDED(flds->get_Item(ATL::CComVariant(L"Rang"), &f)));
|
||||
wxCHECK(GetValue(f, cg.rank), false);
|
||||
}
|
||||
|
||||
{
|
||||
ATL::CComPtr<ADOField> f;
|
||||
wxVERIFY(SUCCEEDED(flds->get_Item(ATL::CComVariant(L"prikazano"), &f)));
|
||||
wxCHECK(GetValue(f, cg.show), false);
|
||||
}
|
||||
|
||||
{
|
||||
ATL::CComPtr<ADOField> f;
|
||||
wxVERIFY(SUCCEEDED(flds->get_Item(ATL::CComVariant(L"opis_en"), &f)));
|
||||
wxCHECK(GetValue(f, cg.name), false);
|
||||
}
|
||||
|
||||
// Read character list from database.
|
||||
wxVERIFY(SUCCEEDED(m_pCharacterGroup1->put_Value(ATL::CComVariant(id.c_str()))));
|
||||
ATL::CComPtr<ADORecordset> rs_chars;
|
||||
wxVERIFY(SUCCEEDED(::CoCreateInstance(CLSID_CADORecordset, NULL, CLSCTX_ALL, IID_IADORecordset, (LPVOID*)&rs_chars)));
|
||||
wxVERIFY(SUCCEEDED(rs_chars->put_CursorLocation(adUseClient)));
|
||||
wxVERIFY(SUCCEEDED(rs_chars->put_CursorType(adOpenForwardOnly)));
|
||||
wxVERIFY(SUCCEEDED(rs_chars->put_LockType(adLockReadOnly)));
|
||||
if (FAILED(rs_chars->Open(ATL::CComVariant(m_comCharacterGroup), ATL::CComVariant(DISP_E_PARAMNOTFOUND, VT_ERROR)))) {
|
||||
_ftprintf(stderr, wxT("%s: error ZCC0100: Error loading character group characters from database. Please make sure the file is ZRCola.zrc compatible.\n"), m_filename.c_str());
|
||||
LogErrors();
|
||||
return false;
|
||||
}
|
||||
|
||||
{
|
||||
cg.chars.clear();
|
||||
ATL::CComPtr<ADOFields> flds;
|
||||
wxVERIFY(SUCCEEDED(rs_chars->get_Fields(&flds)));
|
||||
ATL::CComPtr<ADOField> f;
|
||||
wxVERIFY(SUCCEEDED(flds->get_Item(ATL::CComVariant(L"Znak"), &f)));
|
||||
for (VARIANT_BOOL eof = VARIANT_TRUE; SUCCEEDED(rs_chars->get_EOF(&eof)) && !eof; rs_chars->MoveNext()) {
|
||||
wchar_t c;
|
||||
wxCHECK(GetUnicodeCharacter(f, c), false);
|
||||
cg.chars += c;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@@ -39,9 +39,9 @@ namespace ZRCola {
|
||||
///
|
||||
class translation {
|
||||
public:
|
||||
wchar_t chr; ///< Composed character
|
||||
std::wstring str; ///< Decomposed string
|
||||
int rank; ///< Decomposition rank
|
||||
wchar_t chr; ///< Composed character
|
||||
std::wstring str; ///< Decomposed string
|
||||
int rank; ///< Decomposition rank
|
||||
};
|
||||
|
||||
|
||||
@@ -85,6 +85,20 @@ namespace ZRCola {
|
||||
ZRCola::langid_t lang; ///< Language ID
|
||||
};
|
||||
|
||||
|
||||
///
|
||||
/// Character group
|
||||
///
|
||||
class chrgrp {
|
||||
public:
|
||||
int id; ///< Character group ID
|
||||
int rank; ///< Character group rank
|
||||
bool show; ///< Show initially
|
||||
std::wstring name; ///< Character group name
|
||||
std::wstring chars; ///< Character group characters
|
||||
};
|
||||
|
||||
|
||||
public:
|
||||
DBSource();
|
||||
virtual ~DBSource();
|
||||
@@ -328,9 +342,37 @@ namespace ZRCola {
|
||||
///
|
||||
bool GetLanguageCharacter(const ATL::CComPtr<ADORecordset>& rs, langchar& lc) const;
|
||||
|
||||
|
||||
///
|
||||
/// Returns character groups
|
||||
///
|
||||
/// \param[out] rs Recordset with results
|
||||
///
|
||||
/// \returns
|
||||
/// - true when query succeeds
|
||||
/// - false otherwise
|
||||
///
|
||||
bool SelectCharacterGroups(ATL::CComPtr<ADORecordset>& rs) const;
|
||||
|
||||
|
||||
///
|
||||
/// Returns character group data
|
||||
///
|
||||
/// \param[in] rs Recordset with results
|
||||
/// \param[out] cg Character group
|
||||
///
|
||||
/// \returns
|
||||
/// - true when succeeded
|
||||
/// - false otherwise
|
||||
///
|
||||
bool GetCharacterGroup(const ATL::CComPtr<ADORecordset>& rs, chrgrp& cg) const;
|
||||
|
||||
protected:
|
||||
std::basic_string<TCHAR> m_filename; ///< Database filename
|
||||
ATL::CComPtr<ADOConnection> m_db; ///< Database
|
||||
_locale_t m_locale; ///< Database locale
|
||||
|
||||
ATL::CComPtr<ADOCommand> m_comCharacterGroup; ///< ADO Command for GetCharacterGroup subquery
|
||||
ATL::CComPtr<ADOParameter> m_pCharacterGroup1; ///< \c m_comCharacterGroup parameter
|
||||
};
|
||||
};
|
||||
|
@@ -243,6 +243,56 @@ inline std::ostream& operator <<(std::ostream& stream, const ZRCola::langchar_db
|
||||
}
|
||||
|
||||
|
||||
///
|
||||
/// Writes character group database to a stream
|
||||
///
|
||||
/// \param[in] stream Output stream
|
||||
/// \param[in] db Character group database
|
||||
///
|
||||
/// \returns The stream \p stream
|
||||
///
|
||||
inline std::ostream& operator <<(std::ostream& stream, const ZRCola::chrgrp_db &db)
|
||||
{
|
||||
unsigned __int32 count;
|
||||
|
||||
// Write index count.
|
||||
ZRCola::keyseq_db::indexChr::size_type ks_count = db.idxRnk.size();
|
||||
#if defined(_WIN64) || defined(__x86_64__) || defined(__ppc64__)
|
||||
// 4G check
|
||||
if (ks_count > 0xffffffff) {
|
||||
stream.setstate(std::ios_base::failbit);
|
||||
return stream;
|
||||
}
|
||||
#endif
|
||||
if (stream.fail()) return stream;
|
||||
count = (unsigned __int32)ks_count;
|
||||
stream.write((const char*)&count, sizeof(count));
|
||||
|
||||
// Write rank index.
|
||||
if (stream.fail()) return stream;
|
||||
stream.write((const char*)db.idxRnk.data(), sizeof(unsigned __int32)*count);
|
||||
|
||||
// Write data count.
|
||||
std::vector<unsigned __int16>::size_type data_count = db.data.size();
|
||||
#if defined(_WIN64) || defined(__x86_64__) || defined(__ppc64__)
|
||||
// 4G check
|
||||
if (data_count > 0xffffffff) {
|
||||
stream.setstate(std::ios_base::failbit);
|
||||
return stream;
|
||||
}
|
||||
#endif
|
||||
if (stream.fail()) return stream;
|
||||
count = (unsigned __int32)data_count;
|
||||
stream.write((const char*)&count, sizeof(count));
|
||||
|
||||
// Write data.
|
||||
if (stream.fail()) return stream;
|
||||
stream.write((const char*)db.data.data(), sizeof(unsigned __int16)*count);
|
||||
|
||||
return stream;
|
||||
}
|
||||
|
||||
|
||||
///
|
||||
/// Main function
|
||||
///
|
||||
@@ -549,6 +599,64 @@ int _tmain(int argc, _TCHAR *argv[])
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
// Get character groups.
|
||||
ATL::CComPtr<ADORecordset> rs;
|
||||
if (src.SelectCharacterGroups(rs)) {
|
||||
size_t count = src.GetRecordsetCount(rs);
|
||||
if (count < 0xffffffff) { // 4G check (-1 is reserved for error condition)
|
||||
ZRCola::DBSource::chrgrp cg;
|
||||
ZRCola::chrgrp_db db;
|
||||
|
||||
// Preallocate memory.
|
||||
db.idxRnk.reserve(count);
|
||||
db.data .reserve(count*4);
|
||||
|
||||
// Parse character groups and build index and data.
|
||||
while (!ZRCola::DBSource::IsEOF(rs)) {
|
||||
// Read character group from the database.
|
||||
if (src.GetCharacterGroup(rs, cg)) {
|
||||
// Add character group to index and data.
|
||||
unsigned __int32 idx = db.data.size();
|
||||
wxASSERT_MSG((int)0xffff8000 <= cg.id && cg.id <= (int)0x00007fff, wxT("character group ID out of bounds"));
|
||||
db.data.push_back((unsigned __int16)cg.id);
|
||||
wxASSERT_MSG((int)0xffff8000 <= cg.rank && cg.rank <= (int)0x00007fff, wxT("character group rank out of bounds"));
|
||||
db.data.push_back((unsigned __int16)cg.rank);
|
||||
db.data.push_back(cg.show ? ZRCola::chrgrp_db::chrgrp::SHOW : 0);
|
||||
std::wstring::size_type n_name = cg.name.length();
|
||||
wxASSERT_MSG(n_name <= 0xffff, wxT("character group name too long"));
|
||||
db.data.push_back((unsigned __int16)n_name);
|
||||
std::wstring::size_type n_char = cg.chars.length();
|
||||
wxASSERT_MSG(n_char <= 0xffff, wxT("too many character group characters"));
|
||||
db.data.push_back((unsigned __int16)n_char);
|
||||
for (std::wstring::size_type i = 0; i < n_name; i++)
|
||||
db.data.push_back(cg.name[i]);
|
||||
for (std::wstring::size_type i = 0; i < n_char; i++)
|
||||
db.data.push_back(cg.chars[i]);
|
||||
db.idxRnk.push_back(idx);
|
||||
if (build_pot)
|
||||
pot.insert(cg.name);
|
||||
} else
|
||||
has_errors = true;
|
||||
|
||||
wxVERIFY(SUCCEEDED(rs->MoveNext()));
|
||||
}
|
||||
|
||||
// Sort indices.
|
||||
db.idxRnk.sort();
|
||||
|
||||
// Write character groups to file.
|
||||
dst << ZRCola::chrgrp_rec(db);
|
||||
} else {
|
||||
_ftprintf(stderr, wxT("%s: error ZCC0015: Error getting character group count from database or too many character groups.\n"), (LPCTSTR)filenameIn.c_str());
|
||||
has_errors = true;
|
||||
}
|
||||
} else {
|
||||
_ftprintf(stderr, wxT("%s: error ZCC0014: Error getting character groups from database. Please make sure the file is ZRCola.zrc compatible.\n"), (LPCTSTR)filenameIn.c_str());
|
||||
has_errors = true;
|
||||
}
|
||||
}
|
||||
|
||||
stdex::idrec::close<ZRCola::recordid_t, ZRCola::recordsize_t, ZRCOLA_RECORD_ALIGN>(dst, dst_start);
|
||||
|
||||
if (dst.fail()) {
|
||||
|
@@ -26,6 +26,7 @@
|
||||
|
||||
#include <zrcola/language.h>
|
||||
#include <zrcola/translate.h>
|
||||
#include <zrcolaui/chargroup.h>
|
||||
#include <zrcolaui/keyboard.h>
|
||||
|
||||
#include <wx/app.h>
|
||||
@@ -41,6 +42,7 @@
|
||||
#include <initguid.h> // GUID helper to prevent LNK2001 errors (unresolved external symbol IID_IADO...)
|
||||
#include <adoint.h>
|
||||
#include <adoid.h>
|
||||
#include <atlcomcli.h>
|
||||
|
||||
#include <tchar.h>
|
||||
|
||||
|
Reference in New Issue
Block a user