Centralize credentials and make migration idempotent
- Move all DB credentials to config.asp with DSN/ODBC toggle - Add Zabbix API URL and token to centralized config - Update sql.asp, api.asp, apiusb.asp, zabbix.asp to use config - Add GetConnectionString() and GetEmployeeConnectionString() functions - Make migration SQL idempotent (safe to run multiple times) - Add duplicate index cleanup (appname_2) to migration - Document employee DB access limitation in CLAUDE.md 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -24,6 +24,7 @@ ShopDB is a Classic ASP/VBScript web application for managing manufacturing shop
|
||||
- Production IIS logs
|
||||
- Production MySQL database
|
||||
- Zabbix server (10.48.130.113)
|
||||
- Employee database (wjf_employees) - used by displayprofile.asp (can update code, cannot test)
|
||||
|
||||
For production tasks, user must:
|
||||
- Relay production data/logs to Claude
|
||||
|
||||
18
api.asp
18
api.asp
@@ -1,21 +1,13 @@
|
||||
<%@ Language=VBScript %>
|
||||
<!--#include file="includes/config.asp"-->
|
||||
<%
|
||||
' ============================================================================
|
||||
' DATABASE CONNECTION - Created directly in api.asp to avoid scoping issues
|
||||
' DATABASE CONNECTION - Uses centralized config.asp
|
||||
' ============================================================================
|
||||
Dim objConn, rs, DB_CONN_STRING
|
||||
' Use direct MySQL ODBC driver connection (same as sql.asp) instead of DSN
|
||||
DB_CONN_STRING = "Driver={MySQL ODBC 9.4 Unicode Driver};" & _
|
||||
"Server=192.168.122.1;" & _
|
||||
"Port=3306;" & _
|
||||
"Database=shopdb;" & _
|
||||
"User=570005354;" & _
|
||||
"Password=570005354;" & _
|
||||
"Option=3;" & _
|
||||
"Pooling=True;Max Pool Size=100;"
|
||||
Session.Timeout = 15
|
||||
Dim objConn, rs
|
||||
Session.Timeout = APP_SESSION_TIMEOUT
|
||||
Set objConn = Server.CreateObject("ADODB.Connection")
|
||||
objConn.ConnectionString = DB_CONN_STRING
|
||||
objConn.ConnectionString = GetConnectionString()
|
||||
objConn.Open
|
||||
Set rs = Server.CreateObject("ADODB.Recordset")
|
||||
|
||||
|
||||
19
apiusb.asp
19
apiusb.asp
@@ -1,30 +1,25 @@
|
||||
<%@ Language="VBScript" %>
|
||||
<%
|
||||
Option Explicit
|
||||
%>
|
||||
<!--#include file="includes/config.asp"-->
|
||||
<%
|
||||
'=============================================================================
|
||||
' FILE: apiusb.asp
|
||||
' PURPOSE: API endpoints for USB device operations
|
||||
' SECURITY: Parameterized queries, JSON output
|
||||
' CREATED: 2025-12-07
|
||||
'=============================================================================
|
||||
Option Explicit
|
||||
Response.ContentType = "application/json"
|
||||
Response.Charset = "utf-8"
|
||||
Response.Buffer = True
|
||||
|
||||
' Create database connection directly (avoid sql.asp scoping issues)
|
||||
Dim objConn, DB_CONN_STRING
|
||||
DB_CONN_STRING = "Driver={MySQL ODBC 9.4 Unicode Driver};" & _
|
||||
"Server=192.168.122.1;" & _
|
||||
"Port=3306;" & _
|
||||
"Database=shopdb;" & _
|
||||
"User=570005354;" & _
|
||||
"Password=570005354;" & _
|
||||
"Option=3;" & _
|
||||
"Pooling=True;Max Pool Size=100;"
|
||||
' Database connection using centralized config
|
||||
Dim objConn
|
||||
|
||||
On Error Resume Next
|
||||
Set objConn = Server.CreateObject("ADODB.Connection")
|
||||
objConn.ConnectionString = DB_CONN_STRING
|
||||
objConn.ConnectionString = GetConnectionString()
|
||||
objConn.Open
|
||||
|
||||
If Err.Number <> 0 Then
|
||||
|
||||
@@ -7,6 +7,7 @@ Option Explicit
|
||||
<head>
|
||||
<!--#include file="./includes/header.asp"-->
|
||||
<!--#include file="./includes/wjf_employees-sql.asp"-->
|
||||
<!-- Note: config.asp is included via wjf_employees-sql.asp -->
|
||||
<!-- DataTables CSS -->
|
||||
<link rel="stylesheet" href="assets/plugins/datatables/dataTables.bootstrap4.min.css">
|
||||
</head>
|
||||
@@ -280,15 +281,13 @@ END IF
|
||||
<div class="tab-pane" id="usbhistory">
|
||||
<h5 class="mb-3"><i class="zmdi zmdi-usb"></i> USB Checkout History</h5>
|
||||
<%
|
||||
' Connect to shopdb for USB history
|
||||
' Connect to shopdb for USB history (uses centralized config)
|
||||
Dim objConnShopdb, shopdbAvailable
|
||||
shopdbAvailable = False
|
||||
|
||||
On Error Resume Next
|
||||
Set objConnShopdb = Server.CreateObject("ADODB.Connection")
|
||||
objConnShopdb.ConnectionString = "Driver={MySQL ODBC 9.4 Unicode Driver};" & _
|
||||
"Server=192.168.122.1;Port=3306;Database=shopdb;" & _
|
||||
"User=570005354;Password=570005354;Option=3;"
|
||||
objConnShopdb.ConnectionString = GetConnectionString()
|
||||
objConnShopdb.Open
|
||||
If Err.Number = 0 Then
|
||||
shopdbAvailable = True
|
||||
|
||||
@@ -10,8 +10,17 @@
|
||||
'=============================================================================
|
||||
|
||||
'-----------------------------------------------------------------------------
|
||||
' Database Configuration
|
||||
' Database Configuration - ShopDB (primary)
|
||||
'-----------------------------------------------------------------------------
|
||||
' Set USE_DSN = True for production (DSN-based), False for dev (direct ODBC)
|
||||
Const USE_DSN = False
|
||||
|
||||
' DSN configuration (production)
|
||||
Const DB_DSN = "shopdb"
|
||||
Const DB_DSN_USER = "570005354"
|
||||
Const DB_DSN_PASSWORD = "570005354"
|
||||
|
||||
' Direct ODBC configuration (development)
|
||||
Const DB_DRIVER = "MySQL ODBC 9.4 Unicode Driver"
|
||||
Const DB_SERVER = "192.168.122.1"
|
||||
Const DB_PORT = "3306"
|
||||
@@ -19,6 +28,25 @@ Const DB_NAME = "shopdb"
|
||||
Const DB_USER = "570005354"
|
||||
Const DB_PASSWORD = "570005354"
|
||||
|
||||
'-----------------------------------------------------------------------------
|
||||
' Database Configuration - Employee Database
|
||||
'-----------------------------------------------------------------------------
|
||||
' Set USE_EMP_DSN = True for production (DSN-based), False for dev (direct ODBC)
|
||||
Const USE_EMP_DSN = True
|
||||
|
||||
' DSN configuration (production)
|
||||
Const EMP_DB_DSN = "wjf_employees"
|
||||
Const EMP_DB_DSN_USER = "root"
|
||||
Const EMP_DB_DSN_PASSWORD = "WJF11sql"
|
||||
|
||||
' Direct ODBC configuration (development) - configure if needed
|
||||
Const EMP_DB_DRIVER = "MySQL ODBC 9.4 Unicode Driver"
|
||||
Const EMP_DB_SERVER = "localhost"
|
||||
Const EMP_DB_PORT = "3306"
|
||||
Const EMP_DB_NAME = "wjf_employees"
|
||||
Const EMP_DB_USER = "root"
|
||||
Const EMP_DB_PASSWORD = "WJF11sql"
|
||||
|
||||
'-----------------------------------------------------------------------------
|
||||
' Application Settings
|
||||
'-----------------------------------------------------------------------------
|
||||
@@ -42,11 +70,17 @@ Const DEFAULT_MODEL_ID = 1 ' Default model
|
||||
Const DEFAULT_OS_ID = 1 ' Default operating system
|
||||
|
||||
'-----------------------------------------------------------------------------
|
||||
' External Services
|
||||
' External Services - ServiceNow
|
||||
'-----------------------------------------------------------------------------
|
||||
Const SNOW_BASE_URL = "https://geit.service-now.com/now/nav/ui/search/"
|
||||
Const SNOW_TICKET_PREFIXES = "geinc,gechg,gerit,gesct" ' Valid ServiceNow ticket prefixes
|
||||
|
||||
'-----------------------------------------------------------------------------
|
||||
' External Services - Zabbix API
|
||||
'-----------------------------------------------------------------------------
|
||||
Const ZABBIX_URL = "http://10.48.130.113:8080/api_jsonrpc.php"
|
||||
Const ZABBIX_API_TOKEN = "9e60b0544ec77131d94825eaa2f3f1645335539361fd33644aeb8326697aa48d"
|
||||
|
||||
'-----------------------------------------------------------------------------
|
||||
' File Upload
|
||||
'-----------------------------------------------------------------------------
|
||||
@@ -59,18 +93,45 @@ Const ALLOWED_EXTENSIONS = "jpg,jpeg,png,gif,pdf"
|
||||
|
||||
'-----------------------------------------------------------------------------
|
||||
' FUNCTION: GetConnectionString
|
||||
' PURPOSE: Returns the database connection string with all parameters
|
||||
' RETURNS: Complete ODBC connection string
|
||||
' PURPOSE: Returns the database connection string based on USE_DSN setting
|
||||
' RETURNS: DSN connection string (production) or direct ODBC string (dev)
|
||||
'-----------------------------------------------------------------------------
|
||||
Function GetConnectionString()
|
||||
GetConnectionString = "Driver={" & DB_DRIVER & "};" & _
|
||||
"Server=" & DB_SERVER & ";" & _
|
||||
"Port=" & DB_PORT & ";" & _
|
||||
"Database=" & DB_NAME & ";" & _
|
||||
"User=" & DB_USER & ";" & _
|
||||
"Password=" & DB_PASSWORD & ";" & _
|
||||
"Option=3;" & _
|
||||
"Pooling=True;Max Pool Size=100;"
|
||||
If USE_DSN Then
|
||||
' Production: DSN-based connection with pooling
|
||||
GetConnectionString = "DSN=" & DB_DSN & ";Uid=" & DB_DSN_USER & ";Pwd=" & DB_DSN_PASSWORD & ";Option=3;Pooling=True;Max Pool Size=100;"
|
||||
Else
|
||||
' Development: Direct ODBC driver connection
|
||||
GetConnectionString = "Driver={" & DB_DRIVER & "};" & _
|
||||
"Server=" & DB_SERVER & ";" & _
|
||||
"Port=" & DB_PORT & ";" & _
|
||||
"Database=" & DB_NAME & ";" & _
|
||||
"User=" & DB_USER & ";" & _
|
||||
"Password=" & DB_PASSWORD & ";" & _
|
||||
"Option=3;" & _
|
||||
"Pooling=True;Max Pool Size=100;"
|
||||
End If
|
||||
End Function
|
||||
|
||||
'-----------------------------------------------------------------------------
|
||||
' FUNCTION: GetEmployeeConnectionString
|
||||
' PURPOSE: Returns the employee database connection string based on USE_EMP_DSN
|
||||
' RETURNS: DSN connection string (production) or direct ODBC string (dev)
|
||||
'-----------------------------------------------------------------------------
|
||||
Function GetEmployeeConnectionString()
|
||||
If USE_EMP_DSN Then
|
||||
' Production: DSN-based connection
|
||||
GetEmployeeConnectionString = "DSN=" & EMP_DB_DSN & ";Uid=" & EMP_DB_DSN_USER & ";Pwd=" & EMP_DB_DSN_PASSWORD
|
||||
Else
|
||||
' Development: Direct ODBC driver connection
|
||||
GetEmployeeConnectionString = "Driver={" & EMP_DB_DRIVER & "};" & _
|
||||
"Server=" & EMP_DB_SERVER & ";" & _
|
||||
"Port=" & EMP_DB_PORT & ";" & _
|
||||
"Database=" & EMP_DB_NAME & ";" & _
|
||||
"User=" & EMP_DB_USER & ";" & _
|
||||
"Password=" & EMP_DB_PASSWORD & ";" & _
|
||||
"Option=3;"
|
||||
End If
|
||||
End Function
|
||||
|
||||
'-----------------------------------------------------------------------------
|
||||
|
||||
@@ -1,18 +1,9 @@
|
||||
<!--#include file="config.asp"-->
|
||||
<%
|
||||
' objConn - script-global connection object (no Dim for global scope)
|
||||
Session.Timeout=15
|
||||
Set objConn=Server.CreateObject("ADODB.Connection")
|
||||
' Old DSN connection:
|
||||
' objConn.ConnectionString="DSN=shopdb;Uid=root;Pwd=WJF11sql"
|
||||
' Direct MySQL ODBC connection with pooling enabled:
|
||||
objConn.ConnectionString="Driver={MySQL ODBC 9.4 Unicode Driver};" & _
|
||||
"Server=192.168.122.1;" & _
|
||||
"Port=3306;" & _
|
||||
"Database=shopdb;" & _
|
||||
"User=570005354;" & _
|
||||
"Password=570005354;" & _
|
||||
"Option=3;" & _
|
||||
"Pooling=True;Max Pool Size=100;"
|
||||
Session.Timeout = APP_SESSION_TIMEOUT
|
||||
Set objConn = Server.CreateObject("ADODB.Connection")
|
||||
objConn.ConnectionString = GetConnectionString()
|
||||
objConn.Open
|
||||
set rs = server.createobject("ADODB.Recordset")
|
||||
Set rs = Server.CreateObject("ADODB.Recordset")
|
||||
%>
|
||||
@@ -1,8 +1,10 @@
|
||||
<!--#include file="config.asp"-->
|
||||
<%
|
||||
' Employee database connection - uses centralized config
|
||||
Dim objConn
|
||||
Session.Timeout=15
|
||||
Set objConn=Server.CreateObject("ADODB.Connection")
|
||||
objConn.ConnectionString="DSN=wjf_employees;Uid=root;Pwd=WJF11sql"
|
||||
objConn.Open
|
||||
set rs = server.createobject("ADODB.Recordset")
|
||||
Session.Timeout = APP_SESSION_TIMEOUT
|
||||
Set objConn = Server.CreateObject("ADODB.Connection")
|
||||
objConn.ConnectionString = GetEmployeeConnectionString()
|
||||
objConn.Open
|
||||
Set rs = Server.CreateObject("ADODB.Recordset")
|
||||
%>
|
||||
@@ -1,7 +1,6 @@
|
||||
<!--#include file="config.asp"-->
|
||||
<%
|
||||
' Zabbix API Configuration
|
||||
Const ZABBIX_URL = "http://10.48.130.113:8080/api_jsonrpc.php"
|
||||
Const ZABBIX_API_TOKEN = "9e60b0544ec77131d94825eaa2f3f1645335539361fd33644aeb8326697aa48d"
|
||||
' Zabbix API Configuration - uses ZABBIX_URL and ZABBIX_API_TOKEN from config.asp
|
||||
|
||||
' Function to make HTTP POST request to Zabbix API with Bearer token
|
||||
Function ZabbixAPICall(jsonRequest)
|
||||
|
||||
@@ -5,10 +5,13 @@
|
||||
-- ============================================================================
|
||||
--
|
||||
-- CHANGES:
|
||||
-- 1. Add primary key to installedapps table
|
||||
-- 2. Migrate machines using PC-specific machinetypes to generic PC (33) + pctypeid
|
||||
-- 3. Update models to use generic PC machinetype
|
||||
-- 4. Remove unused PC machinetypes (34-43, 45-46), keep USB Device (44)
|
||||
-- 1. Drop duplicate appname_2 index on applications table
|
||||
-- 2. Add primary key to installedapps table (if not exists)
|
||||
-- 3. Migrate machines using PC-specific machinetypes to generic PC (33) + pctypeid
|
||||
-- 4. Update models to use generic PC machinetype
|
||||
-- 5. Remove unused PC machinetypes (34-43, 45-46), keep USB Device (44)
|
||||
--
|
||||
-- NOTE: This migration is IDEMPOTENT - safe to run multiple times
|
||||
--
|
||||
-- RUN ON: Production database
|
||||
-- BACKUP FIRST: mysqldump -u root -p shopdb > shopdb_backup_$(date +%Y%m%d).sql
|
||||
@@ -18,16 +21,42 @@
|
||||
START TRANSACTION;
|
||||
|
||||
-- ============================================================================
|
||||
-- 1. ADD PRIMARY KEY TO INSTALLEDAPPS TABLE
|
||||
-- 1. DROP DUPLICATE INDEX ON APPLICATIONS
|
||||
-- ============================================================================
|
||||
ALTER TABLE installedapps
|
||||
ADD COLUMN installedappid INT AUTO_INCREMENT PRIMARY KEY FIRST;
|
||||
-- Check if appname_2 index exists before dropping
|
||||
SET @index_exists = (SELECT COUNT(*) FROM information_schema.STATISTICS
|
||||
WHERE table_schema = DATABASE()
|
||||
AND table_name = 'applications'
|
||||
AND index_name = 'appname_2');
|
||||
|
||||
SELECT 'Added PK to installedapps' AS status;
|
||||
SET @sql = IF(@index_exists > 0, 'DROP INDEX appname_2 ON applications', 'SELECT "Index appname_2 does not exist" AS status');
|
||||
PREPARE stmt FROM @sql;
|
||||
EXECUTE stmt;
|
||||
DEALLOCATE PREPARE stmt;
|
||||
|
||||
SELECT IF(@index_exists > 0, 'Dropped duplicate appname_2 index', 'Index appname_2 already removed') AS status;
|
||||
|
||||
-- ============================================================================
|
||||
-- 2. MIGRATE MACHINES FROM PC-SPECIFIC TYPES TO GENERIC PC (33) + PCTYPEID
|
||||
-- 2. ADD PRIMARY KEY TO INSTALLEDAPPS TABLE (if not exists)
|
||||
-- ============================================================================
|
||||
SET @col_exists = (SELECT COUNT(*) FROM information_schema.COLUMNS
|
||||
WHERE table_schema = DATABASE()
|
||||
AND table_name = 'installedapps'
|
||||
AND column_name = 'installedappid');
|
||||
|
||||
SET @sql = IF(@col_exists = 0,
|
||||
'ALTER TABLE installedapps ADD COLUMN installedappid INT AUTO_INCREMENT PRIMARY KEY FIRST',
|
||||
'SELECT "Column installedappid already exists" AS status');
|
||||
PREPARE stmt FROM @sql;
|
||||
EXECUTE stmt;
|
||||
DEALLOCATE PREPARE stmt;
|
||||
|
||||
SELECT IF(@col_exists = 0, 'Added PK to installedapps', 'PK installedappid already exists') AS status;
|
||||
|
||||
-- ============================================================================
|
||||
-- 3. MIGRATE MACHINES FROM PC-SPECIFIC TYPES TO GENERIC PC (33) + PCTYPEID
|
||||
-- ============================================================================
|
||||
-- These UPDATEs are already idempotent (won't change rows that don't match)
|
||||
|
||||
-- PC - Standard (36) → machinetypeid=33, pctypeid=1 (Standard)
|
||||
UPDATE machines
|
||||
@@ -64,11 +93,11 @@ UPDATE machines
|
||||
SET machinetypeid = 33, pctypeid = 4
|
||||
WHERE machinetypeid BETWEEN 34 AND 46 AND pctypeid IS NULL;
|
||||
|
||||
SELECT CONCAT('Total machines now using machinetypeid 34-46: ',
|
||||
SELECT CONCAT('Total machines still using machinetypeid 34-46: ',
|
||||
(SELECT COUNT(*) FROM machines WHERE machinetypeid BETWEEN 34 AND 46)) AS status;
|
||||
|
||||
-- ============================================================================
|
||||
-- 3. UPDATE MODELS TO USE GENERIC PC MACHINETYPE (33)
|
||||
-- 4. UPDATE MODELS TO USE GENERIC PC MACHINETYPE (33)
|
||||
-- ============================================================================
|
||||
UPDATE models
|
||||
SET machinetypeid = 33
|
||||
@@ -77,9 +106,10 @@ WHERE machinetypeid BETWEEN 34 AND 46;
|
||||
SELECT CONCAT('Updated ', ROW_COUNT(), ' models to generic PC type') AS status;
|
||||
|
||||
-- ============================================================================
|
||||
-- 4. DELETE REDUNDANT MACHINETYPES
|
||||
-- 5. DELETE REDUNDANT MACHINETYPES
|
||||
-- ============================================================================
|
||||
-- Keep 33 (PC) and 44 (USB Device), remove 34-43 and 45-46
|
||||
-- These DELETEs are already idempotent (won't delete if rows don't exist)
|
||||
|
||||
DELETE FROM machinetypes WHERE machinetypeid BETWEEN 34 AND 43;
|
||||
SELECT CONCAT('Deleted ', ROW_COUNT(), ' machinetypes (34-43)') AS status;
|
||||
@@ -101,10 +131,13 @@ WHERE m.pctypeid IS NOT NULL
|
||||
GROUP BY m.pctypeid
|
||||
ORDER BY count DESC;
|
||||
|
||||
SELECT 'VERIFICATION - Applications indexes:' AS info;
|
||||
SELECT index_name, column_name FROM information_schema.STATISTICS
|
||||
WHERE table_schema = DATABASE() AND table_name = 'applications';
|
||||
|
||||
-- ============================================================================
|
||||
-- COMMIT (uncomment when ready to apply)
|
||||
-- COMMIT
|
||||
-- ============================================================================
|
||||
COMMIT;
|
||||
-- ROLLBACK; -- Use this instead if something looks wrong
|
||||
|
||||
SELECT 'Migration completed successfully!' AS status;
|
||||
|
||||
Reference in New Issue
Block a user