diff --git a/water-api/scripts/run-migration.sh b/water-api/scripts/run-migration.sh new file mode 100755 index 0000000..a265330 --- /dev/null +++ b/water-api/scripts/run-migration.sh @@ -0,0 +1,62 @@ +#!/bin/bash + +# ============================================================================ +# Database Migration Script +# Run a specific SQL migration file against the database +# ============================================================================ + +# Colors for output +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +NC='\033[0m' # No Color + +# Load environment variables +if [ -f ../.env ]; then + export $(cat ../.env | grep -v '^#' | xargs) +else + echo -e "${RED}Error: .env file not found${NC}" + exit 1 +fi + +# Check if migration file is provided +if [ -z "$1" ]; then + echo -e "${YELLOW}Usage: ./run-migration.sh ${NC}" + echo "" + echo "Available migrations:" + ls -1 ../sql/*.sql | grep -v schema.sql + exit 1 +fi + +MIGRATION_FILE=$1 + +# Check if file exists +if [ ! -f "../sql/$MIGRATION_FILE" ]; then + echo -e "${RED}Error: Migration file not found: ../sql/$MIGRATION_FILE${NC}" + exit 1 +fi + +# Construct database URL +DB_URL="postgresql://${DB_USER}:${DB_PASSWORD}@${DB_HOST}:${DB_PORT}/${DB_NAME}" + +echo -e "${YELLOW}========================================${NC}" +echo -e "${YELLOW}Running migration: $MIGRATION_FILE${NC}" +echo -e "${YELLOW}Database: $DB_NAME${NC}" +echo -e "${YELLOW}========================================${NC}" +echo "" + +# Run the migration +psql "$DB_URL" -f "../sql/$MIGRATION_FILE" + +if [ $? -eq 0 ]; then + echo "" + echo -e "${GREEN}========================================${NC}" + echo -e "${GREEN}✓ Migration completed successfully!${NC}" + echo -e "${GREEN}========================================${NC}" +else + echo "" + echo -e "${RED}========================================${NC}" + echo -e "${RED}✗ Migration failed!${NC}" + echo -e "${RED}========================================${NC}" + exit 1 +fi diff --git a/water-api/sql/add_meter_project_relation.sql b/water-api/sql/add_meter_project_relation.sql new file mode 100644 index 0000000..ccab833 --- /dev/null +++ b/water-api/sql/add_meter_project_relation.sql @@ -0,0 +1,68 @@ +-- ============================================================================ +-- Add project_id column to meters table +-- This establishes the relationship between meters and projects +-- ============================================================================ + +-- Step 1: Add the column as nullable first (to allow existing data) +ALTER TABLE meters +ADD COLUMN IF NOT EXISTS project_id UUID; + +-- Step 2: For existing meters without project_id, try to get it from their concentrator +UPDATE meters m +SET project_id = c.project_id +FROM concentrators c +WHERE m.concentrator_id = c.id + AND m.project_id IS NULL + AND m.concentrator_id IS NOT NULL; + +-- Step 3: Add foreign key constraint +ALTER TABLE meters +DROP CONSTRAINT IF EXISTS meters_project_id_fkey; + +ALTER TABLE meters +ADD CONSTRAINT meters_project_id_fkey +FOREIGN KEY (project_id) +REFERENCES projects(id) +ON DELETE CASCADE; + +-- Step 4: Create index for better query performance +CREATE INDEX IF NOT EXISTS idx_meters_project_id ON meters(project_id); + +-- Step 5: Add comment for documentation +COMMENT ON COLUMN meters.project_id IS 'Project to which this meter belongs'; + +-- ============================================================================ +-- Verify the changes +-- ============================================================================ + +-- Check if the column was added +SELECT + column_name, + data_type, + is_nullable, + column_default +FROM information_schema.columns +WHERE table_name = 'meters' + AND column_name = 'project_id'; + +-- Check the constraint +SELECT + conname AS constraint_name, + contype AS constraint_type, + pg_get_constraintdef(oid) AS constraint_definition +FROM pg_constraint +WHERE conrelid = 'meters'::regclass + AND conname LIKE '%project_id%'; + +-- Show meters with their project info +SELECT + m.id, + m.name, + m.serial_number, + m.project_id, + p.name AS project_name, + c.name AS concentrator_name +FROM meters m +LEFT JOIN projects p ON m.project_id = p.id +LEFT JOIN concentrators c ON m.concentrator_id = c.id +LIMIT 10;