@@ -19,11 +19,12 @@ defmodule DatabaseMigration do
1919 - Set the output_file to your desired output file path.
2020 - Run the script using: elixir scripts/database_migration.exs
2121 """
22- require Logger
2322 alias Algora.Accounts.User
24- alias Algora.Workspace.Ticket
2523 alias Algora.Bounties.Bounty
2624 alias Algora.Payments.Transaction
25+ alias Algora.Workspace.Ticket
26+
27+ require Logger
2728
2829 @ table_mappings % {
2930 "User" => "users" ,
@@ -183,8 +184,6 @@ defmodule DatabaseMigration do
183184 |> Map . put ( "updated_at" , row [ "updated_at" ] )
184185 |> Map . put ( "status" , if ( row [ "succeeded_at" ] == nil , do: :initialized , else: :succeeded ) )
185186 |> Map . put ( "succeeded_at" , row [ "succeeded_at" ] )
186- else
187- nil
188187 end
189188
190189 row
@@ -195,7 +194,8 @@ defmodule DatabaseMigration do
195194 def process_dump ( input_file , output_file ) do
196195 db = collect_data ( input_file )
197196
198- File . stream! ( input_file )
197+ input_file
198+ |> File . stream! ( )
199199 |> Stream . chunk_while (
200200 [ ] ,
201201 & chunk_fun / 2 ,
@@ -208,7 +208,8 @@ defmodule DatabaseMigration do
208208 end
209209
210210 defp collect_data ( input_file ) do
211- File . stream! ( input_file )
211+ input_file
212+ |> File . stream! ( )
212213 |> Stream . chunk_while (
213214 nil ,
214215 & collect_chunk_fun / 2 ,
@@ -233,8 +234,8 @@ defmodule DatabaseMigration do
233234 |> String . split ( ", " )
234235
235236 Enum . map ( data , fn line ->
236- values = String . trim ( line ) |> String . split ( "\t " )
237- Enum . zip ( columns , values ) |> Map . new ( )
237+ values = line |> String . trim ( ) |> String . split ( "\t " )
238+ columns |> Enum . zip ( values ) |> Map . new ( )
238239 end )
239240 end
240241
@@ -257,14 +258,16 @@ defmodule DatabaseMigration do
257258 defp collect_after_fun ( { table , acc } ) , do: { :cont , { table , Enum . reverse ( acc ) } , nil }
258259
259260 defp process_chunk ( chunk , db ) do
260- case extract_copy_section ( chunk ) do
261- % { table: table } = section when table in @ relevant_tables ->
262- transform_section ( section , db )
261+ case_result =
262+ case extract_copy_section ( chunk ) do
263+ % { table: table } = section when table in @ relevant_tables ->
264+ transform_section ( section , db )
263265
264- _ ->
265- nil
266- end
267- |> load_copy_section ( )
266+ _ ->
267+ nil
268+ end
269+
270+ load_copy_section ( case_result )
268271 end
269272
270273 defp transform_section ( % { table: table , columns: _columns , data: data } , db ) do
@@ -309,8 +312,7 @@ defmodule DatabaseMigration do
309312 |> Map . new ( fn { k , v } -> { k , v } end )
310313 |> conditionally_rename_created_at ( )
311314 |> Map . take ( Enum . map ( Map . keys ( default_fields ) , & Atom . to_string / 1 ) )
312- |> Enum . map ( fn { k , v } -> { String . to_existing_atom ( k ) , v } end )
313- |> Map . new ( )
315+ |> Map . new ( fn { k , v } -> { String . to_existing_atom ( k ) , v } end )
314316
315317 # Ensure handle is unique
316318 fields = ensure_unique_handle ( fields )
@@ -368,8 +370,7 @@ defmodule DatabaseMigration do
368370 data_lines =
369371 Enum . map ( data , fn row ->
370372 columns
371- |> Enum . map ( fn col -> serialize_value ( Map . get ( row , col , "" ) ) end )
372- |> Enum . join ( "\t " )
373+ |> Enum . map_join ( "\t " , fn col -> serialize_value ( Map . get ( row , col , "" ) ) end )
373374 |> Kernel . <> ( "\n " )
374375 end )
375376
@@ -381,30 +382,29 @@ defmodule DatabaseMigration do
381382 defp serialize_value ( % Decimal { } = value ) , do: Decimal . to_string ( value )
382383
383384 defp serialize_value ( value ) when is_map ( value ) or is_list ( value ) do
384- try do
385- json = Jason . encode! ( value , escape: :json )
386- # Handle empty arrays specifically
387- if json == "[]" do
388- "{}"
389- else
390- # Escape backslashes and double quotes for PostgreSQL COPY
391- String . replace ( json , [ "\\ " , "\" " ] , fn
392- "\\ " -> "\\ \\ "
393- "\" " -> "\\ \" "
394- end )
395- end
396- rescue
397- _ ->
398- # Fallback to a safe string representation
399- inspect ( value , limit: :infinity , printable_limit: :infinity )
400- |> String . replace ( [ "\\ " , "\n " , "\r " , "\t " ] , fn
401- "\\ " -> "\\ \\ "
402- "\n " -> "\\ n"
403- "\r " -> "\\ r"
404- "\t " -> "\\ t"
405- end )
406- |> String . replace ( "\" " , "\\ \" " )
385+ json = Jason . encode! ( value , escape: :json )
386+ # Handle empty arrays specifically
387+ if json == "[]" do
388+ "{}"
389+ else
390+ # Escape backslashes and double quotes for PostgreSQL COPY
391+ String . replace ( json , [ "\\ " , "\" " ] , fn
392+ "\\ " -> "\\ \\ "
393+ "\" " -> "\\ \" "
394+ end )
407395 end
396+ rescue
397+ _ ->
398+ # Fallback to a safe string representation
399+ value
400+ |> inspect ( limit: :infinity , printable_limit: :infinity )
401+ |> String . replace ( [ "\\ " , "\n " , "\r " , "\t " ] , fn
402+ "\\ " -> "\\ \\ "
403+ "\n " -> "\\ n"
404+ "\r " -> "\\ r"
405+ "\t " -> "\\ t"
406+ end )
407+ |> String . replace ( "\" " , "\\ \" " )
408408 end
409409
410410 defp serialize_value ( value ) when is_nil ( value ) , do: "\\ N"
@@ -413,7 +413,7 @@ defmodule DatabaseMigration do
413413 # Remove any surrounding quotes for numeric values
414414 value =
415415 if String . starts_with? ( value , "\" " ) and String . ends_with? ( value , "\" " ) do
416- String . slice ( value , 1 .. - 2 )
416+ String . slice ( value , 1 .. - 2 // 1 )
417417 else
418418 value
419419 end
@@ -495,40 +495,36 @@ defmodule DatabaseMigration do
495495 defp deserialize_value ( "{}" ) , do: [ ]
496496
497497 defp deserialize_value ( value ) when is_map ( value ) do
498- value
499- |> Enum . map ( fn { k , v } -> { k , deserialize_value ( v ) } end )
500- |> Map . new ( )
498+ Map . new ( value , fn { k , v } -> { k , deserialize_value ( v ) } end )
501499 end
502500
503501 defp deserialize_value ( value ) when is_list ( value ) do
504502 Enum . map ( value , & deserialize_value / 1 )
505503 end
506504
507505 defp deserialize_value ( value ) when is_binary ( value ) do
508- cond do
509- String . starts_with? ( value , "{" ) and String . ends_with? ( value , "}" ) ->
510- value
511- |> String . slice ( 1 .. - 2 )
512- |> String . split ( "," , trim: true )
513- |> Enum . map ( & deserialize_value / 1 )
514-
515- true ->
516- case Integer . parse ( value ) do
517- { int , "" } ->
518- int
519-
520- _ ->
521- case Float . parse ( value ) do
522- { float , "" } -> float
523- _ -> value
524- end
525- end
506+ if String . starts_with? ( value , "{" ) and String . ends_with? ( value , "}" ) do
507+ value
508+ |> String . slice ( 1 .. - 2 // 1 )
509+ |> String . split ( "," , trim: true )
510+ |> Enum . map ( & deserialize_value / 1 )
511+ else
512+ case Integer . parse ( value ) do
513+ { int , "" } ->
514+ int
515+
516+ _ ->
517+ case Float . parse ( value ) do
518+ { float , "" } -> float
519+ _ -> value
520+ end
521+ end
526522 end
527523 end
528524
529525 defp deserialize_value ( value ) , do: value
530526
531- defp clear_tables! ( ) do
527+ defp clear_tables! do
532528 commands =
533529 [
534530 "BEGIN TRANSACTION;" ,
@@ -564,7 +560,7 @@ defmodule DatabaseMigration do
564560 end
565561 end
566562
567- def run! ( ) do
563+ def run! do
568564 input_file = ".local/prod_db.sql"
569565 output_file = ".local/prod_db_new.sql"
570566
0 commit comments