From 2c9ff8050932c51c8f839ecf5f09fd19d089a8af Mon Sep 17 00:00:00 2001 From: jdochoa Date: Tue, 17 Oct 2023 10:47:54 -0600 Subject: [PATCH] User Collation --- html-templates/COLLATION.html | 21 ++++++++ html-templates/COLLATIONprivileges.html | 53 +++++++++++++++++++ html-templates/EXCEPTION.html | 2 +- src/core/StringUtils.cpp | 35 ++++++++++++ src/core/StringUtils.h | 5 ++ src/gui/CommandIds.h | 1 + src/gui/ContextMenuMetadataItemVisitor.cpp | 35 ++++++++++++ src/gui/ContextMenuMetadataItemVisitor.h | 6 +++ src/gui/ExecuteSqlFrame.cpp | 35 ------------ src/gui/HtmlHeaderMetadataItemVisitor.cpp | 8 +++ src/gui/HtmlHeaderMetadataItemVisitor.h | 1 + src/gui/InsertParametersDialog.cpp | 31 +---------- src/gui/MainFrame.cpp | 10 +++- src/gui/MainFrame.h | 1 + src/gui/controls/DataGridRows.cpp | 4 +- src/metadata/CharacterSet.cpp | 46 ++++++++++++++-- src/metadata/CharacterSet.h | 2 + src/metadata/Collation.cpp | 51 ++++++++++++++++-- src/metadata/Collation.h | 13 +++++ src/metadata/CreateDDLVisitor.cpp | 13 +++++ src/metadata/CreateDDLVisitor.h | 1 + .../MetadataItemCreateStatementVisitor.cpp | 24 +++++++++ .../MetadataItemCreateStatementVisitor.h | 2 + src/metadata/collection.h | 11 ++-- src/metadata/database.cpp | 42 ++++----------- src/metadata/database.h | 3 +- src/metadata/metadataitem.cpp | 15 +++--- src/metadata/metadataitem.h | 6 +-- 28 files changed, 353 insertions(+), 124 deletions(-) create mode 100644 html-templates/COLLATION.html create mode 100644 html-templates/COLLATIONprivileges.html diff --git a/html-templates/COLLATION.html b/html-templates/COLLATION.html new file mode 100644 index 000000000..9d95d711c --- /dev/null +++ b/html-templates/COLLATION.html @@ -0,0 +1,21 @@ + + + Collation + + +{%header:Summary%} +
+
+{%object_name%} +
{%object_description%} [edit] +

+ + + + +
Collation info
+
{%object_ddl%}
+
+ + diff --git a/html-templates/COLLATIONprivileges.html b/html-templates/COLLATIONprivileges.html new file mode 100644 index 000000000..147a5661a --- /dev/null +++ b/html-templates/COLLATIONprivileges.html @@ -0,0 +1,53 @@ + + + Privileges + + +{%header:Privileges%} +

+Privileges on {%object_name%} +

+ + + + + + + {%foreach:privilege:: + + + + %} + +
GranteeUSAGE
{%privilegeinfo:grantee_name%}{%foreach:privilegeitem:
:USAGE: + {%privilegeiteminfo:columns%}%} + {%ifeq:{%privilegeitemcount:USAGE%}:0:%} +
+
+
+Grant +and revoke privileges +
+
+ + + + + + + + + + + + + + + + + + + +
Icons
privilege not granted
privilege granted
privilege granted with grant option
Hover over icons to see the grantor
+ + diff --git a/html-templates/EXCEPTION.html b/html-templates/EXCEPTION.html index c4f1f405a..ca1bc8e33 100644 --- a/html-templates/EXCEPTION.html +++ b/html-templates/EXCEPTION.html @@ -8,7 +8,7 @@
{%object_name%}
{%object_description%} [edit] + href="fr://edit_description?parent_window={%parent_window%}&object_handle={%object_handle%}&object_type=EXCEPTION&object_name={%object_name%}">edit]

