Fixed "TRUE/FALSE" => "0/1" mssql

This commit is contained in:
Jan 2026-01-27 10:00:48 +01:00
parent 28ee19d654
commit 5b2018c9e0
17 changed files with 234 additions and 62 deletions

1
.gitignore vendored
View file

@ -14,6 +14,7 @@ target/
.sts4-cache
.env.example
/.env
/.env.*
### IntelliJ IDEA ###
.idea

View file

@ -2,6 +2,8 @@ services:
mysql:
image: mysql:8.4
container_name: lcc-mysql-local
env_file:
- .env.mysql
environment:
MYSQL_ROOT_PASSWORD: ${DB_ROOT_PASSWORD}
MYSQL_DATABASE: lcc
@ -20,6 +22,55 @@ services:
retries: 5
restart: unless-stopped
# MSSQL Database (optional - nur für MSSQL-Tests)
mssql:
image: mcr.microsoft.com/mssql/server:2022-latest
container_name: lcc-mssql-local
environment:
ACCEPT_EULA: "Y"
MSSQL_SA_PASSWORD: ${DB_ROOT_PASSWORD:-YourStrong@Passw0rd123}
MSSQL_PID: "Developer"
volumes:
- mssql-data-local:/var/opt/mssql
- ./docker/mssql-init.sql:/docker-init/mssql-init.sql:ro
ports:
- "1433:1433"
networks:
- lcc-network-local
healthcheck:
test: /opt/mssql-tools18/bin/sqlcmd -S localhost -U sa -P "$${MSSQL_SA_PASSWORD}" -Q "SELECT 1" -C || exit 1
interval: 10s
timeout: 5s
retries: 10
start_period: 30s
restart: unless-stopped
profiles:
- mssql # Startet nur mit: docker-compose --profile mssql up
# MSSQL Init (führt Init-Skript aus)
mssql-init:
image: mcr.microsoft.com/mssql/server:2022-latest
container_name: lcc-mssql-init
depends_on:
mssql:
condition: service_healthy
environment:
MSSQL_SA_PASSWORD: ${DB_ROOT_PASSWORD:-YourStrong@Passw0rd123}
volumes:
- ./docker/mssql-init.sql:/init.sql:ro
command: >
/bin/bash -c "
echo 'Waiting for MSSQL to be ready...' &&
sleep 5 &&
echo 'Running initialization script...' &&
/opt/mssql-tools18/bin/sqlcmd -S mssql -U sa -P \"$$MSSQL_SA_PASSWORD\" -i /init.sql -C &&
echo 'Database initialization complete!' || echo 'Initialization failed or database already exists'
"
networks:
- lcc-network-local
profiles:
- mssql
lcc-app:
#image: git.avatic.de/avatic/lcc:latest
# Oder für lokales Bauen:
@ -29,7 +80,7 @@ services:
mysql:
condition: service_healthy
env_file:
- .env
- .env.mysql
environment:
# Überschreibe die Datasource URL für Docker-Netzwerk
SPRING_DATASOURCE_URL: jdbc:mysql://mysql:3306/lcc
@ -44,6 +95,7 @@ services:
volumes:
mysql-data-local:
mssql-data-local:
networks:
lcc-network-local:

View file

@ -426,4 +426,46 @@ public class MSSQLDialectProvider implements SqlDialectProvider {
public String getTimestampDefinition() {
return "DATETIME2 DEFAULT GETDATE()";
}
// ========== Boolean Literals ==========
/**
* Returns MSSQL boolean TRUE literal as numeric 1.
*
* <p>MSSQL BIT type uses 1 for TRUE.</p>
*
* @return "1"
*/
@Override
public String getBooleanTrue() {
return "1";
}
/**
* Returns MSSQL boolean FALSE literal as numeric 0.
*
* <p>MSSQL BIT type uses 0 for FALSE.</p>
*
* @return "0"
*/
@Override
public String getBooleanFalse() {
return "0";
}
// ========== Identifier Escaping ==========
/**
* Escapes identifier with square brackets for MSSQL reserved words.
*
* <p>MSSQL uses square brackets to escape reserved words like 'file', 'user', 'order'.</p>
*
* @param identifier column or table name to escape
* @return escaped identifier with square brackets
*/
@Override
public String escapeIdentifier(String identifier) {
// MSSQL uses square brackets for escaping reserved words
return "[" + identifier + "]";
}
}

