diff --git a/frappe/commands/test_commands.py b/frappe/commands/test_commands.py index ad00bb0933..a7974e5b61 100644 --- a/frappe/commands/test_commands.py +++ b/frappe/commands/test_commands.py @@ -244,7 +244,10 @@ class TestCommands(BaseTestCommands): self.assertEqual(self.returncode, 0) self.assertEqual(self.stdout, frappe.bold(text="DocType")) - @run_only_if(db_type_is.MARIADB) + @skipIf( + frappe.conf.db_type == "sqlite", + "Not for SQLite for now", + ) def test_restore(self): # step 0: create a site to run the test on global_config = { @@ -733,12 +736,14 @@ class TestBackups(BaseTestCommands): self.assertIsNotNone(after_backup["public"]) self.assertIsNotNone(after_backup["private"]) - @run_only_if(db_type_is.MARIADB) def test_clear_log_table(self): d = frappe.get_doc(doctype="Error Log", title="Something").insert() d.db_set("creation", "2010-01-01", update_modified=False) frappe.db.commit() - + frappe.db.sql_ddl( + IntegrationTestCase.normalize_sql("DROP TABLE IF EXISTS `tabError Log backup_table`") + ) # drop old tables if exists (Maintain Sanity) + frappe.db.sql_ddl(IntegrationTestCase.normalize_sql("DROP TABLE IF EXISTS `tabError Log temp_table`")) tables_before = frappe.db.get_tables(cached=False) self.execute("bench --site {site} clear-log-table --days=30 --doctype='Error Log'") @@ -747,7 +752,6 @@ class TestBackups(BaseTestCommands): self.assertFalse(frappe.db.exists("Error Log", d.name)) tables_after = frappe.db.get_tables(cached=False) - self.assertEqual(set(tables_before), set(tables_after)) def test_backup_with_custom_path(self): diff --git a/frappe/core/doctype/log_settings/log_settings.py b/frappe/core/doctype/log_settings/log_settings.py index d3be04ced2..afbccc853f 100644 --- a/frappe/core/doctype/log_settings/log_settings.py +++ b/frappe/core/doctype/log_settings/log_settings.py @@ -164,18 +164,30 @@ def clear_log_table(doctype, days=90): backup = f"{original} backup_table" try: - frappe.db.sql_ddl(f"CREATE TABLE `{temporary}` LIKE `{original}`") + if frappe.db.db_type == "postgres": + frappe.db.sql_ddl(f'CREATE TABLE "{temporary}" (LIKE "{original}" INCLUDING ALL)') - # Copy all recent data to new table - frappe.db.sql( - f"""INSERT INTO `{temporary}` - SELECT * FROM `{original}` - WHERE `{original}`.`creation` > NOW() - INTERVAL '{days}' DAY""" - ) - frappe.db.sql_ddl(f"RENAME TABLE `{original}` TO `{backup}`, `{temporary}` TO `{original}`") + frappe.db.sql( + f"""INSERT INTO "{temporary}" + SELECT * FROM "{original}" + WHERE "{original}"."creation" > NOW() - INTERVAL '{days}' DAY""" + ) + frappe.db.sql_ddl(f'ALTER TABLE "{original}" RENAME TO "{backup}"') + frappe.db.sql_ddl(f'ALTER TABLE "{temporary}" RENAME TO "{original}"') + elif frappe.db.db_type == "mariadb": + frappe.db.sql_ddl(f"CREATE TABLE `{temporary}` LIKE `{original}`") + + # Copy all recent data to new table + frappe.db.sql( + f"""INSERT INTO `{temporary}` + SELECT * FROM `{original}` + WHERE `{original}`.`creation` > NOW() - INTERVAL '{days}' DAY""" + ) + frappe.db.sql_ddl(f"RENAME TABLE `{original}` TO `{backup}`, `{temporary}` TO `{original}`") except Exception: frappe.db.rollback() frappe.db.sql_ddl(f"DROP TABLE IF EXISTS `{temporary}`") raise else: frappe.db.sql_ddl(f"DROP TABLE `{backup}`") + frappe.db.commit() diff --git a/frappe/database/postgres/schema.py b/frappe/database/postgres/schema.py index 75b944f74a..aca6a778f3 100644 --- a/frappe/database/postgres/schema.py +++ b/frappe/database/postgres/schema.py @@ -76,6 +76,8 @@ class PostgresTable(DBTable): query = [f"ADD COLUMN `{col.fieldname}` {col.get_definition()}" for col in self.add_column] + new_column_names = {col.fieldname for col in self.add_column} + for col in self.change_type: using_clause = "" if col.fieldtype in ("Datetime"): @@ -124,9 +126,10 @@ class PostgresTable(DBTable): for col in self.add_unique: # if index key not exists - create_contraint_query += 'CREATE UNIQUE INDEX IF NOT EXISTS "unique_{index_name}" ON `{table_name}`(`{field}`);'.format( - index_name=col.fieldname, table_name=self.table_name, field=col.fieldname - ) + if col.fieldname not in new_column_names: + create_contraint_query += 'CREATE UNIQUE INDEX IF NOT EXISTS "unique_{index_name}" ON `{table_name}`(`{field}`);'.format( + index_name=col.fieldname, table_name=self.table_name, field=col.fieldname + ) drop_contraint_query = "" for col in self.drop_index: diff --git a/frappe/database/query.py b/frappe/database/query.py index b034aa7812..94f992ed5e 100644 --- a/frappe/database/query.py +++ b/frappe/database/query.py @@ -20,6 +20,7 @@ from frappe.database.utils import ( ) from frappe.model import get_permitted_fields from frappe.model.base_document import DOCTYPES_FOR_DOCTYPE +from frappe.model.document import Document from frappe.query_builder import Criterion, Field, Order, functions from frappe.query_builder.custom import Month, MonthName, Quarter from frappe.query_builder.utils import PseudoColumnMapper @@ -454,6 +455,9 @@ class Engine: else: # Regular value processing for literal comparisons like: table.field = 'value' _value = convert_to_value(value) + + if isinstance(value, Document): + frappe.throw(_("Document cannot be used as a filter value")) _operator = operator # For Date fields with datetime values, convert to date to match db_query behavior diff --git a/frappe/public/js/frappe/list/list_view.js b/frappe/public/js/frappe/list/list_view.js index 6bf010699d..61aa03f0c8 100644 --- a/frappe/public/js/frappe/list/list_view.js +++ b/frappe/public/js/frappe/list/list_view.js @@ -2412,7 +2412,8 @@ frappe.views.ListView = class ListView extends frappe.views.BaseList { .join("\t"); }); const clipboard_data = [headers, ...rows].join("\n"); // Copy to clipboard - frappe.utils.copy_to_clipboard(clipboard_data); + const message = __("Copied {0} rows to clipboard", [selected_items.length]); + frappe.utils.copy_to_clipboard(clipboard_data, message); }, standard: true, }; diff --git a/frappe/tests/test_db_update.py b/frappe/tests/test_db_update.py index a6e483e29e..5deb94cccb 100644 --- a/frappe/tests/test_db_update.py +++ b/frappe/tests/test_db_update.py @@ -139,7 +139,6 @@ class TestDBUpdate(IntegrationTestCase): with self.subTest(f"Checking index {doctype.name} - {field.fieldname}"): self.check_unique_indexes(doctype.name, field.fieldname) - @run_only_if(db_type_is.MARIADB) def test_unique_index_on_alter(self): """Only one unique index should be added"""