@@ -78,6 +78,19 @@ defmodule EctoTrail do
78
78
| { :error , Ecto.Changeset . t ( ) }
79
79
def update_and_log ( changeset , actor_id , opts \\ [ ] ) ,
80
80
do: EctoTrail . update_and_log ( __MODULE__ , changeset , actor_id , opts )
81
+
82
+ @ doc """
83
+ Call `c:Ecto.Repo.delete/2` operation and store deleted objext in a `change_log` table.
84
+ """
85
+ @ spec delete_and_log (
86
+ struct_or_changeset :: Ecto.Schema . t ( ) | Ecto.Changeset . t ( ) ,
87
+ actor_id :: String.T ,
88
+ opts :: Keyword . t ( )
89
+ ) ::
90
+ { :ok , Ecto.Schema . t ( ) }
91
+ | { :error , Ecto.Changeset . t ( ) }
92
+ def delete_and_log ( struct_or_changeset , actor_id , opts \\ [ ] ) ,
93
+ do: EctoTrail . delete_and_log ( __MODULE__ , struct_or_changeset , actor_id , opts )
81
94
end
82
95
end
83
96
@@ -95,7 +108,7 @@ defmodule EctoTrail do
95
108
def insert_and_log ( repo , struct_or_changeset , actor_id , opts \\ [ ] ) do
96
109
Multi . new ( )
97
110
|> Multi . insert ( :operation , struct_or_changeset , opts )
98
- |> run_logging_transaction ( repo , struct_or_changeset , actor_id )
111
+ |> run_logging_transaction ( repo , struct_or_changeset , actor_id , 1 )
99
112
end
100
113
101
114
@ doc """
@@ -114,12 +127,29 @@ defmodule EctoTrail do
114
127
def update_and_log ( repo , changeset , actor_id , opts \\ [ ] ) do
115
128
Multi . new ( )
116
129
|> Multi . update ( :operation , changeset , opts )
117
- |> run_logging_transaction ( repo , changeset , actor_id )
130
+ |> run_logging_transaction ( repo , changeset , actor_id , 2 )
118
131
end
119
132
120
- defp run_logging_transaction ( multi , repo , struct_or_changeset , actor_id ) do
133
+ @ doc """
134
+ Call `c:Ecto.Repo.delete/2` operation and store deleted objext in a `change_log` table.
135
+ """
136
+ @ spec delete_and_log (
137
+ repo :: Ecto.Repo . t ( ) ,
138
+ struct_or_changeset :: Ecto.Schema . t ( ) | Ecto.Changeset . t ( ) ,
139
+ actor_id :: String.T ,
140
+ opts :: Keyword . t ( )
141
+ ) ::
142
+ { :ok , Ecto.Schema . t ( ) }
143
+ | { :error , Ecto.Changeset . t ( ) }
144
+ def delete_and_log ( repo , struct_or_changeset , actor_id , opts \\ [ ] ) do
145
+ Multi . new ( )
146
+ |> Multi . delete ( :operation , struct_or_changeset , opts )
147
+ |> run_logging_transaction ( repo , struct_or_changeset , actor_id , 3 )
148
+ end
149
+
150
+ defp run_logging_transaction ( multi , repo , struct_or_changeset , actor_id , operation_type ) do
121
151
multi
122
- |> Multi . run ( :changelog , & log_changes ( repo , & 1 , struct_or_changeset , actor_id ) )
152
+ |> Multi . run ( :changelog , & log_changes ( repo , & 1 , struct_or_changeset , actor_id , operation_type ) )
123
153
|> repo . transaction ( )
124
154
|> build_result ( )
125
155
end
@@ -130,7 +160,7 @@ defmodule EctoTrail do
130
160
defp build_result ( { :error , :operation , reason , _changes_so_far } ) ,
131
161
do: { :error , reason }
132
162
133
- defp log_changes ( repo , multi_acc , struct_or_changeset , actor_id ) do
163
+ defp log_changes ( repo , multi_acc , struct_or_changeset , actor_id , operation_type ) do
134
164
% { operation: operation } = multi_acc
135
165
associations = operation . __struct__ . __schema__ ( :associations )
136
166
resource = operation . __struct__ . __schema__ ( :source )
@@ -141,6 +171,7 @@ defmodule EctoTrail do
141
171
|> get_changes ( )
142
172
|> get_embed_changes ( embeds )
143
173
|> get_assoc_changes ( associations )
174
+ |> validate_changes ( struct_or_changeset , operation_type )
144
175
145
176
result =
146
177
% {
@@ -166,6 +197,40 @@ defmodule EctoTrail do
166
197
end
167
198
end
168
199
200
+ defp validate_changes ( changes , schema , operation_type ) do
201
+ case operation_type do
202
+ 1 ->
203
+ # this case is entered when the operation type it's an insert operation
204
+ changes
205
+
206
+ 2 ->
207
+ # this case is entered when the operation type it's an update operation
208
+ changes
209
+
210
+ 3 ->
211
+ # this case is entered when the operation type it's a delete operation
212
+ { _ , regreso } =
213
+ Map . from_struct ( schema )
214
+ |> Map . pop ( :__meta__ )
215
+
216
+ IO . inspect ( regreso )
217
+ remove_empty_assosiations ( regreso )
218
+ end
219
+ end
220
+
221
+ defp remove_empty_assosiations ( struct ) do
222
+ new_struct =
223
+ Enum . map ( struct , fn { key , value } ->
224
+ { key ,
225
+ if String . contains? ( Kernel . inspect ( value ) , "Ecto.Association.NotLoaded" ) do
226
+ nil
227
+ else
228
+ value
229
+ end }
230
+ end )
231
+ |> Map . new ( )
232
+ end
233
+
169
234
defp get_changes ( % Changeset { changes: changes } ) ,
170
235
do: map_custom_ecto_types ( changes )
171
236
0 commit comments