Skip to content

Commit

Permalink
Added Strategy, Locale Provider, ICU Locale, ICU Rules, and OID optio…
Browse files Browse the repository at this point in the history
…ns while creating a database. #6383
  • Loading branch information
akshay-joshi authored Sep 4, 2023
1 parent 39a1492 commit c0b868b
Show file tree
Hide file tree
Showing 57 changed files with 2,351 additions and 26 deletions.
14 changes: 14 additions & 0 deletions docs/en_US/database_dialog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ Use the fields in the *General* tab to identify the database:

* Use the *Database* field to add a descriptive name for the database. The name
will be displayed in the *pgAdmin* tree control.
* Use the *OID* field to specify the object identifier to be used for the new
database. Users can specify the value greater than 16383. This option is available
from v15 and above.
* Select the owner of the database from the drop-down listbox in the *Owner*
field.
* Store notes about the database in the *Comment* field.
Expand All @@ -38,11 +41,22 @@ Use the *Definition* tab to set properties for the database:
* Select a tablespace from the drop-down listbox in the *Tablespace* field. The
selected tablespace will be the default tablespace used to contain database
objects.
* Select the strategy from the drop-down listbox in the *Strategy* field while
creating a new database. This option is available from v15 and above.
* Select the locale provider from the drop-down listbox in the *Locale Provider*
field to set the default collation for this database. Possible values are: icu, libc.
This option is available from v15 and above.
* Select the collation order from the drop-down listbox in the *Collation* field.
* Select the character classification from the drop-down listbox in the
*Character Type* field. This affects the categorization of characters, e.g.
lower, upper and digit. The default, or a blank field, uses the character
classification of the template database.
* Select the icu locale from the drop-down listbox in the *ICU Locale* to
specifies the ICU locale ID if the ICU locale provider is used.
This option is available from v15 and above.
* Specify the icu rules in the *ICU Rules* field as additional collation
rules to customize the behavior of the default collation of this database.
This option is available from v16 and above.
* Specify a connection limit in the *Connection Limit* field to configure the
maximum number of connection requests. The default value (*-1*) allows
unlimited connections to the database.
Expand Down
Binary file modified docs/en_US/images/database_advanced.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/en_US/images/database_definition.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/en_US/images/database_general.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/en_US/images/database_parameters.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/en_US/images/database_security.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/en_US/images/database_sql.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 2 additions & 0 deletions docs/en_US/release_notes_7_7.rst
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,12 @@ New features
************

| `Issue #4805 <https://github.com/pgadmin-org/pgadmin4/issues/4805>`_ - Added all the new options of the 'WITH' clause in the subscription dialog.
| `Issue #6383 <https://github.com/pgadmin-org/pgadmin4/issues/6383>`_ - Added Strategy, Locale Provider, ICU Locale, ICU Rules, and OID options while creating a database.
Housekeeping
************

| `Issue #2411 <https://github.com/pgadmin-org/pgadmin4/issues/2411>`_ - Added the 'data type' column in the properties tab of the Columns collection node.
Bug fixes
*********
Expand Down
34 changes: 33 additions & 1 deletion web/pgadmin/browser/server_groups/servers/databases/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,10 @@ class DatabaseView(PGChildNodeView):
{'get': 'get_ctypes'},
{'get': 'get_ctypes'}
],
'get_icu_locale': [
{'get': 'get_icu_locale'},
{'get': 'get_icu_locale'}
],
'vopts': [
{}, {'get': 'variable_options'}
],
Expand Down Expand Up @@ -634,7 +638,7 @@ def get_ctypes(self, gid, sid, did=None):
"""
This function to return list of available collation/character types
"""
res = [{'label': '', 'value': ''}]
res = []
default_list = ['C', 'POSIX']
for val in default_list:
res.append(
Expand All @@ -656,6 +660,28 @@ def get_ctypes(self, gid, sid, did=None):
status=200
)

@check_precondition(action="get_icu_locale")
def get_icu_locale(self, gid, sid, did=None):
"""
This function is used to get the list of icu locale
"""
res = []
SQL = render_template(
"/".join([self.template_path, 'get_icu_locale.sql'])
)
status, rset = self.conn.execute_dict(SQL)
if not status:
return internal_server_error(errormsg=rset)