diff --git a/src/core/StringUtils.cpp b/src/core/StringUtils.cpp index d914d7b08..022007776 100644 --- a/src/core/StringUtils.cpp +++ b/src/core/StringUtils.cpp @@ -277,3 +277,38 @@ wxString wrapText(const wxString& text, size_t maxWidth, size_t indent) return wrappedText; } + +wxString IBPPtype2string(Database* db, IBPP::SDT t, int subtype, int size, + int scale) +{ + if (scale > 0) + return wxString::Format("NUMERIC(%d,%d)", size == 4 ? 9 : 18, scale); + if (t == IBPP::sdString) + { + int bpc = db->getCharsetById(subtype)->getBytesPerChar(); + if (subtype == 1) // charset OCTETS + return wxString::Format("OCTETS(%d)", bpc ? size / bpc : size); + return wxString::Format("STRING(%d)", bpc ? size / bpc : size); + } + switch (t) + { + case IBPP::sdArray: return "ARRAY"; + case IBPP::sdBlob: return wxString::Format("BLOB SUB_TYPE %d", subtype); + case IBPP::sdDate: return "DATE"; + case IBPP::sdTime: return "TIME"; + case IBPP::sdTimestamp: return "TIMESTAMP"; + case IBPP::sdSmallint: return "SMALLINT"; + case IBPP::sdInteger: return "INTEGER"; + case IBPP::sdLargeint: return "BIGINT"; + case IBPP::sdFloat: return "FLOAT"; + case IBPP::sdDouble: return "DOUBLE PRECISION"; + case IBPP::sdBoolean: return "BOOLEAN"; + case IBPP::sdTimeTz: return "TIME WITH TIMEZONE"; + case IBPP::sdTimestampTz: return "TIMESTAMP WITH TIMEZONE"; + case IBPP::sdInt128: return "INT128"; + case IBPP::sdDec16: return "DECFLOAT(16)"; + case IBPP::sdDec34: return "DECFLOAT(34)"; + default: return "UNKNOWN"; + } +} + diff --git a/src/core/StringUtils.h b/src/core/StringUtils.h index f0fbe985d..61c0444bd 100644 --- a/src/core/StringUtils.h +++ b/src/core/StringUtils.h @@ -29,6 +29,8 @@ #include +#include "metadata/CharacterSet.h" +#include "metadata/database.h" std::string wx2std(const wxString& input, wxMBConv* conv = wxConvCurrent); @@ -60,4 +62,7 @@ wxString loadEntireFile(const wxFileName& filename); // Code adapted from wxWidgets' wxTextWrapper function. wxString wrapText(const wxString& text, size_t maxWidth, size_t indent); + +wxString IBPPtype2string(Database* db, IBPP::SDT t, int subtype, int size, int scale); + #endif // FR_STRINGUTILS_H diff --git a/src/gui/CommandIds.h b/src/gui/CommandIds.h index 48320d7a1..dc985ba5f 100644 --- a/src/gui/CommandIds.h +++ b/src/gui/CommandIds.h @@ -135,6 +135,7 @@ enum { Menu_ToggleDisconnected, // create new ... (stuff) + Menu_CreateCollation, Menu_CreateDBTrigger, Menu_CreateDDLTrigger, Menu_CreateDMLTrigger, diff --git a/src/gui/ContextMenuMetadataItemVisitor.cpp b/src/gui/ContextMenuMetadataItemVisitor.cpp index da5446610..57edda125 100644 --- a/src/gui/ContextMenuMetadataItemVisitor.cpp +++ b/src/gui/ContextMenuMetadataItemVisitor.cpp @@ -33,6 +33,8 @@ #include "config/Config.h" #include "gui/CommandIds.h" #include "gui/ContextMenuMetadataItemVisitor.h" +#include "metadata/CharacterSet.h" +#include "metadata/Collation.h" #include "metadata/column.h" #include "metadata/domain.h" #include "metadata/database.h" @@ -481,6 +483,39 @@ void MainObjectMenuMetadataItemVisitor::visitViews(Views& views) addRefreshItem(); } +void MainObjectMenuMetadataItemVisitor::visitCharacterSet(CharacterSet& charset) +{ + addAlterItem(charset); + addSeparator(); + addPropertiesItem(); +} + +void MainObjectMenuMetadataItemVisitor::visitCharacterSets(CharacterSets& charsets) +{ + addRefreshItem(); +} + +void MainObjectMenuMetadataItemVisitor::visitCollation(Collation& collation) +{ + addAlterItem(collation); + addSeparator(); + addPropertiesItem(); +} + +void MainObjectMenuMetadataItemVisitor::visitCollations(Collations& collations) +{ + addRefreshItem(); +} + +void MainObjectMenuMetadataItemVisitor::visitUserCollations(UserCollations& coolations) +{ + addCreateItem(); + addSeparator(); + addGenerateCodeMenu(coolations); + addSeparator(); + addRefreshItem(); +} + void MainObjectMenuMetadataItemVisitor::visitIndex(Index& index) { //menuM->Append(Cmds::Menu_ShowStatisticsValue, _("Show &statistics")); diff --git a/src/gui/ContextMenuMetadataItemVisitor.h b/src/gui/ContextMenuMetadataItemVisitor.h index 5361818f3..0bcfbf334 100644 --- a/src/gui/ContextMenuMetadataItemVisitor.h +++ b/src/gui/ContextMenuMetadataItemVisitor.h @@ -75,6 +75,12 @@ class MainObjectMenuMetadataItemVisitor : public MetadataItemVisitor virtual void visitUsers(Users& users); virtual void visitView(View& view); virtual void visitViews(Views& views); + virtual void visitCharacterSet(CharacterSet& charset); + virtual void visitCharacterSets(CharacterSets& charsets); + virtual void visitCollation(Collation& collation); + virtual void visitCollations(Collations& collations); + virtual void visitUserCollations(UserCollations& coolations); + protected: wxMenu* menuM; virtual void addCreateItem(); diff --git a/src/gui/ExecuteSqlFrame.cpp b/src/gui/ExecuteSqlFrame.cpp index c3050f3b9..6c4298017 100644 --- a/src/gui/ExecuteSqlFrame.cpp +++ b/src/gui/ExecuteSqlFrame.cpp @@ -2237,41 +2237,6 @@ void ExecuteSqlFrame::OnMenuUpdateWhenExecutePossible(wxUpdateUIEvent& event) event.Enable(!closeWhenTransactionDoneM); } -wxString IBPPtype2string(Database *db, IBPP::SDT t, int subtype, int size, - int scale) -{ - if (scale > 0) - return wxString::Format("NUMERIC(%d,%d)", size==4 ? 9:18, scale); - if (t == IBPP::sdString) - { - //CharacterSet cs = db->getCharacterSets()->findById(subtype)->getBytesPerChar(); - //int bpc = cs.getBytesPerChar(); - int bpc = db->getCharacterSets()->findById(subtype)->getBytesPerChar(); - return wxString::Format("STRING(%d)", bpc ? size/bpc : size); - } - switch (t) - { - case IBPP::sdArray: return "ARRAY"; - case IBPP::sdBlob: return wxString::Format( - "BLOB SUB_TYPE %d", subtype); - case IBPP::sdDate: return "DATE"; - case IBPP::sdTime: return "TIME"; - case IBPP::sdTimestamp: return "TIMESTAMP"; - case IBPP::sdSmallint: return "SMALLINT"; - case IBPP::sdInteger: return "INTEGER"; - case IBPP::sdLargeint: return "BIGINT"; - case IBPP::sdFloat: return "FLOAT"; - case IBPP::sdDouble: return "DOUBLE PRECISION"; - case IBPP::sdBoolean: return "BOOLEAN"; - case IBPP::sdTimeTz: return "TIME WITH TIMEZONE"; - case IBPP::sdTimestampTz: return "TIMESTAMP WITH TIMEZONE"; - case IBPP::sdInt128: return "INT128"; - case IBPP::sdDec16: return "DECFLOAT(16)"; - case IBPP::sdDec34: return "DECFLOAT(34)"; - default: return "UNKNOWN"; - } -} - void ExecuteSqlFrame::compareCounts(IBPP::DatabaseCounts& one, IBPP::DatabaseCounts& two) { diff --git a/src/gui/HtmlHeaderMetadataItemVisitor.cpp b/src/gui/HtmlHeaderMetadataItemVisitor.cpp index 0575b5892..393275060 100644 --- a/src/gui/HtmlHeaderMetadataItemVisitor.cpp +++ b/src/gui/HtmlHeaderMetadataItemVisitor.cpp @@ -190,6 +190,14 @@ void HtmlHeaderMetadataItemVisitor::visitView(View& /*view*/) addDDL(); } +void HtmlHeaderMetadataItemVisitor::visitCollation(Collation& /*collation*/) +{ + emptyTitles(); + addSummary(); + addDependencies(); + addDDL(); +} + void HtmlHeaderMetadataItemVisitor::defaultAction() { emptyTitles(); diff --git a/src/gui/HtmlHeaderMetadataItemVisitor.h b/src/gui/HtmlHeaderMetadataItemVisitor.h index 1d4c1fa44..91d22f3a1 100644 --- a/src/gui/HtmlHeaderMetadataItemVisitor.h +++ b/src/gui/HtmlHeaderMetadataItemVisitor.h @@ -49,6 +49,7 @@ class HtmlHeaderMetadataItemVisitor: public MetadataItemVisitor virtual void visitGTTable(GTTable& table); virtual void visitUDF(UDF & function); virtual void visitView(View& view); + virtual void visitCollation(Collation& collation); protected: virtual void defaultAction(); private: diff --git a/src/gui/InsertParametersDialog.cpp b/src/gui/InsertParametersDialog.cpp index 42fc99c37..b31aeeaab 100644 --- a/src/gui/InsertParametersDialog.cpp +++ b/src/gui/InsertParametersDialog.cpp @@ -117,37 +117,8 @@ namespace InsertParametersOptions } -wxString IBPPtype2string(Database *db, IBPP::SDT t, int subtype, int size, - int scale) -{ - if (scale > 0) - return wxString::Format("NUMERIC(%d,%d)", size==4 ? 9:18, scale); - if (t == IBPP::sdString) - { - int bpc = db->getCharsetById(subtype).getBytesPerChar(); - if (subtype == 1) // charset OCTETS - return wxString::Format("OCTETS(%d)", bpc ? size / bpc : size); - return wxString::Format("STRING(%d)", bpc ? size/bpc : size); - } - switch (t) - { - case IBPP::sdArray: return "ARRAY"; - case IBPP::sdBlob: return wxString::Format( - "BLOB SUB_TYPE %d", subtype); - case IBPP::sdDate: return "DATE"; - case IBPP::sdTime: return "TIME"; - case IBPP::sdTimestamp: return "TIMESTAMP"; - case IBPP::sdSmallint: return "SMALLINT"; - case IBPP::sdInteger: return "INTEGER"; - case IBPP::sdLargeint: return "BIGINT"; - case IBPP::sdFloat: return "FLOAT"; - case IBPP::sdDouble: return "DOUBLE PRECISION"; - case IBPP::sdBoolean: return "BOOLEAN"; - default: return "UNKNOWN"; - } -} - }; + using namespace InsertParametersOptions; /* Generator *findAutoincGenerator2(std::vector& triggers, Column *c) diff --git a/src/gui/MainFrame.cpp b/src/gui/MainFrame.cpp index 0aaf67f29..a0b4b7415 100644 --- a/src/gui/MainFrame.cpp +++ b/src/gui/MainFrame.cpp @@ -226,6 +226,7 @@ void MainFrame::buildMainMenu() objectMenuM = new wxMenu(); wxMenu* newMenu = new wxMenu(); + newMenu->Append(Cmds::Menu_CreateCollation, _("&Collation")); newMenu->Append(Cmds::Menu_CreateDBTrigger, _("D&B Trigger")); newMenu->Append(Cmds::Menu_CreateDDLTrigger, _("DD&L Trigger")); newMenu->Append(Cmds::Menu_CreateDMLTrigger, _("DML Tr&igger")); @@ -233,7 +234,7 @@ void MainFrame::buildMainMenu() newMenu->Append(Cmds::Menu_CreateException, _("&Exception")); newMenu->Append(Cmds::Menu_CreateFunction, _("&Function")); newMenu->Append(Cmds::Menu_CreateGenerator, _("&Generator")); - newMenu->Append(Cmds::Menu_CreateGTTTable, _("Global Temporary")); + newMenu->Append(Cmds::Menu_CreateGTTTable, _("Global &Temporary")); newMenu->Append(Cmds::Menu_CreateIndex, _("&Index")); newMenu->Append(Cmds::Menu_CreatePackage, _("P&ackage")); newMenu->Append(Cmds::Menu_CreateProcedure, _("&Procedure")); @@ -466,6 +467,7 @@ EVT_UPDATE_UI(Cmds::Menu_StartupDatabase, MainFrame::OnMenuUpdateIfDatabaseNotCo EVT_BUTTON(MainFrame::ID_button_prev, MainFrame::OnButtonPrevClick) EVT_BUTTON(MainFrame::ID_button_next, MainFrame::OnButtonNextClick) + EVT_MENU(Cmds::Menu_CreateCollation, MainFrame::OnMenuCreateCollation) EVT_MENU(Cmds::Menu_CreateDBTrigger, MainFrame::OnMenuCreateDBTrigger) EVT_MENU(Cmds::Menu_CreateDDLTrigger, MainFrame::OnMenuCreateDDLTrigger) EVT_MENU(Cmds::Menu_CreateDMLTrigger, MainFrame::OnMenuCreateDMLTrigger) @@ -1520,6 +1522,12 @@ void MainFrame::showCreateTemplate(const wxString& statement) showSql(this, wxEmptyString, db, statement); } +void MainFrame::OnMenuCreateCollation(wxCommandEvent& event) +{ + showCreateTemplate( + MetadataItemCreateStatementVisitor::getCreateCollationStatment()); +} + void MainFrame::OnMenuAddColumn(wxCommandEvent& WXUNUSED(event)) { Table* t = dynamic_cast(treeMainM->getSelectedMetadataItem()); diff --git a/src/gui/MainFrame.h b/src/gui/MainFrame.h index f87ffb63d..2efe4d5b2 100644 --- a/src/gui/MainFrame.h +++ b/src/gui/MainFrame.h @@ -109,6 +109,7 @@ class MainFrame: public BaseFrame, private URIHandler, // create new object void showCreateTemplate(const wxString& statement); + void OnMenuCreateCollation(wxCommandEvent& event); void OnMenuCreateDBTrigger(wxCommandEvent& event); void OnMenuCreateDDLTrigger(wxCommandEvent& event); void OnMenuCreateDMLTrigger(wxCommandEvent& event); diff --git a/src/gui/controls/DataGridRows.cpp b/src/gui/controls/DataGridRows.cpp index c75c53ecc..41f7a30c4 100644 --- a/src/gui/controls/DataGridRows.cpp +++ b/src/gui/controls/DataGridRows.cpp @@ -2123,9 +2123,7 @@ bool DataGridRows::initialize(const IBPP::Statement& statement) case IBPP::sdString: { - //CharacterSet cs = databaseM->getCharsetById(statement->ColumnSubtype(col)); - //int bpc = cs.getBytesPerChar(); - int bpc = databaseM->getCharacterSets()->findById(statement->ColumnSubtype(col))->getBytesPerChar(); + int bpc = databaseM->getCharsetById(statement->ColumnSubtype(col))->getBytesPerChar(); int size = statement->ColumnSize(col); if (bpc) size /= bpc; diff --git a/src/metadata/CharacterSet.cpp b/src/metadata/CharacterSet.cpp index d374397d6..822539c1c 100644 --- a/src/metadata/CharacterSet.cpp +++ b/src/metadata/CharacterSet.cpp @@ -75,7 +75,7 @@ void CharacterSet::loadProperties(IBPP::Statement& statement, wxMBConv* converte int Lid; std::string Lstr; statement->Get(2, Lid); - setId(Lid); + setMetadataId(Lid); statement->Get(3, Lid); setBytesPerChar(Lid); @@ -274,12 +274,52 @@ void CharacterSets::acceptVisitor(MetadataItemVisitor* visitor) void CharacterSets::load(ProgressIndicator* progressIndicator) { + + + DatabasePtr db = getDatabase(); + MetadataLoader* loader = db->getMetadataLoader(); + MetadataLoaderTransaction tr(loader); + wxMBConv* converter = db->getCharsetConverter(); + + IBPP::Statement& st1 = loader->getStatement( + CharacterSet::getLoadStatement(true)); + + CollectionType characters; + st1->Execute(); + checkProgressIndicatorCanceled(progressIndicator); + while (st1->Fetch()) + { + if (!st1->IsNull(1)) + { + std::string s; + st1->Get(1, s); + wxString name(std2wxIdentifier(s, converter)); + + CharacterSetPtr character = findByName(name); + if (!character) + { + character.reset(new CharacterSet(db, name)); + initializeLockCount(character, getLockCount()); + } + characters.push_back(character); + character->loadProperties(st1, converter); + } + checkProgressIndicatorCanceled(progressIndicator); + } + + setItems(characters); + + + /* DatabasePtr db = getDatabase(); - wxString stmt("select rdb$character_set_name " + wxString stmt("select rdb$character_set_name, " + "RDB$CHARACTER_SET_ID , " + "c.RDB$BYTES_PER_CHARACTER, " + "c.RDB$DEFAULT_COLLATE_NAME " "from rdb$character_sets " " order by rdb$character_set_name " ); - setItems(db->loadIdentifiers(stmt, progressIndicator)); + setItems(db->loadIdentifiers(stmt, progressIndicator));*/ } const wxString CharacterSets::getTypeName() const diff --git a/src/metadata/CharacterSet.h b/src/metadata/CharacterSet.h index 8e065510a..5be283a9b 100644 --- a/src/metadata/CharacterSet.h +++ b/src/metadata/CharacterSet.h @@ -87,6 +87,8 @@ class CharacterSets : public MetadataCollection virtual void acceptVisitor(MetadataItemVisitor* visitor); void load(ProgressIndicator* progressIndicator); virtual const wxString getTypeName() const; + + }; #endif // FR_CHARACTERSET_H diff --git a/src/metadata/Collation.cpp b/src/metadata/Collation.cpp index fcda0600f..a46821169 100644 --- a/src/metadata/Collation.cpp +++ b/src/metadata/Collation.cpp @@ -46,14 +46,15 @@ std::string Collation::getLoadStatement(bool list) "c.RDB$COLLATION_ID, " //2 "c.RDB$COLLATION_ATTRIBUTES, " //3 "c.RDB$BASE_COLLATION_NAME, " //4 - "c.RDB$SPECIFIC_ATTRIBUTES, " //5 - "from rdb$character_sets c "); + "c.RDB$SPECIFIC_ATTRIBUTES, " //5 + "c.RDB$CHARACTER_SET_ID " //6 + "from RDB$COLLATIONS c "); if (list) { - stmt += " order by c.rdb$character_set_name"; + stmt += " order by c.RDB$COLLATION_NAME"; } else - stmt += " where c.rdb$character_set_name = ?"; + stmt += " where c.RDB$COLLATION_NAME = ?"; return stmt; } @@ -68,7 +69,7 @@ void Collation::loadProperties(IBPP::Statement& statement, wxMBConv* converter) //setName(std2wxIdentifier(Lstr, converter)); statement->Get(2, Lid); - setId(Lid); + setMetadataId(Lid); statement->Get(3, Lid); setAttributes(Lid); @@ -79,6 +80,9 @@ void Collation::loadProperties(IBPP::Statement& statement, wxMBConv* converter) statement->Get(5, Lstr); setSpecificAttributes(std2wxIdentifier(Lstr, converter)); + statement->Get(6, Lid); + setCharacterSetId(Lid); + setPropertiesLoaded(true); } @@ -137,6 +141,16 @@ void Collation::setAttributes(int& attributes) attributesM = attributes; } +int Collation::getCharacterSetId() +{ + return characterSetIdM; +} + +void Collation::setCharacterSetId(int& characterSetId) +{ + characterSetIdM = characterSetId; +} + wxString Collation::getBaseCollectionName() { return baseCollectionNameM; @@ -162,8 +176,35 @@ void Collation::acceptVisitor(MetadataItemVisitor* visitor) visitor->visitCollation(*this); } +const wxString Collation::getTypeName() const +{ + return "COLLATION"; +} + +wxString Collation::getSource() +{ + ensurePropertiesLoaded(); + wxString sql ="FOR " + getDatabase()->getCharsetById(characterSetIdM)->getName_() + " \n"; + if (!getBaseCollectionName().IsEmpty()) + sql =+ "FROM EXTERNAL ('" + getBaseCollectionName() + "'), \n"; + + + if(getAttributes() & TEXTTYPE_ATTR_CASE_INSENSITIVE) + sql += "PAD SPACE, \n"; + if (getAttributes() & TEXTTYPE_ATTR_PAD_SPACE) + sql += "CASE INSENSITIVE, \n"; + if (getAttributes() & TEXTTYPE_ATTR_ACCENT_INSENSITIVE) + sql += "ACCENT INSENSITIVE \n"; + + if (!getSpecificAttibutes().IsEmpty()) + sql += "'" + getSpecificAttibutes() + "'"; + + return sql; +} + void Collations::loadChildren() { + load(0); } diff --git a/src/metadata/Collation.h b/src/metadata/Collation.h index 7c46fd246..5da2ec640 100644 --- a/src/metadata/Collation.h +++ b/src/metadata/Collation.h @@ -30,11 +30,17 @@ #include "metadata/CharacterSet.h" //#include "metadata/privilege.h" +/* attributes passed by the engine to texttype entry-point */ +#define TEXTTYPE_ATTR_PAD_SPACE 1 +#define TEXTTYPE_ATTR_CASE_INSENSITIVE 2 +#define TEXTTYPE_ATTR_ACCENT_INSENSITIVE 4 + class Collations; class Collation : public MetadataItem { private: + int characterSetIdM; int attributesM; wxString baseCollectionNameM; wxString specificAttibutesM; @@ -55,12 +61,19 @@ class Collation : public MetadataItem int getAttributes(); void setAttributes(int& attributes); + int getCharacterSetId(); + void setCharacterSetId(int& characterSetId); wxString getBaseCollectionName(); void setBaseCollectionName(wxString baseName); wxString getSpecificAttibutes(); void setSpecificAttributes(wxString attibutes); virtual void acceptVisitor(MetadataItemVisitor* visitor); + virtual const wxString getTypeName() const; + + wxString getSource(); + + }; diff --git a/src/metadata/CreateDDLVisitor.cpp b/src/metadata/CreateDDLVisitor.cpp index f436e2a08..2ff19085a 100644 --- a/src/metadata/CreateDDLVisitor.cpp +++ b/src/metadata/CreateDDLVisitor.cpp @@ -35,6 +35,7 @@ #include "core/ProgressIndicator.h" #include "metadata/column.h" +#include "metadata/Collation.h" #include "metadata/constraints.h" #include "metadata/CreateDDLVisitor.h" #include "metadata/database.h" @@ -115,6 +116,14 @@ wxString CreateDDLVisitor::getSuffixSql() const return postSqlM + grantSqlM; } +void CreateDDLVisitor::visitCollation(Collation& collation) +{ + preSqlM += "CREATE " + collation.getSource() + "; \n"; + postSqlM << getCommentOn(collation); + sqlM = preSqlM + postSqlM; + +} + // this one is not called from "outside", but from visit(Table) function void CreateDDLVisitor::visitColumn(Column& c) { @@ -199,6 +208,10 @@ void CreateDDLVisitor::visitDatabase(Database& d) try { + + preSqlM << "/********************* COLLATES **********************/\n\n"; + iterateit(this, d.getUserCollations(), progressIndicatorM); + preSqlM << "/********************* ROLES **********************/\n\n"; iterateit(this, d.getRoles(), progressIndicatorM); diff --git a/src/metadata/CreateDDLVisitor.h b/src/metadata/CreateDDLVisitor.h index 4d0ccadc7..36317014d 100644 --- a/src/metadata/CreateDDLVisitor.h +++ b/src/metadata/CreateDDLVisitor.h @@ -51,6 +51,7 @@ class CreateDDLVisitor: public MetadataItemVisitor wxString getPrefixSql() const; wxString getSuffixSql() const; + virtual void visitCollation(Collation& collation); virtual void visitColumn(Column& column); virtual void visitDatabase(Database& database); virtual void visitDomain(Domain& domain); diff --git a/src/metadata/MetadataItemCreateStatementVisitor.cpp b/src/metadata/MetadataItemCreateStatementVisitor.cpp index f1db33390..9ee3b0a19 100644 --- a/src/metadata/MetadataItemCreateStatementVisitor.cpp +++ b/src/metadata/MetadataItemCreateStatementVisitor.cpp @@ -221,6 +221,24 @@ wxString MetadataItemCreateStatementVisitor::getCreateCharacterSetStatement() return ""; } +wxString MetadataItemCreateStatementVisitor::getCreateCollationStatment() +{ + return "CREATE COLLATION collname \n" + "FOR charset \n" + "[FROM {basecoll | EXTERNAL('extname')}] \n" + "[NO PAD | PAD SPACE] \n" + "[CASE[IN]SENSITIVE] \n" + "[ACCENT[IN]SENSITIVE] \n" + "'DISABLE-COMPRESSIONS=0' \n" + "'DISABLE-EXPANSIONS=0' \n" + "'MULTI-LEVEL=0' \n" + "'ICU-VERSION=M.n' \n" + "'LOCALE=xx_YY' \n" + "'NUMERIC-SORT=0' \n" + "'SPECIALS-FIRST=0' \n" + ";"; +} + wxString MetadataItemCreateStatementVisitor::getCreateDBTriggerStatement() { return "SET TERM ^ ;\n\n" @@ -356,6 +374,12 @@ void MetadataItemCreateStatementVisitor::visitCharacterSets(CharacterSets& /*cha statementM = getCreateCharacterSetStatement(); } +void MetadataItemCreateStatementVisitor::visitUserCollations(UserCollations& collations) +{ + statementM = getCreateCollationStatment(); + +} + void MetadataItemCreateStatementVisitor::visitDBTriggers(DBTriggers& /*triggers*/) { statementM = getCreateDBTriggerStatement(); diff --git a/src/metadata/MetadataItemCreateStatementVisitor.h b/src/metadata/MetadataItemCreateStatementVisitor.h index 2947acbd4..a70e28cf3 100644 --- a/src/metadata/MetadataItemCreateStatementVisitor.h +++ b/src/metadata/MetadataItemCreateStatementVisitor.h @@ -32,6 +32,7 @@ class MetadataItemCreateStatementVisitor : public MetadataItemVisitor wxString statementM; public: static wxString getCreateCharacterSetStatement(); + static wxString getCreateCollationStatment(); static wxString getCreateDBTriggerStatement(); static wxString getCreateDDLTriggerStatement(); static wxString getCreateDMLTriggerStatement(); @@ -51,6 +52,7 @@ class MetadataItemCreateStatementVisitor : public MetadataItemVisitor virtual void visitCharacterSets(CharacterSets& characterSets); + virtual void visitUserCollations(UserCollations& collations); virtual void visitDBTriggers(DBTriggers& triggers); virtual void visitDDLTriggers(DDLTriggers& triggers); virtual void visitDMLTriggers(DMLTriggers& triggers); diff --git a/src/metadata/collection.h b/src/metadata/collection.h index ff7145373..3042e4c7c 100644 --- a/src/metadata/collection.h +++ b/src/metadata/collection.h @@ -98,14 +98,15 @@ class MetadataCollection : public MetadataCollectionBase return itemsM.end(); } - iterator getPositionId(const int id) + iterator getPositionMetadataId(const int id) { for (iterator it = itemsM.begin(); it != itemsM.end(); ++it) { - if ((*it)->getId() == id) + if ((*it)->getMetadataId() == id) return it; } return itemsM.end(); + } protected: @@ -218,11 +219,11 @@ class MetadataCollection : public MetadataCollectionBase return (it != itemsM.end()) ? (*it) : ItemType(); }; - ItemType findById(const int id) + ItemType findByMetadataId(const int id) { - iterator it = getPositionId(id); + iterator it = getPositionMetadataId(id); return (it != itemsM.end()) ? (*it) : ItemType(); - }; + } // returns vector of all subnodes virtual bool getChildren(std::vector& temp) diff --git a/src/metadata/database.cpp b/src/metadata/database.cpp index 8751c0f1b..2340b42ae 100644 --- a/src/metadata/database.cpp +++ b/src/metadata/database.cpp @@ -68,34 +68,6 @@ #include "sql/SqlStatement.h" #include "sql/SqlTokenizer.h" -/* -// CharacterSet class -CharacterSet::CharacterSet(const wxString& name, int id, int bytesPerChar) - : nameM(name), idM(id), bytesPerCharM(bytesPerChar) -{ -} - -bool CharacterSet::operator< (const CharacterSet& other) const -{ - return nameM < other.nameM; -} - -int CharacterSet::getBytesPerChar() const -{ - return bytesPerCharM; -} - -int CharacterSet::getId() const -{ - return idM; -} - -wxString CharacterSet::getName() const -{ - return nameM; -} - -*/ // Credentials class void Credentials::setCharset(const wxString& value) { @@ -422,12 +394,13 @@ void Database::getDatabaseTriggers(std::vector& list) std::back_inserter(list), std::mem_fn(&DBTriggerPtr::get)); } -CharacterSet Database::getCharsetById(int id) +CharacterSetPtr Database::getCharsetById(int id) { // if it contains both charset and collation as 2 bytes id %= 256; + //CharacterSetPtr cs = getCharacterSets()->findByMetadataId(id); - return reinterpret_cast(characterSetsM->findById(id)); + return getCharacterSets()->findByMetadataId(id); } wxArrayString Database::getCharacterSet() @@ -573,7 +546,7 @@ MetadataItem* Database::findByIdAndType(NodeType nt, const int id) switch (nt) { case ntCharacterSet: - return characterSetsM->findById(id).get(); + return characterSetsM->findByMetadataId(id).get(); break; default: return 0; @@ -1655,6 +1628,13 @@ CharacterSetsPtr Database::getCharacterSets() return characterSetsM; } +UserCollationsPtr Database::getUserCollations() +{ + wxASSERT(userCollationsM); + userCollationsM->ensureChildrenLoaded(); + return userCollationsM; +} + DBTriggersPtr Database::getDBTriggers() { wxASSERT(DBTriggersM); diff --git a/src/metadata/database.h b/src/metadata/database.h index 0c77442a1..7291d6529 100644 --- a/src/metadata/database.h +++ b/src/metadata/database.h @@ -253,6 +253,7 @@ class Database: public MetadataItem, void getCollections(std::vector& temp, bool system); CharacterSetsPtr getCharacterSets(); + UserCollationsPtr getUserCollations(); DBTriggersPtr getDBTriggers(); DDLTriggersPtr getDDLTriggers(); DMLTriggersPtr getDMLTriggers(); @@ -307,7 +308,7 @@ class Database: public MetadataItem, void addObject(NodeType type, const wxString& name); void parseCommitedSql(const SqlStatement& stm); // reads a DDL statement and does accordingly - CharacterSet getCharsetById(int id); + CharacterSetPtr getCharsetById(int id); wxArrayString getCharacterSet(); wxArrayString getCollations(const wxString& charset); bool isDefaultCollation(const wxString& charset, const wxString& collate); diff --git a/src/metadata/metadataitem.cpp b/src/metadata/metadataitem.cpp index 89ba3e097..b0bae40cf 100644 --- a/src/metadata/metadataitem.cpp +++ b/src/metadata/metadataitem.cpp @@ -64,7 +64,7 @@ template<> ObjectWithHandle::Handle ObjectWithHandle::nextHandle = 0; MetadataItem::MetadataItem() - : Subject(), typeM(ntUnknown), parentM(0), childrenLoadedM(lsNotLoaded), + : Subject(), typeM(ntUnknown), parentM(0), metadataIdM(-1), childrenLoadedM(lsNotLoaded), descriptionLoadedM(lsNotLoaded), propertiesLoadedM(lsNotLoaded) { } @@ -73,7 +73,7 @@ MetadataItem::MetadataItem(NodeType type, MetadataItem* parent, const wxString& name, int id) : Subject(), typeM(type), parentM(parent), identifierM(name, getDatabase() != nullptr ? getDatabase()->getSqlDialect() : 3), - idM(id), + metadataIdM(id), childrenLoadedM(lsNotLoaded), descriptionLoadedM(lsNotLoaded), propertiesLoadedM(lsNotLoaded) { @@ -129,6 +129,7 @@ wxString getNameOfType(NodeType type) case ntPackage: return ("PACKAGE"); case ntIndex: return ("INDEX"); case ntCharacterSet: return ("CHARACTERSET"); + case ntCollation: return ("COLLATION"); default: return ""; } @@ -166,6 +167,8 @@ NodeType getTypeByName(const wxString& name) return ntIndex; else if (name == "CHARACTERSET") return ntCharacterSet; + else if (name == "COLLATION") + return ntCollation; else return ntUnknown; } @@ -729,14 +732,14 @@ void MetadataItem::setType(NodeType type) typeM = type; } -int MetadataItem::getId() +int MetadataItem::getMetadataId() { - return idM; + return metadataIdM; } -void MetadataItem::setId(int id) +void MetadataItem::setMetadataId(int id) { - idM = id; + metadataIdM = id; } bool MetadataItem::isSystem() const diff --git a/src/metadata/metadataitem.h b/src/metadata/metadataitem.h index 7e6ac142d..4dbf9ba6f 100644 --- a/src/metadata/metadataitem.h +++ b/src/metadata/metadataitem.h @@ -87,7 +87,7 @@ class MetadataItem: public Subject, public ObjectWithHandle, MetadataItem* parentM; NodeType typeM; Identifier identifierM; - int idM; + int metadataIdM; enum LoadState { lsNotLoaded, lsLoadPending, lsLoaded, lsNotAvailable }; LoadState childrenLoadedM; @@ -163,8 +163,8 @@ class MetadataItem: public Subject, public ObjectWithHandle, virtual void setName_(const wxString& name); virtual NodeType getType() const; void setType(NodeType type); - virtual int getId(); - virtual void setId(int id); + virtual int getMetadataId(); + virtual void setMetadataId(int id); // returns the name of the data type (f. ex. TABLE) virtual const wxString getTypeName() const;