mirror of
https://github.com/pgadmin-org/pgadmin4.git
synced 2025-02-25 18:55:31 -06:00
Add support for editing data in tables with OIDs but no primary keys. Fixes #2849.
This patch also updates the editor to retrieve all row values on save, thus immediately showing default values and allowing subsequent editing without a refresh.
This commit is contained in:
committed by
Dave Page
parent
61080ce513
commit
0c5a5ba9c2
@@ -15,9 +15,13 @@ WHERE
|
|||||||
{% if clid %}
|
{% if clid %}
|
||||||
AND att.attnum = {{ clid|qtLiteral }}
|
AND att.attnum = {{ clid|qtLiteral }}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{### To show system objects ###}
|
{### To show system objects ###}
|
||||||
{% if not show_sys_objects %}
|
{% if not show_sys_objects and not has_oids %}
|
||||||
AND att.attnum > 0
|
AND att.attnum > 0
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
{### To show oids in view data ###}
|
||||||
|
{% if has_oids %}
|
||||||
|
AND (att.attnum > 0 OR (att.attname = 'oid' AND att.attnum < 0))
|
||||||
|
{% endif %}
|
||||||
AND att.attisdropped IS FALSE
|
AND att.attisdropped IS FALSE
|
||||||
ORDER BY att.attnum
|
ORDER BY att.attnum
|
||||||
|
|||||||
@@ -16,8 +16,12 @@ WHERE
|
|||||||
AND att.attnum = {{ clid|qtLiteral }}
|
AND att.attnum = {{ clid|qtLiteral }}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{### To show system objects ###}
|
{### To show system objects ###}
|
||||||
{% if not show_sys_objects %}
|
{% if not show_sys_objects and not has_oids %}
|
||||||
AND att.attnum > 0
|
AND att.attnum > 0
|
||||||
|
{% endif %}
|
||||||
|
{### To show oids in view data ###}
|
||||||
|
{% if has_oids %}
|
||||||
|
AND (att.attnum > 0 OR (att.attname = 'oid' AND att.attnum < 0))
|
||||||
{% endif %}
|
{% endif %}
|
||||||
AND att.attisdropped IS FALSE
|
AND att.attisdropped IS FALSE
|
||||||
ORDER BY att.attnum
|
ORDER BY att.attnum
|
||||||
|
|||||||
@@ -433,6 +433,9 @@ def start_view_data(trans_id):
|
|||||||
sql = trans_obj.get_sql()
|
sql = trans_obj.get_sql()
|
||||||
pk_names, primary_keys = trans_obj.get_primary_keys(default_conn)
|
pk_names, primary_keys = trans_obj.get_primary_keys(default_conn)
|
||||||
|
|
||||||
|
# Fetch OIDs status
|
||||||
|
has_oids = trans_obj.has_oids(default_conn)
|
||||||
|
|
||||||
# Fetch the applied filter.
|
# Fetch the applied filter.
|
||||||
filter_applied = trans_obj.is_filter_applied()
|
filter_applied = trans_obj.is_filter_applied()
|
||||||
|
|
||||||
@@ -444,6 +447,10 @@ def start_view_data(trans_id):
|
|||||||
|
|
||||||
# Store the primary keys to the session object
|
# Store the primary keys to the session object
|
||||||
session_obj['primary_keys'] = primary_keys
|
session_obj['primary_keys'] = primary_keys
|
||||||
|
|
||||||
|
# Store the OIDs status into session object
|
||||||
|
session_obj['has_oids'] = has_oids
|
||||||
|
|
||||||
update_session_grid_transaction(trans_id, session_obj)
|
update_session_grid_transaction(trans_id, session_obj)
|
||||||
|
|
||||||
# Execute sql asynchronously
|
# Execute sql asynchronously
|
||||||
@@ -655,6 +662,8 @@ def poll(trans_id):
|
|||||||
types = {}
|
types = {}
|
||||||
client_primary_key = None
|
client_primary_key = None
|
||||||
rset = None
|
rset = None
|
||||||
|
has_oids = False
|
||||||
|
oids = None
|
||||||
|
|
||||||
# Check the transaction and connection status
|
# Check the transaction and connection status
|
||||||
status, error_msg, conn, trans_obj, session_obj = check_transaction_status(trans_id)
|
status, error_msg, conn, trans_obj, session_obj = check_transaction_status(trans_id)
|
||||||
@@ -680,6 +689,11 @@ def poll(trans_id):
|
|||||||
if 'primary_keys' in session_obj:
|
if 'primary_keys' in session_obj:
|
||||||
primary_keys = session_obj['primary_keys']
|
primary_keys = session_obj['primary_keys']
|
||||||
|
|
||||||
|
if 'has_oids' in session_obj:
|
||||||
|
has_oids = session_obj['has_oids']
|
||||||
|
if has_oids:
|
||||||
|
oids = {'oid': 'oid'}
|
||||||
|
|
||||||
# Fetch column information
|
# Fetch column information
|
||||||
columns_info = conn.get_column_info()
|
columns_info = conn.get_column_info()
|
||||||
client_primary_key = generate_client_primary_key_name(
|
client_primary_key = generate_client_primary_key_name(
|
||||||
@@ -698,7 +712,8 @@ def poll(trans_id):
|
|||||||
|
|
||||||
SQL = render_template("/".join([template_path,
|
SQL = render_template("/".join([template_path,
|
||||||
'nodes.sql']),
|
'nodes.sql']),
|
||||||
tid=command_obj.obj_id)
|
tid=command_obj.obj_id,
|
||||||
|
has_oids=True)
|
||||||
# rows with attribute not_null
|
# rows with attribute not_null
|
||||||
colst, rset = conn.execute_2darray(SQL)
|
colst, rset = conn.execute_2darray(SQL)
|
||||||
if not colst:
|
if not colst:
|
||||||
@@ -811,7 +826,9 @@ def poll(trans_id):
|
|||||||
'colinfo': columns_info,
|
'colinfo': columns_info,
|
||||||
'primary_keys': primary_keys,
|
'primary_keys': primary_keys,
|
||||||
'types': types,
|
'types': types,
|
||||||
'client_primary_key': client_primary_key
|
'client_primary_key': client_primary_key,
|
||||||
|
'has_oids': has_oids,
|
||||||
|
'oids': oids
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -945,7 +962,7 @@ def save(trans_id):
|
|||||||
and trans_obj is not None and session_obj is not None:
|
and trans_obj is not None and session_obj is not None:
|
||||||
|
|
||||||
# If there is no primary key found then return from the function.
|
# If there is no primary key found then return from the function.
|
||||||
if len(session_obj['primary_keys']) <= 0 or len(changed_data) <= 0:
|
if (len(session_obj['primary_keys']) <= 0 or len(changed_data) <= 0) and 'has_oids' not in session_obj:
|
||||||
return make_json_response(
|
return make_json_response(
|
||||||
data={
|
data={
|
||||||
'status': False,
|
'status': False,
|
||||||
|
|||||||
@@ -364,16 +364,20 @@ class TableCommand(GridCommand):
|
|||||||
# Fetch the primary keys for the table
|
# Fetch the primary keys for the table
|
||||||
pk_names, primary_keys = self.get_primary_keys(default_conn)
|
pk_names, primary_keys = self.get_primary_keys(default_conn)
|
||||||
|
|
||||||
|
# Fetch OIDs status
|
||||||
|
has_oids = self.has_oids(default_conn)
|
||||||
|
|
||||||
sql_filter = self.get_filter()
|
sql_filter = self.get_filter()
|
||||||
|
|
||||||
if sql_filter is None:
|
if sql_filter is None:
|
||||||
sql = render_template("/".join([self.sql_path, 'objectquery.sql']), object_name=self.object_name,
|
sql = render_template("/".join([self.sql_path, 'objectquery.sql']), object_name=self.object_name,
|
||||||
nsp_name=self.nsp_name, pk_names=pk_names, cmd_type=self.cmd_type,
|
nsp_name=self.nsp_name, pk_names=pk_names, cmd_type=self.cmd_type,
|
||||||
limit=self.limit, primary_keys=primary_keys)
|
limit=self.limit, primary_keys=primary_keys, has_oids=has_oids)
|
||||||
else:
|
else:
|
||||||
sql = render_template("/".join([self.sql_path, 'objectquery.sql']), object_name=self.object_name,
|
sql = render_template("/".join([self.sql_path, 'objectquery.sql']), object_name=self.object_name,
|
||||||
nsp_name=self.nsp_name, pk_names=pk_names, cmd_type=self.cmd_type,
|
nsp_name=self.nsp_name, pk_names=pk_names, cmd_type=self.cmd_type,
|
||||||
sql_filter=sql_filter, limit=self.limit, primary_keys=primary_keys)
|
sql_filter=sql_filter, limit=self.limit, primary_keys=primary_keys,
|
||||||
|
has_oids=has_oids)
|
||||||
|
|
||||||
return sql
|
return sql
|
||||||
|
|
||||||
@@ -418,6 +422,31 @@ class TableCommand(GridCommand):
|
|||||||
def can_filter(self):
|
def can_filter(self):
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
def has_oids(self, default_conn=None):
|
||||||
|
"""
|
||||||
|
This function checks whether the table has oids or not.
|
||||||
|
"""
|
||||||
|
driver = get_driver(PG_DEFAULT_DRIVER)
|
||||||
|
if default_conn is None:
|
||||||
|
manager = driver.connection_manager(self.sid)
|
||||||
|
conn = manager.connection(did=self.did, conn_id=self.conn_id)
|
||||||
|
else:
|
||||||
|
conn = default_conn
|
||||||
|
|
||||||
|
if conn.connected():
|
||||||
|
|
||||||
|
# Fetch the table oids status
|
||||||
|
query = render_template("/".join([self.sql_path, 'has_oids.sql']), obj_id=self.obj_id)
|
||||||
|
|
||||||
|
status, has_oids = conn.execute_scalar(query)
|
||||||
|
if not status:
|
||||||
|
raise Exception(has_oids)
|
||||||
|
|
||||||
|
else:
|
||||||
|
raise Exception(gettext('Not connected to server or connection with the server has been closed.'))
|
||||||
|
|
||||||
|
return has_oids
|
||||||
|
|
||||||
def save(self,
|
def save(self,
|
||||||
changed_data,
|
changed_data,
|
||||||
columns_info,
|
columns_info,
|
||||||
@@ -464,6 +493,7 @@ class TableCommand(GridCommand):
|
|||||||
if len(changed_data[of_type]) < 1:
|
if len(changed_data[of_type]) < 1:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
|
||||||
column_type = {}
|
column_type = {}
|
||||||
column_data = {}
|
column_data = {}
|
||||||
for each_col in columns_info:
|
for each_col in columns_info:
|
||||||
@@ -481,6 +511,12 @@ class TableCommand(GridCommand):
|
|||||||
|
|
||||||
# For newly added rows
|
# For newly added rows
|
||||||
if of_type == 'added':
|
if of_type == 'added':
|
||||||
|
# Python dict does not honour the inserted item order
|
||||||
|
# So to insert data in the order, we need to make ordered list of added index
|
||||||
|
# We don't need this mechanism in updated/deleted rows as
|
||||||
|
# it does not matter in those operations
|
||||||
|
added_index = OrderedDict(sorted(changed_data['added_index'].items(),
|
||||||
|
key=lambda x: int(x[0])))
|
||||||
list_of_sql[of_type] = []
|
list_of_sql[of_type] = []
|
||||||
|
|
||||||
# When new rows are added, only changed columns data is
|
# When new rows are added, only changed columns data is
|
||||||
@@ -489,9 +525,12 @@ class TableCommand(GridCommand):
|
|||||||
# of not null which is set by default.
|
# of not null which is set by default.
|
||||||
column_data = {}
|
column_data = {}
|
||||||
pk_names, primary_keys = self.get_primary_keys()
|
pk_names, primary_keys = self.get_primary_keys()
|
||||||
|
has_oids = 'oid' in column_type
|
||||||
|
|
||||||
for each_row in changed_data[of_type]:
|
for each_row in added_index:
|
||||||
data = changed_data[of_type][each_row]['data']
|
# Get the row index to match with the added rows dict key
|
||||||
|
tmp_row_index = added_index[each_row]
|
||||||
|
data = changed_data[of_type][tmp_row_index]['data']
|
||||||
# Remove our unique tracking key
|
# Remove our unique tracking key
|
||||||
data.pop(client_primary_key, None)
|
data.pop(client_primary_key, None)
|
||||||
data.pop('is_row_copied', None)
|
data.pop('is_row_copied', None)
|
||||||
@@ -507,8 +546,16 @@ class TableCommand(GridCommand):
|
|||||||
object_name=self.object_name,
|
object_name=self.object_name,
|
||||||
nsp_name=self.nsp_name,
|
nsp_name=self.nsp_name,
|
||||||
data_type=column_type,
|
data_type=column_type,
|
||||||
pk_names=pk_names)
|
pk_names=pk_names,
|
||||||
list_of_sql[of_type].append({'sql': sql, 'data': data})
|
has_oids=has_oids)
|
||||||
|
select_sql = render_template("/".join([self.sql_path, 'select.sql']),
|
||||||
|
object_name=self.object_name,
|
||||||
|
nsp_name=self.nsp_name,
|
||||||
|
pk_names=pk_names.split(",") if pk_names else None,
|
||||||
|
has_oids=has_oids)
|
||||||
|
list_of_sql[of_type].append({'sql': sql, 'data': data,
|
||||||
|
'client_row': tmp_row_index,
|
||||||
|
'select_sql': select_sql})
|
||||||
# Reset column data
|
# Reset column data
|
||||||
column_data = {}
|
column_data = {}
|
||||||
|
|
||||||
@@ -568,13 +615,15 @@ class TableCommand(GridCommand):
|
|||||||
for opr, sqls in list_of_sql.items():
|
for opr, sqls in list_of_sql.items():
|
||||||
for item in sqls:
|
for item in sqls:
|
||||||
if item['sql']:
|
if item['sql']:
|
||||||
status, res = conn.execute_void(
|
row_added = None
|
||||||
item['sql'], item['data'])
|
|
||||||
rows_affected = conn.rows_affected()
|
|
||||||
|
|
||||||
# store the result of each query in dictionary
|
# Fetch oids/primary keys
|
||||||
query_res[count] = {'status': status, 'result': res,
|
if 'select_sql' in item and item['select_sql']:
|
||||||
'sql': sql, 'rows_affected': rows_affected}
|
status, res = conn.execute_dict(
|
||||||
|
item['sql'], item['data'])
|
||||||
|
else:
|
||||||
|
status, res = conn.execute_void(
|
||||||
|
item['sql'], item['data'])
|
||||||
|
|
||||||
if not status:
|
if not status:
|
||||||
conn.execute_void('ROLLBACK;')
|
conn.execute_void('ROLLBACK;')
|
||||||
@@ -591,6 +640,38 @@ class TableCommand(GridCommand):
|
|||||||
_rowid = 0
|
_rowid = 0
|
||||||
|
|
||||||
return status, res, query_res, _rowid
|
return status, res, query_res, _rowid
|
||||||
|
|
||||||
|
# Select added row from the table
|
||||||
|
if 'select_sql' in item:
|
||||||
|
status, sel_res = conn.execute_dict(
|
||||||
|
item['select_sql'], res['rows'][0])
|
||||||
|
|
||||||
|
if not status:
|
||||||
|
conn.execute_void('ROLLBACK;')
|
||||||
|
# If we roll backed every thing then update the message for
|
||||||
|
# each sql query.
|
||||||
|
for val in query_res:
|
||||||
|
if query_res[val]['status']:
|
||||||
|
query_res[val]['result'] = 'Transaction ROLLBACK'
|
||||||
|
|
||||||
|
# If list is empty set rowid to 1
|
||||||
|
try:
|
||||||
|
_rowid = list_of_rowid[count] if list_of_rowid else 1
|
||||||
|
except Exception:
|
||||||
|
_rowid = 0
|
||||||
|
|
||||||
|
return status, sel_res, query_res, _rowid
|
||||||
|
|
||||||
|
if 'rows' in sel_res and len(sel_res['rows']) > 0:
|
||||||
|
row_added = {item['client_row']: sel_res['rows'][0]}
|
||||||
|
|
||||||
|
rows_affected = conn.rows_affected()
|
||||||
|
|
||||||
|
# store the result of each query in dictionary
|
||||||
|
query_res[count] = {'status': status, 'result': None if row_added else res,
|
||||||
|
'sql': sql, 'rows_affected': rows_affected,
|
||||||
|
'row_added': row_added}
|
||||||
|
|
||||||
count += 1
|
count += 1
|
||||||
|
|
||||||
# Commit the transaction if there is no error found
|
# Commit the transaction if there is no error found
|
||||||
|
|||||||
@@ -599,7 +599,10 @@ define('tools.querytool', [
|
|||||||
options['width'] = column_size[table_name][c.name];
|
options['width'] = column_size[table_name][c.name];
|
||||||
}
|
}
|
||||||
// If grid is editable then add editor else make it readonly
|
// If grid is editable then add editor else make it readonly
|
||||||
if (c.cell == 'Json') {
|
if (c.cell == 'oid') {
|
||||||
|
options['editor'] = null;
|
||||||
|
}
|
||||||
|
else if (c.cell == 'Json') {
|
||||||
options['editor'] = is_editable ? Slick.Editors.JsonText
|
options['editor'] = is_editable ? Slick.Editors.JsonText
|
||||||
: Slick.Editors.ReadOnlyJsonText;
|
: Slick.Editors.ReadOnlyJsonText;
|
||||||
options['formatter'] = c.is_array ? Slick.Formatters.JsonStringArray : Slick.Formatters.JsonString;
|
options['formatter'] = c.is_array ? Slick.Formatters.JsonStringArray : Slick.Formatters.JsonString;
|
||||||
@@ -688,13 +691,14 @@ define('tools.querytool', [
|
|||||||
grid.registerPlugin(gridSelector);
|
grid.registerPlugin(gridSelector);
|
||||||
|
|
||||||
var editor_data = {
|
var editor_data = {
|
||||||
keys: self.handler.primary_keys,
|
keys: (_.isEmpty(self.handler.primary_keys) && self.handler.has_oids) ? self.handler.oids : self.handler.primary_keys,
|
||||||
vals: collection,
|
vals: collection,
|
||||||
columns: columns,
|
columns: columns,
|
||||||
grid: grid,
|
grid: grid,
|
||||||
selection: grid.getSelectionModel(),
|
selection: grid.getSelectionModel(),
|
||||||
editor: self,
|
editor: self,
|
||||||
client_primary_key: self.client_primary_key
|
client_primary_key: self.client_primary_key,
|
||||||
|
has_oids: self.handler.has_oids
|
||||||
};
|
};
|
||||||
|
|
||||||
self.handler.slickgrid = grid;
|
self.handler.slickgrid = grid;
|
||||||
@@ -820,7 +824,8 @@ define('tools.querytool', [
|
|||||||
// self.handler.data_store.updated will holds all the updated data
|
// self.handler.data_store.updated will holds all the updated data
|
||||||
var changed_column = args.grid.getColumns()[args.cell].field,
|
var changed_column = args.grid.getColumns()[args.cell].field,
|
||||||
updated_data = args.item[changed_column], // New value for current field
|
updated_data = args.item[changed_column], // New value for current field
|
||||||
_pk = args.item[self.client_primary_key] || null, // Unique key to identify row
|
_pk = args.item[self.client_primary_key] || null, // Unique key to identify row
|
||||||
|
has_oids = self.handler.has_oids || null, // Unique key to identify row
|
||||||
column_data = {},
|
column_data = {},
|
||||||
_type;
|
_type;
|
||||||
|
|
||||||
@@ -852,6 +857,7 @@ define('tools.querytool', [
|
|||||||
|
|
||||||
column_data[changed_column] = updated_data;
|
column_data[changed_column] = updated_data;
|
||||||
|
|
||||||
|
|
||||||
if (_pk) {
|
if (_pk) {
|
||||||
// Check if it is in newly added row by user?
|
// Check if it is in newly added row by user?
|
||||||
if (_pk in self.handler.data_store.added) {
|
if (_pk in self.handler.data_store.added) {
|
||||||
@@ -859,7 +865,7 @@ define('tools.querytool', [
|
|||||||
self.handler.data_store.added[_pk]['data'],
|
self.handler.data_store.added[_pk]['data'],
|
||||||
column_data);
|
column_data);
|
||||||
//Find type for current column
|
//Find type for current column
|
||||||
self.handler.data_store.added[_pk]['err'] = false
|
self.handler.data_store.added[_pk]['err'] = false;
|
||||||
// Check if it is updated data from existing rows?
|
// Check if it is updated data from existing rows?
|
||||||
} else if (_pk in self.handler.data_store.updated) {
|
} else if (_pk in self.handler.data_store.updated) {
|
||||||
_.extend(
|
_.extend(
|
||||||
@@ -1900,18 +1906,20 @@ define('tools.querytool', [
|
|||||||
_render: function (data) {
|
_render: function (data) {
|
||||||
var self = this;
|
var self = this;
|
||||||
self.colinfo = data.col_info;
|
self.colinfo = data.col_info;
|
||||||
self.primary_keys = data.primary_keys;
|
self.primary_keys = (_.isEmpty(data.primary_keys) && data.has_oids)? data.oids : data.primary_keys;
|
||||||
self.client_primary_key = data.client_primary_key;
|
self.client_primary_key = data.client_primary_key;
|
||||||
self.cell_selected = false;
|
self.cell_selected = false;
|
||||||
self.selected_model = null;
|
self.selected_model = null;
|
||||||
self.changedModels = [];
|
self.changedModels = [];
|
||||||
|
self.has_oids = data.has_oids;
|
||||||
|
self.oids = data.oids;
|
||||||
$('.sql-editor-explain').empty();
|
$('.sql-editor-explain').empty();
|
||||||
|
|
||||||
/* If object don't have primary keys then set the
|
/* If object don't have primary keys then set the
|
||||||
* can_edit flag to false.
|
* can_edit flag to false.
|
||||||
*/
|
*/
|
||||||
if (self.primary_keys === null || self.primary_keys === undefined
|
if ((self.primary_keys === null || self.primary_keys === undefined
|
||||||
|| _.size(self.primary_keys) === 0)
|
|| _.size(self.primary_keys) === 0) && self.has_oids == false)
|
||||||
self.can_edit = false;
|
self.can_edit = false;
|
||||||
else
|
else
|
||||||
self.can_edit = true;
|
self.can_edit = true;
|
||||||
@@ -2072,6 +2080,9 @@ define('tools.querytool', [
|
|||||||
}
|
}
|
||||||
// Identify cell type of column.
|
// Identify cell type of column.
|
||||||
switch (type) {
|
switch (type) {
|
||||||
|
case "oid":
|
||||||
|
col_cell = 'oid';
|
||||||
|
break;
|
||||||
case "json":
|
case "json":
|
||||||
case "json[]":
|
case "json[]":
|
||||||
case "jsonb":
|
case "jsonb":
|
||||||
@@ -2128,7 +2139,7 @@ define('tools.querytool', [
|
|||||||
'pos': c.pos,
|
'pos': c.pos,
|
||||||
'label': column_label,
|
'label': column_label,
|
||||||
'cell': col_cell,
|
'cell': col_cell,
|
||||||
'can_edit': self.can_edit,
|
'can_edit': (c.name == 'oid') ? false : self.can_edit,
|
||||||
'type': type,
|
'type': type,
|
||||||
'not_null': c.not_null,
|
'not_null': c.not_null,
|
||||||
'has_default_val': c.has_default_val,
|
'has_default_val': c.has_default_val,
|
||||||
@@ -2379,7 +2390,26 @@ define('tools.querytool', [
|
|||||||
dataView = grid.getData(),
|
dataView = grid.getData(),
|
||||||
data_length = dataView.getLength(),
|
data_length = dataView.getLength(),
|
||||||
data = [];
|
data = [];
|
||||||
|
|
||||||
if (res.data.status) {
|
if (res.data.status) {
|
||||||
|
if(is_added) {
|
||||||
|
// Update the rows in a grid after addition
|
||||||
|
dataView.beginUpdate();
|
||||||
|
_.each(res.data.query_result, function (r) {
|
||||||
|
if(!_.isNull(r.row_added)) {
|
||||||
|
// Fetch temp_id returned by server after addition
|
||||||
|
var row_id = Object.keys(r.row_added)[0];
|
||||||
|
_.each(req_data.added_index, function(v, k) {
|
||||||
|
if (v == row_id) {
|
||||||
|
// Fetch item data through row index
|
||||||
|
var item = grid.getDataItem(k);
|
||||||
|
_.extend(item, r.row_added[row_id]);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
});
|
||||||
|
dataView.endUpdate();
|
||||||
|
}
|
||||||
// Remove flag is_row_copied from copied rows
|
// Remove flag is_row_copied from copied rows
|
||||||
_.each(data, function (row, idx) {
|
_.each(data, function (row, idx) {
|
||||||
if (row.is_row_copied) {
|
if (row.is_row_copied) {
|
||||||
@@ -2412,15 +2442,6 @@ define('tools.querytool', [
|
|||||||
grid.setSelectedRows([]);
|
grid.setSelectedRows([]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// whether a cell is editable or not is decided in
|
|
||||||
// grid.onBeforeEditCell function (on cell click)
|
|
||||||
// but this function should do its job after save
|
|
||||||
// operation. So assign list of added rows to original
|
|
||||||
// rows_to_disable array.
|
|
||||||
if (is_added) {
|
|
||||||
self.rows_to_disable = _.clone(self.temp_new_rows);
|
|
||||||
}
|
|
||||||
|
|
||||||
grid.setSelectedRows([]);
|
grid.setSelectedRows([]);
|
||||||
|
|
||||||
// Reset data store
|
// Reset data store
|
||||||
|
|||||||
@@ -0,0 +1,6 @@
|
|||||||
|
{# ============= Check object has OIDs or not ============= #}
|
||||||
|
{% if obj_id %}
|
||||||
|
SELECT rel.relhasoids AS has_oids
|
||||||
|
FROM pg_class rel
|
||||||
|
WHERE rel.oid = {{ obj_id }}::oid
|
||||||
|
{% endif %}
|
||||||
@@ -5,4 +5,6 @@ INSERT INTO {{ conn|qtIdent(nsp_name, object_name) }} (
|
|||||||
) VALUES (
|
) VALUES (
|
||||||
{% for col in data_to_be_saved %}
|
{% for col in data_to_be_saved %}
|
||||||
{% if not loop.first %}, {% endif %}%({{ col }})s::{{ data_type[col] }}{% endfor %}
|
{% if not loop.first %}, {% endif %}%({{ col }})s::{{ data_type[col] }}{% endfor %}
|
||||||
);
|
)
|
||||||
|
{% if pk_names %} returning {{pk_names}}{% endif %}
|
||||||
|
{% if has_oids %} returning oid{% endif %};
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
{# SQL query for objects #}
|
{# SQL query for objects #}
|
||||||
SELECT * FROM {{ conn|qtIdent(nsp_name, object_name) }}
|
SELECT {% if has_oids %}oid, {% endif %}* FROM {{ conn|qtIdent(nsp_name, object_name) }}
|
||||||
{% if sql_filter %}
|
{% if sql_filter %}
|
||||||
WHERE {{ sql_filter }}
|
WHERE {{ sql_filter }}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
{# Select table rows #}
|
||||||
|
SELECT {% if has_oids %}oid, {% endif %}* FROM {{ conn|qtIdent(nsp_name, object_name) }}
|
||||||
|
WHERE
|
||||||
|
{% if has_oids %}
|
||||||
|
oid = %(oid)s
|
||||||
|
{% elif pk_names %}
|
||||||
|
{% for pk in pk_names %}
|
||||||
|
{% if not loop.first %} AND {% endif %}{{ conn|qtIdent(pk) }} = %({{ pk }})s{% endfor %}
|
||||||
|
{% endif %};
|
||||||
Reference in New Issue
Block a user