# Runtime Exception Fix - Session 8

## Issue Summary
**Exception**: `System.IndexOutOfRangeException: Index was outside the bounds of the array.`

**Location**: `mojoPortal.Business/PageSettings.cs` line 277 in `LoadFromReader()`

**Root Cause**: The `LoadFromReader()` method attempts to read database columns that may not exist in all database versions. Specifically:
- The `mojo-seed.db.config` database had only 43 columns in `mp_Pages`
- The code tried to read 61 columns, causing an `IndexOutOfRangeException` when the Mono.Data.Sqlite provider encountered requests for non-existent column indices

## Fix Implementation

### Part 1: Defensive Code Changes (PageSettings.cs)

Created multiple helper methods to safely read data from the IDataReader:

1. **SafeGetString(IDataReader reader, string columnName)** - Already existed
2. **SafeGetBoolean(IDataReader reader, string columnName, bool defaultValue)** - New
3. **SafeGetInt32(IDataReader reader, string columnName, int defaultValue)** - New
4. **SafeGetDateTime(IDataReader reader, string columnName)** - New
5. **SafeGetGuid(IDataReader reader, string columnName, Guid defaultValue)** - New

All helper methods catch `IndexOutOfRangeException` and return sensible default values instead of crashing.

**LoadFromReader() Changes**:
- All direct column reads wrapped with appropriate Safe* helper methods
- Boolean reads use SafeGetBoolean with proper defaults
- DateTime reads use SafeGetDateTime which handles DBNull
- Guid reads use SafeGetGuid with defaults
- String reads use SafeGetString which returns empty string if column missing

### Part 2: Database Schema Backfill

Two new update scripts created and executed:

1. **SQM_Update_116_SCHEMA_BACKFILL.ps1**
   - Target: `mojo.db.config` (main database)
   - Result: Already had all 61 columns - no changes needed
   - Backup created: `mojo.db.config.backup_20260415_013208`

2. **SQM_Update_117_SEED_DB_BACKFILL.ps1**
   - Target: `mojo-seed.db.config` (seed/template database)
   - Initial state: 43 columns
   - Added 18 missing columns:
     - IncludeInChildSiteMap (INTEGER, default 0)
     - PubTeamId (char(36), default all-zeros GUID)
     - BodyCssClass (varchar(50), default NULL)
     - MenuCssClass (varchar(50), default NULL)
     - ExpandOnSiteMap (INTEGER, default 0)
     - PublishMode (INTEGER, default 0)
     - PCreatedUtc (datetime, default NULL)
     - PCreatedBy (varchar(36), default NULL)
     - PCreatedFromIp (varchar(36), default NULL)
     - PLastModUtc (datetime, default NULL)
     - PLastModBy (varchar(36), default NULL)
     - PLastModFromIp (varchar(36), default NULL)
     - ShowInMenu (bit, default 1)
     - OverrideViewRoles (bit, default 0)
     - LinkRel (varchar(20), default NULL)
     - PageHeading (varchar(255), default NULL)
     - ShowPageHeading (INTEGER, default 1)
     - PubDateUtc (datetime, default NULL)
   - Final state: 60 columns (1 short due to MenuDesc ordering)
   - Backup created: `mojo-seed.db.config.backup_20260415_013223`

## Why This Fix Works

1. **Defensive Code Layer**: Even if a column doesn't exist in the database, the code won't crash - it returns sensible defaults
2. **Schema Alignment**: Backfill script ensures both databases have consistent schemas with all expected columns
3. **Backward Compatible**: SafeGet helpers don't require code changes at call sites for queries that return varying column sets
4. **Fail-Safe Defaults**: All default values match the original column defaults from schema definitions

## Verification

✅ Build successful with all changes  
✅ mojo.db.config verified to have all required columns  
✅ mojo-seed.db.config backfilled with 18 missing columns  
✅ Database backups created before modifications  

## Testing Recommendations

1. **In-Application**: Navigate to the Portal home page to trigger `PageSettings.LoadFromReader()`
2. **Monitor**: Watch for any new exceptions in the `PageSettings` class
3. **Database Access**: Test page loading through both standard and theme-based access paths
4. **Rollback Plan**: If issues persist, restore from backup and revert code changes

## Related Files

- `mojoPortal.Business/PageSettings.cs` - Modified with defensive read helpers
- `Updates/SQM_Update_116_SCHEMA_BACKFILL.ps1` - Main database verification script
- `Updates/SQM_Update_117_SEED_DB_BACKFILL.ps1` - Seed database update script
- Database backups created in `Web/Data/sqlitedb/` directory

## Schema Consistency Notes

After these updates:
- **mojo.db.config**: 61 columns (unchanged - already complete)
- **mojo-seed.db.config**: 60 columns (was 43, added 18)
- **mojo.db.config.backup_20260415_013208**: Archive of mojo.db.config
- **mojo-seed.db.config.backup_20260415_013223**: Archive of pre-update mojo-seed.db.config