for row in rset['rows']:
res.append(
{'label': row['colliculocale'], 'value': row['colliculocale']})

return make_json_response(
data=res,
status=200
)

@check_precondition(action="create")
def create(self, gid, sid):
"""Create the database."""
Expand Down Expand Up @@ -1230,6 +1256,12 @@ def sql(self, gid, sid, did):
did=did, conn=conn, last_system_oid=0,
show_system_objects=False,
)

# try to connect the db if not connected
# don't delete the below code as it is needed for Database RESQL tests.
if not conn.connected():
conn.connect()

status, res = conn.execute_dict(SQL)

if not status:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,10 @@ define('pgadmin.node.database', [
cacheLevel: 'server',
});

let icu_locale = ()=>getNodeAjaxOptions('get_icu_locale', this, treeNodeInfo, itemNodeData, {
cacheLevel: 'server',
});

return new DatabaseSchema(
()=>getNodeVariableSchema(this, treeNodeInfo, itemNodeData, false, true),
(privileges)=>getNodePrivilegeRoleSchema(this, treeNodeInfo, itemNodeData, privileges),
Expand Down Expand Up @@ -360,6 +364,7 @@ define('pgadmin.node.database', [
}),
datcollate: c_types,
datctype: c_types,
daticulocale: icu_locale,
},
{
datowner: pgBrowser.serverInfo[treeNodeInfo.server._id].user.name,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ export default class DatabaseSchema extends BaseUISchema {
char_type: undefined,
datconnlimit: -1,
datallowconn: undefined,
datlocaleprovider: 'libc',
variables: [],
privileges: [],
securities: [],
Expand All @@ -82,6 +83,7 @@ export default class DatabaseSchema extends BaseUISchema {
spcname: [],
datcollate: [],
datctype: [],
daticulocale: [],
...fieldOptions,
};
}
Expand All @@ -100,6 +102,9 @@ export default class DatabaseSchema extends BaseUISchema {
id: 'did', label: gettext('OID'), cell: 'text', mode: ['properties'],
editable: false, type: 'text',
},{
id: 'datoid', label: gettext('OID'), mode: ['create'], type: 'int',
min: 16384, min_version: 150000
}, {
id: 'datowner', label: gettext('Owner'),
editable: false, type: 'select', options: this.fieldOptions.role,
controlProps: { allowClear: false }, isCollectionProperty: true,
Expand All @@ -125,17 +130,90 @@ export default class DatabaseSchema extends BaseUISchema {
editable: false, type: 'select', group: gettext('Definition'),
options: this.fieldOptions.spcname,
controlProps: { allowClear: false },
},{
id: 'datstrategy', label: gettext('Strategy'),
editable: false, type: 'select', group: gettext('Definition'),
readonly: function(state) {return !obj.isNew(state); },
mode: ['create'],
options: [{
label: gettext('WAL Log'),
value: 'wal_log',
}, {
label: gettext('File Copy'),
value: 'file_copy',
}],
min_version: 150000
}, {
id: 'datlocaleprovider', label: gettext('Locale Provider'),
editable: false, type: 'select', group: gettext('Definition'),
readonly: function(state) {return !obj.isNew(state); },
controlProps: { allowClear: false },
options: [{
label: gettext('icu'),
value: 'icu',
}, {
label: gettext('libc'),
value: 'libc',
}],
min_version: 150000
},{
id: 'datcollate', label: gettext('Collation'),
editable: false, type: 'select', group: gettext('Definition'),
readonly: function(state) {return !obj.isNew(state); },
options: this.fieldOptions.datcollate,
deps: ['datlocaleprovider'],
depChange: (state)=>{
if (state.datlocaleprovider !== 'libc')
return { datcollate: '' };
},
disabled: function(state) {
return state.datlocaleprovider !== 'libc';
},
},{
id: 'datctype', label: gettext('Character type'),
editable: false, type: 'select', group: gettext('Definition'),
readonly: function(state) {return !obj.isNew(state); },
options: this.fieldOptions.datctype,
deps: ['datlocaleprovider'],
depChange: (state)=>{
if (state.datlocaleprovider !== 'libc')
return { datctype: '' };
},
disabled: function(state) {
return state.datlocaleprovider !== 'libc';
},
},{
id: 'daticulocale', label: gettext('ICU Locale'),
editable: false, type: 'select', group: gettext('Definition'),
readonly: function(state) {return !obj.isNew(state); },
options: this.fieldOptions.daticulocale,
deps: ['datlocaleprovider'],
depChange: (state)=>{
if (state.datlocaleprovider !== 'icu')
return { daticulocale: '' };
},
disabled: function(state) {
return state.datlocaleprovider !== 'icu';
},
min_version: 150000
}, {
id: 'datcollversion', label: gettext('Collation Version'),
editable: false, type: 'text', group: gettext('Definition'),
mode: ['properties'], min_version: 150000
}, {
id: 'daticurules', label: gettext('ICU Rules'),
editable: false, type: 'text', group: gettext('Definition'),
readonly: function(state) {return !obj.isNew(state); },
deps: ['datlocaleprovider'],
depChange: (state)=>{
if (state.datlocaleprovider !== 'icu')
return { daticurules: '' };
},
disabled: function(state) {
return state.datlocaleprovider !== 'icu';
},
min_version: 160000
}, {
id: 'datconnlimit', label: gettext('Connection limit'),
editable: false, type: 'int', group: gettext('Definition'),
min: -1,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{% if data %}
CREATE DATABASE {{ conn|qtIdent(data.name) }}
{% if data.datowner %}
WITH{% endif %}{% if data.datowner %}

OWNER = {{ conn|qtIdent(data.datowner) }}{% endif %}{% if data.template %}

TEMPLATE = {{ conn|qtIdent(data.template) }}{% endif %}{% if data.encoding %}

ENCODING = {{ data.encoding|qtLiteral(conn) }}{% endif %}{% if data.datstrategy %}

STRATEGY = {{ data.datstrategy|qtLiteral(conn) }}{% endif %}{% if data.datcollate %}

LC_COLLATE = {{ data.datcollate|qtLiteral(conn) }}{% endif %}{% if data.datctype %}

LC_CTYPE = {{ data.datctype|qtLiteral(conn) }}{% endif %}{% if data.daticulocale %}

ICU_LOCALE = {{ data.daticulocale|qtLiteral(conn) }}{% endif %}{% if data.datlocaleprovider %}

LOCALE_PROVIDER = {{ data.datlocaleprovider|qtLiteral(conn) }}{% endif %}{% if data.spcname %}

TABLESPACE = {{ conn|qtIdent(data.spcname) }}{% endif %}{% if data.datconnlimit %}

CONNECTION LIMIT = {{ data.datconnlimit }}{% endif %}{% if data.datoid %}

OID = {{ data.datoid }}{% endif %}

IS_TEMPLATE = {{ data.is_template }};
{% endif %}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
SELECT colliculocale from pg_collation where collprovider = 'i'
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
SELECT
db.oid AS did, db.oid, db.datname AS name, db.dattablespace AS spcoid,
spcname, datallowconn, pg_catalog.pg_encoding_to_char(encoding) AS encoding,
pg_catalog.pg_get_userbyid(datdba) AS datowner,
(select pg_catalog.current_setting('lc_collate')) as datcollate,
(select pg_catalog.current_setting('lc_ctype')) as datctype,
CASE WHEN datlocprovider = 'i' THEN 'icu' ELSE 'libc' END datlocaleprovider,
daticulocale, datcollversion,
datconnlimit,
pg_catalog.has_database_privilege(db.oid, 'CREATE') AS cancreate,
pg_catalog.current_setting('default_tablespace') AS default_tablespace,
descr.description AS comments, db.datistemplate AS is_template,
{### Default ACL for Tables ###}
'' AS tblacl,
{### Default ACL for Sequnces ###}
'' AS seqacl,
{### Default ACL for Functions ###}
'' AS funcacl,
pg_catalog.array_to_string(datacl::text[], ', ') AS acl
FROM pg_catalog.pg_database db
LEFT OUTER JOIN pg_catalog.pg_tablespace ta ON db.dattablespace=ta.OID
LEFT OUTER JOIN pg_catalog.pg_shdescription descr ON (
db.oid=descr.objoid AND descr.classoid='pg_database'::regclass
)
WHERE
{% if show_user_defined_templates is defined %}
db.datistemplate = {{show_user_defined_templates}} AND
{% endif %}
{% if did %}
db.oid = {{ did|qtLiteral(conn) }}::OID
{% else %}
{% if name %}
db.datname = {{ name|qtLiteral(conn) }}::text
{% endif %}
{% endif %}

{% if db_restrictions %}
{% if did or name %}AND{% endif %}
db.datname in ({{db_restrictions}})
{% elif not did and not name%}
db.oid > {{ last_system_oid }}::OID OR db.datname IN ('postgres', 'edb')
{% endif %}

ORDER BY datname;
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
{% if data %}
CREATE DATABASE {{ conn|qtIdent(data.name) }}
{% if data.datowner %}
WITH{% endif %}{% if data.datowner %}

OWNER = {{ conn|qtIdent(data.datowner) }}{% endif %}{% if data.template %}

TEMPLATE = {{ conn|qtIdent(data.template) }}{% endif %}{% if data.encoding %}

ENCODING = {{ data.encoding|qtLiteral(conn) }}{% endif %}{% if data.datstrategy %}

STRATEGY = {{ data.datstrategy|qtLiteral(conn) }}{% endif %}{% if data.datcollate %}

LC_COLLATE = {{ data.datcollate|qtLiteral(conn) }}{% endif %}{% if data.datctype %}

LC_CTYPE = {{ data.datctype|qtLiteral(conn) }}{% endif %}{% if data.daticulocale %}

ICU_LOCALE = {{ data.daticulocale|qtLiteral(conn) }}{% endif %}{% if data.daticurules %}

ICU_RULES = {{ data.daticurules|qtLiteral(conn) }}{% endif %}{% if data.datlocaleprovider %}

LOCALE_PROVIDER = {{ data.datlocaleprovider|qtLiteral(conn) }}{% endif %}{% if data.spcname %}

TABLESPACE = {{ conn|qtIdent(data.spcname) }}{% endif %}{% if data.datconnlimit %}

CONNECTION LIMIT = {{ data.datconnlimit }}{% endif %}{% if data.datoid %}

OID = {{ data.datoid }}{% endif %}

IS_TEMPLATE = {{ data.is_template }};
{% endif %}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ SELECT
db.oid AS did, db.oid, db.datname AS name, db.dattablespace AS spcoid,
spcname, datallowconn, pg_catalog.pg_encoding_to_char(encoding) AS encoding,
pg_catalog.pg_get_userbyid(datdba) AS datowner, db.datcollate, db.datctype,
datconnlimit,
datconnlimit, daticulocale, daticurules, datcollversion,
CASE WHEN datlocprovider = 'i' THEN 'icu' ELSE 'libc' END datlocaleprovider,
pg_catalog.has_database_privilege(db.oid, 'CREATE') AS cancreate,
pg_catalog.current_setting('default_tablespace') AS default_tablespace,
descr.description AS comments, db.datistemplate AS is_template,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
-- Database: <TEST_DB_NAME>

-- DROP DATABASE IF EXISTS <TEST_DB_NAME>;

CREATE DATABASE <TEST_DB_NAME>
WITH
OWNER = postgres
ENCODING = 'UTF8'
LC_COLLATE = '<LC_COLLATE>'
LC_CTYPE = '<LC_CTYPE>'
LOCALE_PROVIDER = 'libc'
TABLESPACE = pg_default
CONNECTION LIMIT = -1
IS_TEMPLATE = False;

ALTER DEFAULT PRIVILEGES FOR ROLE postgres REVOKE EXECUTE ON FUNCTIONS FROM PUBLIC;
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
-- Database: <TEST_DB_NAME>

-- DROP DATABASE IF EXISTS <TEST_DB_NAME>;

CREATE DATABASE <TEST_DB_NAME>
WITH
OWNER = postgres
ENCODING = 'UTF8'
LC_COLLATE = '<LC_COLLATE>'
LC_CTYPE = '<LC_CTYPE>'
LOCALE_PROVIDER = 'libc'
TABLESPACE = pg_default
CONNECTION LIMIT = -1
IS_TEMPLATE = False;
Loading

0 comments on commit c0b868b

Please sign in to comment.