Skip to content

Commit

Permalink
Fix being able to edit tables (#411)
Browse files Browse the repository at this point in the history
* set metadata

* fix edit table

* fix breaking changes
  • Loading branch information
nasc17 authored May 24, 2023
1 parent 5d7478a commit afcefe9
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 46 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ def get(self, connection: ServerConnection, schema_name: str, object_name: str,

server = Server(connection)
result_object: Table = None
object_metadata = ObjectMetadata(server.urn_base, None, object_type, object_name, schema_name)
object_metadata = ObjectMetadata(server.urn_base, 0, object_type, object_name, schema_name)

if object_type.lower() == 'table':
result_object = server.find_table(object_metadata)
Expand Down
72 changes: 47 additions & 25 deletions ossdbtoolsservice/edit_data/update_management/row_edit.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,30 +58,52 @@ def validate_column_is_updatable(self, column_index: int):

def build_where_clause(self):

if len(self.table_metadata.key_columns) == 0:
raise TypeError(f'Table {self.table_metadata.table_name} does not have a single column that can be trusted for uniqueness')
if len(self.table_metadata.key_columns) != 0:

where_start = 'WHERE {0}'
column_name_template = '"{0}" {1}'
parameters = []
where_clauses = []

row = self.result_set.get_row(self.row_id)

for column in self.table_metadata.key_columns:
cell: DbCellValue = row[column.ordinal]

cell_data_clause = ''
column_name = column.name
if cell.is_null is True:
cell_data_clause += 'IS NULL'
elif isinstance(cell.raw_object, bytearray) or column.db_column.data_type.lower() == 'text':
cell_data_clause += 'IS NOT NULL'
else:
cell_data_clause += '= %s'
parameters.append(cell.raw_object)

where_clauses.append(column_name_template.format(column_name, cell_data_clause))
query_template = where_start.format(' AND '.join(where_clauses))
else:
where_start = 'WHERE CTID IN ( SELECT CTID FROM {0} {1} LIMIT 1)'
where_body = 'WHERE {0}'
column_name_template = '"{0}" {1}'
parameters = []
where_clauses = []

row = self.result_set.get_row(self.row_id)

for i, cell in enumerate(row):
cell_data_clause = ''
column_name = self.table_metadata.db_columns[i].column_name
if cell.is_null is True:
cell_data_clause += 'IS NULL'
elif isinstance(cell.raw_object, bytearray) or self.table_metadata.db_columns[i].data_type.lower() == 'text':
cell_data_clause += 'IS NOT NULL'
else:
cell_data_clause += '= %s'
parameters.append(cell.raw_object)

where_clauses.append(column_name_template.format(column_name, cell_data_clause))
body = where_body.format(' AND '.join(where_clauses))
query_template = where_start.format(self.table_metadata.multipart_name, body)

where_start = 'WHERE {0}'
column_name_template = '"{0}" {1}'
parameters = []
where_clauses = []

row = self.result_set.get_row(self.row_id)

for column in self.table_metadata.key_columns:
cell: DbCellValue = row[column.ordinal]

cell_data_clause = ''
column_name = column.name
if cell.is_null is True:
cell_data_clause += 'IS NULL'
elif isinstance(cell.raw_object, bytearray) or column.db_column.data_type.lower() == 'text':
cell_data_clause += 'IS NOT NULL'
else:
cell_data_clause += '= %s'
parameters.append(cell.raw_object)

where_clauses.append(column_name_template.format(column_name, cell_data_clause))

query_template = where_start.format(' AND '.join(where_clauses))
return EditScript(query_template, parameters)
48 changes: 28 additions & 20 deletions pgsmo/objects/table_objects/column/9.2_plus/nodes.sql
Original file line number Diff line number Diff line change
Expand Up @@ -5,30 +5,38 @@
# This software is released under the PostgreSQL Licence
#}
SELECT
attname as name, attnum as OID, typ.oid AS typoid, typ.typname AS datatype, attnotnull as not_null, attr.atthasdef as has_default_val
,nspname, relname, attrelid,
CASE WHEN typ.typtype = 'd' THEN typ.typtypmod ELSE atttypmod END AS typmod,
CASE WHEN atthasdef THEN (SELECT pg_get_expr(adbin, cls.oid) FROM pg_attrdef WHERE adrelid = cls.oid AND adnum = attr.attnum) ELSE NULL END AS default,
TRUE AS is_updatable, /* Supported only since PG 8.2 */
FALSE AS isprimarykey, /* Can't do ANY() on pg_index.indkey which is int2vector */
FALSE AS isunique /* Can't do ANY() on pg_index.indkey which is int2vector */
attname AS name,
attnum AS OID,
typ.oid AS typoid,
typ.typname AS datatype,
attnotnull AS not_null,
attr.atthasdef AS has_default_val,
nspname,
relname,
attrelid,
CASE WHEN typ.typtype = 'd' THEN typ.typtypmod ELSE atttypmod END AS typmod,
CASE WHEN atthasdef THEN (SELECT pg_get_expr(adbin, cls.oid) FROM pg_attrdef WHERE adrelid = cls.oid AND adnum = attr.attnum) ELSE NULL END AS default,
TRUE AS is_updatable, /* Supported only since PG 8.2 */
-- Add this expression to show if each column is a primary key column. Can't do ANY() on pg_index.indkey which is int2vector
CASE WHEN EXISTS (SELECT * FROM information_schema.key_column_usage WHERE table_schema = nspname AND table_name = relname AND column_name = attname) THEN TRUE ELSE FALSE END AS isprimarykey,
CASE WHEN EXISTS (SELECT * FROM information_schema.table_constraints WHERE table_schema = nspname AND table_name = relname AND constraint_type = 'UNIQUE' AND constraint_name IN (SELECT constraint_name FROM information_schema.constraint_column_usage WHERE table_schema = nspname AND table_name = relname AND column_name = attname)) THEN TRUE ELSE FALSE END AS isunique
FROM pg_attribute AS attr
JOIN pg_type AS typ ON attr.atttypid = typ.oid
JOIN pg_class AS cls ON cls.oid = attr.attrelid
JOIN pg_namespace AS ns ON ns.oid = cls.relnamespace
LEFT OUTER JOIN information_schema.columns AS col ON col.table_schema = nspname AND
col.table_name = relname AND
col.column_name = attname
col.table_name = relname AND
col.column_name = attname
WHERE
attr.attrelid = {{ parent_id|qtLiteral }}::oid
{% if clid %}
AND attr.attnum = {{ clid|qtLiteral }}
{% endif %}
{### To show system objects ###}
{% if not show_sys_objects %}
AND attr.attnum > 0
{% endif %}
AND atttypid <> 0 AND
relkind IN ('r', 'v', 'm') AND
NOT attisdropped
attr.attrelid = {{ parent_id|qtLiteral }}::oid
{% if clid %}
AND attr.attnum = {{ clid|qtLiteral }}
{% endif %}
{### To show system objects ###}
{% if not show_sys_objects %}
AND attr.attnum > 0
{% endif %}
AND atttypid <> 0 AND
relkind IN ('r', 'v', 'm') AND
NOT attisdropped
ORDER BY attnum

0 comments on commit afcefe9

Please sign in to comment.