View file

@ -181,4 +181,24 @@ public class MySQLDialectProvider implements SqlDialectProvider {
public String getTimestampDefinition() {
return "TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP";
}
// ========== Boolean Literals ==========
@Override
public String getBooleanTrue() {
return "TRUE";
}
@Override
public String getBooleanFalse() {
return "FALSE";
}
// ========== Identifier Escaping ==========
@Override
public String escapeIdentifier(String identifier) {
// MySQL uses backticks for escaping reserved words
return "`" + identifier + "`";
}
}

View file

@ -335,6 +335,52 @@ public interface SqlDialectProvider {
*/
String getTimestampDefinition();
// ========== Boolean Literals ==========
/**
* Returns the SQL literal for boolean TRUE value.
*
* <p>Database-specific implementations:</p>
* <ul>
* <li>MySQL: {@code TRUE}</li>
* <li>MSSQL: {@code 1}</li>
* </ul>
*
* @return SQL literal for true
*/
String getBooleanTrue();
/**
* Returns the SQL literal for boolean FALSE value.
*
* <p>Database-specific implementations:</p>
* <ul>
* <li>MySQL: {@code FALSE}</li>
* <li>MSSQL: {@code 0}</li>
* </ul>
*
* @return SQL literal for false
*/
String getBooleanFalse();
// ========== Identifier Escaping ==========
/**
* Escapes a column or table identifier if it conflicts with reserved words.
*
* <p>Database-specific implementations:</p>
* <ul>
* <li>MySQL: {@code `identifier`}</li>
* <li>MSSQL: {@code [identifier]}</li>
* </ul>
*
* <p>Used for reserved words like "file", "user", "order", etc.</p>
*
* @param identifier column or table name to escape
* @return escaped identifier
*/
String escapeIdentifier(String identifier);
// ========== Helper Enums ==========
/**

View file

@ -27,13 +27,13 @@ public class MaterialRepository {
this.dialectProvider = dialectProvider;
}
private static String buildCountQuery(String filter, boolean excludeDeprecated) {
private String buildCountQuery(String filter, boolean excludeDeprecated) {
StringBuilder queryBuilder = new StringBuilder("""
SELECT count(*)
FROM material WHERE 1=1""");
if (excludeDeprecated) {
queryBuilder.append(" AND is_deprecated = FALSE");
queryBuilder.append(" AND is_deprecated = ").append(dialectProvider.getBooleanFalse());
}
if (filter != null) {
queryBuilder.append(" AND (name LIKE ? OR part_number LIKE ?) ");
@ -48,7 +48,7 @@ public class MaterialRepository {
FROM material WHERE 1=1""");
if (excludeDeprecated) {
queryBuilder.append(" AND is_deprecated = FALSE");
queryBuilder.append(" AND is_deprecated = ").append(dialectProvider.getBooleanFalse());
}
if (filter != null) {
queryBuilder.append(" AND (name LIKE ? OR part_number LIKE ? ) ");
@ -99,7 +99,7 @@ public class MaterialRepository {
@Transactional
public Optional<Integer> setDeprecatedById(Integer id) {
String query = "UPDATE material SET is_deprecated = TRUE WHERE id = ?";
String query = "UPDATE material SET is_deprecated = " + dialectProvider.getBooleanTrue() + " WHERE id = ?";
return Optional.ofNullable(jdbcTemplate.update(query, id) == 0 ? null : id);
}
@ -140,7 +140,7 @@ public class MaterialRepository {
@Transactional
public Optional<Material> getById(Integer id) {
String query = "SELECT * FROM material WHERE id = ? AND is_deprecated = FALSE";
String query = "SELECT * FROM material WHERE id = ? AND is_deprecated = " + dialectProvider.getBooleanFalse();
var material = jdbcTemplate.query(query, new MaterialMapper(), id);
@ -152,7 +152,7 @@ public class MaterialRepository {
@Transactional
public void deleteById(Integer id) {
String deleteQuery = "UPDATE material SET is_deprecated = TRUE WHERE id = ?";
String deleteQuery = "UPDATE material SET is_deprecated = " + dialectProvider.getBooleanTrue() + " WHERE id = ?";
jdbcTemplate.update(deleteQuery, id);
}
@ -216,9 +216,9 @@ public class MaterialRepository {
.map(id -> "?")
.collect(Collectors.joining(","));
String sql = "UPDATE material SET is_deprecated = TRUE WHERE id IN ("+placeholders+")";
String sql = "UPDATE material SET is_deprecated = " + dialectProvider.getBooleanTrue() + " WHERE id IN ("+placeholders+")";
jdbcTemplate.update(sql, ids);
jdbcTemplate.update(sql, ids.toArray());
}

View file

@ -127,7 +127,7 @@ public class NodeRepository {
WHERE 1=1""");
if (excludeDeprecated) {
queryBuilder.append(" AND node.is_deprecated = FALSE");
queryBuilder.append(" AND node.is_deprecated = ").append(dialectProvider.getBooleanFalse());
}
if (filter != null) {
queryBuilder.append(" AND (node.name LIKE ? OR node.external_mapping_id LIKE ? OR node.address LIKE ? OR country.iso_code LIKE ?)");
@ -145,7 +145,7 @@ public class NodeRepository {
""");
if (excludeDeprecated) {
queryBuilder.append(" AND node.is_deprecated = FALSE");
queryBuilder.append(" AND node.is_deprecated = ").append(dialectProvider.getBooleanFalse());
}
if (filter != null) {
queryBuilder.append(" AND (node.name LIKE ? OR node.external_mapping_id LIKE ? OR node.address LIKE ? OR country.iso_code LIKE ?)");
@ -406,9 +406,9 @@ public class NodeRepository {
if(node.isUserNode()) {
String query = String.format("""
SELECT * FROM node
WHERE is_deprecated = FALSE AND
WHERE is_deprecated = %s AND
(%s) <= ?
""", haversineFormula);
""", dialectProvider.getBooleanFalse(), haversineFormula);
return jdbcTemplate.query(query, new NodeMapper(), node.getGeoLat(), node.getGeoLng(), regionRadius);
}
@ -416,9 +416,9 @@ public class NodeRepository {
String query = String.format("""
SELECT * FROM node
WHERE is_deprecated = FALSE AND id != ? AND
WHERE is_deprecated = %s AND id != ? AND
(%s) <= ?
""", haversineFormula);
""", dialectProvider.getBooleanFalse(), haversineFormula);
return jdbcTemplate.query(query, new NodeMapper(), node.getId(), node.getGeoLat(), node.getGeoLng(), regionRadius);
}
@ -435,12 +435,12 @@ public class NodeRepository {
* Returns an empty list if no outbound nodes are found.
*/
public List<Node> getAllOutboundFor(Integer countryId) {
String query = """
String query = String.format("""
SELECT node.*
FROM node
LEFT JOIN outbound_country_mapping ON outbound_country_mapping.node_id = node.id
WHERE node.is_deprecated = FALSE AND (outbound_country_mapping.country_id = ? OR (node.is_intermediate = TRUE AND node.country_id = ?))
""";
WHERE node.is_deprecated = %s AND (outbound_country_mapping.country_id = ? OR (node.is_intermediate = %s AND node.country_id = ?))
""", dialectProvider.getBooleanFalse(), dialectProvider.getBooleanTrue());
return jdbcTemplate.query(query, new NodeMapper(), countryId, countryId);
}

