mirror of
https://github.com/pgadmin-org/pgadmin4.git
synced 2025-02-25 18:55:31 -06:00
FTS Parser support
This commit is contained in:
Binary file not shown.
|
After Width: | Height: | Size: 620 B |
Binary file not shown.
|
After Width: | Height: | Size: 715 B |
@@ -0,0 +1,193 @@
|
||||
define(
|
||||
['jquery', 'underscore', 'underscore.string', 'pgadmin',
|
||||
'pgadmin.browser', 'alertify', 'pgadmin.browser.collection'],
|
||||
function($, _, S, pgAdmin, pgBrowser, alertify) {
|
||||
|
||||
// Extend the collection class for fts parser
|
||||
if (!pgBrowser.Nodes['coll-fts_parser']) {
|
||||
var fts_parsers = pgAdmin.Browser.Nodes['coll-fts_parser'] =
|
||||
pgAdmin.Browser.Collection.extend({
|
||||
node: 'fts_parser',
|
||||
label: '{{ _('FTS Parsers') }}',
|
||||
type: 'coll-fts_parser',
|
||||
columns: ['name', 'description']
|
||||
});
|
||||
};
|
||||
|
||||
// Extend the node class for fts parser
|
||||
if (!pgBrowser.Nodes['fts_parser']) {
|
||||
pgAdmin.Browser.Nodes['fts_parser'] = pgAdmin.Browser.Node.extend({
|
||||
parent_type: ['schema', 'catalog'],
|
||||
type: 'fts_parser',
|
||||
canDrop: true,
|
||||
canDropCascade: true,
|
||||
label: '{{ _('FTS Parser') }}',
|
||||
hasSQL: true,
|
||||
hasDepends: true,
|
||||
Init: function() {
|
||||
|
||||
// Avoid multiple registration of menus
|
||||
if (this.initialized)
|
||||
return;
|
||||
|
||||
this.initialized = true;
|
||||
|
||||
// Add context menus for fts parser
|
||||
pgBrowser.add_menus([{
|
||||
name: 'create_fts_parser_on_schema', node: 'schema', module: this,
|
||||
applies: ['object', 'context'], callback: 'show_obj_properties',
|
||||
category: 'create', priority: 4, label: '{{ _('FTS Parser...') }}',
|
||||
icon: 'wcTabIcon icon-fts_parser', data: {action: 'create'}
|
||||
},{
|
||||
name: 'create_fts_parser_on_coll', node: 'coll-fts_parser',
|
||||
applies: ['object', 'context'], callback: 'show_obj_properties',
|
||||
category: 'create', priority: 4, label: '{{ _('FTS Parser...') }}',
|
||||
icon: 'wcTabIcon icon-fts_parser', data: {action: 'create'},
|
||||
module: this
|
||||
},{
|
||||
name: 'create_fts_parser', node: 'fts_parser', module: this,
|
||||
applies: ['object', 'context'], callback: 'show_obj_properties',
|
||||
category: 'create', priority: 4, label: '{{ _('FTS Parser...') }}',
|
||||
icon: 'wcTabIcon icon-fts_parser', data: {action: 'create'}
|
||||
}]);
|
||||
|
||||
},
|
||||
|
||||
// Defining backform model for fts parser node
|
||||
model: pgAdmin.Browser.Node.Model.extend({
|
||||
defaults: {
|
||||
name: undefined, // Fts parser name
|
||||
description: undefined, // Comment on parser
|
||||
schema: undefined, // Schema name to which parser belongs
|
||||
prsstart: undefined, // Start function for fts parser
|
||||
prstoken: undefined, // Token function for fts parser
|
||||
prsend: undefined, // End function for fts parser
|
||||
prslextype: undefined, // Lextype function for fts parser
|
||||
prsheadline: undefined // Headline function for fts parse
|
||||
},
|
||||
initialize: function() {
|
||||
pgAdmin.Browser.Node.Model.prototype.initialize.apply(this,
|
||||
arguments
|
||||
);
|
||||
if (_.isUndefined(this.get('schema'))) {
|
||||
this.set('schema', this.node_info.schema._id);
|
||||
}
|
||||
},
|
||||
// Defining schema for fts parser
|
||||
schema: [{
|
||||
id: 'name', label: '{{ _('Name') }}', cell: 'string',
|
||||
type: 'text', cellHeaderClasses: 'width_percent_50'
|
||||
},{
|
||||
id: 'oid', label:'{{ _('OID') }}', cell: 'string',
|
||||
editable: false, type: 'text', disabled: true, mode:['properties']
|
||||
},{
|
||||
id: 'schema', label: '{{ _('Schema')}}', cell: 'string',
|
||||
type: 'text', mode: ['create','edit'], node: 'schema',
|
||||
control: 'node-list-by-id'
|
||||
},{
|
||||
id: 'description', label:'{{ _('Comment') }}', cell: 'string',
|
||||
type: 'multiline', cellHeaderClasses: 'width_percent_50'
|
||||
},{
|
||||
id: 'prsstart', label: '{{ _('Start function')}}',
|
||||
type: 'text', disabled: function(m) { return !m.isNew(); },
|
||||
control: 'node-ajax-options', url: 'start_functions',
|
||||
group: '{{ _('Definition') }}'
|
||||
},{
|
||||
id: 'prstoken', label: '{{ _('Get next token function')}}',
|
||||
type: 'text', disabled: function(m) { return !m.isNew(); },
|
||||
control: 'node-ajax-options', url: 'token_functions',
|
||||
group: '{{ _('Definition') }}'
|
||||
},{
|
||||
id: 'prsend', label: '{{ _('End function')}}',
|
||||
type: 'text', disabled: function(m) { return !m.isNew(); },
|
||||
control: 'node-ajax-options', url: 'end_functions',
|
||||
group: '{{ _('Definition') }}'
|
||||
},{
|
||||
id: 'prslextype', label: '{{ _('Lextypes function')}}',
|
||||
type: 'text', disabled: function(m) { return !m.isNew(); },
|
||||
control: 'node-ajax-options', url: 'lextype_functions',
|
||||
group: '{{ _('Definition') }}'
|
||||
},{
|
||||
id: 'prsheadline', label: '{{ _('Headline function')}}',
|
||||
type: 'text', disabled: function(m) { return !m.isNew(); },
|
||||
control: 'node-ajax-options', url: 'headline_functions',
|
||||
group: '{{ _('Definition') }}'
|
||||
}],
|
||||
|
||||
/*
|
||||
* Triggers control specific error messages for parser name,
|
||||
* start, token, end, lextype functions and schema, if any one of them is not specified
|
||||
* while creating new fts parser
|
||||
*/
|
||||
validate: function(keys){
|
||||
var name = this.get('name');
|
||||
var start = this.get('prsstart');
|
||||
var token = this.get('prstoken');
|
||||
var end = this.get('prsend');
|
||||
var lextype = this.get('prslextype');
|
||||
var schema = this.get('schema');
|
||||
|
||||
// Validate fts parser name
|
||||
if (_.isUndefined(name) ||
|
||||
_.isNull(name) ||
|
||||
String(name).replace(/^\s+|\s+$/g, '') == '') {
|
||||
var msg = '{{ _('Name must be specified!') }}';
|
||||
this.errorModel.set('name', msg);
|
||||
return msg;
|
||||
}
|
||||
|
||||
// Validate start function control
|
||||
else if (_.isUndefined(start) ||
|
||||
_.isNull(start) ||
|
||||
String(start).replace(/^\s+|\s+$/g, '') == '') {
|
||||
var msg = '{{ _('Start function must be selected!') }}';
|
||||
this.errorModel.set('prsstart', msg);
|
||||
return msg;
|
||||
}
|
||||
|
||||
// Validate gettoken function control
|
||||
else if (_.isUndefined(token) ||
|
||||
_.isNull(token) ||
|
||||
String(token).replace(/^\s+|\s+$/g, '') == '') {
|
||||
var msg = '{{ _('Get next token function must be selected!') }}';
|
||||
this.errorModel.set('prstoken', msg);
|
||||
return msg;
|
||||
}
|
||||
|
||||
// Validate end function control
|
||||
else if (_.isUndefined(end) ||
|
||||
_.isNull(end) ||
|
||||
String(end).replace(/^\s+|\s+$/g, '') == '') {
|
||||
var msg = '{{ _('End function must be selected!') }}';
|
||||
this.errorModel.set('prsend', msg);
|
||||
return msg;
|
||||
}
|
||||
|
||||
// Validate lextype function control
|
||||
else if (_.isUndefined(lextype) ||
|
||||
_.isNull(lextype) ||
|
||||
String(lextype).replace(/^\s+|\s+$/g, '') == '') {
|
||||
var msg = '{{ _('Lextype function must be selected!') }}';
|
||||
this.errorModel.set('prslextype', msg);
|
||||
return msg;
|
||||
}
|
||||
|
||||
// Validate schema for fts parser
|
||||
else if (_.isUndefined(schema) ||
|
||||
_.isNull(schema) ||
|
||||
String(schema).replace(/^\s+|\s+$/g, '') == '') {
|
||||
var msg = '{{ _('Schema must be selected!') }}';
|
||||
this.errorModel.set('schema', msg);
|
||||
return msg;
|
||||
}
|
||||
else this.errorModel.clear();
|
||||
|
||||
this.trigger('on-status-clear');
|
||||
return null;
|
||||
}
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
return pgBrowser.Nodes['coll-fts_parser'];
|
||||
});
|
||||
@@ -0,0 +1,15 @@
|
||||
{# CREATE FTS PARSER Statement #}
|
||||
{% if data and data.schema and data.name and data.prsstart and data.prstoken and data.prsend and data.prslextype %}
|
||||
CREATE TEXT SEARCH PARSER {{ conn|qtIdent(data.schema, data.name) }} (
|
||||
START = {{data.prsstart}},
|
||||
GETTOKEN = {{data.prstoken}},
|
||||
END = {{data.prsend}},
|
||||
LEXTYPES = {{data.prslextype}}{% if data.prsheadline and data.prsheadline != '-'%},
|
||||
HEADLINE = {{data.prsheadline}}{% endif %}
|
||||
);
|
||||
|
||||
{# Description for FTS_PARSER #}
|
||||
{% if data.description %}
|
||||
COMMENT ON TEXT SEARCH PARSER {{ conn|qtIdent(data.schema, data.name) }}
|
||||
IS {{ data.description|qtLiteral }};
|
||||
{% endif %}{% endif %}
|
||||
@@ -0,0 +1,23 @@
|
||||
{# FETCH FTS PARSER NAME Statement #}
|
||||
{% if pid %}
|
||||
SELECT
|
||||
p.prsname AS name,
|
||||
(
|
||||
SELECT
|
||||
nspname
|
||||
FROM
|
||||
pg_namespace
|
||||
WHERE
|
||||
oid = p.prsnamespace
|
||||
) as schema
|
||||
FROM
|
||||
pg_ts_parser p LEFT JOIN pg_description d
|
||||
ON d.objoid=p.oid AND d.classoid='pg_ts_parser'::regclass
|
||||
WHERE
|
||||
p.oid = {{pid}}::OID;
|
||||
{% endif %}
|
||||
|
||||
{# DROP FTS PARSER Statement #}
|
||||
{% if schema and name %}
|
||||
DROP TEXT SEARCH PARSER {{conn|qtIdent(schema)}}.{{conn|qtIdent(name)}} {% if cascade %}CASCADE{%endif%};
|
||||
{% endif %}
|
||||
@@ -0,0 +1,58 @@
|
||||
{# FETCH start functions for FTS_PARSER #}
|
||||
{% if start %}
|
||||
SELECT
|
||||
proname, nspname
|
||||
FROM
|
||||
pg_proc JOIN pg_namespace n ON n.oid=pronamespace
|
||||
WHERE
|
||||
proargtypes='2281 23'
|
||||
ORDER BY proname;
|
||||
{% endif %}
|
||||
|
||||
{# FETCH token functions for FTS_PARSER #}
|
||||
{% if token %}
|
||||
SELECT
|
||||
proname, nspname
|
||||
FROM
|
||||
pg_proc JOIN pg_namespace n ON n.oid=pronamespace
|
||||
WHERE
|
||||
proargtypes='2281 2281 2281'
|
||||
ORDER BY
|
||||
proname;
|
||||
{% endif %}
|
||||
|
||||
{# FETCH end functions for FTS_PARSER #}
|
||||
{% if end %}
|
||||
SELECT
|
||||
proname, nspname
|
||||
FROM
|
||||
pg_proc JOIN pg_namespace n ON n.oid=pronamespace
|
||||
WHERE
|
||||
prorettype=2278 and proargtypes='2281'
|
||||
ORDER BY
|
||||
proname;
|
||||
{% endif %}
|
||||
|
||||
{# FETCH lextype functions for FTS_PARSER #}
|
||||
{% if lextype %}
|
||||
SELECT
|
||||
proname, nspname
|
||||
FROM
|
||||
pg_proc JOIN pg_namespace n ON n.oid=pronamespace
|
||||
WHERE
|
||||
prorettype=2281 and proargtypes='2281'
|
||||
ORDER BY
|
||||
proname;
|
||||
{% endif %}
|
||||
|
||||
{# FETCH headline functions for FTS_PARSER #}
|
||||
{% if headline %}
|
||||
SELECT
|
||||
proname, nspname
|
||||
FROM
|
||||
pg_proc JOIN pg_namespace n ON n.oid=pronamespace
|
||||
WHERE
|
||||
proargtypes='2281 2281 3615'
|
||||
ORDER BY
|
||||
proname;
|
||||
{% endif %}
|
||||
@@ -0,0 +1,13 @@
|
||||
{# FETCH FTS PARSER name statement #}
|
||||
SELECT
|
||||
oid, prsname as name
|
||||
FROM
|
||||
pg_ts_parser prs
|
||||
WHERE
|
||||
{% if scid %}
|
||||
prs.prsnamespace = {{scid}}::OID
|
||||
{% elif pid %}
|
||||
prs.oid = {{pid}}::OID
|
||||
{% endif %}
|
||||
|
||||
ORDER BY name
|
||||
@@ -0,0 +1,30 @@
|
||||
{# FETCH properties for FTS PARSER #}
|
||||
SELECT
|
||||
prs.oid,
|
||||
prs.prsname as name,
|
||||
prs.prsstart,
|
||||
prs.prstoken,
|
||||
prs.prsend,
|
||||
prs.prslextype,
|
||||
prs.prsheadline,
|
||||
description,
|
||||
prs.prsnamespace AS schema
|
||||
FROM
|
||||
pg_ts_parser prs
|
||||
LEFT OUTER JOIN pg_description des
|
||||
ON
|
||||
(
|
||||
des.objoid=prs.oid
|
||||
AND des.classoid='pg_ts_parser'::regclass
|
||||
)
|
||||
WHERE
|
||||
{% if scid %}
|
||||
prs.prsnamespace = {{scid}}::OID
|
||||
{% elif name %}
|
||||
prs.prsname = {{name|qtLiteral}}
|
||||
{% endif %}
|
||||
{% if pid %}
|
||||
AND prs.oid = {{pid}}::OID
|
||||
{% endif %}
|
||||
ORDER BY
|
||||
prs.prsname
|
||||
@@ -0,0 +1,19 @@
|
||||
{# FETCH statement for SCHEMA name #}
|
||||
{% if data.schema %}
|
||||
SELECT
|
||||
nspname
|
||||
FROM
|
||||
pg_namespace
|
||||
WHERE
|
||||
oid = {{data.schema}}::OID
|
||||
|
||||
{% elif data.id %}
|
||||
SELECT
|
||||
nspname
|
||||
FROM
|
||||
pg_namespace nsp
|
||||
LEFT JOIN pg_ts_parser prs
|
||||
ON prs.prsnamespace = nsp.oid
|
||||
WHERE
|
||||
prs.oid = {{data.id}}::OID
|
||||
{% endif %}
|
||||
@@ -0,0 +1,46 @@
|
||||
{# Reverse engineered sql for FTS PARSER #}
|
||||
{% if pid and scid %}
|
||||
SELECT
|
||||
array_to_string(array_agg(sql), E'\n\n') as sql
|
||||
FROM
|
||||
(
|
||||
SELECT
|
||||
E'-- Text Search Parser: ' || nspname || E'.' || prs.prsname ||
|
||||
E'\n\n-- DROP TEXT SEARCH PARSER ' || nspname || E'.' || prs.prsname ||
|
||||
E'\n\nCREATE TEXT SEARCH PARSER ' || nspname || E'.' || prs.prsname || E' (\n' ||
|
||||
E' START = ' || prs.prsstart || E',\n' ||
|
||||
E' GETTOKEN = ' || prs.prstoken || E',\n' ||
|
||||
E' END = ' || prs.prsend || E',\n' ||
|
||||
E' LEXTYPES = ' || prs.prslextype ||
|
||||
CASE
|
||||
WHEN prs.prsheadline != '-'::regclass THEN E',\n HEADLINE = ' || prs.prsheadline
|
||||
ELSE '' END || E'\n);' ||
|
||||
CASE
|
||||
WHEN description IS NOT NULL THEN
|
||||
E'\n\nCOMMENT ON TEXT SEARCH PARSER ' || nspname || E'.' || prs.prsname ||
|
||||
E' IS ' || pg_catalog.quote_literal(description) || E';'
|
||||
ELSE '' END as sql
|
||||
FROM
|
||||
pg_ts_parser prs
|
||||
LEFT JOIN (
|
||||
SELECT
|
||||
des.description as description,
|
||||
des.objoid as descoid
|
||||
FROM
|
||||
pg_description des
|
||||
WHERE
|
||||
des.objoid={{pid}}::OID AND des.classoid='pg_ts_parser'::regclass
|
||||
) a ON (a.descoid = prs.oid)
|
||||
LEFT JOIN (
|
||||
SELECT
|
||||
nspname,
|
||||
nsp.oid as noid
|
||||
FROM
|
||||
pg_namespace nsp
|
||||
WHERE
|
||||
oid = {{scid}}::OID
|
||||
) b ON (b.noid = prs.prsnamespace)
|
||||
WHERE
|
||||
prs.oid={{pid}}::OID
|
||||
) as c;
|
||||
{% endif %}
|
||||
@@ -0,0 +1,22 @@
|
||||
{# UPDATE statement for FTS PARSER #}
|
||||
{% if data %}
|
||||
{% if data.name and data.name != o_data.name %}
|
||||
ALTER TEXT SEARCH PARSER {{conn|qtIdent(o_data.schema)}}.{{conn|qtIdent(o_data.name)}}
|
||||
RENAME TO {{data.name}};
|
||||
{% endif %}
|
||||
|
||||
{#in case of rename, use new fts template name #}
|
||||
{% if data.name and data.name != o_data.name %}
|
||||
{% set name = data.name %}
|
||||
{% else %}
|
||||
{% set name = o_data.name %}
|
||||
{% endif %}
|
||||
{% if data.schema and data.schema != o_data.schema %}
|
||||
ALTER TEXT SEARCH PARSER {{conn|qtIdent(o_data.schema)}}.{{conn|qtIdent(name)}}
|
||||
SET SCHEMA {{data.schema}};
|
||||
{% endif %}
|
||||
{% if "description" in data and data.description != o_data.description %}
|
||||
COMMENT ON TEXT SEARCH PARSER {{conn|qtIdent(o_data.schema)}}.{{conn|qtIdent(name)}}
|
||||
IS {{ data.description|qtLiteral }};
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
Reference in New Issue
Block a user