From f4cb4fe3cc10ba2f835ac4f2289494d645fea3e1 Mon Sep 17 00:00:00 2001 From: ivan-pelly Date: Wed, 18 Feb 2026 06:15:53 -0800 Subject: [PATCH] Database objects initial check in --- db/Objects/tables/goal.sql | 18 ++ db/Objects/tables/health_note.sql | 12 ++ db/Objects/tables/password_history.sql | 9 + db/Objects/tables/password_reset_token.sql | 14 ++ db/Objects/tables/permission.sql | 9 + db/Objects/tables/program.sql | 10 + db/Objects/tables/progress_event.sql | 17 ++ db/Objects/tables/progress_report.sql | 17 ++ db/Objects/tables/role.sql | 7 + db/Objects/tables/role_permission.sql | 10 + db/Objects/tables/school_district.sql | 7 + db/Objects/tables/student.sql | 12 ++ db/Objects/tables/user.sql | 14 ++ db/Objects/tables/user_program.sql | 13 ++ db/Objects/tables/user_student.sql | 12 ++ db/dump-objects.ps1 | 232 +++++++++++++++++++++ 16 files changed, 413 insertions(+) create mode 100644 db/Objects/tables/goal.sql create mode 100644 db/Objects/tables/health_note.sql create mode 100644 db/Objects/tables/password_history.sql create mode 100644 db/Objects/tables/password_reset_token.sql create mode 100644 db/Objects/tables/permission.sql create mode 100644 db/Objects/tables/program.sql create mode 100644 db/Objects/tables/progress_event.sql create mode 100644 db/Objects/tables/progress_report.sql create mode 100644 db/Objects/tables/role.sql create mode 100644 db/Objects/tables/role_permission.sql create mode 100644 db/Objects/tables/school_district.sql create mode 100644 db/Objects/tables/student.sql create mode 100644 db/Objects/tables/user.sql create mode 100644 db/Objects/tables/user_program.sql create mode 100644 db/Objects/tables/user_student.sql create mode 100644 db/dump-objects.ps1 diff --git a/db/Objects/tables/goal.sql b/db/Objects/tables/goal.sql new file mode 100644 index 0000000..c63dae3 --- /dev/null +++ b/db/Objects/tables/goal.sql @@ -0,0 +1,18 @@ +CREATE TABLE `goal` ( + `id_goal` int NOT NULL, + `id_goal_parent` int DEFAULT NULL, + `id_student` int DEFAULT NULL, + `id_user_created` int DEFAULT NULL, + `title` varchar(255) DEFAULT NULL, + `description` text, + `category` varchar(100) DEFAULT NULL, + `created_at` timestamp NULL DEFAULT NULL, + `updated_at` timestamp NULL DEFAULT NULL, + PRIMARY KEY (`id_goal`), + KEY `id_goal_parent` (`id_goal_parent`), + KEY `id_student` (`id_student`), + KEY `id_user_created` (`id_user_created`), + CONSTRAINT `goal_ibfk_1` FOREIGN KEY (`id_goal_parent`) REFERENCES `goal` (`id_goal`), + CONSTRAINT `goal_ibfk_2` FOREIGN KEY (`id_student`) REFERENCES `student` (`id_student`), + CONSTRAINT `goal_ibfk_3` FOREIGN KEY (`id_user_created`) REFERENCES `user` (`id_user`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; diff --git a/db/Objects/tables/health_note.sql b/db/Objects/tables/health_note.sql new file mode 100644 index 0000000..a80dd49 --- /dev/null +++ b/db/Objects/tables/health_note.sql @@ -0,0 +1,12 @@ +CREATE TABLE `health_note` ( + `id_health_note` int NOT NULL, + `id_student` int DEFAULT NULL, + `id_user_created` int DEFAULT NULL, + `content` text, + `created_at` timestamp NULL DEFAULT NULL, + PRIMARY KEY (`id_health_note`), + KEY `id_student` (`id_student`), + KEY `id_user_created` (`id_user_created`), + CONSTRAINT `health_note_ibfk_1` FOREIGN KEY (`id_student`) REFERENCES `student` (`id_student`), + CONSTRAINT `health_note_ibfk_2` FOREIGN KEY (`id_user_created`) REFERENCES `user` (`id_user`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; diff --git a/db/Objects/tables/password_history.sql b/db/Objects/tables/password_history.sql new file mode 100644 index 0000000..1e38ad1 --- /dev/null +++ b/db/Objects/tables/password_history.sql @@ -0,0 +1,9 @@ +CREATE TABLE `password_history` ( + `id_password_history` int NOT NULL, + `id_user` int DEFAULT NULL, + `password_hash` varchar(255) NOT NULL, + `created_at` timestamp NULL DEFAULT NULL, + PRIMARY KEY (`id_password_history`), + KEY `idx_user_created` (`id_user`,`created_at`), + CONSTRAINT `password_history_ibfk_1` FOREIGN KEY (`id_user`) REFERENCES `user` (`id_user`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; diff --git a/db/Objects/tables/password_reset_token.sql b/db/Objects/tables/password_reset_token.sql new file mode 100644 index 0000000..36adeb4 --- /dev/null +++ b/db/Objects/tables/password_reset_token.sql @@ -0,0 +1,14 @@ +CREATE TABLE `password_reset_token` ( + `id_password_reset_token` int NOT NULL, + `id_user` int DEFAULT NULL, + `token_hash` varchar(255) DEFAULT NULL, + `expires_at` timestamp NOT NULL, + `created_at` timestamp NULL DEFAULT NULL, + `used_at` timestamp NULL DEFAULT NULL, + `invalidated_at` timestamp NULL DEFAULT NULL, + `request_ip` varchar(45) DEFAULT NULL, + PRIMARY KEY (`id_password_reset_token`), + UNIQUE KEY `uq_token_hash` (`token_hash`), + KEY `idx_user_created` (`id_user`,`created_at`), + CONSTRAINT `password_reset_token_ibfk_1` FOREIGN KEY (`id_user`) REFERENCES `user` (`id_user`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; diff --git a/db/Objects/tables/permission.sql b/db/Objects/tables/permission.sql new file mode 100644 index 0000000..e602a4e --- /dev/null +++ b/db/Objects/tables/permission.sql @@ -0,0 +1,9 @@ +CREATE TABLE `permission` ( + `id_permission` int NOT NULL, + `name` varchar(100) DEFAULT NULL, + `description` text, + `resource` varchar(100) DEFAULT NULL, + `action` varchar(50) DEFAULT NULL, + `scope` varchar(50) DEFAULT NULL, + PRIMARY KEY (`id_permission`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; diff --git a/db/Objects/tables/program.sql b/db/Objects/tables/program.sql new file mode 100644 index 0000000..8c55278 --- /dev/null +++ b/db/Objects/tables/program.sql @@ -0,0 +1,10 @@ +CREATE TABLE `program` ( + `id_program` int NOT NULL, + `id_school_district` int DEFAULT NULL, + `name` varchar(255) DEFAULT NULL, + `description` text, + `created_at` timestamp NULL DEFAULT NULL, + PRIMARY KEY (`id_program`), + KEY `id_school_district` (`id_school_district`), + CONSTRAINT `program_ibfk_1` FOREIGN KEY (`id_school_district`) REFERENCES `school_district` (`id_school_district`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; diff --git a/db/Objects/tables/progress_event.sql b/db/Objects/tables/progress_event.sql new file mode 100644 index 0000000..b6ab03d --- /dev/null +++ b/db/Objects/tables/progress_event.sql @@ -0,0 +1,17 @@ +CREATE TABLE `progress_event` ( + `id_progress_event` int NOT NULL, + `id_student` int DEFAULT NULL, + `id_goal` int DEFAULT NULL, + `id_user_created` int DEFAULT NULL, + `content` text, + `is_sensitive` tinyint(1) DEFAULT NULL, + `created_at` timestamp NULL DEFAULT NULL, + `updated_at` timestamp NULL DEFAULT NULL, + PRIMARY KEY (`id_progress_event`), + KEY `id_student` (`id_student`), + KEY `id_goal` (`id_goal`), + KEY `id_user_created` (`id_user_created`), + CONSTRAINT `progress_event_ibfk_1` FOREIGN KEY (`id_student`) REFERENCES `student` (`id_student`), + CONSTRAINT `progress_event_ibfk_2` FOREIGN KEY (`id_goal`) REFERENCES `goal` (`id_goal`), + CONSTRAINT `progress_event_ibfk_3` FOREIGN KEY (`id_user_created`) REFERENCES `user` (`id_user`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; diff --git a/db/Objects/tables/progress_report.sql b/db/Objects/tables/progress_report.sql new file mode 100644 index 0000000..d113573 --- /dev/null +++ b/db/Objects/tables/progress_report.sql @@ -0,0 +1,17 @@ +CREATE TABLE `progress_report` ( + `id_progress_report` int NOT NULL, + `id_student` int DEFAULT NULL, + `id_goal` int DEFAULT NULL, + `id_user_created` int DEFAULT NULL, + `period` varchar(10) DEFAULT NULL, + `year` int DEFAULT NULL, + `summary` text, + `generated_at` timestamp NULL DEFAULT NULL, + PRIMARY KEY (`id_progress_report`), + KEY `id_student` (`id_student`), + KEY `id_goal` (`id_goal`), + KEY `id_user_created` (`id_user_created`), + CONSTRAINT `progress_report_ibfk_1` FOREIGN KEY (`id_student`) REFERENCES `student` (`id_student`), + CONSTRAINT `progress_report_ibfk_2` FOREIGN KEY (`id_goal`) REFERENCES `goal` (`id_goal`), + CONSTRAINT `progress_report_ibfk_3` FOREIGN KEY (`id_user_created`) REFERENCES `user` (`id_user`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; diff --git a/db/Objects/tables/role.sql b/db/Objects/tables/role.sql new file mode 100644 index 0000000..f39790b --- /dev/null +++ b/db/Objects/tables/role.sql @@ -0,0 +1,7 @@ +CREATE TABLE `role` ( + `id_role` int NOT NULL, + `name` varchar(100) DEFAULT NULL, + `description` text, + `created_at` timestamp NULL DEFAULT NULL, + PRIMARY KEY (`id_role`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; diff --git a/db/Objects/tables/role_permission.sql b/db/Objects/tables/role_permission.sql new file mode 100644 index 0000000..8f683dc --- /dev/null +++ b/db/Objects/tables/role_permission.sql @@ -0,0 +1,10 @@ +CREATE TABLE `role_permission` ( + `id_role_permission` int NOT NULL, + `id_role` int DEFAULT NULL, + `id_permission` int DEFAULT NULL, + PRIMARY KEY (`id_role_permission`), + KEY `id_role` (`id_role`), + KEY `id_permission` (`id_permission`), + CONSTRAINT `role_permission_ibfk_1` FOREIGN KEY (`id_role`) REFERENCES `role` (`id_role`), + CONSTRAINT `role_permission_ibfk_2` FOREIGN KEY (`id_permission`) REFERENCES `permission` (`id_permission`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; diff --git a/db/Objects/tables/school_district.sql b/db/Objects/tables/school_district.sql new file mode 100644 index 0000000..a82e78a --- /dev/null +++ b/db/Objects/tables/school_district.sql @@ -0,0 +1,7 @@ +CREATE TABLE `school_district` ( + `id_school_district` int NOT NULL, + `name` varchar(255) DEFAULT NULL, + `contact_email` varchar(255) DEFAULT NULL, + `created_at` timestamp NULL DEFAULT NULL, + PRIMARY KEY (`id_school_district`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; diff --git a/db/Objects/tables/student.sql b/db/Objects/tables/student.sql new file mode 100644 index 0000000..5212f8c --- /dev/null +++ b/db/Objects/tables/student.sql @@ -0,0 +1,12 @@ +CREATE TABLE `student` ( + `id_student` int NOT NULL, + `id_program` int DEFAULT NULL, + `identifier` varchar(50) DEFAULT NULL, + `program_year` int DEFAULT NULL, + `enrollment_date` date DEFAULT NULL, + `expected_grad` date DEFAULT NULL, + `created_at` timestamp NULL DEFAULT NULL, + PRIMARY KEY (`id_student`), + KEY `id_program` (`id_program`), + CONSTRAINT `student_ibfk_1` FOREIGN KEY (`id_program`) REFERENCES `program` (`id_program`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; diff --git a/db/Objects/tables/user.sql b/db/Objects/tables/user.sql new file mode 100644 index 0000000..633b7b7 --- /dev/null +++ b/db/Objects/tables/user.sql @@ -0,0 +1,14 @@ +CREATE TABLE `user` ( + `id_user` int NOT NULL, + `id_role` int DEFAULT NULL, + `email` varchar(255) DEFAULT NULL, + `name` varchar(255) DEFAULT NULL, + `password_hash` varchar(255) DEFAULT NULL, + `password_updated_at` timestamp NULL DEFAULT NULL, + `failed_login_attempts` int DEFAULT '0', + `locked_until` timestamp NULL DEFAULT NULL, + `created_at` timestamp NULL DEFAULT NULL, + PRIMARY KEY (`id_user`), + KEY `id_role` (`id_role`), + CONSTRAINT `user_ibfk_1` FOREIGN KEY (`id_role`) REFERENCES `role` (`id_role`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; diff --git a/db/Objects/tables/user_program.sql b/db/Objects/tables/user_program.sql new file mode 100644 index 0000000..ead3e83 --- /dev/null +++ b/db/Objects/tables/user_program.sql @@ -0,0 +1,13 @@ +CREATE TABLE `user_program` ( + `id_user_program` int NOT NULL, + `id_user` int DEFAULT NULL, + `id_program` int DEFAULT NULL, + `is_primary` tinyint(1) DEFAULT '0', + `status` varchar(20) DEFAULT 'active', + `joined_at` timestamp NULL DEFAULT NULL, + PRIMARY KEY (`id_user_program`), + UNIQUE KEY `uq_user_program` (`id_user`,`id_program`), + KEY `idx_id_program` (`id_program`), + CONSTRAINT `user_program_ibfk_1` FOREIGN KEY (`id_user`) REFERENCES `user` (`id_user`), + CONSTRAINT `user_program_ibfk_2` FOREIGN KEY (`id_program`) REFERENCES `program` (`id_program`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; diff --git a/db/Objects/tables/user_student.sql b/db/Objects/tables/user_student.sql new file mode 100644 index 0000000..efcf954 --- /dev/null +++ b/db/Objects/tables/user_student.sql @@ -0,0 +1,12 @@ +CREATE TABLE `user_student` ( + `id_user_student` int NOT NULL, + `id_user` int DEFAULT NULL, + `id_student` int DEFAULT NULL, + `access_level` varchar(50) DEFAULT NULL, + `is_primary` tinyint(1) DEFAULT NULL, + PRIMARY KEY (`id_user_student`), + KEY `id_user` (`id_user`), + KEY `id_student` (`id_student`), + CONSTRAINT `user_student_ibfk_1` FOREIGN KEY (`id_user`) REFERENCES `user` (`id_user`), + CONSTRAINT `user_student_ibfk_2` FOREIGN KEY (`id_student`) REFERENCES `student` (`id_student`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; diff --git a/db/dump-objects.ps1 b/db/dump-objects.ps1 new file mode 100644 index 0000000..6945144 --- /dev/null +++ b/db/dump-objects.ps1 @@ -0,0 +1,232 @@ +# dump-objects.ps1 + +$mysql = "C:\Program Files\MySQL\MySQL Server 8.4\bin\mysql.exe" +$baseOutputDir = Join-Path $PSScriptRoot "Objects" +$database = "winstudentgoaltracker" + +# Get password once +$securePass = Read-Host "Enter MySQL password" -AsSecureString +$pass = [Runtime.InteropServices.Marshal]::PtrToStringAuto( + [Runtime.InteropServices.Marshal]::SecureStringToBSTR($securePass)) + +# Connection parameters +$connParams = @("-h", "10.66.66.1", "-P", "3309", "-u", "root", "-p$pass") + +# ============================================================================= +# CONNECTION TEST +# ============================================================================= +Write-Host "Testing connection to MySQL..." +$connTest = & $mysql @connParams -N -B --raw -e "SELECT 1" 2>&1 +if ($LASTEXITCODE -ne 0) { + Write-Host "" + Write-Host "ERROR: Could not connect to MySQL. Details:" -ForegroundColor Red + Write-Host ($connTest | Out-String).Trim() -ForegroundColor Red + Write-Host "" + Write-Host "Check your password, host (10.66.66.1), port (3309), and that the MySQL server is reachable." -ForegroundColor Yellow + exit 1 +} +Write-Host "Connection OK." -ForegroundColor Green + +# Helper function to initialize output directory +function Initialize-OutputDir { + param([string]$path) + if (Test-Path $path) { + Remove-Item "$path\*.sql" -Force + } + else { + New-Item -ItemType Directory -Path $path -Force | Out-Null + } + return (Resolve-Path $path).Path +} + +# Helper function to run mysql and clean output +function Invoke-MySqlQuery { + param([string]$query) + $raw = & $mysql @connParams -N -B --raw -e $query 2>$null + if ($LASTEXITCODE -ne 0) { return $null } + return @($raw) | ForEach-Object { $_ -replace "`r", "" } | ForEach-Object { $_.TrimEnd() } | Where-Object { $_ -ne "" } +} + +# ============================================================================= +# TABLES (includes indexes; triggers handled separately) +# ============================================================================= +$tableDir = Initialize-OutputDir "$baseOutputDir\tables" + +Write-Host "`nFetching table list..." +$tables = Invoke-MySqlQuery "SELECT TABLE_NAME FROM information_schema.TABLES WHERE TABLE_SCHEMA = '$database' AND TABLE_TYPE = 'BASE TABLE'" +$tables = @($tables | Where-Object { $_ -ne $null -and $_.Trim() -ne "" }) +Write-Host "Found $($tables.Count) tables" + +foreach ($table in $tables) { + $table = $table.Trim() + Write-Host " Dumping: $table" + + $lines = @(Invoke-MySqlQuery "SHOW CREATE TABLE ``$database``.``$table``") + if (-not $lines) { + Write-Warning "Failed to dump table: $table" + continue + } + + # SHOW CREATE TABLE: TableNameCreateStatement + $firstLineParts = $lines[0] -split "`t", 2 + $createStmt = $firstLineParts[1] + + if ($lines.Count -gt 1) { + $createStmt += "`n" + ($lines[1..($lines.Count - 1)] -join "`n") + } + + # Get triggers for this table + $triggerLines = Invoke-MySqlQuery "SELECT TRIGGER_NAME FROM information_schema.TRIGGERS WHERE EVENT_OBJECT_SCHEMA = '$database' AND EVENT_OBJECT_TABLE = '$table'" + $triggers = @($triggerLines | Where-Object { $_ -ne $null -and $_.Trim() -ne "" }) + + $triggerSql = "" + foreach ($trigger in $triggers) { + $trigger = $trigger.Trim() + $triggerDef = Invoke-MySqlQuery "SHOW CREATE TRIGGER ``$database``.``$trigger``" + if ($triggerDef) { + # SHOW CREATE TRIGGER: TriggerNamesql_modeCreateStatement... + $triggerParts = $triggerDef[0] -split "`t", 4 + $triggerCreate = $triggerParts[2] + if ($triggerDef.Count -gt 1) { + $triggerCreate += "`n" + ($triggerDef[1..($triggerDef.Count - 1)] -join "`n") + } + # Remove trailing charset columns and normalize line endings + $triggerCreate = $triggerCreate -replace "END\t.*$", "END" -replace "`r", "" -replace "\n{2,}", "`n" + $triggerSql += "`n`nDELIMITER ;;`n$triggerCreate;;`nDELIMITER ;" + } + } + + $content = "$createStmt;$triggerSql`n" + $filePath = Join-Path $tableDir "$table.sql" + [System.IO.File]::WriteAllText($filePath, $content) +} + +# ============================================================================= +# VIEWS +# ============================================================================= +$viewDir = Initialize-OutputDir "$baseOutputDir\views" + +Write-Host "`nFetching view list..." +$views = Invoke-MySqlQuery "SELECT TABLE_NAME FROM information_schema.VIEWS WHERE TABLE_SCHEMA = '$database'" +$views = @($views | Where-Object { $_ -ne $null -and $_.Trim() -ne "" }) +Write-Host "Found $($views.Count) views" + +foreach ($view in $views) { + $view = $view.Trim() + Write-Host " Dumping: $view" + + $lines = @(Invoke-MySqlQuery "SHOW CREATE VIEW ``$database``.``$view``") + if (-not $lines) { + Write-Warning "Failed to dump view: $view" + continue + } + + # SHOW CREATE VIEW: ViewNameCreateStatementcharsetcollation + $firstLineParts = $lines[0] -split "`t", 2 + $createStmt = $firstLineParts[1] + + if ($lines.Count -gt 1) { + $createStmt += "`n" + ($lines[1..($lines.Count - 1)] -join "`n") + } + + # Remove trailing charset columns if present + $createStmt = $createStmt -replace "\t[^\t]+\t[^\t]+$", "" + + # Basic formatting to break long lines + $createStmt = $createStmt -replace " select ", "`nselect " + $createStmt = $createStmt -replace " from ", "`nfrom " + $createStmt = $createStmt -replace " left join ", "`nleft join " + $createStmt = $createStmt -replace " inner join ", "`ninner join " + $createStmt = $createStmt -replace " join ", "`njoin " + $createStmt = $createStmt -replace " where ", "`nwhere " + $createStmt = $createStmt -replace " and ", "`n and " + $createStmt = $createStmt -replace " or ", "`n or " + + $content = "$createStmt;`n" + $filePath = Join-Path $viewDir "$view.sql" + [System.IO.File]::WriteAllText($filePath, $content) +} + +# ============================================================================= +# FUNCTIONS +# ============================================================================= +$functionDir = Initialize-OutputDir "$baseOutputDir\functions" + +Write-Host "`nFetching function list..." +$functions = Invoke-MySqlQuery "SELECT ROUTINE_NAME FROM information_schema.ROUTINES WHERE ROUTINE_SCHEMA = '$database' AND ROUTINE_TYPE = 'FUNCTION'" +$functions = @($functions | Where-Object { $_ -ne $null -and $_.Trim() -ne "" }) +Write-Host "Found $($functions.Count) functions" + +foreach ($func in $functions) { + $func = $func.Trim() + Write-Host " Dumping: $func" + + $lines = @(Invoke-MySqlQuery "SHOW CREATE FUNCTION ``$database``.``$func``") + if (-not $lines) { + Write-Warning "Failed to dump function: $func" + continue + } + + # SHOW CREATE FUNCTION: FuncNamesql_modeCreateStatement... + $firstLineParts = $lines[0] -split "`t", 3 + $createStmt = $firstLineParts[2] + + if ($lines.Count -gt 1) { + $createStmt += "`n" + ($lines[1..($lines.Count - 1)] -join "`n") + } + + $createStmt = $createStmt -replace "END\t.*$", "END" + + $content = "DELIMITER ;;`n$createStmt;;`nDELIMITER ;`n" + $filePath = Join-Path $functionDir "$func.sql" + [System.IO.File]::WriteAllText($filePath, $content) +} + +# ============================================================================= +# PROCEDURES +# ============================================================================= +$procedureDir = Initialize-OutputDir "$baseOutputDir\procedures" + +Write-Host "`nFetching procedure list..." +$procs = Invoke-MySqlQuery "SELECT ROUTINE_NAME FROM information_schema.ROUTINES WHERE ROUTINE_SCHEMA = '$database' AND ROUTINE_TYPE = 'PROCEDURE'" +$procs = @($procs | Where-Object { $_ -ne $null -and $_.Trim() -ne "" }) +Write-Host "Found $($procs.Count) procedures" + +foreach ($proc in $procs) { + $proc = $proc.Trim() + Write-Host " Dumping: $proc" + + $lines = @(Invoke-MySqlQuery "SHOW CREATE PROCEDURE ``$database``.``$proc``") + if (-not $lines) { + Write-Warning "Failed to dump procedure: $proc" + continue + } + + # SHOW CREATE PROCEDURE: ProcNamesql_modeCreateStatement... + $firstLineParts = $lines[0] -split "`t", 3 + $createStmt = $firstLineParts[2] + + if ($lines.Count -gt 1) { + $createStmt += "`n" + ($lines[1..($lines.Count - 1)] -join "`n") + } + + $createStmt = $createStmt -replace "END\t.*$", "END" + + $content = "DELIMITER ;;`n$createStmt;;`nDELIMITER ;`n" + $filePath = Join-Path $procedureDir "$proc.sql" + [System.IO.File]::WriteAllText($filePath, $content) +} + +# ============================================================================= +# SUMMARY +# ============================================================================= +$baseOutputDirFull = (Resolve-Path $baseOutputDir).Path +Write-Host "`n==========================================" +Write-Host "Done! Schema exported to: $baseOutputDirFull" +Write-Host " Tables: $($tables.Count)" +Write-Host " Views: $($views.Count)" +Write-Host " Functions: $($functions.Count)" +Write-Host " Procedures: $($procs.Count)" +Write-Host "==========================================" + +explorer.exe $baseOutputDirFull \ No newline at end of file