From 7322e9d8c201b970edab828ee75af7260cc9391a Mon Sep 17 00:00:00 2001 From: Adrian Kumpf Date: Mon, 3 Feb 2020 13:48:34 +0100 Subject: [PATCH] Set ON DELETE foreign key constraints --- docs/maintenance/manually_fixing_data.md | 19 ++++- lib/teslamate/locations.ex | 3 +- lib/teslamate/locations/geo_fence.ex | 8 +- lib/teslamate/log/drive.ex | 2 +- .../20200203120311_cascade_delete.exs | 80 +++++++++++++++++++ 5 files changed, 100 insertions(+), 12 deletions(-) create mode 100644 priv/repo/migrations/20200203120311_cascade_delete.exs diff --git a/docs/maintenance/manually_fixing_data.md b/docs/maintenance/manually_fixing_data.md index ca790231..ba2d8030 100644 --- a/docs/maintenance/manually_fixing_data.md +++ b/docs/maintenance/manually_fixing_data.md @@ -20,9 +20,20 @@ First you need to find out the ID of the drive you want to delete: Afterwards run the following query: ```sql -BEGIN; -UPDATE drives SET start_position_id = NULL, end_position_id = NULL WHERE id = 9999; -DELETE FROM positions WHERE drive_id = 9999; DELETE FROM drives WHERE id = 9999; -COMMIT; +``` + +## Delete a specific charge + +If for some reason a charge was recorded incorrectly, you can delete it manually. + +First you need to find out the ID of the charge you want to delete: + +- Open the `Charges` dashboard and click on the start date of the charge. +- The URL will contain the drive id, for example `&var-charging_process_id=9999`. + +Afterwards run the following query: + +```sql +DELETE FROM charging_processes WHERE id = 9999; ``` diff --git a/lib/teslamate/locations.ex b/lib/teslamate/locations.ex index 5840bd06..f1f715bb 100644 --- a/lib/teslamate/locations.ex +++ b/lib/teslamate/locations.ex @@ -238,8 +238,7 @@ defmodule TeslaMate.Locations do def delete_geofence(%GeoFence{} = geofence) do Repo.transaction(fn -> - with :ok <- remove_geofence(geofence), - {:ok, geofence} <- Repo.delete(geofence), + with {:ok, geofence} <- Repo.delete(geofence), :ok <- clear_cache() do geofence else diff --git a/lib/teslamate/locations/geo_fence.ex b/lib/teslamate/locations/geo_fence.ex index 22046ec4..648311fc 100644 --- a/lib/teslamate/locations/geo_fence.ex +++ b/lib/teslamate/locations/geo_fence.ex @@ -13,12 +13,10 @@ defmodule TeslaMate.Locations.GeoFence do field :longitude, :float field :radius, :float - has_many :charging_processes, ChargingProcess, - foreign_key: :geofence_id, - on_delete: :nilify_all + has_many :charging_processes, ChargingProcess, foreign_key: :geofence_id - has_many :drives_start, Drive, foreign_key: :start_geofence_id, on_delete: :nilify_all - has_many :drives_end, Drive, foreign_key: :end_geofence_id, on_delete: :nilify_all + has_many :drives_start, Drive, foreign_key: :start_geofence_id + has_many :drives_end, Drive, foreign_key: :end_geofence_id many_to_many :sleep_mode_whitelist, Car, join_through: "geofence_sleep_mode_whitelist", diff --git a/lib/teslamate/log/drive.ex b/lib/teslamate/log/drive.ex index 4bf0daa0..9cf4ebf9 100644 --- a/lib/teslamate/log/drive.ex +++ b/lib/teslamate/log/drive.ex @@ -34,7 +34,7 @@ defmodule TeslaMate.Log.Drive do belongs_to :car, Car - has_many :positions, Position, on_delete: :delete_all + has_many :positions, Position end @doc false diff --git a/priv/repo/migrations/20200203120311_cascade_delete.exs b/priv/repo/migrations/20200203120311_cascade_delete.exs new file mode 100644 index 00000000..f4d1617c --- /dev/null +++ b/priv/repo/migrations/20200203120311_cascade_delete.exs @@ -0,0 +1,80 @@ +defmodule TeslaMate.Repo.Migrations.CascadeDelete do + use Ecto.Migration + + def up do + drop(constraint(:cars, "cars_settings_id_fkey")) + + alter table(:cars) do + modify(:settings_id, references(:car_settings, on_delete: :delete_all), null: false) + end + + drop(constraint(:charges, "charges_charging_process_id_fkey")) + + alter table(:charges) do + modify(:charging_process_id, references(:charging_processes, on_delete: :delete_all), + null: false + ) + end + + drop(constraint(:charging_processes, "charging_processes_car_id_fkey")) + drop(constraint(:charging_processes, "charging_processes_address_id_fkey")) + drop(constraint(:charging_processes, "charging_processes_geofence_id_fkey")) + + alter table(:charging_processes) do + modify(:car_id, references(:cars, on_delete: :delete_all), null: false) + modify(:address_id, references(:addresses, on_delete: :nilify_all)) + modify(:geofence_id, references(:geofences, on_delete: :nilify_all)) + end + + drop_if_exists(constraint(:drives, "trips_car_id_fkey")) + drop_if_exists(constraint(:drives, "drives_car_id_fkey")) + + drop(constraint(:drives, "drives_start_position_id_fkey")) + drop(constraint(:drives, "drives_end_position_id_fkey")) + + drop_if_exists(constraint(:drives, "trips_start_address_id_fkey")) + drop_if_exists(constraint(:drives, "trips_end_address_id_fkey")) + drop_if_exists(constraint(:drives, "drives_start_address_id_fkey")) + drop_if_exists(constraint(:drives, "drives_end_address_id_fkey")) + + drop(constraint(:drives, "drives_start_geofence_id_fkey")) + drop(constraint(:drives, "drives_end_geofence_id_fkey")) + + alter table(:drives) do + modify(:car_id, references(:cars, on_delete: :delete_all), null: false) + + modify(:start_position_id, references(:positions, on_delete: :nilify_all)) + modify(:end_position_id, references(:positions, on_delete: :nilify_all)) + + modify(:start_address_id, references(:addresses, on_delete: :nilify_all)) + modify(:end_address_id, references(:addresses, on_delete: :nilify_all)) + + modify(:start_geofence_id, references(:geofences, on_delete: :nilify_all)) + modify(:end_geofence_id, references(:geofences, on_delete: :nilify_all)) + end + + drop(constraint(:positions, "positions_car_id_fkey")) + drop(constraint(:positions, "positions_drive_id_fkey")) + + alter table(:positions) do + modify(:car_id, references(:cars, on_delete: :delete_all), null: false) + modify(:drive_id, references(:drives, on_delete: :nilify_all)) + end + + drop(constraint(:states, "states_car_id_fkey")) + + alter table(:states) do + modify(:car_id, references(:cars, on_delete: :delete_all), null: false) + end + + drop(constraint(:updates, "updates_car_id_fkey")) + + alter table(:updates) do + modify(:car_id, references(:cars, on_delete: :delete_all), null: false) + end + end + + def down do + :ok + end +end