u
This commit is contained in:
@@ -15,7 +15,7 @@ Creates a new printer for the user's selected company.
|
|||||||
| `googleAuthId` | `number` | The id of the Google auth user. |
|
| `googleAuthId` | `number` | The id of the Google auth user. |
|
||||||
| `input` | `object` | Printer input. |
|
| `input` | `object` | Printer input. |
|
||||||
| `input.address` | `string` | Printer address (network IP/host/path). |
|
| `input.address` | `string` | Printer address (network IP/host/path). |
|
||||||
| `input.type` | `string` | Printer type ("esc/pos" or "zpl"). |
|
| `input.type` | `string` | Printer type ("esc/pos", "zpl", or "ipp"). |
|
||||||
| `[input.model]` | `string` | Optional printer model name. |
|
| `[input.model]` | `string` | Optional printer model name. |
|
||||||
| `[input.serial]` | `string` | Optional printer serial number. |
|
| `[input.serial]` | `string` | Optional printer serial number. |
|
||||||
| `[input.sort]` | `number` | Optional sort order (auto-increments if omitted). |
|
| `[input.sort]` | `number` | Optional sort order (auto-increments if omitted). |
|
||||||
@@ -149,7 +149,7 @@ Updates a printer for the user's selected company.
|
|||||||
| `id` | `number` | The printer ID to update. |
|
| `id` | `number` | The printer ID to update. |
|
||||||
| `input` | `object` | Update payload. |
|
| `input` | `object` | Update payload. |
|
||||||
| `[input.address]` | `string` | The printer address. |
|
| `[input.address]` | `string` | The printer address. |
|
||||||
| `[input.type]` | `string` | The printer type ("esc/pos" or "zpl"). |
|
| `[input.type]` | `string` | The printer type ("esc/pos", "zpl", or "ipp"). |
|
||||||
| `[input.model]` | `string|null` | The printer model. |
|
| `[input.model]` | `string|null` | The printer model. |
|
||||||
| `[input.serial]` | `string|null` | The printer serial. |
|
| `[input.serial]` | `string|null` | The printer serial. |
|
||||||
| `[input.sort]` | `number` | The sort order. |
|
| `[input.sort]` | `number` | The sort order. |
|
||||||
|
|||||||
105
scripts/migrate-printer-type-ipp.js
Normal file
105
scripts/migrate-printer-type-ipp.js
Normal file
@@ -0,0 +1,105 @@
|
|||||||
|
import 'dotenv/config';
|
||||||
|
import Database from 'better-sqlite3';
|
||||||
|
import { MssqlProvider } from '../src/providers/mssql/index.js';
|
||||||
|
|
||||||
|
async function migrateSqlite(sqlitePath) {
|
||||||
|
console.log(`Migrating SQLite database at: ${sqlitePath}`);
|
||||||
|
const db = new Database(sqlitePath);
|
||||||
|
|
||||||
|
const row = db.prepare("SELECT sql FROM sqlite_master WHERE type = 'table' AND name = 'printer'").get();
|
||||||
|
if (!row) {
|
||||||
|
console.log('Printer table does not exist in SQLite.');
|
||||||
|
db.close();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (row.sql.includes("'ipp'")) {
|
||||||
|
console.log("SQLite printer table already includes 'ipp' in CHECK constraint.");
|
||||||
|
db.close();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
db.pragma('foreign_keys = OFF');
|
||||||
|
db.exec(`
|
||||||
|
BEGIN TRANSACTION;
|
||||||
|
CREATE TABLE printer_new (
|
||||||
|
id INTEGER PRIMARY KEY,
|
||||||
|
company_id INTEGER NOT NULL,
|
||||||
|
address TEXT NOT NULL,
|
||||||
|
type TEXT NOT NULL CHECK (type IN ('esc/pos', 'zpl', 'ipp')),
|
||||||
|
model TEXT,
|
||||||
|
serial TEXT,
|
||||||
|
sort INTEGER NOT NULL DEFAULT 0,
|
||||||
|
"desc" TEXT,
|
||||||
|
FOREIGN KEY (company_id) REFERENCES company(id) ON DELETE CASCADE
|
||||||
|
);
|
||||||
|
INSERT INTO printer_new (id, company_id, address, type, model, serial, sort, "desc")
|
||||||
|
SELECT id, company_id, address, type, model, serial, sort, "desc"
|
||||||
|
FROM printer;
|
||||||
|
DROP TABLE printer;
|
||||||
|
ALTER TABLE printer_new RENAME TO printer;
|
||||||
|
COMMIT;
|
||||||
|
`);
|
||||||
|
db.pragma('foreign_keys = ON');
|
||||||
|
|
||||||
|
const fkErrors = db.pragma('foreign_key_check');
|
||||||
|
if (fkErrors.length > 0) {
|
||||||
|
console.error('Foreign key check failed after SQLite migration:', fkErrors);
|
||||||
|
} else {
|
||||||
|
console.log('SQLite migration completed successfully.');
|
||||||
|
}
|
||||||
|
|
||||||
|
const updatedRow = db.prepare("SELECT sql FROM sqlite_master WHERE type = 'table' AND name = 'printer'").get();
|
||||||
|
console.log('Updated SQLite printer table SQL:', updatedRow?.sql);
|
||||||
|
db.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
async function migrateMssql() {
|
||||||
|
console.log('Migrating MSSQL database...');
|
||||||
|
const config = {
|
||||||
|
server: process.env.MSSQL_SERVER,
|
||||||
|
database: process.env.MSSQL_DATABASE,
|
||||||
|
user: process.env.MSSQL_USER,
|
||||||
|
password: process.env.MSSQL_PASSWORD,
|
||||||
|
options: {
|
||||||
|
encrypt: false,
|
||||||
|
trustServerCertificate: true,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
const provider = new MssqlProvider(config);
|
||||||
|
const pool = await provider.ensurePool();
|
||||||
|
const tableRes = await pool.request().query(`
|
||||||
|
SELECT * FROM sys.tables WHERE name = 'printer'
|
||||||
|
`);
|
||||||
|
if (tableRes.recordset.length === 0) {
|
||||||
|
console.log('Printer table does not exist in MSSQL.');
|
||||||
|
await provider.close();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Drop old CK_printer_type constraint if exists and add new one
|
||||||
|
await pool.request().query(`
|
||||||
|
IF EXISTS (SELECT * FROM sys.check_constraints WHERE name = 'CK_printer_type')
|
||||||
|
BEGIN
|
||||||
|
ALTER TABLE printer DROP CONSTRAINT CK_printer_type;
|
||||||
|
END
|
||||||
|
ALTER TABLE printer ADD CONSTRAINT CK_printer_type CHECK (type IN ('esc/pos', 'zpl', 'ipp'));
|
||||||
|
`);
|
||||||
|
console.log('MSSQL migration completed successfully.');
|
||||||
|
await provider.close();
|
||||||
|
} catch (err) {
|
||||||
|
console.warn('MSSQL migration skipped/failed (possibly server not running):', err.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function run() {
|
||||||
|
await migrateSqlite('/home/seb/src/dashback/data/dash.db');
|
||||||
|
await migrateMssql();
|
||||||
|
}
|
||||||
|
|
||||||
|
run().catch((err) => {
|
||||||
|
console.error('Migration failed:', err);
|
||||||
|
process.exit(1);
|
||||||
|
});
|
||||||
@@ -800,7 +800,7 @@ BEGIN
|
|||||||
sort INT NOT NULL CONSTRAINT DF_printer_sort DEFAULT 0,
|
sort INT NOT NULL CONSTRAINT DF_printer_sort DEFAULT 0,
|
||||||
[desc] NVARCHAR(MAX) NULL,
|
[desc] NVARCHAR(MAX) NULL,
|
||||||
CONSTRAINT FK_printer_company FOREIGN KEY (company_id) REFERENCES company(id) ON DELETE CASCADE,
|
CONSTRAINT FK_printer_company FOREIGN KEY (company_id) REFERENCES company(id) ON DELETE CASCADE,
|
||||||
CONSTRAINT CK_printer_type CHECK (type IN ('esc/pos', 'zpl'))
|
CONSTRAINT CK_printer_type CHECK (type IN ('esc/pos', 'zpl', 'ipp'))
|
||||||
);
|
);
|
||||||
END
|
END
|
||||||
`;
|
`;
|
||||||
|
|||||||
@@ -553,7 +553,7 @@ CREATE TABLE IF NOT EXISTS printer (
|
|||||||
id INTEGER PRIMARY KEY,
|
id INTEGER PRIMARY KEY,
|
||||||
company_id INTEGER NOT NULL,
|
company_id INTEGER NOT NULL,
|
||||||
address TEXT NOT NULL,
|
address TEXT NOT NULL,
|
||||||
type TEXT NOT NULL CHECK (type IN ('esc/pos', 'zpl')),
|
type TEXT NOT NULL CHECK (type IN ('esc/pos', 'zpl', 'ipp')),
|
||||||
model TEXT,
|
model TEXT,
|
||||||
serial TEXT,
|
serial TEXT,
|
||||||
sort INTEGER NOT NULL DEFAULT 0,
|
sort INTEGER NOT NULL DEFAULT 0,
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import {
|
|||||||
import resolveSelectedCompanyAccess from '../companyuser/resolveSelectedCompanyAccess.js';
|
import resolveSelectedCompanyAccess from '../companyuser/resolveSelectedCompanyAccess.js';
|
||||||
import makeRunner from '../runner.js';
|
import makeRunner from '../runner.js';
|
||||||
|
|
||||||
const VALID_TYPES = new Set(['esc/pos', 'zpl']);
|
const VALID_TYPES = new Set(['esc/pos', 'zpl', 'ipp']);
|
||||||
|
|
||||||
function shape(row) {
|
function shape(row) {
|
||||||
return {
|
return {
|
||||||
@@ -42,7 +42,7 @@ export default function create(provider) {
|
|||||||
* @param {number} googleAuthId - The id of the Google auth user.
|
* @param {number} googleAuthId - The id of the Google auth user.
|
||||||
* @param {object} input - Printer input.
|
* @param {object} input - Printer input.
|
||||||
* @param {string} input.address - Printer address (network IP/host/path).
|
* @param {string} input.address - Printer address (network IP/host/path).
|
||||||
* @param {string} input.type - Printer type ("esc/pos" or "zpl").
|
* @param {string} input.type - Printer type ("esc/pos", "zpl", or "ipp").
|
||||||
* @param {string} [input.model] - Optional printer model name.
|
* @param {string} [input.model] - Optional printer model name.
|
||||||
* @param {string} [input.serial] - Optional printer serial number.
|
* @param {string} [input.serial] - Optional printer serial number.
|
||||||
* @param {number} [input.sort] - Optional sort order (auto-increments if omitted).
|
* @param {number} [input.sort] - Optional sort order (auto-increments if omitted).
|
||||||
@@ -67,7 +67,7 @@ export default function create(provider) {
|
|||||||
|
|
||||||
const type = typeof input.type === 'string' ? input.type.trim() : '';
|
const type = typeof input.type === 'string' ? input.type.trim() : '';
|
||||||
if (!type || !VALID_TYPES.has(type)) {
|
if (!type || !VALID_TYPES.has(type)) {
|
||||||
throw new Error('Invalid printer type: must be "esc/pos" or "zpl"');
|
throw new Error('Invalid printer type: must be "esc/pos", "zpl", or "ipp"');
|
||||||
}
|
}
|
||||||
|
|
||||||
const runner = makeRunner(provider, tx);
|
const runner = makeRunner(provider, tx);
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import {
|
|||||||
import resolveSelectedCompanyAccess from '../companyuser/resolveSelectedCompanyAccess.js';
|
import resolveSelectedCompanyAccess from '../companyuser/resolveSelectedCompanyAccess.js';
|
||||||
import makeRunner from '../runner.js';
|
import makeRunner from '../runner.js';
|
||||||
|
|
||||||
const VALID_TYPES = new Set(['esc/pos', 'zpl']);
|
const VALID_TYPES = new Set(['esc/pos', 'zpl', 'ipp']);
|
||||||
|
|
||||||
function shape(row) {
|
function shape(row) {
|
||||||
return {
|
return {
|
||||||
@@ -43,7 +43,7 @@ export default function update(provider) {
|
|||||||
* @param {number} id - The printer ID to update.
|
* @param {number} id - The printer ID to update.
|
||||||
* @param {object} input - Update payload.
|
* @param {object} input - Update payload.
|
||||||
* @param {string} [input.address] - The printer address.
|
* @param {string} [input.address] - The printer address.
|
||||||
* @param {string} [input.type] - The printer type ("esc/pos" or "zpl").
|
* @param {string} [input.type] - The printer type ("esc/pos", "zpl", or "ipp").
|
||||||
* @param {string|null} [input.model] - The printer model.
|
* @param {string|null} [input.model] - The printer model.
|
||||||
* @param {string|null} [input.serial] - The printer serial.
|
* @param {string|null} [input.serial] - The printer serial.
|
||||||
* @param {number} [input.sort] - The sort order.
|
* @param {number} [input.sort] - The sort order.
|
||||||
@@ -80,7 +80,7 @@ export default function update(provider) {
|
|||||||
if (input.type !== undefined) {
|
if (input.type !== undefined) {
|
||||||
const cleaned = typeof input.type === 'string' ? input.type.trim() : '';
|
const cleaned = typeof input.type === 'string' ? input.type.trim() : '';
|
||||||
if (!cleaned || !VALID_TYPES.has(cleaned)) {
|
if (!cleaned || !VALID_TYPES.has(cleaned)) {
|
||||||
throw new Error('Invalid printer type: must be "esc/pos" or "zpl"');
|
throw new Error('Invalid printer type: must be "esc/pos", "zpl", or "ipp"');
|
||||||
}
|
}
|
||||||
type = cleaned;
|
type = cleaned;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user