mirror of
https://github.com/levinsv/pgadmin3.git
synced 2026-05-15 14:15:49 -06:00
444 lines
11 KiB
C++
444 lines
11 KiB
C++
//////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// pgAdmin III - PostgreSQL Tools
|
|
//
|
|
// Copyright (C) 2002 - 2016, The pgAdmin Development Team
|
|
// This software is released under the PostgreSQL Licence
|
|
//
|
|
// dlgTextSearchConfiguration.cpp - PostgreSQL Text Search Configuration Property
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
// wxWindows headers
|
|
#include <wx/wx.h>
|
|
|
|
// App headers
|
|
#include "pgAdmin3.h"
|
|
#include "utils/misc.h"
|
|
#include "utils/pgDefs.h"
|
|
|
|
#include "dlg/dlgTextSearchConfiguration.h"
|
|
#include "schema/pgSchema.h"
|
|
#include "schema/pgTextSearchConfiguration.h"
|
|
#include "schema/pgDatatype.h"
|
|
|
|
|
|
// pointer to controls
|
|
#define cbParser CTRL_COMBOBOX2("cbParser")
|
|
#define cbCopy CTRL_COMBOBOX2("cbCopy")
|
|
#define lstTokens CTRL_LISTVIEW("lstTokens")
|
|
#define cbToken CTRL_COMBOBOX2("cbToken")
|
|
#define txtDictionary CTRL_TEXT("txtDictionary")
|
|
#define cbDictionary CTRL_CHOICE("cbDictionary")
|
|
#define btnAdd CTRL_BUTTON("wxID_ADD")
|
|
#define btnRemove CTRL_BUTTON("wxID_REMOVE")
|
|
|
|
|
|
BEGIN_EVENT_TABLE(dlgTextSearchConfiguration, dlgTypeProperty)
|
|
EVT_TEXT(XRCID("cbParser"), dlgTextSearchConfiguration::OnChange)
|
|
EVT_COMBOBOX(XRCID("cbParser"), dlgTextSearchConfiguration::OnChange)
|
|
EVT_TEXT(XRCID("cbCopy"), dlgTextSearchConfiguration::OnChange)
|
|
EVT_COMBOBOX(XRCID("cbCopy"), dlgTextSearchConfiguration::OnChange)
|
|
EVT_LIST_ITEM_SELECTED(XRCID("lstTokens"), dlgTextSearchConfiguration::OnSelChangeToken)
|
|
EVT_TEXT(XRCID("cbToken"), dlgTextSearchConfiguration::OnChangeCbToken)
|
|
EVT_COMBOBOX(XRCID("cbToken"), dlgTextSearchConfiguration::OnChangeCbToken)
|
|
EVT_TEXT(XRCID("txtDictionary"), dlgTextSearchConfiguration::OnChangeTxtDictionary)
|
|
EVT_CHOICE(XRCID("cbDictionary"), dlgTextSearchConfiguration::OnChangeCbDictionary)
|
|
EVT_BUTTON(wxID_ADD, dlgTextSearchConfiguration::OnAddToken)
|
|
EVT_BUTTON(wxID_REMOVE, dlgTextSearchConfiguration::OnRemoveToken)
|
|
#ifdef __WXMAC__
|
|
EVT_SIZE( dlgTextSearchConfiguration::OnChangeSize)
|
|
#endif
|
|
END_EVENT_TABLE();
|
|
|
|
|
|
|
|
dlgProperty *pgTextSearchConfigurationFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent)
|
|
{
|
|
return new dlgTextSearchConfiguration(this, frame, (pgTextSearchConfiguration *)node, (pgSchema *)parent);
|
|
}
|
|
|
|
dlgTextSearchConfiguration::dlgTextSearchConfiguration(pgaFactory *f, frmMain *frame, pgTextSearchConfiguration *node, pgSchema *sch)
|
|
: dlgTypeProperty(f, frame, wxT("dlgTextSearchConfiguration"))
|
|
{
|
|
schema = sch;
|
|
config = node;
|
|
dirtyTokens = false;
|
|
|
|
lstTokens->CreateColumns(0, _("Token"), _("Dictionaries"));
|
|
|
|
cbCopy->Disable();
|
|
}
|
|
|
|
|
|
pgObject *dlgTextSearchConfiguration::GetObject()
|
|
{
|
|
return config;
|
|
}
|
|
|
|
|
|
int dlgTextSearchConfiguration::Go(bool modal)
|
|
{
|
|
wxString qry;
|
|
pgSet *set;
|
|
|
|
cbParser->Append(wxT(""));
|
|
|
|
qry = wxT("SELECT prsname, nspname\n")
|
|
wxT(" FROM pg_ts_parser\n")
|
|
wxT(" JOIN pg_namespace n ON n.oid=prsnamespace\n")
|
|
wxT(" ORDER BY prsname\n");
|
|
|
|
set = connection->ExecuteSet(qry);
|
|
if (set)
|
|
{
|
|
while (!set->Eof())
|
|
{
|
|
wxString procname = database->GetSchemaPrefix(set->GetVal(wxT("nspname"))) + set->GetVal(wxT("prsname"));
|
|
cbParser->Append(procname);
|
|
set->MoveNext();
|
|
}
|
|
delete set;
|
|
}
|
|
|
|
cbCopy->Append(wxT(""));
|
|
|
|
qry = wxT("SELECT cfgname, nspname\n")
|
|
wxT(" FROM pg_ts_config\n")
|
|
wxT(" JOIN pg_namespace n ON n.oid=cfgnamespace\n")
|
|
wxT(" ORDER BY nspname, cfgname\n");
|
|
|
|
set = connection->ExecuteSet(qry);
|
|
if (set)
|
|
{
|
|
cbCopy->Enable();
|
|
while (!set->Eof())
|
|
{
|
|
wxString configname = database->GetSchemaPrefix(set->GetVal(wxT("nspname"))) + set->GetVal(wxT("cfgname"));
|
|
cbCopy->Append(configname);
|
|
set->MoveNext();
|
|
}
|
|
delete set;
|
|
}
|
|
|
|
if (config)
|
|
{
|
|
// edit mode
|
|
cbSchema->Enable(connection->BackendMinimumVersion(9, 1));
|
|
cbParser->SetValue(config->GetParser());
|
|
cbCopy->Disable();
|
|
|
|
// second tab handling
|
|
size_t i;
|
|
for (i = 0 ; i < config->GetTokens().GetCount() ; i++)
|
|
{
|
|
wxString token = config->GetTokens().Item(i);
|
|
lstTokens->AppendItem(token.BeforeFirst('/'), token.AfterFirst('/'));
|
|
}
|
|
|
|
pgSet *tokens;
|
|
tokens = connection->ExecuteSet(
|
|
wxT("SELECT alias FROM ts_token_type(")
|
|
+ config->GetParserOidStr()
|
|
+ wxT(") ORDER BY alias"));
|
|
|
|
if (tokens)
|
|
{
|
|
while (!tokens->Eof())
|
|
{
|
|
cbToken->Append(tokens->GetVal(wxT("alias")));
|
|
tokens->MoveNext();
|
|
}
|
|
delete tokens;
|
|
}
|
|
|
|
pgSet *dictionaries;
|
|
dictionaries = connection->ExecuteSet(
|
|
wxT("SELECT dictname FROM pg_ts_dict ORDER BY dictname"));
|
|
|
|
if (dictionaries)
|
|
{
|
|
while (!dictionaries->Eof())
|
|
{
|
|
cbDictionary->Append(dictionaries->GetVal(wxT("dictname")));
|
|
dictionaries->MoveNext();
|
|
}
|
|
delete dictionaries;
|
|
}
|
|
|
|
if (!connection->BackendMinimumVersion(8, 0))
|
|
cbOwner->Disable();
|
|
}
|
|
else
|
|
{
|
|
// create mode
|
|
}
|
|
|
|
btnAdd->Disable();
|
|
btnRemove->Disable();
|
|
|
|
return dlgProperty::Go(modal);
|
|
}
|
|
|
|
|
|
pgObject *dlgTextSearchConfiguration::CreateObject(pgCollection *collection)
|
|
{
|
|
pgObject *obj = textSearchConfigurationFactory.CreateObjects(collection, 0,
|
|
wxT("\n AND cfg.cfgname=") + qtDbString(GetName()) +
|
|
wxT("\n AND cfg.cfgnamespace=") + schema->GetOidStr());
|
|
|
|
return obj;
|
|
}
|
|
|
|
|
|
#ifdef __WXMAC__
|
|
void dlgTextSearchConfiguration::OnChangeSize(wxSizeEvent &ev)
|
|
{
|
|
lstTokens->SetSize(wxDefaultCoord, wxDefaultCoord,
|
|
ev.GetSize().GetWidth(), ev.GetSize().GetHeight() - 350);
|
|
if (GetAutoLayout())
|
|
{
|
|
Layout();
|
|
}
|
|
}
|
|
#endif
|
|
|
|
|
|
void dlgTextSearchConfiguration::CheckChange()
|
|
{
|
|
if (config)
|
|
{
|
|
EnableOK(txtName->GetValue() != config->GetName()
|
|
|| cbSchema->GetValue() != config->GetSchema()->GetName()
|
|
|| txtComment->GetValue() != config->GetComment()
|
|
|| cbOwner->GetValue() != config->GetOwner()
|
|
|| dirtyTokens);
|
|
}
|
|
else
|
|
{
|
|
wxString name = GetName();
|
|
bool enable = true;
|
|
CheckValid(enable, !name.IsEmpty(), _("Please specify name."));
|
|
CheckValid(enable, cbParser->GetGuessedSelection() > 0 || cbCopy->GetGuessedSelection() > 0 , _("Please select a parser or a configuration to copy."));
|
|
|
|
EnableOK(enable);
|
|
}
|
|
}
|
|
|
|
|
|
void dlgTextSearchConfiguration::OnChange(wxCommandEvent &ev)
|
|
{
|
|
cbParser->Enable(cbCopy->GetValue().Length() == 0);
|
|
cbCopy->Enable(cbParser->GetValue().Length() == 0);
|
|
|
|
CheckChange();
|
|
}
|
|
|
|
void dlgTextSearchConfiguration::OnChangeCbToken(wxCommandEvent &ev)
|
|
{
|
|
bool found = false;
|
|
|
|
for (int pos = 0 ; pos < lstTokens->GetItemCount() ; pos++)
|
|
{
|
|
if (lstTokens->GetText(pos).IsSameAs(cbToken->GetValue(), false))
|
|
{
|
|
lstTokens->Select(pos);
|
|
found = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
btnAdd->Enable(cbToken->GetValue().Length() > 0);
|
|
}
|
|
|
|
|
|
void dlgTextSearchConfiguration::OnChangeCbDictionary(wxCommandEvent &ev)
|
|
{
|
|
if (!txtDictionary->GetValue().Matches(wxT("*") + cbDictionary->GetStringSelection() + wxT("*")))
|
|
{
|
|
wxString dicts = txtDictionary->GetValue();
|
|
if (dicts.Length() > 0)
|
|
dicts += wxT(",");
|
|
dicts += cbDictionary->GetStringSelection();
|
|
|
|
txtDictionary->SetValue(dicts);
|
|
}
|
|
btnAdd->Enable(cbToken->GetValue().Length() > 0);
|
|
}
|
|
|
|
|
|
void dlgTextSearchConfiguration::OnChangeTxtDictionary(wxCommandEvent &ev)
|
|
{
|
|
btnAdd->Enable(cbToken->GetValue().Length() > 0);
|
|
}
|
|
|
|
|
|
void dlgTextSearchConfiguration::OnSelChangeToken(wxListEvent &ev)
|
|
{
|
|
int row = lstTokens->GetSelection();
|
|
if (row >= 0)
|
|
{
|
|
cbToken->SetValue(lstTokens->GetText(row, 0));
|
|
txtDictionary->SetValue(lstTokens->GetText(row, 1));
|
|
}
|
|
|
|
btnAdd->Enable(cbToken->GetValue().Length() > 0);
|
|
btnRemove->Enable(row >= 0);
|
|
}
|
|
|
|
|
|
void dlgTextSearchConfiguration::OnAddToken(wxCommandEvent &ev)
|
|
{
|
|
bool found = false;
|
|
|
|
for (int pos = 0 ; pos < lstTokens->GetItemCount() ; pos++)
|
|
{
|
|
if (lstTokens->GetText(pos).IsSameAs(cbToken->GetValue(), false))
|
|
{
|
|
lstTokens->SetItem(pos, 1, txtDictionary->GetValue());
|
|
found = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (!found)
|
|
{
|
|
lstTokens->AppendItem(cbToken->GetValue(), txtDictionary->GetValue());
|
|
}
|
|
|
|
btnAdd->Disable();
|
|
|
|
dirtyTokens = true;
|
|
|
|
CheckChange();
|
|
}
|
|
|
|
|
|
void dlgTextSearchConfiguration::OnRemoveToken(wxCommandEvent &ev)
|
|
{
|
|
for (int pos = 0 ; pos < lstTokens->GetItemCount() ; pos++)
|
|
{
|
|
if (lstTokens->GetText(pos).IsSameAs(cbToken->GetValue(), false))
|
|
{
|
|
lstTokens->DeleteItem(pos);
|
|
break;
|
|
}
|
|
}
|
|
|
|
cbToken->SetValue(wxT(""));
|
|
txtDictionary->SetValue(wxT(""));
|
|
|
|
btnRemove->Disable();
|
|
|
|
dirtyTokens = true;
|
|
|
|
CheckChange();
|
|
}
|
|
|
|
|
|
wxString dlgTextSearchConfiguration::GetSql()
|
|
{
|
|
wxString sql;
|
|
wxString objname;
|
|
|
|
if (config)
|
|
{
|
|
objname = schema->GetQuotedPrefix() + qtIdent(config->GetName());
|
|
}
|
|
else
|
|
{
|
|
objname = schema->GetQuotedPrefix() + qtIdent(GetName());
|
|
}
|
|
|
|
if (cbParser->GetValue().Length() > 0)
|
|
{
|
|
wxArrayString toks;
|
|
size_t index;
|
|
|
|
if (config)
|
|
{
|
|
for (index = 0 ; index < config->GetTokens().GetCount() ; index++)
|
|
toks.Add(config->GetTokens().Item(index));
|
|
}
|
|
|
|
int cnt = lstTokens->GetItemCount();
|
|
int pos;
|
|
|
|
// check for changed or added tokens
|
|
for (pos = 0 ; pos < cnt ; pos++)
|
|
{
|
|
wxString newTok = lstTokens->GetText(pos);
|
|
wxString newVal = lstTokens->GetText(pos, 1);
|
|
|
|
wxString oldVal;
|
|
|
|
for (index = 0 ; index < toks.GetCount() ; index++)
|
|
{
|
|
wxString tok = toks.Item(index);
|
|
if (tok.BeforeFirst('/').IsSameAs(newTok, false))
|
|
{
|
|
oldVal = tok.Mid(newTok.Length() + 1);
|
|
toks.RemoveAt(index);
|
|
break;
|
|
}
|
|
}
|
|
if (oldVal != newVal)
|
|
{
|
|
if (oldVal.Length() == 0)
|
|
{
|
|
sql += wxT("ALTER TEXT SEARCH CONFIGURATION ") + objname
|
|
+ wxT("\n ADD MAPPING FOR ") + newTok
|
|
+ wxT("\n WITH ") + newVal
|
|
+ wxT(";\n");
|
|
}
|
|
else
|
|
{
|
|
sql += wxT("ALTER TEXT SEARCH CONFIGURATION ") + objname
|
|
+ wxT("\n ALTER MAPPING FOR ") + newTok
|
|
+ wxT("\n WITH ") + newVal
|
|
+ wxT(";\n");
|
|
}
|
|
}
|
|
}
|
|
|
|
// check for removed tokens
|
|
wxString oldTok;
|
|
for (pos = 0 ; pos < (int)toks.GetCount() ; pos++)
|
|
{
|
|
if (!toks.Item(pos).BeforeFirst('/').IsSameAs(oldTok, false))
|
|
{
|
|
oldTok = toks.Item(pos).BeforeFirst('/');
|
|
sql += wxT("ALTER TEXT SEARCH CONFIGURATION ") + objname
|
|
+ wxT(" DROP MAPPING FOR ") + oldTok
|
|
+ wxT(";\n");
|
|
}
|
|
}
|
|
}
|
|
|
|
if (config)
|
|
{
|
|
// edit mode
|
|
objname = schema->GetQuotedPrefix() + qtIdent(GetName());
|
|
AppendNameChange(sql, wxT("TEXT SEARCH CONFIGURATION ") + config->GetQuotedFullIdentifier());
|
|
AppendOwnerChange(sql, wxT("TEXT SEARCH CONFIGURATION ") + objname);
|
|
AppendSchemaChange(sql, wxT("TEXT SEARCH CONFIGURATION ") + objname);
|
|
}
|
|
else
|
|
{
|
|
// create mode
|
|
objname = qtIdent(cbSchema->GetValue()) + wxT(".") + qtIdent(GetName());
|
|
sql = wxT("CREATE TEXT SEARCH CONFIGURATION ")
|
|
+ objname
|
|
+ wxT(" (");
|
|
|
|
AppendIfFilled(sql, wxT("\n PARSER="), cbParser->GetValue());
|
|
AppendIfFilled(sql, wxT("\n COPY="), cbCopy->GetValue());
|
|
|
|
sql += wxT("\n);\n");
|
|
|
|
}
|
|
|
|
AppendComment(sql, wxT("TEXT SEARCH CONFIGURATION ") + qtIdent(cbSchema->GetValue()) + wxT(".") + qtIdent(GetName()), config);
|
|
|
|
return sql;
|
|
}
|