View file

@ -116,7 +116,7 @@ public class CountryRepository {
FROM country WHERE 1=1""");
if (excludeDeprecated) {
queryBuilder.append(" AND is_deprecated = FALSE");
queryBuilder.append(" AND is_deprecated = ").append(dialectProvider.getBooleanFalse());
}
if (filter != null) {
queryBuilder.append(" AND (iso_code LIKE ? OR region_code LIKE ? or name LIKE ?) ");

View file

@ -114,12 +114,12 @@ public class DumpRepository {
}
private List<ErrorLogTraceItemDto> loadErrorTraceItems(Integer errorId) {
String traceQuery = """
SELECT line, file, method, fullPath
String traceQuery = String.format("""
SELECT line, %s, method, fullPath
FROM sys_error_trace_item
WHERE error_id = :errorId
ORDER BY id
""";
""", dialectProvider.escapeIdentifier("file"));
MapSqlParameterSource params = new MapSqlParameterSource("errorId", errorId);

View file

@ -102,7 +102,8 @@ public class SysErrorRepository {
}
private void insertTraceItems(Integer errorId, List<SysErrorTraceItem> traceItems) {
String traceSql = "INSERT INTO sys_error_trace_item (error_id, line, file, method, fullPath) VALUES (?, ?, ?, ?, ?)";
String traceSql = String.format("INSERT INTO sys_error_trace_item (error_id, line, %s, method, fullPath) VALUES (?, ?, ?, ?, ?)",
dialectProvider.escapeIdentifier("file"));
jdbcTemplate.batchUpdate(traceSql, traceItems, traceItems.size(),
(ps, traceItem) -> {
@ -170,12 +171,12 @@ public class SysErrorRepository {
return;
}
String traceSql = """
SELECT error_id, id, line, file, method, fullPath
String traceSql = String.format("""
SELECT error_id, id, line, %s, method, fullPath
FROM sys_error_trace_item
WHERE error_id IN (:errorIds)
ORDER BY error_id, id
""";
""", dialectProvider.escapeIdentifier("file"));
MapSqlParameterSource traceParameters = new MapSqlParameterSource("errorIds", errorIds);

View file

@ -1,5 +1,6 @@
package de.avatic.lcc.repositories.packaging;
import de.avatic.lcc.database.dialect.SqlDialectProvider;
import de.avatic.lcc.model.db.packaging.PackagingDimension;
import de.avatic.lcc.model.db.packaging.PackagingType;
import de.avatic.lcc.model.db.utils.DimensionUnit;
@ -19,9 +20,11 @@ import java.util.Optional;
public class PackagingDimensionRepository {
private final JdbcTemplate jdbcTemplate;
private final SqlDialectProvider dialectProvider;
public PackagingDimensionRepository(JdbcTemplate jdbcTemplate) {
public PackagingDimensionRepository(JdbcTemplate jdbcTemplate, SqlDialectProvider dialectProvider) {
this.jdbcTemplate = jdbcTemplate;
this.dialectProvider = dialectProvider;
}
@Transactional
@ -113,7 +116,7 @@ public class PackagingDimensionRepository {
}
public Optional<Integer> setDeprecatedById(Integer id) {
String query = "UPDATE packaging_dimension SET is_deprecated = TRUE WHERE id = ?";
String query = "UPDATE packaging_dimension SET is_deprecated = " + dialectProvider.getBooleanTrue() + " WHERE id = ?";
return Optional.ofNullable(jdbcTemplate.update(query, id) == 0 ? null : id);
}

View file

@ -83,7 +83,7 @@ public class PackagingRepository {
WHERE 1=1""");
if (excludeDeprecated) {
queryBuilder.append(" AND is_deprecated = FALSE");
queryBuilder.append(" AND is_deprecated = ").append(dialectProvider.getBooleanFalse());
}
if (materialId != null) {
queryBuilder.append(" AND material_id = ?");
@ -151,7 +151,7 @@ public class PackagingRepository {
@Transactional
public Optional<Integer> setDeprecatedById(Integer id) {
String query = "UPDATE packaging SET is_deprecated = TRUE WHERE id = ?";
String query = "UPDATE packaging SET is_deprecated = " + dialectProvider.getBooleanTrue() + " WHERE id = ?";
return Optional.ofNullable(jdbcTemplate.update(query, id) == 0 ? null : id);
}

View file

@ -710,7 +710,7 @@ public class PremiseRepository {
return premiseIds;
}
String sql = "SELECT id FROM premise WHERE id IN (:ids) AND tariff_unlocked = TRUE";
String sql = "SELECT id FROM premise WHERE id IN (:ids) AND tariff_unlocked = " + dialectProvider.getBooleanTrue();
List<Integer> unlockedIds = namedParameterJdbcTemplate.query(
sql,
@ -736,7 +736,7 @@ public class PremiseRepository {
/**
* Encapsulates SQL query building logic
*/
private static class QueryBuilder {
private class QueryBuilder {
private static final String BASE_JOIN_QUERY = """
FROM premise AS p
LEFT JOIN material as m ON p.material_id = m.id
@ -838,7 +838,7 @@ public class PremiseRepository {
private void appendBooleanCondition(StringBuilder queryBuilder, Boolean condition, String field) {
if (condition != null && condition) {
queryBuilder.append(" OR ").append(field).append(" = TRUE");
queryBuilder.append(" OR ").append(field).append(" = ").append(dialectProvider.getBooleanTrue());
}
}
}

View file

@ -1,5 +1,6 @@
package de.avatic.lcc.repositories.premise;
import de.avatic.lcc.database.dialect.SqlDialectProvider;
import de.avatic.lcc.model.db.premises.route.Route;
import de.avatic.lcc.util.exception.internalerror.DatabaseException;
import org.springframework.jdbc.core.JdbcTemplate;
@ -20,9 +21,11 @@ import java.util.Optional;
public class RouteRepository {
private final JdbcTemplate jdbcTemplate;
private final SqlDialectProvider dialectProvider;
public RouteRepository(JdbcTemplate jdbcTemplate) {
public RouteRepository(JdbcTemplate jdbcTemplate, SqlDialectProvider dialectProvider) {
this.jdbcTemplate = jdbcTemplate;
this.dialectProvider = dialectProvider;
}
public List<Route> getByDestinationId(Integer id) {
@ -31,7 +34,7 @@ public class RouteRepository {
}
public Optional<Route> getSelectedByDestinationId(Integer id) {
String query = "SELECT * FROM premise_route WHERE premise_destination_id = ? AND is_selected = TRUE";
String query = "SELECT * FROM premise_route WHERE premise_destination_id = ? AND is_selected = " + dialectProvider.getBooleanTrue();
var route = jdbcTemplate.query(query, new RouteMapper(), id);
if(route.isEmpty()) {
@ -78,12 +81,12 @@ public class RouteRepository {
}
public void updateSelectedByDestinationId(Integer destinationId, Integer selectedRouteId) {
String deselectQuery = """
UPDATE premise_route SET is_selected = FALSE WHERE is_selected = TRUE AND premise_destination_id = ?
""";
String selectQuery = """
UPDATE premise_route SET is_selected = TRUE WHERE id = ?
""";
String deselectQuery = String.format("""
UPDATE premise_route SET is_selected = %s WHERE is_selected = %s AND premise_destination_id = ?
""", dialectProvider.getBooleanFalse(), dialectProvider.getBooleanTrue());
String selectQuery = String.format("""
UPDATE premise_route SET is_selected = %s WHERE id = ?
""", dialectProvider.getBooleanTrue());
jdbcTemplate.update(deselectQuery, destinationId);
var affectedRowsSelect = jdbcTemplate.update(selectQuery, selectedRouteId);

View file

@ -135,10 +135,12 @@ public class ContainerRateRepository {
LEFT JOIN node AS from_node ON from_node.id = container_rate.from_node_id
LEFT JOIN validity_period ON validity_period.id = container_rate.validity_period_id
WHERE validity_period.state = ?
AND to_node.is_deprecated = FALSE
AND from_node.is_deprecated = FALSE
AND to_node.is_deprecated = %s
AND from_node.is_deprecated = %s
AND (container_rate.container_rate_type = ? OR container_rate.container_rate_type = ?)
AND container_rate.from_node_id = ? AND to_node.country_id IN (%s)""".formatted(
dialectProvider.getBooleanFalse(),
dialectProvider.getBooleanFalse(),
destinationCountryPlaceholders);
List<Object> params = new ArrayList<>();
@ -154,7 +156,7 @@ public class ContainerRateRepository {
@Transactional
public List<ContainerRate> getPostRunsFor(ContainerRate mainRun) {
String query = """
String query = String.format("""
SELECT container_rate.id AS id,
container_rate.validity_period_id AS validity_period_id,
container_rate.container_rate_type AS container_rate_type,
@ -171,9 +173,11 @@ public class ContainerRateRepository {
LEFT JOIN node AS from_node ON from_node.id = container_rate.from_node_id
LEFT JOIN validity_period ON validity_period.id = container_rate.validity_period_id
WHERE validity_period.state = ?
AND to_node.is_deprecated = FALSE
AND from_node.is_deprecated = FALSE
AND container_rate.from_node_id = ? AND container_rate.container_rate_type = ?""";
AND to_node.is_deprecated = %s
AND from_node.is_deprecated = %s
AND container_rate.from_node_id = ? AND container_rate.container_rate_type = ?""",
dialectProvider.getBooleanFalse(),
dialectProvider.getBooleanFalse());
return jdbcTemplate.query(query, new ContainerRateMapper(true), ValidityPeriodState.VALID.name(), mainRun.getToNodeId(), TransportType.POST_RUN.name());
}

View file

@ -46,7 +46,7 @@ public class UserNodeRepository {
}
if (excludeDeprecated) {
queryBuilder.append(" AND is_deprecated = FALSE");
queryBuilder.append(" AND is_deprecated = ").append(dialectProvider.getBooleanFalse());
}
queryBuilder.append(" ").append(dialectProvider.buildPaginationClause(limit, 0));

View file

@ -6,7 +6,7 @@ CREATE TABLE property_set
id INT NOT NULL IDENTITY(1,1) PRIMARY KEY,
start_date DATETIME2 NOT NULL DEFAULT GETDATE(),
end_date DATETIME2 NULL,
state CHAR(8) NOT NULL,
state VARCHAR(8) NOT NULL,
CONSTRAINT chk_property_state_values CHECK (state IN ('DRAFT', 'VALID', 'INVALID', 'EXPIRED')),
CONSTRAINT chk_property_date_range CHECK (end_date IS NULL OR end_date > start_date)
);
@ -235,7 +235,7 @@ CREATE TABLE distance_matrix
to_geo_lng DECIMAL(8, 4) CHECK (to_geo_lng BETWEEN -180 AND 180),
distance DECIMAL(15, 2) NOT NULL,
updated_at DATETIME2 NOT NULL DEFAULT GETDATE(),
state CHAR(10) NOT NULL,
state VARCHAR(10) NOT NULL,
FOREIGN KEY (from_node_id) REFERENCES node (id),
FOREIGN KEY (to_node_id) REFERENCES node (id),
FOREIGN KEY (from_user_node_id) REFERENCES sys_user_node (id),
@ -262,7 +262,7 @@ CREATE TABLE validity_period
start_date DATETIME2 NOT NULL DEFAULT GETDATE(),
end_date DATETIME2 DEFAULT NULL,
renewals INT DEFAULT 0,
state CHAR(8) NOT NULL CHECK (state IN ('DRAFT', 'VALID', 'INVALID', 'EXPIRED')),
state VARCHAR(8) NOT NULL CHECK (state IN ('DRAFT', 'VALID', 'INVALID', 'EXPIRED')),
CONSTRAINT chk_validity_date_range CHECK (end_date IS NULL OR end_date > start_date)
);
@ -272,7 +272,7 @@ CREATE TABLE container_rate
id INT NOT NULL IDENTITY(1,1) PRIMARY KEY,
from_node_id INT NOT NULL,
to_node_id INT NOT NULL,
container_rate_type CHAR(8) CHECK (container_rate_type IN ('RAIL', 'SEA', 'POST_RUN', 'ROAD')),
container_rate_type VARCHAR(8) CHECK (container_rate_type IN ('RAIL', 'SEA', 'POST_RUN', 'ROAD')),
rate_teu DECIMAL(15, 2) NOT NULL,
rate_feu DECIMAL(15, 2) NOT NULL,
rate_hc DECIMAL(15, 2) NOT NULL,
@ -407,7 +407,7 @@ CREATE TABLE premise
tariff_measure INT DEFAULT NULL,
tariff_rate DECIMAL(8, 4) DEFAULT NULL,
tariff_unlocked BIT DEFAULT 0,
state CHAR(10) NOT NULL DEFAULT 'DRAFT',
state VARCHAR(10) NOT NULL DEFAULT 'DRAFT',
individual_hu_length INT,
individual_hu_height INT,
individual_hu_width INT,
@ -499,8 +499,8 @@ CREATE TABLE premise_route_section
from_route_node_id INT NOT NULL,
to_route_node_id INT NOT NULL,
list_position INT NOT NULL,
transport_type CHAR(16) CHECK (transport_type IN ('RAIL', 'SEA', 'ROAD', 'POST_RUN')),
rate_type CHAR(16) CHECK (rate_type IN ('CONTAINER', 'MATRIX', 'NEAR_BY')),
transport_type VARCHAR(16) CHECK (transport_type IN ('RAIL', 'SEA', 'ROAD', 'POST_RUN')),
rate_type VARCHAR(16) CHECK (rate_type IN ('CONTAINER', 'MATRIX', 'NEAR_BY')),
is_pre_run BIT DEFAULT 0,
is_main_run BIT DEFAULT 0,
is_post_run BIT DEFAULT 0,
@ -522,7 +522,7 @@ CREATE TABLE calculation_job
calculation_date DATETIME2 NOT NULL DEFAULT GETDATE(),
validity_period_id INT NOT NULL,
property_set_id INT NOT NULL,
job_state CHAR(10) NOT NULL CHECK (job_state IN ('CREATED', 'SCHEDULED', 'VALID', 'INVALID', 'EXCEPTION')),
job_state VARCHAR(10) NOT NULL CHECK (job_state IN ('CREATED', 'SCHEDULED', 'VALID', 'INVALID', 'EXCEPTION')),
error_id INT DEFAULT NULL,
user_id INT NOT NULL,
FOREIGN KEY (premise_id) REFERENCES premise (id),
@ -567,7 +567,7 @@ CREATE TABLE calculation_job_destination
annual_air_freight_cost DECIMAL(15, 2) NOT NULL,
is_d2d BIT DEFAULT 0,
rate_d2d DECIMAL(15, 2) DEFAULT NULL,
container_type CHAR(8),
container_type VARCHAR(8),
hu_count INT NOT NULL,
layer_structure NVARCHAR(MAX),
layer_count INT NOT NULL,
@ -591,7 +591,7 @@ CREATE TABLE calculation_job_route_section
id INT NOT NULL IDENTITY(1,1) PRIMARY KEY,
premise_route_section_id INT,
calculation_job_destination_id INT NOT NULL,
transport_type CHAR(16) CHECK (transport_type IN ('RAIL', 'SEA', 'ROAD', 'POST_RUN', 'MATRIX', 'D2D')),
transport_type VARCHAR(16) CHECK (transport_type IN ('RAIL', 'SEA', 'ROAD', 'POST_RUN', 'MATRIX', 'D2D')),
is_unmixed_price BIT DEFAULT 0,
is_cbm_price BIT DEFAULT 0,
is_weight_price BIT DEFAULT 0,
@ -617,9 +617,9 @@ CREATE TABLE bulk_operation
(
id INT NOT NULL IDENTITY(1,1) PRIMARY KEY,
user_id INT NOT NULL,
bulk_file_type CHAR(32) NOT NULL,
bulk_processing_type CHAR(32) NOT NULL,
state CHAR(10) NOT NULL,
bulk_file_type VARCHAR(32) NOT NULL,
bulk_processing_type VARCHAR(32) NOT NULL,
state VARCHAR(10) NOT NULL,
[file] VARBINARY(MAX) DEFAULT NULL,
validity_period_id INT DEFAULT NULL,
created_at DATETIME2 NOT NULL DEFAULT GETDATE(),
@ -642,7 +642,7 @@ CREATE TABLE sys_error
pinia VARCHAR(MAX),
calculation_job_id INT DEFAULT NULL,
bulk_operation_id INT DEFAULT NULL,
type CHAR(16) NOT NULL DEFAULT 'BACKEND',
type VARCHAR(16) NOT NULL DEFAULT 'BACKEND',
created_at DATETIME2 NOT NULL DEFAULT GETDATE(),
FOREIGN KEY (user_id) REFERENCES sys_user (id),
FOREIGN KEY (calculation_job_id) REFERENCES calculation_job (id),