20260804223152
This commit is contained in:
1 parent
75b1ccaa6d
commit
7c9761a4fc
71 files changed
+5534
-9113
No files matched your search
Whitespace-only changes.
@@ -1,65 +0,0 @@
|
||||
[INFO] Scanning for projects...
|
||||
[INFO]
|
||||
[INFO] -------------------------< cn.g3soft:fms-api >--------------------------
|
||||
[INFO] Building fms-api 0.0.1-SNAPSHOT
|
||||
[INFO] from pom.xml
|
||||
[INFO] --------------------------------[ jar ]---------------------------------
|
||||
[INFO]
|
||||
[INFO] >>> spring-boot-maven-plugin:4.1.0:run (default-cli) > test-compile @ fms-api >>>
|
||||
[INFO]
|
||||
[INFO] --- maven-resources-plugin:3.5.0:resources (default-resources) @ fms-api ---
|
||||
[INFO] Copying 1 resource from src\main\resources to target\classes
|
||||
[INFO] Copying 0 resource from src\main\resources to target\classes
|
||||
[INFO]
|
||||
[INFO] --- maven-compiler-plugin:3.15.0:compile (default-compile) @ fms-api ---
|
||||
[INFO] Nothing to compile - all classes are up to date.
|
||||
[INFO]
|
||||
[INFO] --- maven-resources-plugin:3.5.0:testResources (default-testResources) @ fms-api ---
|
||||
[INFO] skip non existing resourceDirectory D:\workspace\code\fms\fms-api\src\test\resources
|
||||
[INFO]
|
||||
[INFO] --- maven-compiler-plugin:3.15.0:testCompile (default-testCompile) @ fms-api ---
|
||||
[INFO] Nothing to compile - all classes are up to date.
|
||||
[INFO]
|
||||
[INFO] <<< spring-boot-maven-plugin:4.1.0:run (default-cli) < test-compile @ fms-api <<<
|
||||
[INFO]
|
||||
[INFO]
|
||||
[INFO] --- spring-boot-maven-plugin:4.1.0:run (default-cli) @ fms-api ---
|
||||
[INFO] Attaching agents: []
|
||||
|
||||
. ____ _ __ _ _
|
||||
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
|
||||
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
|
||||
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
|
||||
' |____| .__|_| |_|_| |_\__, | / / / /
|
||||
=========|_|==============|___/=/_/_/_/
|
||||
|
||||
:: Spring Boot :: (v4.1.0)
|
||||
|
||||
2026-08-04T15:49:27.744+08:00 INFO 10960 --- [fms-api] [ restartedMain] cn.g3soft.fmsapi.FmsApiApplication : Starting FmsApiApplication using Java 21 with PID 10960 (D:\workspace\code\fms\fms-api\target\classes started by Administrator in D:\workspace\code\fms\fms-api)
|
||||
2026-08-04T15:49:27.753+08:00 INFO 10960 --- [fms-api] [ restartedMain] cn.g3soft.fmsapi.FmsApiApplication : No active profile set, falling back to 1 default profile: "default"
|
||||
2026-08-04T15:49:27.901+08:00 INFO 10960 --- [fms-api] [ restartedMain] .e.DevToolsPropertyDefaultsPostProcessor : Devtools property defaults active! Set 'spring.devtools.add-properties' to 'false' to disable
|
||||
2026-08-04T15:49:27.902+08:00 INFO 10960 --- [fms-api] [ restartedMain] .e.DevToolsPropertyDefaultsPostProcessor : For additional web related logging consider setting the 'logging.level.web' property to 'DEBUG'
|
||||
2026-08-04T15:49:29.777+08:00 INFO 10960 --- [fms-api] [ restartedMain] o.s.boot.tomcat.TomcatWebServer : Tomcat initialized with port 8088 (http)
|
||||
2026-08-04T15:49:29.805+08:00 INFO 10960 --- [fms-api] [ restartedMain] o.apache.catalina.core.StandardService : Starting service [Tomcat]
|
||||
2026-08-04T15:49:29.807+08:00 INFO 10960 --- [fms-api] [ restartedMain] o.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/11.0.22]
|
||||
2026-08-04T15:49:29.858+08:00 INFO 10960 --- [fms-api] [ restartedMain] b.w.c.s.WebApplicationContextInitializer : Root WebApplicationContext: initialization completed in 1954 ms
|
||||
2026-08-04T15:49:30.455+08:00 INFO 10960 --- [fms-api] [ restartedMain] c.g3soft.fmsapi.utils.IpRegionSearcher : ip2region Searcher 初始化完成,数据大小 11114380 字节
|
||||
2026-08-04T15:49:31.639+08:00 INFO 10960 --- [fms-api] [ restartedMain] o.s.boot.tomcat.TomcatWebServer : Tomcat started on port 8088 (http) with context path '/api'
|
||||
2026-08-04T15:49:31.656+08:00 INFO 10960 --- [fms-api] [ restartedMain] cn.g3soft.fmsapi.FmsApiApplication : Started FmsApiApplication in 5.07 seconds (process running for 7.639)
|
||||
2026-08-04T15:50:46.035+08:00 INFO 10960 --- [fms-api] [nio-8088-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/api] : Initializing Spring DispatcherServlet 'dispatcherServlet'
|
||||
2026-08-04T15:50:46.038+08:00 INFO 10960 --- [fms-api] [nio-8088-exec-1] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet'
|
||||
2026-08-04T15:50:46.039+08:00 INFO 10960 --- [fms-api] [nio-8088-exec-1] o.s.web.servlet.DispatcherServlet : Completed initialization in 1 ms
|
||||
2026-08-04T15:50:46.425+08:00 INFO 10960 --- [fms-api] [nio-8088-exec-1] com.alibaba.druid.pool.DruidDataSource : {dataSource-1,G3HD} inited
|
||||
[INFO] ------------------------------------------------------------------------
|
||||
[INFO] BUILD FAILURE
|
||||
[INFO] ------------------------------------------------------------------------
|
||||
[INFO] Total time: 01:37 h
|
||||
[INFO] Finished at: 2026-08-04T17:27:10+08:00
|
||||
[INFO] ------------------------------------------------------------------------
|
||||
[ERROR] Failed to execute goal org.springframework.boot:spring-boot-maven-plugin:4.1.0:run (default-cli) on project fms-api: Process terminated with exit code: -1 -> [Help 1]
|
||||
[ERROR]
|
||||
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
|
||||
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
|
||||
[ERROR]
|
||||
[ERROR] For more information about the errors and possible solutions, please read the following articles:
|
||||
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoExecutionException
|
||||
@@ -1,934 +0,0 @@
|
||||
/*
|
||||
One-time cutover from the original mixed module tree to the resource model.
|
||||
|
||||
This migration intentionally does not keep compatibility tables or dual writes.
|
||||
Existing module, field, action and grant IDs are preserved where the entity keeps
|
||||
the same meaning. IDs only need to be unique inside their owning table.
|
||||
*/
|
||||
SET NOCOUNT ON;
|
||||
SET XACT_ABORT ON;
|
||||
|
||||
IF DB_NAME() <> N'FMS'
|
||||
THROW 53300, N'This migration can only run against the FMS database.', 1;
|
||||
|
||||
/* CUTOVER_INSTALLED_GUARD_START */
|
||||
IF OBJECT_ID(N'dbo.s_module_page', N'U') IS NOT NULL
|
||||
BEGIN
|
||||
PRINT N'Module architecture already installed.';
|
||||
RETURN;
|
||||
END;
|
||||
/* CUTOVER_INSTALLED_GUARD_END */
|
||||
|
||||
IF OBJECT_ID(N'dbo.s_module', N'U') IS NULL
|
||||
THROW 53301, N'dbo.s_module does not exist.', 1;
|
||||
|
||||
DECLARE @HasPartialArchitecture bit = CASE WHEN
|
||||
OBJECT_ID(N'dbo.s_module_profile', N'U') IS NOT NULL
|
||||
OR OBJECT_ID(N'dbo.s_function_node', N'U') IS NOT NULL
|
||||
OR OBJECT_ID(N'dbo.s_page_node', N'U') IS NOT NULL
|
||||
THEN 1 ELSE 0 END;
|
||||
|
||||
IF @HasPartialArchitecture = 1 AND (
|
||||
COL_LENGTH(N'dbo.s_module', N'b_parent_id') IS NULL
|
||||
OR OBJECT_ID(N'dbo.s_module_field_list', N'U') IS NULL
|
||||
OR OBJECT_ID(N'dbo.s_module_field_edit', N'U') IS NULL
|
||||
OR OBJECT_ID(N'dbo.s_module_field_query', N'U') IS NULL
|
||||
OR OBJECT_ID(N'dbo.s_module_field_group', N'U') IS NULL
|
||||
OR OBJECT_ID(N'dbo.s_module_power', N'U') IS NULL
|
||||
OR OBJECT_ID(N'dbo.s_module_field', N'U') IS NULL
|
||||
OR OBJECT_ID(N'dbo.b_user_power', N'U') IS NULL
|
||||
OR OBJECT_ID(N'dbo.b_user_module', N'U') IS NULL
|
||||
)
|
||||
THROW 53302, N'Unsafe partial module architecture detected. Restore the database before retrying.', 1;
|
||||
|
||||
BEGIN TRANSACTION;
|
||||
|
||||
/*
|
||||
Earlier implementation work may have created these three derived tables while
|
||||
the original module tables were still authoritative. They are regenerated below
|
||||
from the validated source model, so remove them inside this transaction only.
|
||||
*/
|
||||
IF @HasPartialArchitecture = 1
|
||||
BEGIN
|
||||
IF OBJECT_ID(N'dbo.s_page_node', N'U') IS NOT NULL DROP TABLE dbo.s_page_node;
|
||||
IF OBJECT_ID(N'dbo.s_function_node', N'U') IS NOT NULL DROP TABLE dbo.s_function_node;
|
||||
IF OBJECT_ID(N'dbo.s_module_profile', N'U') IS NOT NULL DROP TABLE dbo.s_module_profile;
|
||||
END;
|
||||
GO
|
||||
|
||||
/* RETURN in the first batch means the architecture was already installed. */
|
||||
IF @@TRANCOUNT = 0
|
||||
RETURN;
|
||||
|
||||
/* Preserve the source tables only for the duration of this transaction. */
|
||||
DECLARE @LegacyTables TABLE (b_old sysname NOT NULL, b_legacy sysname NOT NULL, b_xh int NOT NULL);
|
||||
INSERT INTO @LegacyTables VALUES
|
||||
(N's_module_field_list', N'z_legacy_module_field_list', 10),
|
||||
(N's_module_field_edit', N'z_legacy_module_field_edit', 20),
|
||||
(N's_module_field_query', N'z_legacy_module_field_query', 30),
|
||||
(N's_module_field_group', N'z_legacy_module_field_group', 40),
|
||||
(N's_module_auto_code', N'z_legacy_module_auto_code', 50),
|
||||
(N's_module_power', N'z_legacy_module_power', 60),
|
||||
(N's_module_field', N'z_legacy_module_field', 70),
|
||||
(N'b_user_power', N'z_legacy_user_power', 80),
|
||||
(N'b_user_module', N'z_legacy_user_module', 90),
|
||||
(N's_module', N'z_legacy_module', 100);
|
||||
|
||||
IF EXISTS (
|
||||
SELECT 1 FROM @LegacyTables
|
||||
WHERE OBJECT_ID(N'dbo.' + b_old, N'U') IS NOT NULL
|
||||
AND OBJECT_ID(N'dbo.' + b_legacy, N'U') IS NOT NULL
|
||||
)
|
||||
THROW 53303, N'Legacy staging tables already exist.', 1;
|
||||
|
||||
DECLARE @OldName sysname;
|
||||
DECLARE @LegacyName sysname;
|
||||
DECLARE @QualifiedOldName nvarchar(517);
|
||||
DECLARE table_cursor CURSOR LOCAL FAST_FORWARD FOR
|
||||
SELECT b_old, b_legacy FROM @LegacyTables ORDER BY b_xh;
|
||||
OPEN table_cursor;
|
||||
FETCH NEXT FROM table_cursor INTO @OldName, @LegacyName;
|
||||
WHILE @@FETCH_STATUS = 0
|
||||
BEGIN
|
||||
SET @QualifiedOldName = QUOTENAME(N'dbo') + N'.' + QUOTENAME(@OldName);
|
||||
IF OBJECT_ID(@QualifiedOldName, N'U') IS NOT NULL
|
||||
EXEC sys.sp_rename @QualifiedOldName, @LegacyName, N'OBJECT';
|
||||
FETCH NEXT FROM table_cursor INTO @OldName, @LegacyName;
|
||||
END;
|
||||
CLOSE table_cursor;
|
||||
DEALLOCATE table_cursor;
|
||||
|
||||
/* Constraint names are schema-wide and sp_rename does not change them with the table. */
|
||||
DECLARE @ConstraintName sysname;
|
||||
DECLARE @LegacyConstraintName sysname;
|
||||
DECLARE @QualifiedConstraintName nvarchar(517);
|
||||
DECLARE constraint_cursor CURSOR LOCAL FAST_FORWARD FOR
|
||||
SELECT object_row.name,
|
||||
CONVERT(sysname, N'z_legacy_c_' + CONVERT(varchar(20), object_row.object_id))
|
||||
FROM sys.objects AS object_row
|
||||
INNER JOIN sys.tables AS table_row ON table_row.object_id = object_row.parent_object_id
|
||||
INNER JOIN @LegacyTables AS legacy_row ON legacy_row.b_legacy = table_row.name
|
||||
WHERE table_row.schema_id = SCHEMA_ID(N'dbo')
|
||||
AND object_row.type IN (N'C', N'D', N'F', N'PK', N'UQ');
|
||||
OPEN constraint_cursor;
|
||||
FETCH NEXT FROM constraint_cursor INTO @ConstraintName, @LegacyConstraintName;
|
||||
WHILE @@FETCH_STATUS = 0
|
||||
BEGIN
|
||||
SET @QualifiedConstraintName = QUOTENAME(N'dbo') + N'.' + QUOTENAME(@ConstraintName);
|
||||
EXEC sys.sp_rename @QualifiedConstraintName, @LegacyConstraintName, N'OBJECT';
|
||||
FETCH NEXT FROM constraint_cursor INTO @ConstraintName, @LegacyConstraintName;
|
||||
END;
|
||||
CLOSE constraint_cursor;
|
||||
DEALLOCATE constraint_cursor;
|
||||
|
||||
CREATE TABLE dbo.s_module (
|
||||
b_id bigint NOT NULL,
|
||||
b_code varchar(50) NOT NULL,
|
||||
b_name nvarchar(100) NOT NULL,
|
||||
b_i18n varchar(150) NOT NULL,
|
||||
b_module_type varchar(20) NOT NULL,
|
||||
b_canuse int NOT NULL CONSTRAINT DF_s_module_canuse DEFAULT (1),
|
||||
CONSTRAINT PK_s_module PRIMARY KEY (b_id),
|
||||
CONSTRAINT UQ_s_module_code UNIQUE (b_code),
|
||||
CONSTRAINT UQ_s_module_id_type UNIQUE (b_id, b_module_type),
|
||||
CONSTRAINT CK_s_module_type CHECK (b_module_type IN ('page', 'data', 'report', 'dashboard', 'workflow')),
|
||||
CONSTRAINT CK_s_module_canuse CHECK (b_canuse IN (0, 1))
|
||||
);
|
||||
|
||||
CREATE TABLE dbo.s_module_page (
|
||||
b_module_id bigint NOT NULL,
|
||||
b_module_type varchar(20) NOT NULL CONSTRAINT DF_s_module_page_type DEFAULT ('page'),
|
||||
b_route varchar(200) NOT NULL,
|
||||
b_page_mode varchar(20) NOT NULL CONSTRAINT DF_s_module_page_mode DEFAULT ('custom'),
|
||||
b_component_key varchar(100) NOT NULL,
|
||||
CONSTRAINT PK_s_module_page PRIMARY KEY (b_module_id),
|
||||
CONSTRAINT UQ_s_module_page_route UNIQUE (b_route),
|
||||
CONSTRAINT CK_s_module_page_type CHECK (b_module_type = 'page'),
|
||||
CONSTRAINT CK_s_module_page_mode CHECK (b_page_mode IN ('generic', 'custom')),
|
||||
CONSTRAINT FK_s_module_page_module FOREIGN KEY (b_module_id, b_module_type)
|
||||
REFERENCES dbo.s_module (b_id, b_module_type)
|
||||
);
|
||||
|
||||
CREATE TABLE dbo.s_module_data (
|
||||
b_module_id bigint NOT NULL,
|
||||
b_module_type varchar(20) NOT NULL CONSTRAINT DF_s_module_data_type DEFAULT ('data'),
|
||||
b_viewtable varchar(128) NOT NULL,
|
||||
b_savetable varchar(128) NULL,
|
||||
b_keyfield varchar(50) NOT NULL,
|
||||
b_orderfield varchar(500) NULL,
|
||||
CONSTRAINT PK_s_module_data PRIMARY KEY (b_module_id),
|
||||
CONSTRAINT CK_s_module_data_type CHECK (b_module_type = 'data'),
|
||||
CONSTRAINT FK_s_module_data_module FOREIGN KEY (b_module_id, b_module_type)
|
||||
REFERENCES dbo.s_module (b_id, b_module_type)
|
||||
);
|
||||
|
||||
CREATE TABLE dbo.s_module_report (
|
||||
b_module_id bigint NOT NULL,
|
||||
b_module_type varchar(20) NOT NULL CONSTRAINT DF_s_module_report_type DEFAULT ('report'),
|
||||
b_data_module_id bigint NOT NULL,
|
||||
b_profile_id bigint NOT NULL,
|
||||
b_renderer_key varchar(100) NOT NULL,
|
||||
b_options nvarchar(max) NULL,
|
||||
CONSTRAINT PK_s_module_report PRIMARY KEY (b_module_id),
|
||||
CONSTRAINT CK_s_module_report_type CHECK (b_module_type = 'report'),
|
||||
CONSTRAINT FK_s_module_report_module FOREIGN KEY (b_module_id, b_module_type)
|
||||
REFERENCES dbo.s_module (b_id, b_module_type)
|
||||
);
|
||||
|
||||
CREATE TABLE dbo.s_module_dashboard (
|
||||
b_module_id bigint NOT NULL,
|
||||
b_module_type varchar(20) NOT NULL CONSTRAINT DF_s_module_dashboard_type DEFAULT ('dashboard'),
|
||||
b_component_key varchar(100) NOT NULL,
|
||||
b_options nvarchar(max) NULL,
|
||||
CONSTRAINT PK_s_module_dashboard PRIMARY KEY (b_module_id),
|
||||
CONSTRAINT CK_s_module_dashboard_type CHECK (b_module_type = 'dashboard'),
|
||||
CONSTRAINT FK_s_module_dashboard_module FOREIGN KEY (b_module_id, b_module_type)
|
||||
REFERENCES dbo.s_module (b_id, b_module_type)
|
||||
);
|
||||
|
||||
CREATE TABLE dbo.s_module_workflow (
|
||||
b_module_id bigint NOT NULL,
|
||||
b_module_type varchar(20) NOT NULL CONSTRAINT DF_s_module_workflow_type DEFAULT ('workflow'),
|
||||
b_engine_key varchar(100) NOT NULL,
|
||||
b_options nvarchar(max) NULL,
|
||||
CONSTRAINT PK_s_module_workflow PRIMARY KEY (b_module_id),
|
||||
CONSTRAINT CK_s_module_workflow_type CHECK (b_module_type = 'workflow'),
|
||||
CONSTRAINT FK_s_module_workflow_module FOREIGN KEY (b_module_id, b_module_type)
|
||||
REFERENCES dbo.s_module (b_id, b_module_type)
|
||||
);
|
||||
|
||||
CREATE TABLE dbo.s_module_profile (
|
||||
b_id bigint NOT NULL,
|
||||
b_module_id bigint NOT NULL,
|
||||
b_module_type varchar(20) NOT NULL CONSTRAINT DF_s_module_profile_type DEFAULT ('data'),
|
||||
b_code varchar(50) NOT NULL,
|
||||
b_name nvarchar(100) NOT NULL,
|
||||
b_i18n varchar(150) NOT NULL,
|
||||
b_default int NOT NULL CONSTRAINT DF_s_module_profile_default DEFAULT (0),
|
||||
b_canuse int NOT NULL CONSTRAINT DF_s_module_profile_canuse DEFAULT (1),
|
||||
b_xh int NOT NULL CONSTRAINT DF_s_module_profile_xh DEFAULT (0),
|
||||
CONSTRAINT PK_s_module_profile PRIMARY KEY (b_id),
|
||||
CONSTRAINT UQ_s_module_profile_code UNIQUE (b_module_id, b_code),
|
||||
CONSTRAINT UQ_s_module_profile_module_id UNIQUE (b_module_id, b_id),
|
||||
CONSTRAINT CK_s_module_profile_type CHECK (b_module_type = 'data'),
|
||||
CONSTRAINT CK_s_module_profile_flags CHECK (b_default IN (0, 1) AND b_canuse IN (0, 1)),
|
||||
CONSTRAINT FK_s_module_profile_module FOREIGN KEY (b_module_id, b_module_type)
|
||||
REFERENCES dbo.s_module (b_id, b_module_type)
|
||||
);
|
||||
CREATE UNIQUE INDEX UX_s_module_profile_default
|
||||
ON dbo.s_module_profile (b_module_id) WHERE b_default = 1;
|
||||
CREATE INDEX IX_s_module_profile_module
|
||||
ON dbo.s_module_profile (b_module_id, b_canuse, b_xh, b_id);
|
||||
|
||||
ALTER TABLE dbo.s_module_report
|
||||
ADD CONSTRAINT FK_s_module_report_profile
|
||||
FOREIGN KEY (b_data_module_id, b_profile_id)
|
||||
REFERENCES dbo.s_module_profile (b_module_id, b_id);
|
||||
|
||||
CREATE TABLE dbo.s_function_node (
|
||||
b_id bigint NOT NULL,
|
||||
b_code varchar(50) NOT NULL,
|
||||
b_parent_id bigint NULL,
|
||||
b_node_type varchar(20) NOT NULL,
|
||||
b_module_id bigint NULL,
|
||||
b_module_type varchar(20) NULL,
|
||||
b_name nvarchar(150) NOT NULL,
|
||||
b_i18n varchar(150) NOT NULL,
|
||||
b_canmenu int NOT NULL CONSTRAINT DF_s_function_node_canmenu DEFAULT (1),
|
||||
b_canuse int NOT NULL CONSTRAINT DF_s_function_node_canuse DEFAULT (1),
|
||||
b_xh int NOT NULL CONSTRAINT DF_s_function_node_xh DEFAULT (0),
|
||||
CONSTRAINT PK_s_function_node PRIMARY KEY (b_id),
|
||||
CONSTRAINT UQ_s_function_node_code UNIQUE (b_code),
|
||||
CONSTRAINT CK_s_function_node_type CHECK (b_node_type IN ('directory', 'entry')),
|
||||
CONSTRAINT CK_s_function_node_parent CHECK (b_parent_id IS NULL OR b_parent_id <> b_id),
|
||||
CONSTRAINT CK_s_function_node_target CHECK (
|
||||
(b_node_type = 'directory' AND b_module_id IS NULL AND b_module_type IS NULL)
|
||||
OR (b_node_type = 'entry' AND b_module_id IS NOT NULL AND b_module_type = 'page')
|
||||
),
|
||||
CONSTRAINT CK_s_function_node_flags CHECK (b_canmenu IN (0, 1) AND b_canuse IN (0, 1)),
|
||||
CONSTRAINT FK_s_function_node_module FOREIGN KEY (b_module_id, b_module_type)
|
||||
REFERENCES dbo.s_module (b_id, b_module_type)
|
||||
);
|
||||
CREATE INDEX IX_s_function_node_parent
|
||||
ON dbo.s_function_node (b_parent_id, b_canuse, b_xh, b_id);
|
||||
CREATE INDEX IX_s_function_node_module
|
||||
ON dbo.s_function_node (b_module_id, b_canuse, b_id);
|
||||
|
||||
CREATE TABLE dbo.s_page_node (
|
||||
b_id bigint NOT NULL,
|
||||
b_code varchar(50) NOT NULL,
|
||||
b_page_module_id bigint NOT NULL,
|
||||
b_page_module_type varchar(20) NOT NULL CONSTRAINT DF_s_page_node_page_type DEFAULT ('page'),
|
||||
b_parent_id bigint NULL,
|
||||
b_node_type varchar(20) NOT NULL,
|
||||
b_module_id bigint NULL,
|
||||
b_module_type varchar(20) NULL,
|
||||
b_profile_id bigint NULL,
|
||||
b_name nvarchar(150) NOT NULL,
|
||||
b_i18n varchar(150) NOT NULL,
|
||||
b_fixed_condition nvarchar(max) NULL,
|
||||
b_param_mapping nvarchar(max) NULL,
|
||||
b_permission_required int NOT NULL CONSTRAINT DF_s_page_node_permission DEFAULT (0),
|
||||
b_canuse int NOT NULL CONSTRAINT DF_s_page_node_canuse DEFAULT (1),
|
||||
b_xh int NOT NULL CONSTRAINT DF_s_page_node_xh DEFAULT (0),
|
||||
CONSTRAINT PK_s_page_node PRIMARY KEY (b_id),
|
||||
CONSTRAINT UQ_s_page_node_code UNIQUE (b_page_module_id, b_code),
|
||||
CONSTRAINT UQ_s_page_node_page_id UNIQUE (b_page_module_id, b_id),
|
||||
CONSTRAINT CK_s_page_node_page_type CHECK (b_page_module_type = 'page'),
|
||||
CONSTRAINT CK_s_page_node_type CHECK (b_node_type IN ('group', 'tab', 'section', 'module_ref')),
|
||||
CONSTRAINT CK_s_page_node_parent CHECK (b_parent_id IS NULL OR b_parent_id <> b_id),
|
||||
CONSTRAINT CK_s_page_node_target CHECK (
|
||||
(b_node_type IN ('group', 'tab', 'section')
|
||||
AND b_module_id IS NULL AND b_module_type IS NULL AND b_profile_id IS NULL)
|
||||
OR (b_node_type = 'module_ref' AND b_module_id IS NOT NULL
|
||||
AND b_module_type IN ('data', 'report', 'dashboard', 'workflow')
|
||||
AND ((b_module_type = 'data' AND b_profile_id IS NOT NULL)
|
||||
OR (b_module_type <> 'data' AND b_profile_id IS NULL)))
|
||||
),
|
||||
CONSTRAINT CK_s_page_node_flags CHECK (b_permission_required IN (0, 1) AND b_canuse IN (0, 1)),
|
||||
CONSTRAINT FK_s_page_node_page FOREIGN KEY (b_page_module_id, b_page_module_type)
|
||||
REFERENCES dbo.s_module (b_id, b_module_type),
|
||||
CONSTRAINT FK_s_page_node_module FOREIGN KEY (b_module_id, b_module_type)
|
||||
REFERENCES dbo.s_module (b_id, b_module_type),
|
||||
CONSTRAINT FK_s_page_node_profile FOREIGN KEY (b_module_id, b_profile_id)
|
||||
REFERENCES dbo.s_module_profile (b_module_id, b_id)
|
||||
);
|
||||
CREATE INDEX IX_s_page_node_tree
|
||||
ON dbo.s_page_node (b_page_module_id, b_parent_id, b_canuse, b_xh, b_id);
|
||||
CREATE INDEX IX_s_page_node_module
|
||||
ON dbo.s_page_node (b_module_id, b_profile_id, b_page_module_id, b_canuse);
|
||||
|
||||
CREATE TABLE dbo.s_module_field (
|
||||
b_id bigint NOT NULL,
|
||||
b_module_id bigint NOT NULL,
|
||||
b_module_type varchar(20) NOT NULL CONSTRAINT DF_s_module_field_type DEFAULT ('data'),
|
||||
b_field varchar(50) NOT NULL,
|
||||
b_name nvarchar(100) NOT NULL,
|
||||
b_i18n varchar(150) NOT NULL,
|
||||
b_type varchar(30) NOT NULL,
|
||||
b_default_value nvarchar(500) NULL,
|
||||
b_options nvarchar(max) NULL,
|
||||
b_canuse int NOT NULL CONSTRAINT DF_s_module_field_canuse DEFAULT (1),
|
||||
CONSTRAINT PK_s_module_field PRIMARY KEY (b_id),
|
||||
CONSTRAINT UQ_s_module_field UNIQUE (b_module_id, b_field),
|
||||
CONSTRAINT UQ_s_module_field_module_id UNIQUE (b_module_id, b_id),
|
||||
CONSTRAINT CK_s_module_field_type CHECK (b_module_type = 'data'),
|
||||
CONSTRAINT CK_s_module_field_canuse CHECK (b_canuse IN (0, 1)),
|
||||
CONSTRAINT FK_s_module_field_module FOREIGN KEY (b_module_id, b_module_type)
|
||||
REFERENCES dbo.s_module (b_id, b_module_type)
|
||||
);
|
||||
CREATE INDEX IX_s_module_field_module ON dbo.s_module_field (b_module_id, b_canuse, b_id);
|
||||
|
||||
CREATE TABLE dbo.s_module_layout_group (
|
||||
b_id bigint NOT NULL,
|
||||
b_module_id bigint NOT NULL,
|
||||
b_profile_id bigint NOT NULL,
|
||||
b_parent_id bigint NULL,
|
||||
b_scene varchar(20) NOT NULL,
|
||||
b_name nvarchar(100) NOT NULL,
|
||||
b_i18n varchar(150) NOT NULL,
|
||||
b_xh int NOT NULL CONSTRAINT DF_s_module_layout_group_xh DEFAULT (0),
|
||||
b_canuse int NOT NULL CONSTRAINT DF_s_module_layout_group_canuse DEFAULT (1),
|
||||
CONSTRAINT PK_s_module_layout_group PRIMARY KEY (b_id),
|
||||
CONSTRAINT UQ_s_module_layout_group_profile_id UNIQUE (b_profile_id, b_id),
|
||||
CONSTRAINT CK_s_module_layout_group_scene CHECK (b_scene IN ('list', 'form', 'shared')),
|
||||
CONSTRAINT CK_s_module_layout_group_parent CHECK (b_parent_id IS NULL OR b_parent_id <> b_id),
|
||||
CONSTRAINT CK_s_module_layout_group_canuse CHECK (b_canuse IN (0, 1)),
|
||||
CONSTRAINT FK_s_module_layout_group_profile FOREIGN KEY (b_module_id, b_profile_id)
|
||||
REFERENCES dbo.s_module_profile (b_module_id, b_id),
|
||||
CONSTRAINT FK_s_module_layout_group_parent FOREIGN KEY (b_profile_id, b_parent_id)
|
||||
REFERENCES dbo.s_module_layout_group (b_profile_id, b_id)
|
||||
);
|
||||
CREATE INDEX IX_s_module_layout_group_tree
|
||||
ON dbo.s_module_layout_group (b_profile_id, b_scene, b_parent_id, b_xh, b_id);
|
||||
|
||||
CREATE TABLE dbo.s_module_field_list (
|
||||
b_id bigint NOT NULL,
|
||||
b_module_id bigint NOT NULL,
|
||||
b_profile_id bigint NOT NULL,
|
||||
b_field_id bigint NOT NULL,
|
||||
b_group_id bigint NULL,
|
||||
b_i18n varchar(150) NULL,
|
||||
b_visible int NOT NULL CONSTRAINT DF_s_module_field_list_visible DEFAULT (1),
|
||||
b_xh int NOT NULL CONSTRAINT DF_s_module_field_list_xh DEFAULT (0),
|
||||
b_width int NULL,
|
||||
CONSTRAINT PK_s_module_field_list PRIMARY KEY (b_id),
|
||||
CONSTRAINT UQ_s_module_field_list UNIQUE (b_profile_id, b_field_id),
|
||||
CONSTRAINT CK_s_module_field_list_visible CHECK (b_visible IN (0, 1)),
|
||||
CONSTRAINT FK_s_module_field_list_profile FOREIGN KEY (b_module_id, b_profile_id)
|
||||
REFERENCES dbo.s_module_profile (b_module_id, b_id),
|
||||
CONSTRAINT FK_s_module_field_list_field FOREIGN KEY (b_module_id, b_field_id)
|
||||
REFERENCES dbo.s_module_field (b_module_id, b_id),
|
||||
CONSTRAINT FK_s_module_field_list_group FOREIGN KEY (b_profile_id, b_group_id)
|
||||
REFERENCES dbo.s_module_layout_group (b_profile_id, b_id)
|
||||
);
|
||||
CREATE INDEX IX_s_module_field_list_order
|
||||
ON dbo.s_module_field_list (b_profile_id, b_group_id, b_xh, b_id);
|
||||
|
||||
CREATE TABLE dbo.s_module_field_form (
|
||||
b_id bigint NOT NULL,
|
||||
b_module_id bigint NOT NULL,
|
||||
b_profile_id bigint NOT NULL,
|
||||
b_field_id bigint NOT NULL,
|
||||
b_group_id bigint NULL,
|
||||
b_required int NOT NULL CONSTRAINT DF_s_module_field_form_required DEFAULT (0),
|
||||
b_readonly int NOT NULL CONSTRAINT DF_s_module_field_form_readonly DEFAULT (0),
|
||||
b_disabled int NOT NULL CONSTRAINT DF_s_module_field_form_disabled DEFAULT (0),
|
||||
b_visible int NOT NULL CONSTRAINT DF_s_module_field_form_visible DEFAULT (1),
|
||||
b_xh int NOT NULL CONSTRAINT DF_s_module_field_form_xh DEFAULT (0),
|
||||
CONSTRAINT PK_s_module_field_form PRIMARY KEY (b_id),
|
||||
CONSTRAINT UQ_s_module_field_form UNIQUE (b_profile_id, b_field_id),
|
||||
CONSTRAINT CK_s_module_field_form_flags CHECK (
|
||||
b_required IN (0, 1) AND b_readonly IN (0, 1)
|
||||
AND b_disabled IN (0, 1) AND b_visible IN (0, 1)
|
||||
),
|
||||
CONSTRAINT FK_s_module_field_form_profile FOREIGN KEY (b_module_id, b_profile_id)
|
||||
REFERENCES dbo.s_module_profile (b_module_id, b_id),
|
||||
CONSTRAINT FK_s_module_field_form_field FOREIGN KEY (b_module_id, b_field_id)
|
||||
REFERENCES dbo.s_module_field (b_module_id, b_id),
|
||||
CONSTRAINT FK_s_module_field_form_group FOREIGN KEY (b_profile_id, b_group_id)
|
||||
REFERENCES dbo.s_module_layout_group (b_profile_id, b_id)
|
||||
);
|
||||
CREATE INDEX IX_s_module_field_form_order
|
||||
ON dbo.s_module_field_form (b_profile_id, b_group_id, b_xh, b_id);
|
||||
|
||||
CREATE TABLE dbo.s_module_field_query (
|
||||
b_id bigint NOT NULL,
|
||||
b_module_id bigint NOT NULL,
|
||||
b_profile_id bigint NOT NULL,
|
||||
b_field_id bigint NOT NULL,
|
||||
b_component varchar(30) NOT NULL,
|
||||
b_operator varchar(20) NOT NULL,
|
||||
b_default_value nvarchar(500) NULL,
|
||||
b_xh int NOT NULL CONSTRAINT DF_s_module_field_query_xh DEFAULT (0),
|
||||
b_canuse int NOT NULL CONSTRAINT DF_s_module_field_query_canuse DEFAULT (1),
|
||||
CONSTRAINT PK_s_module_field_query PRIMARY KEY (b_id),
|
||||
CONSTRAINT UQ_s_module_field_query UNIQUE (b_profile_id, b_field_id),
|
||||
CONSTRAINT CK_s_module_field_query_operator CHECK (b_operator IN ('=', 'like', 'between', 'in')),
|
||||
CONSTRAINT CK_s_module_field_query_canuse CHECK (b_canuse IN (0, 1)),
|
||||
CONSTRAINT FK_s_module_field_query_profile FOREIGN KEY (b_module_id, b_profile_id)
|
||||
REFERENCES dbo.s_module_profile (b_module_id, b_id),
|
||||
CONSTRAINT FK_s_module_field_query_field FOREIGN KEY (b_module_id, b_field_id)
|
||||
REFERENCES dbo.s_module_field (b_module_id, b_id)
|
||||
);
|
||||
CREATE INDEX IX_s_module_field_query_order
|
||||
ON dbo.s_module_field_query (b_profile_id, b_canuse, b_xh, b_id);
|
||||
|
||||
CREATE TABLE dbo.s_module_action (
|
||||
b_id bigint NOT NULL,
|
||||
b_module_id bigint NOT NULL,
|
||||
b_code varchar(50) NOT NULL,
|
||||
b_name nvarchar(100) NOT NULL,
|
||||
b_i18n varchar(150) NOT NULL,
|
||||
b_xh int NOT NULL CONSTRAINT DF_s_module_action_xh DEFAULT (0),
|
||||
b_canuse int NOT NULL CONSTRAINT DF_s_module_action_canuse DEFAULT (1),
|
||||
CONSTRAINT PK_s_module_action PRIMARY KEY (b_id),
|
||||
CONSTRAINT UQ_s_module_action UNIQUE (b_module_id, b_code),
|
||||
CONSTRAINT UQ_s_module_action_module_id UNIQUE (b_module_id, b_id),
|
||||
CONSTRAINT CK_s_module_action_canuse CHECK (b_canuse IN (0, 1)),
|
||||
CONSTRAINT FK_s_module_action_module FOREIGN KEY (b_module_id) REFERENCES dbo.s_module (b_id)
|
||||
);
|
||||
CREATE INDEX IX_s_module_action_order ON dbo.s_module_action (b_module_id, b_canuse, b_xh, b_id);
|
||||
|
||||
CREATE TABLE dbo.s_module_relation (
|
||||
b_id bigint NOT NULL,
|
||||
b_code varchar(50) NOT NULL,
|
||||
b_name nvarchar(100) NOT NULL,
|
||||
b_i18n varchar(150) NOT NULL,
|
||||
b_parent_module_id bigint NOT NULL,
|
||||
b_parent_field_id bigint NOT NULL,
|
||||
b_child_module_id bigint NOT NULL,
|
||||
b_child_field_id bigint NOT NULL,
|
||||
b_relation_type varchar(20) NOT NULL,
|
||||
b_canuse int NOT NULL CONSTRAINT DF_s_module_relation_canuse DEFAULT (1),
|
||||
CONSTRAINT PK_s_module_relation PRIMARY KEY (b_id),
|
||||
CONSTRAINT UQ_s_module_relation_code UNIQUE (b_parent_module_id, b_code),
|
||||
CONSTRAINT CK_s_module_relation_type CHECK (b_relation_type IN ('one_to_one', 'one_to_many')),
|
||||
CONSTRAINT CK_s_module_relation_modules CHECK (b_parent_module_id <> b_child_module_id),
|
||||
CONSTRAINT FK_s_module_relation_parent_field FOREIGN KEY (b_parent_module_id, b_parent_field_id)
|
||||
REFERENCES dbo.s_module_field (b_module_id, b_id),
|
||||
CONSTRAINT FK_s_module_relation_child_field FOREIGN KEY (b_child_module_id, b_child_field_id)
|
||||
REFERENCES dbo.s_module_field (b_module_id, b_id)
|
||||
);
|
||||
CREATE INDEX IX_s_module_relation_child ON dbo.s_module_relation (b_child_module_id, b_canuse, b_id);
|
||||
|
||||
CREATE TABLE dbo.s_module_auto_code (
|
||||
b_id bigint NOT NULL,
|
||||
b_module_id bigint NOT NULL,
|
||||
b_field_id bigint NOT NULL,
|
||||
b_prefix nvarchar(100) NOT NULL CONSTRAINT DF_s_module_auto_code_prefix DEFAULT (N''),
|
||||
b_date_format varchar(30) NOT NULL CONSTRAINT DF_s_module_auto_code_date_format DEFAULT ('yyyyMM'),
|
||||
b_separator nvarchar(10) NOT NULL CONSTRAINT DF_s_module_auto_code_separator DEFAULT (N'-'),
|
||||
b_sequence_width int NOT NULL CONSTRAINT DF_s_module_auto_code_width DEFAULT (5),
|
||||
b_reset_type varchar(10) NOT NULL CONSTRAINT DF_s_module_auto_code_reset DEFAULT ('month'),
|
||||
b_start_value bigint NOT NULL CONSTRAINT DF_s_module_auto_code_start DEFAULT (1),
|
||||
b_current_period varchar(8) NULL,
|
||||
b_current_value bigint NOT NULL CONSTRAINT DF_s_module_auto_code_current DEFAULT (0),
|
||||
b_canuse int NOT NULL CONSTRAINT DF_s_module_auto_code_canuse DEFAULT (1),
|
||||
CONSTRAINT PK_s_module_auto_code PRIMARY KEY (b_id),
|
||||
CONSTRAINT UQ_s_module_auto_code_module UNIQUE (b_module_id),
|
||||
CONSTRAINT CK_s_module_auto_code_reset CHECK (b_reset_type IN ('none', 'year', 'month', 'day')),
|
||||
CONSTRAINT FK_s_module_auto_code_field FOREIGN KEY (b_module_id, b_field_id)
|
||||
REFERENCES dbo.s_module_field (b_module_id, b_id)
|
||||
);
|
||||
|
||||
CREATE TABLE dbo.s_module_import (
|
||||
b_id bigint NOT NULL,
|
||||
b_module_id bigint NOT NULL,
|
||||
b_profile_id bigint NOT NULL,
|
||||
b_mode varchar(30) NOT NULL,
|
||||
b_options nvarchar(max) NULL,
|
||||
b_canuse int NOT NULL CONSTRAINT DF_s_module_import_canuse DEFAULT (1),
|
||||
CONSTRAINT PK_s_module_import PRIMARY KEY (b_id),
|
||||
CONSTRAINT UQ_s_module_import_profile UNIQUE (b_profile_id),
|
||||
CONSTRAINT FK_s_module_import_profile FOREIGN KEY (b_module_id, b_profile_id)
|
||||
REFERENCES dbo.s_module_profile (b_module_id, b_id)
|
||||
);
|
||||
|
||||
CREATE TABLE dbo.s_module_export (
|
||||
b_id bigint NOT NULL,
|
||||
b_module_id bigint NOT NULL,
|
||||
b_profile_id bigint NOT NULL,
|
||||
b_mode varchar(30) NOT NULL,
|
||||
b_options nvarchar(max) NULL,
|
||||
b_canuse int NOT NULL CONSTRAINT DF_s_module_export_canuse DEFAULT (1),
|
||||
CONSTRAINT PK_s_module_export PRIMARY KEY (b_id),
|
||||
CONSTRAINT UQ_s_module_export_profile UNIQUE (b_profile_id),
|
||||
CONSTRAINT FK_s_module_export_profile FOREIGN KEY (b_module_id, b_profile_id)
|
||||
REFERENCES dbo.s_module_profile (b_module_id, b_id)
|
||||
);
|
||||
|
||||
CREATE TABLE dbo.s_module_file (
|
||||
b_id bigint NOT NULL,
|
||||
b_module_id bigint NOT NULL,
|
||||
b_category_mode varchar(30) NOT NULL,
|
||||
b_options nvarchar(max) NULL,
|
||||
b_canuse int NOT NULL CONSTRAINT DF_s_module_file_canuse DEFAULT (1),
|
||||
CONSTRAINT PK_s_module_file PRIMARY KEY (b_id),
|
||||
CONSTRAINT UQ_s_module_file_module UNIQUE (b_module_id),
|
||||
CONSTRAINT FK_s_module_file_module FOREIGN KEY (b_module_id) REFERENCES dbo.s_module (b_id)
|
||||
);
|
||||
|
||||
CREATE TABLE dbo.s_module_workflow_binding (
|
||||
b_id bigint NOT NULL,
|
||||
b_module_id bigint NOT NULL,
|
||||
b_action_id bigint NULL,
|
||||
b_workflow_module_id bigint NOT NULL,
|
||||
b_workflow_module_type varchar(20) NOT NULL CONSTRAINT DF_s_module_workflow_binding_type DEFAULT ('workflow'),
|
||||
b_event_code varchar(50) NOT NULL,
|
||||
b_xh int NOT NULL CONSTRAINT DF_s_module_workflow_binding_xh DEFAULT (0),
|
||||
b_canuse int NOT NULL CONSTRAINT DF_s_module_workflow_binding_canuse DEFAULT (1),
|
||||
CONSTRAINT PK_s_module_workflow_binding PRIMARY KEY (b_id),
|
||||
CONSTRAINT UQ_s_module_workflow_binding UNIQUE (b_module_id, b_event_code, b_workflow_module_id),
|
||||
CONSTRAINT CK_s_module_workflow_binding_type CHECK (b_workflow_module_type = 'workflow'),
|
||||
CONSTRAINT FK_s_module_workflow_binding_module FOREIGN KEY (b_module_id) REFERENCES dbo.s_module (b_id),
|
||||
CONSTRAINT FK_s_module_workflow_binding_action FOREIGN KEY (b_module_id, b_action_id)
|
||||
REFERENCES dbo.s_module_action (b_module_id, b_id),
|
||||
CONSTRAINT FK_s_module_workflow_binding_workflow FOREIGN KEY (b_workflow_module_id, b_workflow_module_type)
|
||||
REFERENCES dbo.s_module (b_id, b_module_type)
|
||||
);
|
||||
|
||||
CREATE TABLE dbo.b_role (
|
||||
b_id bigint NOT NULL,
|
||||
b_code varchar(50) NOT NULL,
|
||||
b_name nvarchar(100) NOT NULL,
|
||||
b_i18n varchar(150) NOT NULL,
|
||||
b_is_super int NOT NULL CONSTRAINT DF_b_role_super DEFAULT (0),
|
||||
b_canuse int NOT NULL CONSTRAINT DF_b_role_canuse DEFAULT (1),
|
||||
b_xh int NOT NULL CONSTRAINT DF_b_role_xh DEFAULT (0),
|
||||
CONSTRAINT PK_b_role PRIMARY KEY (b_id),
|
||||
CONSTRAINT UQ_b_role_code UNIQUE (b_code),
|
||||
CONSTRAINT CK_b_role_flags CHECK (b_is_super IN (0, 1) AND b_canuse IN (0, 1))
|
||||
);
|
||||
|
||||
CREATE TABLE dbo.b_user_role (
|
||||
b_id bigint NOT NULL,
|
||||
b_user_id bigint NOT NULL,
|
||||
b_role_id bigint NOT NULL,
|
||||
b_inputuser_id bigint NOT NULL,
|
||||
b_inputdatetime datetime2 NOT NULL CONSTRAINT DF_b_user_role_time DEFAULT (SYSDATETIME()),
|
||||
CONSTRAINT PK_b_user_role PRIMARY KEY (b_id),
|
||||
CONSTRAINT UQ_b_user_role UNIQUE (b_user_id, b_role_id),
|
||||
CONSTRAINT FK_b_user_role_user FOREIGN KEY (b_user_id) REFERENCES dbo.b_user (b_id),
|
||||
CONSTRAINT FK_b_user_role_role FOREIGN KEY (b_role_id) REFERENCES dbo.b_role (b_id)
|
||||
);
|
||||
|
||||
CREATE TABLE dbo.b_role_function_node (
|
||||
b_id bigint NOT NULL,
|
||||
b_role_id bigint NOT NULL,
|
||||
b_function_node_id bigint NOT NULL,
|
||||
CONSTRAINT PK_b_role_function_node PRIMARY KEY (b_id),
|
||||
CONSTRAINT UQ_b_role_function_node UNIQUE (b_role_id, b_function_node_id),
|
||||
CONSTRAINT FK_b_role_function_node_role FOREIGN KEY (b_role_id) REFERENCES dbo.b_role (b_id),
|
||||
CONSTRAINT FK_b_role_function_node_node FOREIGN KEY (b_function_node_id) REFERENCES dbo.s_function_node (b_id)
|
||||
);
|
||||
|
||||
CREATE TABLE dbo.b_role_page_node (
|
||||
b_id bigint NOT NULL,
|
||||
b_role_id bigint NOT NULL,
|
||||
b_page_node_id bigint NOT NULL,
|
||||
CONSTRAINT PK_b_role_page_node PRIMARY KEY (b_id),
|
||||
CONSTRAINT UQ_b_role_page_node UNIQUE (b_role_id, b_page_node_id),
|
||||
CONSTRAINT FK_b_role_page_node_role FOREIGN KEY (b_role_id) REFERENCES dbo.b_role (b_id),
|
||||
CONSTRAINT FK_b_role_page_node_node FOREIGN KEY (b_page_node_id) REFERENCES dbo.s_page_node (b_id)
|
||||
);
|
||||
|
||||
CREATE TABLE dbo.b_role_action (
|
||||
b_id bigint NOT NULL,
|
||||
b_role_id bigint NOT NULL,
|
||||
b_action_id bigint NOT NULL,
|
||||
CONSTRAINT PK_b_role_action PRIMARY KEY (b_id),
|
||||
CONSTRAINT UQ_b_role_action UNIQUE (b_role_id, b_action_id),
|
||||
CONSTRAINT FK_b_role_action_role FOREIGN KEY (b_role_id) REFERENCES dbo.b_role (b_id),
|
||||
CONSTRAINT FK_b_role_action_action FOREIGN KEY (b_action_id) REFERENCES dbo.s_module_action (b_id)
|
||||
);
|
||||
|
||||
/* Reserved contract for later backend row-scope enforcement. */
|
||||
CREATE TABLE dbo.b_role_data_scope (
|
||||
b_id bigint NOT NULL,
|
||||
b_role_id bigint NOT NULL,
|
||||
b_module_id bigint NOT NULL,
|
||||
b_scope_type varchar(20) NOT NULL,
|
||||
b_options nvarchar(max) NULL,
|
||||
CONSTRAINT PK_b_role_data_scope PRIMARY KEY (b_id),
|
||||
CONSTRAINT UQ_b_role_data_scope UNIQUE (b_role_id, b_module_id),
|
||||
CONSTRAINT CK_b_role_data_scope_type CHECK (
|
||||
b_scope_type IN ('all', 'self', 'department', 'custom')
|
||||
),
|
||||
CONSTRAINT FK_b_role_data_scope_role FOREIGN KEY (b_role_id) REFERENCES dbo.b_role (b_id),
|
||||
CONSTRAINT FK_b_role_data_scope_module FOREIGN KEY (b_module_id) REFERENCES dbo.s_module (b_id)
|
||||
);
|
||||
CREATE INDEX IX_b_role_data_scope_module
|
||||
ON dbo.b_role_data_scope (b_module_id, b_role_id);
|
||||
|
||||
CREATE TABLE dbo.b_user_function_node (
|
||||
b_id bigint NOT NULL,
|
||||
b_user_id bigint NOT NULL,
|
||||
b_function_node_id bigint NOT NULL,
|
||||
b_inputuser_id bigint NOT NULL,
|
||||
b_inputdatetime datetime2 NOT NULL CONSTRAINT DF_b_user_function_node_time DEFAULT (SYSDATETIME()),
|
||||
CONSTRAINT PK_b_user_function_node PRIMARY KEY (b_id),
|
||||
CONSTRAINT UQ_b_user_function_node UNIQUE (b_user_id, b_function_node_id),
|
||||
CONSTRAINT FK_b_user_function_node_user FOREIGN KEY (b_user_id) REFERENCES dbo.b_user (b_id),
|
||||
CONSTRAINT FK_b_user_function_node_node FOREIGN KEY (b_function_node_id) REFERENCES dbo.s_function_node (b_id)
|
||||
);
|
||||
|
||||
CREATE TABLE dbo.b_user_page_node (
|
||||
b_id bigint NOT NULL,
|
||||
b_user_id bigint NOT NULL,
|
||||
b_page_node_id bigint NOT NULL,
|
||||
b_inputuser_id bigint NOT NULL,
|
||||
b_inputdatetime datetime2 NOT NULL CONSTRAINT DF_b_user_page_node_time DEFAULT (SYSDATETIME()),
|
||||
CONSTRAINT PK_b_user_page_node PRIMARY KEY (b_id),
|
||||
CONSTRAINT UQ_b_user_page_node UNIQUE (b_user_id, b_page_node_id),
|
||||
CONSTRAINT FK_b_user_page_node_user FOREIGN KEY (b_user_id) REFERENCES dbo.b_user (b_id),
|
||||
CONSTRAINT FK_b_user_page_node_node FOREIGN KEY (b_page_node_id) REFERENCES dbo.s_page_node (b_id)
|
||||
);
|
||||
|
||||
CREATE TABLE dbo.b_user_action (
|
||||
b_id bigint NOT NULL,
|
||||
b_user_id bigint NOT NULL,
|
||||
b_action_id bigint NOT NULL,
|
||||
b_inputuser_id bigint NOT NULL,
|
||||
b_inputdatetime datetime2 NOT NULL CONSTRAINT DF_b_user_action_time DEFAULT (SYSDATETIME()),
|
||||
CONSTRAINT PK_b_user_action PRIMARY KEY (b_id),
|
||||
CONSTRAINT UQ_b_user_action UNIQUE (b_user_id, b_action_id),
|
||||
CONSTRAINT FK_b_user_action_user FOREIGN KEY (b_user_id) REFERENCES dbo.b_user (b_id),
|
||||
CONSTRAINT FK_b_user_action_action FOREIGN KEY (b_action_id) REFERENCES dbo.s_module_action (b_id)
|
||||
);
|
||||
|
||||
CREATE INDEX IX_b_user_role_user ON dbo.b_user_role (b_user_id, b_role_id);
|
||||
CREATE INDEX IX_b_user_function_node_user ON dbo.b_user_function_node (b_user_id, b_function_node_id);
|
||||
CREATE INDEX IX_b_user_page_node_user ON dbo.b_user_page_node (b_user_id, b_page_node_id);
|
||||
CREATE INDEX IX_b_user_action_user ON dbo.b_user_action (b_user_id, b_action_id);
|
||||
|
||||
/* Convert resources. Directories move exclusively to the function tree. */
|
||||
INSERT INTO dbo.s_module (b_id, b_code, b_name, b_i18n, b_module_type, b_canuse)
|
||||
SELECT b_id, b_code, b_name, 'meta.module.' + CONVERT(varchar(30), b_id), b_module_type, b_canuse
|
||||
FROM dbo.z_legacy_module
|
||||
WHERE b_module_type IN ('page', 'data');
|
||||
|
||||
INSERT INTO dbo.s_module_page (b_module_id, b_route, b_page_mode, b_component_key)
|
||||
SELECT
|
||||
b_id,
|
||||
CASE WHEN b_code = 'm_metadata' THEN '/system/module-management' ELSE b_route END,
|
||||
'custom',
|
||||
CASE b_route
|
||||
WHEN '/base/othercompany' THEN 'base_othercompany'
|
||||
WHEN '/base/contact' THEN 'base_contact'
|
||||
WHEN '/base/otherdata' THEN 'base_otherdata'
|
||||
WHEN '/system/metadata' THEN 'module_management'
|
||||
WHEN '/system/module-management' THEN 'module_management'
|
||||
WHEN '/system/i18n-type' THEN 'i18n_type'
|
||||
WHEN '/system/login-log' THEN 'login_log'
|
||||
WHEN '/system/user' THEN 'user_management'
|
||||
ELSE b_code
|
||||
END
|
||||
FROM dbo.z_legacy_module
|
||||
WHERE b_module_type = 'page';
|
||||
|
||||
INSERT INTO dbo.s_module_data (b_module_id, b_viewtable, b_savetable, b_keyfield, b_orderfield)
|
||||
SELECT b_id, b_viewtable, b_savetable, ISNULL(NULLIF(b_keyfield, ''), 'b_id'), b_orderfield
|
||||
FROM dbo.z_legacy_module
|
||||
WHERE b_module_type = 'data';
|
||||
|
||||
INSERT INTO dbo.s_module_profile (
|
||||
b_id, b_module_id, b_code, b_name, b_i18n, b_default, b_canuse, b_xh
|
||||
)
|
||||
SELECT b_id, b_id, 'default', N'默认', 'meta.profile.' + CONVERT(varchar(30), b_id), 1, 1, 10
|
||||
FROM dbo.z_legacy_module
|
||||
WHERE b_module_type = 'data';
|
||||
|
||||
INSERT INTO dbo.s_function_node (
|
||||
b_id, b_code, b_parent_id, b_node_type, b_module_id, b_module_type,
|
||||
b_name, b_i18n, b_canmenu, b_canuse, b_xh
|
||||
)
|
||||
SELECT
|
||||
b_id, b_code, b_parent_id,
|
||||
CASE WHEN b_module_type = 'directory' THEN 'directory' ELSE 'entry' END,
|
||||
CASE WHEN b_module_type = 'page' THEN b_id ELSE NULL END,
|
||||
CASE WHEN b_module_type = 'page' THEN 'page' ELSE NULL END,
|
||||
b_name, 'meta.node.' + CONVERT(varchar(30), b_id), b_canmenu, b_canuse, b_xh
|
||||
FROM dbo.z_legacy_module
|
||||
WHERE b_module_type IN ('directory', 'page');
|
||||
|
||||
IF OBJECT_ID(N'dbo.b_other_bmfl', N'U') IS NOT NULL
|
||||
BEGIN
|
||||
DECLARE @OtherDataPageId bigint;
|
||||
SELECT @OtherDataPageId = b_id FROM dbo.z_legacy_module
|
||||
WHERE b_code = 'base_otherdata' AND b_module_type = 'page';
|
||||
|
||||
IF @OtherDataPageId IS NOT NULL
|
||||
BEGIN
|
||||
IF EXISTS (
|
||||
SELECT 1
|
||||
FROM dbo.b_other_bmfl source_row
|
||||
LEFT JOIN dbo.z_legacy_module module_row
|
||||
ON module_row.b_code = source_row.b_module_code
|
||||
AND module_row.b_module_type = 'data'
|
||||
WHERE source_row.b_node_type = 'module' AND module_row.b_id IS NULL
|
||||
)
|
||||
THROW 53304, N'b_other_bmfl contains unresolved module references.', 1;
|
||||
|
||||
INSERT INTO dbo.s_page_node (
|
||||
b_id, b_code, b_page_module_id, b_parent_id, b_node_type,
|
||||
b_module_id, b_module_type, b_profile_id, b_name, b_i18n, b_canuse, b_xh
|
||||
)
|
||||
SELECT
|
||||
source_row.b_id,
|
||||
'node_' + CONVERT(varchar(30), source_row.b_id),
|
||||
@OtherDataPageId,
|
||||
source_row.b_parent_id,
|
||||
CASE WHEN source_row.b_node_type = 'module' THEN 'module_ref' ELSE 'group' END,
|
||||
module_row.b_id,
|
||||
CASE WHEN module_row.b_id IS NULL THEN NULL ELSE 'data' END,
|
||||
module_row.b_id,
|
||||
source_row.b_name,
|
||||
'meta.node.' + CONVERT(varchar(30), source_row.b_id),
|
||||
source_row.b_canuse,
|
||||
source_row.b_xh
|
||||
FROM dbo.b_other_bmfl source_row
|
||||
LEFT JOIN dbo.z_legacy_module module_row
|
||||
ON module_row.b_code = source_row.b_module_code
|
||||
AND module_row.b_module_type = 'data';
|
||||
END;
|
||||
END;
|
||||
|
||||
INSERT INTO dbo.s_page_node (
|
||||
b_id, b_code, b_page_module_id, b_parent_id, b_node_type,
|
||||
b_module_id, b_module_type, b_profile_id, b_name, b_i18n, b_canuse, b_xh
|
||||
)
|
||||
SELECT
|
||||
data_module.b_id,
|
||||
'module_' + data_module.b_code,
|
||||
data_module.b_parent_id,
|
||||
NULL,
|
||||
'module_ref',
|
||||
data_module.b_id,
|
||||
'data',
|
||||
data_module.b_id,
|
||||
data_module.b_name,
|
||||
'meta.node.' + CONVERT(varchar(30), data_module.b_id),
|
||||
data_module.b_canuse,
|
||||
data_module.b_xh
|
||||
FROM dbo.z_legacy_module data_module
|
||||
INNER JOIN dbo.z_legacy_module page_module
|
||||
ON page_module.b_id = data_module.b_parent_id AND page_module.b_module_type = 'page'
|
||||
WHERE data_module.b_module_type = 'data'
|
||||
AND NOT EXISTS (
|
||||
SELECT 1 FROM dbo.s_page_node node WHERE node.b_module_id = data_module.b_id
|
||||
);
|
||||
|
||||
INSERT INTO dbo.s_module_field (
|
||||
b_id, b_module_id, b_field, b_name, b_i18n, b_type,
|
||||
b_default_value, b_options, b_canuse
|
||||
)
|
||||
SELECT
|
||||
b_id, b_module_id, b_field, b_name,
|
||||
'meta.field.' + CONVERT(varchar(30), b_id), b_type,
|
||||
b_default_value, b_options, b_canuse
|
||||
FROM dbo.z_legacy_module_field;
|
||||
|
||||
INSERT INTO dbo.s_module_layout_group (
|
||||
b_id, b_module_id, b_profile_id, b_parent_id, b_scene,
|
||||
b_name, b_i18n, b_xh, b_canuse
|
||||
)
|
||||
SELECT
|
||||
b_id, b_module_id, b_module_id, b_parent_id, 'shared',
|
||||
b_title, 'meta.group.' + CONVERT(varchar(30), b_id), b_xh, b_canuse
|
||||
FROM dbo.z_legacy_module_field_group;
|
||||
|
||||
INSERT INTO dbo.s_module_field_list (
|
||||
b_id, b_module_id, b_profile_id, b_field_id, b_group_id,
|
||||
b_i18n, b_visible, b_xh, b_width
|
||||
)
|
||||
SELECT b_id, b_module_id, b_module_id, b_field_id, b_group_id,
|
||||
b_i18n, b_visible, b_xh, b_width
|
||||
FROM dbo.z_legacy_module_field_list
|
||||
WHERE b_field_id IS NOT NULL;
|
||||
|
||||
INSERT INTO dbo.s_module_field_form (
|
||||
b_id, b_module_id, b_profile_id, b_field_id, b_group_id,
|
||||
b_required, b_readonly, b_disabled, b_visible, b_xh
|
||||
)
|
||||
SELECT b_id, b_module_id, b_module_id, b_field_id, b_group_id,
|
||||
b_required, b_readonly, b_disabled, b_visible, b_xh
|
||||
FROM dbo.z_legacy_module_field_edit;
|
||||
|
||||
INSERT INTO dbo.s_module_field_query (
|
||||
b_id, b_module_id, b_profile_id, b_field_id, b_component,
|
||||
b_operator, b_default_value, b_xh, b_canuse
|
||||
)
|
||||
SELECT b_id, b_module_id, b_module_id, b_field_id, b_component,
|
||||
b_operator, b_default_value, b_xh, b_canuse
|
||||
FROM dbo.z_legacy_module_field_query;
|
||||
|
||||
INSERT INTO dbo.s_module_action (
|
||||
b_id, b_module_id, b_code, b_name, b_i18n, b_xh, b_canuse
|
||||
)
|
||||
SELECT b_id, b_module_id, b_code, b_name,
|
||||
'meta.action.' + CONVERT(varchar(30), b_id), b_xh, b_canuse
|
||||
FROM dbo.z_legacy_module_power
|
||||
WHERE b_module_id IN (SELECT b_id FROM dbo.s_module);
|
||||
|
||||
ALTER TABLE dbo.s_function_node
|
||||
ADD CONSTRAINT FK_s_function_node_parent
|
||||
FOREIGN KEY (b_parent_id) REFERENCES dbo.s_function_node (b_id);
|
||||
|
||||
ALTER TABLE dbo.s_page_node
|
||||
ADD CONSTRAINT FK_s_page_node_parent
|
||||
FOREIGN KEY (b_page_module_id, b_parent_id)
|
||||
REFERENCES dbo.s_page_node (b_page_module_id, b_id);
|
||||
|
||||
IF OBJECT_ID(N'dbo.z_legacy_module_auto_code', N'U') IS NOT NULL
|
||||
BEGIN
|
||||
INSERT INTO dbo.s_module_auto_code (
|
||||
b_id, b_module_id, b_field_id, b_prefix, b_date_format, b_separator,
|
||||
b_sequence_width, b_reset_type, b_start_value, b_current_period,
|
||||
b_current_value, b_canuse
|
||||
)
|
||||
SELECT b_id, b_module_id, b_field_id, b_prefix, b_date_format, b_separator,
|
||||
b_sequence_width, b_reset_type, b_start_value, b_current_period,
|
||||
b_current_value, b_canuse
|
||||
FROM dbo.z_legacy_module_auto_code;
|
||||
END;
|
||||
|
||||
DECLARE @AdminId bigint;
|
||||
SELECT TOP (1) @AdminId = b_id FROM dbo.b_user
|
||||
WHERE b_canuse = 1
|
||||
ORDER BY CASE WHEN b_account = N'g3soft' THEN 0 ELSE 1 END, b_id;
|
||||
IF @AdminId IS NULL
|
||||
THROW 53305, N'Enabled administrator user not found.', 1;
|
||||
|
||||
INSERT INTO dbo.b_role (b_id, b_code, b_name, b_i18n, b_is_super, b_canuse, b_xh)
|
||||
VALUES (@AdminId, 'system_admin', N'系统管理员', 'meta.role.' + CONVERT(varchar(30), @AdminId), 1, 1, 0);
|
||||
INSERT INTO dbo.b_user_role (b_id, b_user_id, b_role_id, b_inputuser_id)
|
||||
VALUES (@AdminId, @AdminId, @AdminId, @AdminId);
|
||||
|
||||
;WITH function_grants AS (
|
||||
SELECT
|
||||
MIN(grant_row.b_id) AS b_id,
|
||||
grant_row.b_user_id,
|
||||
COALESCE(page_module.b_id, data_parent.b_id) AS b_function_node_id,
|
||||
MIN(grant_row.b_inputuser_id) AS b_inputuser_id,
|
||||
MIN(grant_row.b_inputdatetime) AS b_inputdatetime
|
||||
FROM dbo.z_legacy_user_module grant_row
|
||||
INNER JOIN dbo.z_legacy_module granted_module ON granted_module.b_id = grant_row.b_module_id
|
||||
LEFT JOIN dbo.z_legacy_module page_module
|
||||
ON page_module.b_id = granted_module.b_id AND granted_module.b_module_type = 'page'
|
||||
LEFT JOIN dbo.z_legacy_module data_parent
|
||||
ON data_parent.b_id = granted_module.b_parent_id
|
||||
AND granted_module.b_module_type = 'data'
|
||||
AND data_parent.b_module_type = 'page'
|
||||
GROUP BY grant_row.b_user_id, COALESCE(page_module.b_id, data_parent.b_id)
|
||||
)
|
||||
INSERT INTO dbo.b_user_function_node (
|
||||
b_id, b_user_id, b_function_node_id, b_inputuser_id, b_inputdatetime
|
||||
)
|
||||
SELECT b_id, b_user_id, b_function_node_id, b_inputuser_id, b_inputdatetime
|
||||
FROM function_grants
|
||||
WHERE b_function_node_id IS NOT NULL AND b_user_id <> @AdminId;
|
||||
|
||||
INSERT INTO dbo.b_user_action (
|
||||
b_id, b_user_id, b_action_id, b_inputuser_id, b_inputdatetime
|
||||
)
|
||||
SELECT grant_row.b_id, grant_row.b_user_id, grant_row.b_power_id,
|
||||
grant_row.b_inputuser_id, grant_row.b_inputdatetime
|
||||
FROM dbo.z_legacy_user_power grant_row
|
||||
INNER JOIN dbo.s_module_action action_row ON action_row.b_id = grant_row.b_power_id
|
||||
WHERE grant_row.b_user_id <> @AdminId;
|
||||
|
||||
/* Keep existing translated values while moving managed entities to ID-based keys. */
|
||||
UPDATE i18n
|
||||
SET b_key = 'meta.module.' + CONVERT(varchar(30), module_row.b_id)
|
||||
FROM dbo.b_i18n i18n
|
||||
INNER JOIN dbo.z_legacy_module module_row ON module_row.b_i18n = i18n.b_key
|
||||
WHERE module_row.b_module_type IN ('page', 'data');
|
||||
|
||||
UPDATE i18n
|
||||
SET b_key = 'meta.node.' + CONVERT(varchar(30), module_row.b_id)
|
||||
FROM dbo.b_i18n i18n
|
||||
INNER JOIN dbo.z_legacy_module module_row ON module_row.b_i18n = i18n.b_key
|
||||
WHERE module_row.b_module_type = 'directory';
|
||||
|
||||
UPDATE i18n
|
||||
SET b_key = 'meta.field.' + CONVERT(varchar(30), field_row.b_id)
|
||||
FROM dbo.b_i18n i18n
|
||||
INNER JOIN dbo.z_legacy_module_field field_row ON field_row.b_i18n = i18n.b_key;
|
||||
|
||||
UPDATE i18n
|
||||
SET b_key = 'meta.action.' + CONVERT(varchar(30), action_row.b_id)
|
||||
FROM dbo.b_i18n i18n
|
||||
INNER JOIN dbo.z_legacy_module_power action_row ON action_row.b_i18n = i18n.b_key;
|
||||
|
||||
IF EXISTS (
|
||||
SELECT 1 FROM dbo.s_module module_row
|
||||
LEFT JOIN dbo.s_module_page page_row ON page_row.b_module_id = module_row.b_id
|
||||
LEFT JOIN dbo.s_module_data data_row ON data_row.b_module_id = module_row.b_id
|
||||
WHERE (module_row.b_module_type = 'page' AND page_row.b_module_id IS NULL)
|
||||
OR (module_row.b_module_type = 'data' AND data_row.b_module_id IS NULL)
|
||||
)
|
||||
THROW 53306, N'Module subtype conversion is incomplete.', 1;
|
||||
|
||||
IF EXISTS (
|
||||
SELECT 1 FROM dbo.s_page_node node
|
||||
LEFT JOIN dbo.s_module_profile profile_row ON profile_row.b_id = node.b_profile_id
|
||||
WHERE node.b_module_type = 'data'
|
||||
AND (profile_row.b_id IS NULL OR profile_row.b_module_id <> node.b_module_id)
|
||||
)
|
||||
THROW 53307, N'Page node profile conversion is invalid.', 1;
|
||||
|
||||
/* Remove the source model only after every conversion check succeeds. */
|
||||
DROP TABLE dbo.z_legacy_user_power;
|
||||
DROP TABLE dbo.z_legacy_user_module;
|
||||
IF OBJECT_ID(N'dbo.z_legacy_module_auto_code', N'U') IS NOT NULL DROP TABLE dbo.z_legacy_module_auto_code;
|
||||
DROP TABLE dbo.z_legacy_module_field_list;
|
||||
DROP TABLE dbo.z_legacy_module_field_edit;
|
||||
DROP TABLE dbo.z_legacy_module_field_query;
|
||||
DROP TABLE dbo.z_legacy_module_field_group;
|
||||
DROP TABLE dbo.z_legacy_module_power;
|
||||
DROP TABLE dbo.z_legacy_module_field;
|
||||
DROP TABLE dbo.z_legacy_module;
|
||||
IF OBJECT_ID(N'dbo.b_other_bmfl', N'U') IS NOT NULL DROP TABLE dbo.b_other_bmfl;
|
||||
|
||||
COMMIT TRANSACTION;
|
||||
@@ -0,0 +1,14 @@
|
||||
/* 删除 b_other_bmfl 分类树表。
|
||||
其他数据分类树已完全迁移至 s_module(b_module_type = 'data_category'),
|
||||
前端不再读写此表。 */
|
||||
SET NOCOUNT ON;
|
||||
SET XACT_ABORT ON;
|
||||
|
||||
BEGIN TRANSACTION;
|
||||
|
||||
IF OBJECT_ID(N'dbo.b_other_bmfl', N'U') IS NOT NULL
|
||||
BEGIN
|
||||
DROP TABLE dbo.b_other_bmfl;
|
||||
END;
|
||||
|
||||
COMMIT TRANSACTION;
|
||||
@@ -1,468 +0,0 @@
|
||||
/* Runtime read contracts for the module architecture. */
|
||||
SET NOCOUNT ON;
|
||||
SET XACT_ABORT ON;
|
||||
|
||||
IF EXISTS (
|
||||
SELECT required.name
|
||||
FROM (VALUES
|
||||
(N's_module'), (N's_module_page'), (N's_module_data'), (N's_module_report'),
|
||||
(N's_module_dashboard'), (N's_module_workflow'), (N's_function_node'),
|
||||
(N's_page_node'), (N's_module_profile'), (N's_module_field'),
|
||||
(N's_module_field_list'), (N's_module_field_form'), (N's_module_field_query'),
|
||||
(N's_module_action'), (N'b_role'), (N'b_user_role'),
|
||||
(N'b_role_function_node'), (N'b_role_page_node'), (N'b_role_action'),
|
||||
(N'b_user_function_node'), (N'b_user_page_node'), (N'b_user_action')
|
||||
) AS required(name)
|
||||
LEFT JOIN sys.tables AS actual
|
||||
ON actual.name = required.name AND actual.schema_id = SCHEMA_ID(N'dbo')
|
||||
WHERE actual.object_id IS NULL
|
||||
)
|
||||
THROW 53400, N'Module architecture is incomplete. Run migration 033 first.', 1;
|
||||
GO
|
||||
|
||||
CREATE OR ALTER VIEW dbo.v_s_function_node
|
||||
AS
|
||||
SELECT
|
||||
node.b_id,
|
||||
node.b_code,
|
||||
node.b_parent_id,
|
||||
node.b_node_type,
|
||||
node.b_module_id,
|
||||
node.b_name,
|
||||
node.b_i18n,
|
||||
node.b_canmenu,
|
||||
node.b_canuse,
|
||||
node.b_xh,
|
||||
module_row.b_code AS b_module_code,
|
||||
module_row.b_name AS b_module_name,
|
||||
module_row.b_i18n AS b_module_i18n,
|
||||
page_row.b_route,
|
||||
page_row.b_page_mode,
|
||||
page_row.b_component_key
|
||||
FROM dbo.s_function_node AS node
|
||||
LEFT JOIN dbo.s_module AS module_row ON module_row.b_id = node.b_module_id
|
||||
LEFT JOIN dbo.s_module_page AS page_row ON page_row.b_module_id = node.b_module_id;
|
||||
GO
|
||||
|
||||
CREATE OR ALTER VIEW dbo.v_s_page_node
|
||||
AS
|
||||
SELECT
|
||||
node.b_id,
|
||||
node.b_code,
|
||||
node.b_page_module_id,
|
||||
node.b_parent_id,
|
||||
node.b_node_type,
|
||||
node.b_module_id,
|
||||
node.b_profile_id,
|
||||
node.b_name,
|
||||
node.b_i18n,
|
||||
node.b_fixed_condition,
|
||||
node.b_param_mapping,
|
||||
node.b_permission_required,
|
||||
node.b_canuse,
|
||||
node.b_xh,
|
||||
page_module.b_code AS b_page_code,
|
||||
page_module.b_name AS b_page_name,
|
||||
page_module.b_i18n AS b_page_i18n,
|
||||
ref_module.b_code AS b_module_code,
|
||||
ref_module.b_name AS b_module_name,
|
||||
ref_module.b_i18n AS b_module_i18n,
|
||||
profile_row.b_code AS b_profile_code,
|
||||
profile_row.b_name AS b_profile_name,
|
||||
profile_row.b_i18n AS b_profile_i18n
|
||||
FROM dbo.s_page_node AS node
|
||||
INNER JOIN dbo.s_module AS page_module ON page_module.b_id = node.b_page_module_id
|
||||
LEFT JOIN dbo.s_module AS ref_module ON ref_module.b_id = node.b_module_id
|
||||
LEFT JOIN dbo.s_module_profile AS profile_row ON profile_row.b_id = node.b_profile_id;
|
||||
GO
|
||||
|
||||
CREATE OR ALTER VIEW dbo.v_s_module_profile
|
||||
AS
|
||||
SELECT
|
||||
profile_row.b_id,
|
||||
profile_row.b_module_id,
|
||||
profile_row.b_code,
|
||||
profile_row.b_name,
|
||||
profile_row.b_i18n,
|
||||
profile_row.b_default,
|
||||
profile_row.b_canuse,
|
||||
profile_row.b_xh,
|
||||
module_row.b_code AS b_module_code,
|
||||
module_row.b_name AS b_module_name,
|
||||
module_row.b_i18n AS b_module_i18n,
|
||||
module_row.b_module_type
|
||||
FROM dbo.s_module_profile AS profile_row
|
||||
INNER JOIN dbo.s_module AS module_row ON module_row.b_id = profile_row.b_module_id;
|
||||
GO
|
||||
|
||||
CREATE OR ALTER VIEW dbo.v_s_module_runtime
|
||||
AS
|
||||
SELECT
|
||||
module_row.b_id AS b_module_id,
|
||||
module_row.b_code AS b_module_code,
|
||||
module_row.b_name AS b_module_name,
|
||||
module_row.b_i18n AS b_module_i18n,
|
||||
module_row.b_module_type,
|
||||
profile_row.b_id AS b_profile_id,
|
||||
profile_row.b_code AS b_profile_code,
|
||||
profile_row.b_name AS b_profile_name,
|
||||
profile_row.b_i18n AS b_profile_i18n,
|
||||
profile_row.b_default,
|
||||
module_data.b_viewtable,
|
||||
module_data.b_savetable,
|
||||
module_data.b_keyfield,
|
||||
module_data.b_orderfield,
|
||||
module_page.b_route,
|
||||
module_page.b_page_mode,
|
||||
module_page.b_component_key,
|
||||
module_report.b_renderer_key,
|
||||
module_report.b_options AS b_report_options,
|
||||
module_dashboard.b_options AS b_dashboard_options,
|
||||
module_workflow.b_options AS b_workflow_options,
|
||||
module_row.b_canuse,
|
||||
profile_row.b_canuse AS b_profile_canuse
|
||||
FROM dbo.s_module AS module_row
|
||||
LEFT JOIN dbo.s_module_profile AS profile_row
|
||||
ON profile_row.b_module_id = module_row.b_id
|
||||
LEFT JOIN dbo.s_module_data AS module_data
|
||||
ON module_data.b_module_id = module_row.b_id
|
||||
LEFT JOIN dbo.s_module_page AS module_page
|
||||
ON module_page.b_module_id = module_row.b_id
|
||||
LEFT JOIN dbo.s_module_report AS module_report
|
||||
ON module_report.b_module_id = module_row.b_id
|
||||
LEFT JOIN dbo.s_module_dashboard AS module_dashboard
|
||||
ON module_dashboard.b_module_id = module_row.b_id
|
||||
LEFT JOIN dbo.s_module_workflow AS module_workflow
|
||||
ON module_workflow.b_module_id = module_row.b_id
|
||||
WHERE module_row.b_module_type <> 'data'
|
||||
OR profile_row.b_id IS NOT NULL;
|
||||
GO
|
||||
|
||||
CREATE OR ALTER VIEW dbo.v_s_module_field_list
|
||||
AS
|
||||
SELECT
|
||||
config_row.b_id,
|
||||
config_row.b_module_id,
|
||||
config_row.b_profile_id,
|
||||
config_row.b_field_id,
|
||||
config_row.b_group_id,
|
||||
config_row.b_i18n AS b_list_i18n,
|
||||
config_row.b_visible,
|
||||
config_row.b_xh,
|
||||
config_row.b_width,
|
||||
field_row.b_field,
|
||||
field_row.b_name,
|
||||
field_row.b_i18n,
|
||||
field_row.b_type,
|
||||
field_row.b_default_value,
|
||||
field_row.b_options,
|
||||
field_row.b_canuse AS b_field_canuse,
|
||||
group_row.b_name AS b_group_name,
|
||||
group_row.b_i18n AS b_group_i18n
|
||||
FROM dbo.s_module_field_list AS config_row
|
||||
INNER JOIN dbo.s_module_field AS field_row ON field_row.b_id = config_row.b_field_id
|
||||
LEFT JOIN dbo.s_module_layout_group AS group_row ON group_row.b_id = config_row.b_group_id;
|
||||
GO
|
||||
|
||||
CREATE OR ALTER VIEW dbo.v_s_module_field_form
|
||||
AS
|
||||
SELECT
|
||||
config_row.b_id,
|
||||
config_row.b_module_id,
|
||||
config_row.b_profile_id,
|
||||
config_row.b_field_id,
|
||||
config_row.b_group_id,
|
||||
config_row.b_required,
|
||||
config_row.b_readonly,
|
||||
config_row.b_disabled,
|
||||
config_row.b_visible,
|
||||
config_row.b_xh,
|
||||
field_row.b_field,
|
||||
field_row.b_name,
|
||||
field_row.b_i18n,
|
||||
field_row.b_type,
|
||||
field_row.b_default_value,
|
||||
field_row.b_options,
|
||||
field_row.b_canuse AS b_field_canuse,
|
||||
group_row.b_name AS b_group_name,
|
||||
group_row.b_i18n AS b_group_i18n
|
||||
FROM dbo.s_module_field_form AS config_row
|
||||
INNER JOIN dbo.s_module_field AS field_row ON field_row.b_id = config_row.b_field_id
|
||||
LEFT JOIN dbo.s_module_layout_group AS group_row ON group_row.b_id = config_row.b_group_id;
|
||||
GO
|
||||
|
||||
CREATE OR ALTER VIEW dbo.v_s_module_field_query
|
||||
AS
|
||||
SELECT
|
||||
config_row.b_id,
|
||||
config_row.b_module_id,
|
||||
config_row.b_profile_id,
|
||||
config_row.b_field_id,
|
||||
config_row.b_component,
|
||||
config_row.b_operator,
|
||||
config_row.b_default_value,
|
||||
config_row.b_xh,
|
||||
config_row.b_canuse,
|
||||
field_row.b_field,
|
||||
field_row.b_name,
|
||||
field_row.b_i18n,
|
||||
field_row.b_type,
|
||||
field_row.b_options,
|
||||
field_row.b_canuse AS b_field_canuse
|
||||
FROM dbo.s_module_field_query AS config_row
|
||||
INNER JOIN dbo.s_module_field AS field_row ON field_row.b_id = config_row.b_field_id;
|
||||
GO
|
||||
|
||||
CREATE OR ALTER VIEW dbo.v_s_module_action
|
||||
AS
|
||||
SELECT
|
||||
action_row.b_id,
|
||||
action_row.b_module_id,
|
||||
action_row.b_code,
|
||||
action_row.b_name,
|
||||
action_row.b_i18n,
|
||||
action_row.b_xh,
|
||||
action_row.b_canuse,
|
||||
module_row.b_code AS b_module_code,
|
||||
module_row.b_name AS b_module_name,
|
||||
module_row.b_i18n AS b_module_i18n
|
||||
FROM dbo.s_module_action AS action_row
|
||||
INNER JOIN dbo.s_module AS module_row ON module_row.b_id = action_row.b_module_id;
|
||||
GO
|
||||
|
||||
CREATE OR ALTER VIEW dbo.v_s_user_function_permission
|
||||
AS
|
||||
SELECT user_grant.b_user_id, user_grant.b_function_node_id
|
||||
FROM dbo.b_user_function_node AS user_grant
|
||||
UNION
|
||||
SELECT role_user.b_user_id, role_grant.b_function_node_id
|
||||
FROM dbo.b_user_role AS role_user
|
||||
INNER JOIN dbo.b_role AS role_row ON role_row.b_id = role_user.b_role_id AND role_row.b_canuse = 1
|
||||
INNER JOIN dbo.b_role_function_node AS role_grant ON role_grant.b_role_id = role_row.b_id
|
||||
UNION
|
||||
SELECT role_user.b_user_id, node.b_id
|
||||
FROM dbo.b_user_role AS role_user
|
||||
INNER JOIN dbo.b_role AS role_row ON role_row.b_id = role_user.b_role_id AND role_row.b_canuse = 1 AND role_row.b_is_super = 1
|
||||
INNER JOIN dbo.s_function_node AS node ON node.b_canuse = 1;
|
||||
GO
|
||||
|
||||
CREATE OR ALTER VIEW dbo.v_s_user_page_permission
|
||||
AS
|
||||
SELECT user_grant.b_user_id, user_grant.b_page_node_id
|
||||
FROM dbo.b_user_page_node AS user_grant
|
||||
UNION
|
||||
SELECT role_user.b_user_id, role_grant.b_page_node_id
|
||||
FROM dbo.b_user_role AS role_user
|
||||
INNER JOIN dbo.b_role AS role_row ON role_row.b_id = role_user.b_role_id AND role_row.b_canuse = 1
|
||||
INNER JOIN dbo.b_role_page_node AS role_grant ON role_grant.b_role_id = role_row.b_id
|
||||
UNION
|
||||
SELECT role_user.b_user_id, node.b_id
|
||||
FROM dbo.b_user_role AS role_user
|
||||
INNER JOIN dbo.b_role AS role_row ON role_row.b_id = role_user.b_role_id AND role_row.b_canuse = 1 AND role_row.b_is_super = 1
|
||||
INNER JOIN dbo.s_page_node AS node ON node.b_canuse = 1 AND node.b_permission_required = 1;
|
||||
GO
|
||||
|
||||
CREATE OR ALTER VIEW dbo.v_s_user_action_permission
|
||||
AS
|
||||
SELECT user_grant.b_user_id, user_grant.b_action_id
|
||||
FROM dbo.b_user_action AS user_grant
|
||||
UNION
|
||||
SELECT role_user.b_user_id, role_grant.b_action_id
|
||||
FROM dbo.b_user_role AS role_user
|
||||
INNER JOIN dbo.b_role AS role_row ON role_row.b_id = role_user.b_role_id AND role_row.b_canuse = 1
|
||||
INNER JOIN dbo.b_role_action AS role_grant ON role_grant.b_role_id = role_row.b_id
|
||||
UNION
|
||||
SELECT role_user.b_user_id, action_row.b_id
|
||||
FROM dbo.b_user_role AS role_user
|
||||
INNER JOIN dbo.b_role AS role_row ON role_row.b_id = role_user.b_role_id AND role_row.b_canuse = 1 AND role_row.b_is_super = 1
|
||||
INNER JOIN dbo.s_module_action AS action_row ON action_row.b_canuse = 1;
|
||||
GO
|
||||
|
||||
/* Tree cycles and technical-code changes are domain constraints not expressible by CHECK. */
|
||||
CREATE OR ALTER TRIGGER dbo.TR_s_function_node_tree
|
||||
ON dbo.s_function_node
|
||||
AFTER INSERT, UPDATE
|
||||
AS
|
||||
BEGIN
|
||||
SET NOCOUNT ON;
|
||||
IF EXISTS (
|
||||
SELECT 1
|
||||
FROM inserted AS child
|
||||
INNER JOIN dbo.s_function_node AS parent_row ON parent_row.b_id = child.b_parent_id
|
||||
WHERE parent_row.b_node_type <> 'directory'
|
||||
)
|
||||
THROW 53408, N'Function nodes can only be placed below a directory.', 1;
|
||||
IF EXISTS (
|
||||
SELECT 1
|
||||
FROM inserted AS parent_row
|
||||
INNER JOIN dbo.s_function_node AS child ON child.b_parent_id = parent_row.b_id
|
||||
WHERE parent_row.b_node_type <> 'directory'
|
||||
)
|
||||
THROW 53409, N'Function entries cannot contain child nodes.', 1;
|
||||
DECLARE @Cycle bit = 0;
|
||||
;WITH tree AS (
|
||||
SELECT i.b_id AS origin_id, i.b_parent_id AS current_id
|
||||
FROM inserted AS i
|
||||
WHERE i.b_parent_id IS NOT NULL
|
||||
UNION ALL
|
||||
SELECT tree.origin_id, parent_row.b_parent_id
|
||||
FROM tree
|
||||
INNER JOIN dbo.s_function_node AS parent_row ON parent_row.b_id = tree.current_id
|
||||
WHERE tree.current_id IS NOT NULL
|
||||
)
|
||||
SELECT TOP (1) @Cycle = 1 FROM tree WHERE current_id = origin_id OPTION (MAXRECURSION 32767);
|
||||
IF @Cycle = 1 THROW 53401, N'Function node parent cycle detected.', 1;
|
||||
END;
|
||||
GO
|
||||
|
||||
CREATE OR ALTER TRIGGER dbo.TR_s_page_node_tree
|
||||
ON dbo.s_page_node
|
||||
AFTER INSERT, UPDATE
|
||||
AS
|
||||
BEGIN
|
||||
SET NOCOUNT ON;
|
||||
IF EXISTS (
|
||||
SELECT 1
|
||||
FROM inserted AS child
|
||||
INNER JOIN dbo.s_page_node AS parent_row
|
||||
ON parent_row.b_page_module_id = child.b_page_module_id
|
||||
AND parent_row.b_id = child.b_parent_id
|
||||
WHERE parent_row.b_node_type = 'module_ref'
|
||||
)
|
||||
THROW 53410, N'Page module references cannot contain child nodes.', 1;
|
||||
IF EXISTS (
|
||||
SELECT 1
|
||||
FROM inserted AS parent_row
|
||||
INNER JOIN dbo.s_page_node AS child
|
||||
ON child.b_page_module_id = parent_row.b_page_module_id
|
||||
AND child.b_parent_id = parent_row.b_id
|
||||
WHERE parent_row.b_node_type = 'module_ref'
|
||||
)
|
||||
THROW 53411, N'Page module references cannot contain child nodes.', 1;
|
||||
DECLARE @Cycle bit = 0;
|
||||
;WITH tree AS (
|
||||
SELECT i.b_page_module_id AS page_id, i.b_id AS origin_id, i.b_parent_id AS current_id
|
||||
FROM inserted AS i
|
||||
WHERE i.b_parent_id IS NOT NULL
|
||||
UNION ALL
|
||||
SELECT tree.page_id, tree.origin_id, parent_row.b_parent_id
|
||||
FROM tree
|
||||
INNER JOIN dbo.s_page_node AS parent_row
|
||||
ON parent_row.b_page_module_id = tree.page_id AND parent_row.b_id = tree.current_id
|
||||
WHERE tree.current_id IS NOT NULL
|
||||
)
|
||||
SELECT TOP (1) @Cycle = 1 FROM tree WHERE current_id = origin_id OPTION (MAXRECURSION 32767);
|
||||
IF @Cycle = 1 THROW 53402, N'Page node parent cycle detected.', 1;
|
||||
END;
|
||||
GO
|
||||
|
||||
CREATE OR ALTER TRIGGER dbo.TR_s_module_immutable_code
|
||||
ON dbo.s_module
|
||||
AFTER UPDATE
|
||||
AS
|
||||
BEGIN
|
||||
SET NOCOUNT ON;
|
||||
IF UPDATE(b_code) OR UPDATE(b_module_type)
|
||||
BEGIN
|
||||
IF EXISTS (
|
||||
SELECT 1 FROM inserted i INNER JOIN deleted d ON d.b_id = i.b_id
|
||||
WHERE i.b_code <> d.b_code OR i.b_module_type <> d.b_module_type
|
||||
)
|
||||
THROW 53403, N'Module technical code and type are immutable.', 1;
|
||||
END;
|
||||
END;
|
||||
GO
|
||||
|
||||
CREATE OR ALTER TRIGGER dbo.TR_s_function_node_immutable_code
|
||||
ON dbo.s_function_node
|
||||
AFTER UPDATE
|
||||
AS
|
||||
BEGIN
|
||||
SET NOCOUNT ON;
|
||||
IF (UPDATE(b_code) OR UPDATE(b_node_type)) AND EXISTS (
|
||||
SELECT 1 FROM inserted i INNER JOIN deleted d ON d.b_id = i.b_id
|
||||
WHERE i.b_code <> d.b_code OR i.b_node_type <> d.b_node_type
|
||||
) THROW 53404, N'Function node technical code and type are immutable.', 1;
|
||||
END;
|
||||
GO
|
||||
|
||||
CREATE OR ALTER TRIGGER dbo.TR_s_page_node_immutable_code
|
||||
ON dbo.s_page_node
|
||||
AFTER UPDATE
|
||||
AS
|
||||
BEGIN
|
||||
SET NOCOUNT ON;
|
||||
IF (UPDATE(b_code) OR UPDATE(b_node_type) OR UPDATE(b_page_module_id)) AND EXISTS (
|
||||
SELECT 1 FROM inserted i INNER JOIN deleted d ON d.b_id = i.b_id
|
||||
WHERE i.b_code <> d.b_code OR i.b_node_type <> d.b_node_type
|
||||
OR i.b_page_module_id <> d.b_page_module_id
|
||||
) THROW 53405, N'Page node technical code, type and owning page are immutable.', 1;
|
||||
END;
|
||||
GO
|
||||
|
||||
CREATE OR ALTER TRIGGER dbo.TR_s_module_profile_immutable_code
|
||||
ON dbo.s_module_profile
|
||||
AFTER UPDATE
|
||||
AS
|
||||
BEGIN
|
||||
SET NOCOUNT ON;
|
||||
IF (UPDATE(b_code) OR UPDATE(b_module_id)) AND EXISTS (
|
||||
SELECT 1
|
||||
FROM inserted i
|
||||
INNER JOIN deleted d ON d.b_id = i.b_id
|
||||
WHERE i.b_code <> d.b_code OR i.b_module_id <> d.b_module_id
|
||||
) THROW 53412, N'Profile technical code and owning module are immutable.', 1;
|
||||
END;
|
||||
GO
|
||||
|
||||
CREATE OR ALTER TRIGGER dbo.TR_s_module_field_immutable_code
|
||||
ON dbo.s_module_field
|
||||
AFTER UPDATE
|
||||
AS
|
||||
BEGIN
|
||||
SET NOCOUNT ON;
|
||||
IF (UPDATE(b_field) OR UPDATE(b_module_id)) AND EXISTS (
|
||||
SELECT 1 FROM inserted i INNER JOIN deleted d ON d.b_id = i.b_id
|
||||
WHERE i.b_field <> d.b_field OR i.b_module_id <> d.b_module_id
|
||||
) THROW 53406, N'Field technical code and owning module are immutable.', 1;
|
||||
END;
|
||||
GO
|
||||
|
||||
CREATE OR ALTER TRIGGER dbo.TR_s_module_action_immutable_code
|
||||
ON dbo.s_module_action
|
||||
AFTER UPDATE
|
||||
AS
|
||||
BEGIN
|
||||
SET NOCOUNT ON;
|
||||
IF (UPDATE(b_code) OR UPDATE(b_module_id)) AND EXISTS (
|
||||
SELECT 1 FROM inserted i INNER JOIN deleted d ON d.b_id = i.b_id
|
||||
WHERE i.b_code <> d.b_code OR i.b_module_id <> d.b_module_id
|
||||
) THROW 53407, N'Action technical code and owning module are immutable.', 1;
|
||||
END;
|
||||
GO
|
||||
|
||||
CREATE OR ALTER TRIGGER dbo.TR_s_module_relation_immutable_code
|
||||
ON dbo.s_module_relation
|
||||
AFTER UPDATE
|
||||
AS
|
||||
BEGIN
|
||||
SET NOCOUNT ON;
|
||||
IF (UPDATE(b_code) OR UPDATE(b_parent_module_id)) AND EXISTS (
|
||||
SELECT 1 FROM inserted i INNER JOIN deleted d ON d.b_id = i.b_id
|
||||
WHERE i.b_code <> d.b_code OR i.b_parent_module_id <> d.b_parent_module_id
|
||||
) THROW 53413, N'Relation technical code and owning module are immutable.', 1;
|
||||
END;
|
||||
GO
|
||||
|
||||
CREATE OR ALTER TRIGGER dbo.TR_b_role_immutable_code
|
||||
ON dbo.b_role
|
||||
AFTER UPDATE
|
||||
AS
|
||||
BEGIN
|
||||
SET NOCOUNT ON;
|
||||
IF UPDATE(b_code) AND EXISTS (
|
||||
SELECT 1 FROM inserted i INNER JOIN deleted d ON d.b_id = i.b_id
|
||||
WHERE i.b_code <> d.b_code
|
||||
) THROW 53414, N'Role technical code is immutable.', 1;
|
||||
END;
|
||||
GO
|
||||
@@ -0,0 +1,563 @@
|
||||
/*
|
||||
Restore the pre-2026-08-03 module model and keep one intentional extension:
|
||||
s_module.b_module_type = 'data_category'. Data categories belong to a page or
|
||||
another data category, so arbitrary nesting needs no separate composition model.
|
||||
|
||||
This script is executed by ApplySimpleModuleRestore in one JDBC transaction.
|
||||
*/
|
||||
SET NOCOUNT ON;
|
||||
SET XACT_ABORT ON;
|
||||
|
||||
IF DB_NAME() <> N'FMS'
|
||||
THROW 53500, N'This migration can only run against the FMS database.', 1;
|
||||
|
||||
IF OBJECT_ID(N'dbo.s_module_page', N'U') IS NULL
|
||||
THROW 53501, N'The split module architecture is not installed.', 1;
|
||||
|
||||
IF COL_LENGTH(N'dbo.s_module', N'b_parent_id') IS NOT NULL
|
||||
THROW 53502, N'The simple module tree is already installed.', 1;
|
||||
|
||||
IF OBJECT_ID(N'dbo.z_restore_module', N'U') IS NOT NULL
|
||||
THROW 53503, N'A previous restore staging table exists.', 1;
|
||||
|
||||
DECLARE @AdminId bigint = (
|
||||
SELECT TOP (1) b_id
|
||||
FROM dbo.b_user
|
||||
WHERE b_canuse = 1
|
||||
ORDER BY CASE WHEN b_account = N'g3soft' THEN 0 ELSE 1 END, b_id
|
||||
);
|
||||
IF @AdminId IS NULL
|
||||
THROW 53504, N'Enabled administrator user not found.', 1;
|
||||
|
||||
CREATE TABLE dbo.z_restore_module (
|
||||
b_id bigint NOT NULL,
|
||||
b_code varchar(50) NOT NULL,
|
||||
b_parent_id bigint NULL,
|
||||
b_name nvarchar(100) NOT NULL,
|
||||
b_i18n varchar(150) NULL,
|
||||
b_module_type varchar(20) NOT NULL,
|
||||
b_route varchar(200) NULL,
|
||||
b_viewtable varchar(128) NULL,
|
||||
b_savetable varchar(128) NULL,
|
||||
b_keyfield varchar(50) NULL,
|
||||
b_orderfield varchar(500) NULL,
|
||||
b_canmenu int NOT NULL,
|
||||
b_canuse int NOT NULL,
|
||||
b_xh int NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE dbo.z_restore_i18n_map (
|
||||
b_new_key varchar(150) NOT NULL,
|
||||
b_old_key varchar(150) NOT NULL,
|
||||
CONSTRAINT PK_z_restore_i18n_map PRIMARY KEY (b_new_key)
|
||||
);
|
||||
|
||||
/* Menu directories remain ordinary tree nodes. */
|
||||
INSERT INTO dbo.z_restore_module
|
||||
SELECT node.b_id, node.b_code, node.b_parent_id, node.b_name,
|
||||
'menu.' + node.b_code, 'directory', NULL, NULL, NULL, NULL, NULL,
|
||||
node.b_canmenu, node.b_canuse, node.b_xh
|
||||
FROM dbo.s_function_node AS node
|
||||
WHERE node.b_node_type = 'directory';
|
||||
|
||||
INSERT INTO dbo.z_restore_i18n_map
|
||||
SELECT node.b_i18n, 'menu.' + node.b_code
|
||||
FROM dbo.s_function_node AS node
|
||||
WHERE node.b_node_type = 'directory';
|
||||
|
||||
/* A page module and its function entry collapse back into one row. */
|
||||
;WITH page_entry AS (
|
||||
SELECT node.*,
|
||||
ROW_NUMBER() OVER (PARTITION BY node.b_module_id ORDER BY node.b_id) AS rn
|
||||
FROM dbo.s_function_node AS node
|
||||
WHERE node.b_node_type = 'entry'
|
||||
)
|
||||
INSERT INTO dbo.z_restore_module
|
||||
SELECT module_row.b_id, module_row.b_code, entry.b_parent_id, module_row.b_name,
|
||||
'menu.' + module_row.b_code, 'page', page_row.b_route,
|
||||
NULL, NULL, NULL, NULL,
|
||||
COALESCE(entry.b_canmenu, 0),
|
||||
CASE WHEN module_row.b_canuse = 1 AND COALESCE(entry.b_canuse, 1) = 1 THEN 1 ELSE 0 END,
|
||||
COALESCE(entry.b_xh, 0)
|
||||
FROM dbo.s_module AS module_row
|
||||
INNER JOIN dbo.s_module_page AS page_row ON page_row.b_module_id = module_row.b_id
|
||||
LEFT JOIN page_entry AS entry ON entry.b_module_id = module_row.b_id AND entry.rn = 1;
|
||||
|
||||
INSERT INTO dbo.z_restore_i18n_map
|
||||
SELECT module_row.b_i18n, 'menu.' + module_row.b_code
|
||||
FROM dbo.s_module AS module_row
|
||||
WHERE module_row.b_module_type = 'page';
|
||||
|
||||
/* Page containers become lightweight, arbitrarily nested data categories. */
|
||||
INSERT INTO dbo.z_restore_module
|
||||
SELECT node.b_id,
|
||||
CONVERT(varchar(50), 'data_category_' + CONVERT(varchar(30), node.b_id)),
|
||||
COALESCE(node.b_parent_id, node.b_page_module_id),
|
||||
node.b_name,
|
||||
CONVERT(varchar(150), 'menu.data_category_' + CONVERT(varchar(30), node.b_id)),
|
||||
'data_category', NULL, NULL, NULL, NULL, NULL,
|
||||
0, node.b_canuse, node.b_xh
|
||||
FROM dbo.s_page_node AS node
|
||||
WHERE node.b_node_type IN ('group', 'tab', 'section');
|
||||
|
||||
INSERT INTO dbo.z_restore_i18n_map
|
||||
SELECT node.b_i18n,
|
||||
CONVERT(varchar(150), 'menu.data_category_' + CONVERT(varchar(30), node.b_id))
|
||||
FROM dbo.s_page_node AS node
|
||||
WHERE node.b_node_type IN ('group', 'tab', 'section');
|
||||
|
||||
/* A data module has one owning parent again. Prefer its first active page reference. */
|
||||
;WITH module_reference AS (
|
||||
SELECT node.*,
|
||||
ROW_NUMBER() OVER (
|
||||
PARTITION BY node.b_module_id
|
||||
ORDER BY node.b_canuse DESC, node.b_page_module_id, node.b_xh, node.b_id
|
||||
) AS rn
|
||||
FROM dbo.s_page_node AS node
|
||||
WHERE node.b_node_type = 'module_ref' AND node.b_module_type = 'data'
|
||||
)
|
||||
INSERT INTO dbo.z_restore_module
|
||||
SELECT module_row.b_id, module_row.b_code,
|
||||
COALESCE(reference.b_parent_id, reference.b_page_module_id),
|
||||
module_row.b_name, 'module.' + module_row.b_code, 'data', NULL,
|
||||
data_row.b_viewtable, data_row.b_savetable, data_row.b_keyfield, data_row.b_orderfield,
|
||||
0, module_row.b_canuse, COALESCE(reference.b_xh, 0)
|
||||
FROM dbo.s_module AS module_row
|
||||
INNER JOIN dbo.s_module_data AS data_row ON data_row.b_module_id = module_row.b_id
|
||||
LEFT JOIN module_reference AS reference
|
||||
ON reference.b_module_id = module_row.b_id AND reference.rn = 1;
|
||||
|
||||
INSERT INTO dbo.z_restore_i18n_map
|
||||
SELECT module_row.b_i18n, 'module.' + module_row.b_code
|
||||
FROM dbo.s_module AS module_row
|
||||
WHERE module_row.b_module_type = 'data';
|
||||
|
||||
IF EXISTS (
|
||||
SELECT b_id FROM dbo.z_restore_module GROUP BY b_id HAVING COUNT(*) > 1
|
||||
)
|
||||
THROW 53505, N'Module IDs collide while restoring the simple tree.', 1;
|
||||
|
||||
IF EXISTS (
|
||||
SELECT b_code FROM dbo.z_restore_module GROUP BY b_code HAVING COUNT(*) > 1
|
||||
)
|
||||
THROW 53506, N'Module codes collide while restoring the simple tree.', 1;
|
||||
|
||||
IF EXISTS (
|
||||
SELECT 1
|
||||
FROM dbo.z_restore_module AS child
|
||||
LEFT JOIN dbo.z_restore_module AS parent_row ON parent_row.b_id = child.b_parent_id
|
||||
WHERE child.b_parent_id IS NOT NULL AND parent_row.b_id IS NULL
|
||||
)
|
||||
THROW 53507, N'A restored module has an unresolved parent.', 1;
|
||||
|
||||
/* Flatten the default Profile back to the original module-owned configuration. */
|
||||
SELECT field_row.b_id, field_row.b_module_id, field_row.b_field, field_row.b_name,
|
||||
CONVERT(varchar(150), 'field.' + module_row.b_code + '.' + field_row.b_field) AS b_i18n,
|
||||
field_row.b_type, field_row.b_default_value, field_row.b_options, field_row.b_canuse
|
||||
INTO dbo.z_restore_module_field
|
||||
FROM dbo.s_module_field AS field_row
|
||||
INNER JOIN dbo.s_module AS module_row ON module_row.b_id = field_row.b_module_id;
|
||||
|
||||
INSERT INTO dbo.z_restore_i18n_map
|
||||
SELECT field_row.b_i18n,
|
||||
CONVERT(varchar(150), 'field.' + module_row.b_code + '.' + field_row.b_field)
|
||||
FROM dbo.s_module_field AS field_row
|
||||
INNER JOIN dbo.s_module AS module_row ON module_row.b_id = field_row.b_module_id;
|
||||
|
||||
SELECT auto_row.b_id, auto_row.b_module_id, auto_row.b_field_id, auto_row.b_prefix,
|
||||
auto_row.b_date_format, auto_row.b_separator, auto_row.b_sequence_width,
|
||||
auto_row.b_reset_type, auto_row.b_start_value, auto_row.b_current_period,
|
||||
auto_row.b_current_value, auto_row.b_canuse
|
||||
INTO dbo.z_restore_module_auto_code
|
||||
FROM dbo.s_module_auto_code AS auto_row;
|
||||
|
||||
SELECT group_row.b_id, group_row.b_module_id, group_row.b_parent_id,
|
||||
group_row.b_name AS b_title, group_row.b_i18n, group_row.b_xh, group_row.b_canuse
|
||||
INTO dbo.z_restore_module_field_group
|
||||
FROM dbo.s_module_layout_group AS group_row
|
||||
INNER JOIN dbo.s_module_profile AS profile_row
|
||||
ON profile_row.b_id = group_row.b_profile_id AND profile_row.b_default = 1;
|
||||
|
||||
SELECT config.b_id, config.b_module_id, config.b_field_id, config.b_group_id,
|
||||
config.b_i18n, config.b_visible, config.b_xh, config.b_width
|
||||
INTO dbo.z_restore_module_field_list
|
||||
FROM dbo.s_module_field_list AS config
|
||||
INNER JOIN dbo.s_module_profile AS profile_row
|
||||
ON profile_row.b_id = config.b_profile_id AND profile_row.b_default = 1;
|
||||
|
||||
SELECT config.b_id, config.b_module_id, config.b_field_id, config.b_required,
|
||||
config.b_readonly, config.b_disabled, config.b_visible, config.b_group_id, config.b_xh
|
||||
INTO dbo.z_restore_module_field_edit
|
||||
FROM dbo.s_module_field_form AS config
|
||||
INNER JOIN dbo.s_module_profile AS profile_row
|
||||
ON profile_row.b_id = config.b_profile_id AND profile_row.b_default = 1;
|
||||
|
||||
SELECT config.b_id, config.b_module_id, config.b_field_id, config.b_component,
|
||||
config.b_operator, config.b_default_value, config.b_xh, config.b_canuse
|
||||
INTO dbo.z_restore_module_field_query
|
||||
FROM dbo.s_module_field_query AS config
|
||||
INNER JOIN dbo.s_module_profile AS profile_row
|
||||
ON profile_row.b_id = config.b_profile_id AND profile_row.b_default = 1;
|
||||
|
||||
SELECT action_row.b_id, action_row.b_module_id, action_row.b_code, action_row.b_name,
|
||||
CONVERT(varchar(150), 'power.' + module_row.b_code + '.' + action_row.b_code) AS b_i18n,
|
||||
action_row.b_xh, action_row.b_canuse
|
||||
INTO dbo.z_restore_module_power
|
||||
FROM dbo.s_module_action AS action_row
|
||||
INNER JOIN dbo.s_module AS module_row ON module_row.b_id = action_row.b_module_id;
|
||||
|
||||
INSERT INTO dbo.z_restore_i18n_map
|
||||
SELECT action_row.b_i18n,
|
||||
CONVERT(varchar(150), 'power.' + module_row.b_code + '.' + action_row.b_code)
|
||||
FROM dbo.s_module_action AS action_row
|
||||
INNER JOIN dbo.s_module AS module_row ON module_row.b_id = action_row.b_module_id;
|
||||
|
||||
CREATE TABLE dbo.z_restore_user_module (
|
||||
b_user_id bigint NOT NULL,
|
||||
b_module_id bigint NOT NULL,
|
||||
CONSTRAINT PK_z_restore_user_module PRIMARY KEY (b_user_id, b_module_id)
|
||||
);
|
||||
|
||||
;WITH allowed_page AS (
|
||||
SELECT permission.b_user_id, node.b_module_id
|
||||
FROM dbo.v_s_user_function_permission AS permission
|
||||
INNER JOIN dbo.s_function_node AS node
|
||||
ON node.b_id = permission.b_function_node_id AND node.b_node_type = 'entry'
|
||||
), allowed_module AS (
|
||||
SELECT b_user_id, b_module_id FROM allowed_page
|
||||
UNION
|
||||
SELECT page_permission.b_user_id, page_node.b_module_id
|
||||
FROM allowed_page AS page_permission
|
||||
INNER JOIN dbo.s_page_node AS page_node
|
||||
ON page_node.b_page_module_id = page_permission.b_module_id
|
||||
AND page_node.b_node_type = 'module_ref'
|
||||
LEFT JOIN dbo.v_s_user_page_permission AS node_permission
|
||||
ON node_permission.b_user_id = page_permission.b_user_id
|
||||
AND node_permission.b_page_node_id = page_node.b_id
|
||||
WHERE page_node.b_permission_required = 0 OR node_permission.b_page_node_id IS NOT NULL
|
||||
UNION
|
||||
SELECT permission.b_user_id, action_row.b_module_id
|
||||
FROM dbo.v_s_user_action_permission AS permission
|
||||
INNER JOIN dbo.s_module_action AS action_row ON action_row.b_id = permission.b_action_id
|
||||
)
|
||||
INSERT INTO dbo.z_restore_user_module (b_user_id, b_module_id)
|
||||
SELECT DISTINCT allowed_module.b_user_id, allowed_module.b_module_id
|
||||
FROM allowed_module
|
||||
INNER JOIN dbo.z_restore_module AS module_row ON module_row.b_id = allowed_module.b_module_id;
|
||||
|
||||
SELECT permission.b_user_id, action_row.b_module_id, permission.b_action_id AS b_power_id
|
||||
INTO dbo.z_restore_user_power
|
||||
FROM dbo.v_s_user_action_permission AS permission
|
||||
INNER JOIN dbo.s_module_action AS action_row ON action_row.b_id = permission.b_action_id
|
||||
INNER JOIN dbo.z_restore_module AS module_row ON module_row.b_id = action_row.b_module_id;
|
||||
|
||||
/* Preserve translations while returning generated keys to their old code-based form. */
|
||||
UPDATE old_translation
|
||||
SET old_translation.b_value = new_translation.b_value
|
||||
FROM dbo.b_i18n AS old_translation
|
||||
INNER JOIN dbo.z_restore_i18n_map AS key_map ON key_map.b_old_key = old_translation.b_key
|
||||
INNER JOIN dbo.b_i18n AS new_translation
|
||||
ON new_translation.b_key = key_map.b_new_key
|
||||
AND new_translation.b_locale = old_translation.b_locale;
|
||||
|
||||
DELETE new_translation
|
||||
FROM dbo.b_i18n AS new_translation
|
||||
INNER JOIN dbo.z_restore_i18n_map AS key_map ON key_map.b_new_key = new_translation.b_key
|
||||
WHERE EXISTS (
|
||||
SELECT 1 FROM dbo.b_i18n AS old_translation
|
||||
WHERE old_translation.b_key = key_map.b_old_key
|
||||
AND old_translation.b_locale = new_translation.b_locale
|
||||
);
|
||||
|
||||
UPDATE translation
|
||||
SET translation.b_key = key_map.b_old_key
|
||||
FROM dbo.b_i18n AS translation
|
||||
INNER JOIN dbo.z_restore_i18n_map AS key_map ON key_map.b_new_key = translation.b_key;
|
||||
GO
|
||||
|
||||
/* Remove runtime views before replacing their source tables. */
|
||||
IF OBJECT_ID(N'dbo.v_s_user_action_permission', N'V') IS NOT NULL DROP VIEW dbo.v_s_user_action_permission;
|
||||
IF OBJECT_ID(N'dbo.v_s_user_page_permission', N'V') IS NOT NULL DROP VIEW dbo.v_s_user_page_permission;
|
||||
IF OBJECT_ID(N'dbo.v_s_user_function_permission', N'V') IS NOT NULL DROP VIEW dbo.v_s_user_function_permission;
|
||||
IF OBJECT_ID(N'dbo.v_s_module_action', N'V') IS NOT NULL DROP VIEW dbo.v_s_module_action;
|
||||
IF OBJECT_ID(N'dbo.v_s_module_field_query', N'V') IS NOT NULL DROP VIEW dbo.v_s_module_field_query;
|
||||
IF OBJECT_ID(N'dbo.v_s_module_field_form', N'V') IS NOT NULL DROP VIEW dbo.v_s_module_field_form;
|
||||
IF OBJECT_ID(N'dbo.v_s_module_field_list', N'V') IS NOT NULL DROP VIEW dbo.v_s_module_field_list;
|
||||
IF OBJECT_ID(N'dbo.v_s_module_runtime', N'V') IS NOT NULL DROP VIEW dbo.v_s_module_runtime;
|
||||
IF OBJECT_ID(N'dbo.v_s_module_profile', N'V') IS NOT NULL DROP VIEW dbo.v_s_module_profile;
|
||||
IF OBJECT_ID(N'dbo.v_s_page_node', N'V') IS NOT NULL DROP VIEW dbo.v_s_page_node;
|
||||
IF OBJECT_ID(N'dbo.v_s_function_node', N'V') IS NOT NULL DROP VIEW dbo.v_s_function_node;
|
||||
|
||||
/* Drop all foreign keys owned by or referencing the split architecture. */
|
||||
DECLARE @DropForeignKeys nvarchar(max) = N'';
|
||||
SELECT @DropForeignKeys = @DropForeignKeys
|
||||
+ N'ALTER TABLE ' + QUOTENAME(OBJECT_SCHEMA_NAME(fk.parent_object_id)) + N'.'
|
||||
+ QUOTENAME(OBJECT_NAME(fk.parent_object_id)) + N' DROP CONSTRAINT ' + QUOTENAME(fk.name) + N';'
|
||||
FROM sys.foreign_keys AS fk
|
||||
WHERE OBJECT_SCHEMA_NAME(fk.parent_object_id) = N'dbo'
|
||||
AND (
|
||||
OBJECT_NAME(fk.parent_object_id) IN (
|
||||
N's_module', N's_module_page', N's_module_data', N's_module_report',
|
||||
N's_module_dashboard', N's_module_workflow', N's_module_profile',
|
||||
N's_function_node', N's_page_node', N's_module_field', N's_module_layout_group',
|
||||
N's_module_field_list', N's_module_field_form', N's_module_field_query',
|
||||
N's_module_action', N's_module_relation', N's_module_auto_code',
|
||||
N's_module_import', N's_module_export', N's_module_file',
|
||||
N's_module_workflow_binding', N'b_role', N'b_user_role',
|
||||
N'b_role_function_node', N'b_role_page_node', N'b_role_action',
|
||||
N'b_role_data_scope', N'b_user_function_node', N'b_user_page_node', N'b_user_action'
|
||||
)
|
||||
OR OBJECT_NAME(fk.referenced_object_id) IN (
|
||||
N's_module', N's_module_profile', N's_function_node', N's_page_node',
|
||||
N's_module_field', N's_module_layout_group', N's_module_action', N'b_role'
|
||||
)
|
||||
);
|
||||
IF @DropForeignKeys <> N'' EXEC sys.sp_executesql @DropForeignKeys;
|
||||
|
||||
DROP TABLE dbo.s_module_workflow_binding;
|
||||
DROP TABLE dbo.s_module_relation;
|
||||
DROP TABLE dbo.s_module_import;
|
||||
DROP TABLE dbo.s_module_export;
|
||||
DROP TABLE dbo.s_module_file;
|
||||
DROP TABLE dbo.s_module_field_list;
|
||||
DROP TABLE dbo.s_module_field_form;
|
||||
DROP TABLE dbo.s_module_field_query;
|
||||
DROP TABLE dbo.s_module_layout_group;
|
||||
DROP TABLE dbo.s_module_auto_code;
|
||||
DROP TABLE dbo.b_user_action;
|
||||
DROP TABLE dbo.b_user_page_node;
|
||||
DROP TABLE dbo.b_user_function_node;
|
||||
DROP TABLE dbo.b_role_data_scope;
|
||||
DROP TABLE dbo.b_role_action;
|
||||
DROP TABLE dbo.b_role_page_node;
|
||||
DROP TABLE dbo.b_role_function_node;
|
||||
DROP TABLE dbo.b_user_role;
|
||||
DROP TABLE dbo.b_role;
|
||||
DROP TABLE dbo.s_page_node;
|
||||
DROP TABLE dbo.s_function_node;
|
||||
DROP TABLE dbo.s_module_action;
|
||||
DROP TABLE dbo.s_module_field;
|
||||
DROP TABLE dbo.s_module_report;
|
||||
DROP TABLE dbo.s_module_dashboard;
|
||||
DROP TABLE dbo.s_module_workflow;
|
||||
DROP TABLE dbo.s_module_page;
|
||||
DROP TABLE dbo.s_module_data;
|
||||
DROP TABLE dbo.s_module_profile;
|
||||
DROP TABLE dbo.s_module;
|
||||
GO
|
||||
|
||||
/* Recreate the compact pre-refactor model. */
|
||||
DECLARE @AdminId bigint = (
|
||||
SELECT TOP (1) b_id
|
||||
FROM dbo.b_user
|
||||
WHERE b_canuse = 1
|
||||
ORDER BY CASE WHEN b_account = N'g3soft' THEN 0 ELSE 1 END, b_id
|
||||
);
|
||||
|
||||
CREATE TABLE dbo.s_module (
|
||||
b_id bigint NOT NULL,
|
||||
b_code varchar(50) NOT NULL,
|
||||
b_parent_id bigint NULL,
|
||||
b_name nvarchar(100) NOT NULL,
|
||||
b_i18n varchar(150) NULL,
|
||||
b_module_type varchar(20) NOT NULL,
|
||||
b_route varchar(200) NULL,
|
||||
b_viewtable varchar(128) NULL,
|
||||
b_savetable varchar(128) NULL,
|
||||
b_keyfield varchar(50) NULL,
|
||||
b_orderfield varchar(500) NULL,
|
||||
b_canmenu int NOT NULL CONSTRAINT DF_s_module_canmenu DEFAULT (0),
|
||||
b_canuse int NOT NULL CONSTRAINT DF_s_module_canuse DEFAULT (1),
|
||||
b_xh int NOT NULL CONSTRAINT DF_s_module_xh DEFAULT (0),
|
||||
CONSTRAINT PK_s_module PRIMARY KEY (b_id),
|
||||
CONSTRAINT UQ_s_module_code UNIQUE (b_code),
|
||||
CONSTRAINT CK_s_module_type CHECK (b_module_type IN ('directory', 'page', 'data_category', 'data')),
|
||||
CONSTRAINT CK_s_module_flags CHECK (b_canmenu IN (0, 1) AND b_canuse IN (0, 1)),
|
||||
CONSTRAINT CK_s_module_parent CHECK (b_parent_id IS NULL OR b_parent_id <> b_id),
|
||||
CONSTRAINT FK_s_module_parent FOREIGN KEY (b_parent_id) REFERENCES dbo.s_module (b_id)
|
||||
);
|
||||
CREATE UNIQUE INDEX UX_s_module_route ON dbo.s_module (b_route) WHERE b_route IS NOT NULL;
|
||||
CREATE INDEX IX_s_module_parent ON dbo.s_module (b_parent_id, b_xh, b_id);
|
||||
|
||||
CREATE TABLE dbo.s_module_field (
|
||||
b_id bigint NOT NULL, b_module_id bigint NOT NULL, b_field varchar(50) NOT NULL,
|
||||
b_name nvarchar(100) NOT NULL, b_i18n varchar(150) NULL, b_type varchar(30) NOT NULL,
|
||||
b_default_value nvarchar(500) NULL, b_options nvarchar(max) NULL,
|
||||
b_canuse int NOT NULL CONSTRAINT DF_s_module_field_canuse DEFAULT (1),
|
||||
CONSTRAINT PK_s_module_field PRIMARY KEY (b_id),
|
||||
CONSTRAINT UQ_s_module_field UNIQUE (b_module_id, b_field),
|
||||
CONSTRAINT FK_s_module_field_module FOREIGN KEY (b_module_id) REFERENCES dbo.s_module (b_id)
|
||||
);
|
||||
CREATE INDEX IX_s_module_field_module ON dbo.s_module_field (b_module_id, b_canuse, b_id);
|
||||
|
||||
CREATE TABLE dbo.s_module_auto_code (
|
||||
b_id bigint NOT NULL, b_module_id bigint NOT NULL, b_field_id bigint NOT NULL,
|
||||
b_prefix nvarchar(100) NOT NULL CONSTRAINT DF_s_module_auto_code_prefix DEFAULT (N''),
|
||||
b_date_format varchar(30) NOT NULL CONSTRAINT DF_s_module_auto_code_date_format DEFAULT ('yyyyMM'),
|
||||
b_separator nvarchar(10) NOT NULL CONSTRAINT DF_s_module_auto_code_separator DEFAULT (N'-'),
|
||||
b_sequence_width int NOT NULL CONSTRAINT DF_s_module_auto_code_sequence_width DEFAULT (5),
|
||||
b_reset_type varchar(10) NOT NULL CONSTRAINT DF_s_module_auto_code_reset_type DEFAULT ('month'),
|
||||
b_start_value bigint NOT NULL CONSTRAINT DF_s_module_auto_code_start_value DEFAULT (1),
|
||||
b_current_period varchar(8) NULL,
|
||||
b_current_value bigint NOT NULL CONSTRAINT DF_s_module_auto_code_current_value DEFAULT (0),
|
||||
b_canuse int NOT NULL CONSTRAINT DF_s_module_auto_code_canuse DEFAULT (1),
|
||||
CONSTRAINT PK_s_module_auto_code PRIMARY KEY (b_id),
|
||||
CONSTRAINT UQ_s_module_auto_code_module UNIQUE (b_module_id),
|
||||
CONSTRAINT FK_s_module_auto_code_module FOREIGN KEY (b_module_id) REFERENCES dbo.s_module (b_id),
|
||||
CONSTRAINT FK_s_module_auto_code_field FOREIGN KEY (b_field_id) REFERENCES dbo.s_module_field (b_id)
|
||||
);
|
||||
CREATE INDEX IX_s_module_auto_code_field ON dbo.s_module_auto_code (b_field_id);
|
||||
|
||||
CREATE TABLE dbo.s_module_field_group (
|
||||
b_id bigint NOT NULL, b_module_id bigint NOT NULL, b_parent_id bigint NULL,
|
||||
b_title nvarchar(100) NOT NULL, b_i18n varchar(150) NULL,
|
||||
b_xh int NOT NULL CONSTRAINT DF_s_module_field_group_xh DEFAULT (0),
|
||||
b_canuse int NOT NULL CONSTRAINT DF_s_module_field_group_canuse DEFAULT (1),
|
||||
CONSTRAINT PK_s_module_field_group PRIMARY KEY (b_id),
|
||||
CONSTRAINT FK_s_module_field_group_module FOREIGN KEY (b_module_id) REFERENCES dbo.s_module (b_id)
|
||||
);
|
||||
CREATE INDEX IX_s_module_field_group_module ON dbo.s_module_field_group (b_module_id, b_canuse, b_xh, b_id);
|
||||
|
||||
CREATE TABLE dbo.s_module_field_list (
|
||||
b_id bigint NOT NULL, b_module_id bigint NOT NULL, b_field_id bigint NULL,
|
||||
b_group_id bigint NULL, b_i18n varchar(150) NULL,
|
||||
b_visible int NOT NULL CONSTRAINT DF_s_module_field_list_visible DEFAULT (1),
|
||||
b_xh int NOT NULL CONSTRAINT DF_s_module_field_list_xh DEFAULT (0), b_width int NULL,
|
||||
CONSTRAINT PK_s_module_field_list PRIMARY KEY (b_id),
|
||||
CONSTRAINT FK_s_module_field_list_module FOREIGN KEY (b_module_id) REFERENCES dbo.s_module (b_id),
|
||||
CONSTRAINT FK_s_module_field_list_field FOREIGN KEY (b_field_id) REFERENCES dbo.s_module_field (b_id),
|
||||
CONSTRAINT FK_s_module_field_list_group FOREIGN KEY (b_group_id) REFERENCES dbo.s_module_field_group (b_id)
|
||||
);
|
||||
CREATE UNIQUE INDEX UX_s_module_field_list_field ON dbo.s_module_field_list (b_module_id, b_field_id) WHERE b_field_id IS NOT NULL;
|
||||
CREATE INDEX IX_s_module_field_list_tree ON dbo.s_module_field_list (b_module_id, b_group_id, b_xh, b_id);
|
||||
|
||||
CREATE TABLE dbo.s_module_field_edit (
|
||||
b_id bigint NOT NULL, b_module_id bigint NOT NULL, b_field_id bigint NOT NULL,
|
||||
b_required int NOT NULL CONSTRAINT DF_s_module_field_edit_required DEFAULT (0),
|
||||
b_readonly int NOT NULL CONSTRAINT DF_s_module_field_edit_readonly DEFAULT (0),
|
||||
b_disabled int NOT NULL CONSTRAINT DF_s_module_field_edit_disabled DEFAULT (0),
|
||||
b_visible int NOT NULL CONSTRAINT DF_s_module_field_edit_visible DEFAULT (1),
|
||||
b_group_id bigint NULL, b_xh int NOT NULL CONSTRAINT DF_s_module_field_edit_xh DEFAULT (0),
|
||||
CONSTRAINT PK_s_module_field_edit PRIMARY KEY (b_id),
|
||||
CONSTRAINT UQ_s_module_field_edit UNIQUE (b_module_id, b_field_id),
|
||||
CONSTRAINT FK_s_module_field_edit_module FOREIGN KEY (b_module_id) REFERENCES dbo.s_module (b_id),
|
||||
CONSTRAINT FK_s_module_field_edit_field FOREIGN KEY (b_field_id) REFERENCES dbo.s_module_field (b_id),
|
||||
CONSTRAINT FK_s_module_field_edit_group FOREIGN KEY (b_group_id) REFERENCES dbo.s_module_field_group (b_id)
|
||||
);
|
||||
CREATE INDEX IX_s_module_field_edit_module ON dbo.s_module_field_edit (b_module_id, b_xh, b_id);
|
||||
|
||||
CREATE TABLE dbo.s_module_field_query (
|
||||
b_id bigint NOT NULL, b_module_id bigint NOT NULL, b_field_id bigint NOT NULL,
|
||||
b_component varchar(30) NOT NULL, b_operator varchar(20) NOT NULL,
|
||||
b_default_value nvarchar(500) NULL,
|
||||
b_xh int NOT NULL CONSTRAINT DF_s_module_field_query_xh DEFAULT (0),
|
||||
b_canuse int NOT NULL CONSTRAINT DF_s_module_field_query_canuse DEFAULT (1),
|
||||
CONSTRAINT PK_s_module_field_query PRIMARY KEY (b_id),
|
||||
CONSTRAINT UQ_s_module_field_query UNIQUE (b_module_id, b_field_id),
|
||||
CONSTRAINT FK_s_module_field_query_module FOREIGN KEY (b_module_id) REFERENCES dbo.s_module (b_id),
|
||||
CONSTRAINT FK_s_module_field_query_field FOREIGN KEY (b_field_id) REFERENCES dbo.s_module_field (b_id)
|
||||
);
|
||||
CREATE INDEX IX_s_module_field_query_module ON dbo.s_module_field_query (b_module_id, b_canuse, b_xh, b_id);
|
||||
|
||||
CREATE TABLE dbo.s_module_power (
|
||||
b_id bigint NOT NULL, b_module_id bigint NOT NULL, b_code varchar(50) NOT NULL,
|
||||
b_name nvarchar(100) NOT NULL, b_i18n varchar(150) NULL,
|
||||
b_xh int NOT NULL CONSTRAINT DF_s_module_power_xh DEFAULT (0),
|
||||
b_canuse int NOT NULL CONSTRAINT DF_s_module_power_canuse DEFAULT (1),
|
||||
CONSTRAINT PK_s_module_power PRIMARY KEY (b_id),
|
||||
CONSTRAINT UQ_s_module_power UNIQUE (b_module_id, b_code),
|
||||
CONSTRAINT FK_s_module_power_module FOREIGN KEY (b_module_id) REFERENCES dbo.s_module (b_id)
|
||||
);
|
||||
|
||||
CREATE TABLE dbo.b_user_module (
|
||||
b_id bigint NOT NULL, b_user_id bigint NOT NULL, b_module_id bigint NOT NULL,
|
||||
b_inputuser_id bigint NOT NULL,
|
||||
b_inputdatetime datetime NOT NULL CONSTRAINT DF_b_user_module_inputdatetime DEFAULT (GETDATE()),
|
||||
CONSTRAINT PK_b_user_module PRIMARY KEY (b_id),
|
||||
CONSTRAINT UQ_b_user_module UNIQUE (b_user_id, b_module_id),
|
||||
CONSTRAINT FK_b_user_module_user FOREIGN KEY (b_user_id) REFERENCES dbo.b_user (b_id),
|
||||
CONSTRAINT FK_b_user_module_module FOREIGN KEY (b_module_id) REFERENCES dbo.s_module (b_id)
|
||||
);
|
||||
|
||||
CREATE TABLE dbo.b_user_power (
|
||||
b_id bigint NOT NULL, b_user_id bigint NOT NULL, b_module_id bigint NOT NULL,
|
||||
b_power_id bigint NOT NULL, b_inputuser_id bigint NOT NULL,
|
||||
b_inputdatetime datetime NOT NULL CONSTRAINT DF_b_user_power_inputdatetime DEFAULT (GETDATE()),
|
||||
CONSTRAINT PK_b_user_power PRIMARY KEY (b_id),
|
||||
CONSTRAINT UQ_b_user_power UNIQUE (b_user_id, b_power_id),
|
||||
CONSTRAINT FK_b_user_power_user FOREIGN KEY (b_user_id) REFERENCES dbo.b_user (b_id),
|
||||
CONSTRAINT FK_b_user_power_module FOREIGN KEY (b_module_id) REFERENCES dbo.s_module (b_id),
|
||||
CONSTRAINT FK_b_user_power_power FOREIGN KEY (b_power_id) REFERENCES dbo.s_module_power (b_id)
|
||||
);
|
||||
CREATE INDEX IX_b_user_power_module ON dbo.b_user_power (b_module_id, b_user_id);
|
||||
|
||||
INSERT INTO dbo.s_module SELECT * FROM dbo.z_restore_module;
|
||||
INSERT INTO dbo.s_module_field SELECT * FROM dbo.z_restore_module_field;
|
||||
INSERT INTO dbo.s_module_auto_code SELECT * FROM dbo.z_restore_module_auto_code;
|
||||
INSERT INTO dbo.s_module_field_group SELECT * FROM dbo.z_restore_module_field_group;
|
||||
INSERT INTO dbo.s_module_field_list SELECT * FROM dbo.z_restore_module_field_list;
|
||||
INSERT INTO dbo.s_module_field_edit SELECT * FROM dbo.z_restore_module_field_edit;
|
||||
INSERT INTO dbo.s_module_field_query SELECT * FROM dbo.z_restore_module_field_query;
|
||||
INSERT INTO dbo.s_module_power SELECT * FROM dbo.z_restore_module_power;
|
||||
|
||||
INSERT INTO dbo.b_user_module (b_id, b_user_id, b_module_id, b_inputuser_id)
|
||||
SELECT 860000000000000000 + ROW_NUMBER() OVER (ORDER BY b_user_id, b_module_id),
|
||||
b_user_id, b_module_id, @AdminId
|
||||
FROM dbo.z_restore_user_module;
|
||||
|
||||
INSERT INTO dbo.b_user_power (b_id, b_user_id, b_module_id, b_power_id, b_inputuser_id)
|
||||
SELECT 870000000000000000 + ROW_NUMBER() OVER (ORDER BY b_user_id, b_power_id),
|
||||
b_user_id, b_module_id, b_power_id, @AdminId
|
||||
FROM dbo.z_restore_user_power;
|
||||
|
||||
DROP TABLE dbo.z_restore_user_power;
|
||||
DROP TABLE dbo.z_restore_user_module;
|
||||
DROP TABLE dbo.z_restore_module_power;
|
||||
DROP TABLE dbo.z_restore_module_field_query;
|
||||
DROP TABLE dbo.z_restore_module_field_edit;
|
||||
DROP TABLE dbo.z_restore_module_field_list;
|
||||
DROP TABLE dbo.z_restore_module_field_group;
|
||||
DROP TABLE dbo.z_restore_module_auto_code;
|
||||
DROP TABLE dbo.z_restore_module_field;
|
||||
DROP TABLE dbo.z_restore_i18n_map;
|
||||
DROP TABLE dbo.z_restore_module;
|
||||
GO
|
||||
|
||||
CREATE OR ALTER TRIGGER dbo.TR_s_module_simple_tree
|
||||
ON dbo.s_module
|
||||
AFTER INSERT, UPDATE
|
||||
AS
|
||||
BEGIN
|
||||
SET NOCOUNT ON;
|
||||
|
||||
IF EXISTS (
|
||||
SELECT 1
|
||||
FROM inserted AS child
|
||||
INNER JOIN dbo.s_module AS parent_row ON parent_row.b_id = child.b_parent_id
|
||||
WHERE (child.b_module_type = 'directory' AND parent_row.b_module_type <> 'directory')
|
||||
OR (child.b_module_type = 'page' AND parent_row.b_module_type <> 'directory')
|
||||
OR (child.b_module_type = 'data_category' AND parent_row.b_module_type NOT IN ('page', 'data_category'))
|
||||
OR (child.b_module_type = 'data' AND parent_row.b_module_type NOT IN ('page', 'data_category'))
|
||||
)
|
||||
THROW 53508, N'Invalid parent type in the simple module tree.', 1;
|
||||
|
||||
IF EXISTS (
|
||||
SELECT 1 FROM inserted
|
||||
WHERE b_module_type IN ('data_category', 'data') AND b_parent_id IS NULL
|
||||
)
|
||||
THROW 53509, N'Data categories and data modules require a page parent.', 1;
|
||||
|
||||
DECLARE @Cycle bit = 0;
|
||||
;WITH tree AS (
|
||||
SELECT child.b_id AS origin_id, child.b_parent_id AS current_id
|
||||
FROM inserted AS child
|
||||
WHERE child.b_parent_id IS NOT NULL
|
||||
UNION ALL
|
||||
SELECT tree.origin_id, parent_row.b_parent_id
|
||||
FROM tree
|
||||
INNER JOIN dbo.s_module AS parent_row ON parent_row.b_id = tree.current_id
|
||||
WHERE tree.current_id IS NOT NULL
|
||||
)
|
||||
SELECT TOP (1) @Cycle = 1 FROM tree WHERE current_id = origin_id OPTION (MAXRECURSION 32767);
|
||||
IF @Cycle = 1 THROW 53510, N'Module tree cycle detected.', 1;
|
||||
END;
|
||||
@@ -1,28 +0,0 @@
|
||||
# Database migrations
|
||||
|
||||
Module architecture cutover is manual and is not run during application startup.
|
||||
|
||||
Run against a backed-up `FMS` database in this order:
|
||||
|
||||
1. `033_create_module_structure.sql`
|
||||
2. `034_module_runtime_views.sql`
|
||||
3. `verify_module_architecture.sql`
|
||||
|
||||
`033` is a one-time transaction: it migrates valid metadata and removes the old metadata tables only after conversion checks pass. It intentionally does not create compatibility views or dual writes.
|
||||
If the earlier intermediate implementation created only `s_module_profile`, `s_function_node`, or `s_page_node`, `033` verifies that the complete source model still exists and regenerates those derived tables inside the same transaction. Other partial target states are rejected.
|
||||
|
||||
`033` and `034` use SQL Server `GO` batch separators. Use SSMS, Azure Data Studio, `sqlcmd`, or another runner that understands `GO`.
|
||||
|
||||
`verify_module_architecture.sql` is a target-schema verification script. It does not modify application tables.
|
||||
|
||||
To check and conditionally apply `034` with the repository JDBC driver on Windows:
|
||||
|
||||
```powershell
|
||||
$jdk = "D:\devtool\jdk\jdk-21\bin"
|
||||
$driver = "tools\migration\mssql-jdbc-13.4.0.jre11.jar"
|
||||
& "$jdk\javac.exe" -encoding UTF-8 -cp $driver -d $env:TEMP config\migrations\tools\ApplyModuleRuntimeViews.java
|
||||
& "$jdk\java.exe" -cp "$env:TEMP;$driver" ApplyModuleRuntimeViews
|
||||
```
|
||||
|
||||
The tool refuses non-`FMS` catalogs and executes `034` only when a required runtime view is missing.
|
||||
For a database in the validated intermediate state, run `ApplyModuleRuntimeViews --dry-run-cutover` first. After verifying a database backup, `ApplyModuleRuntimeViews --apply-cutover` executes `033`, then conditionally executes `034` and verifies all required runtime views.
|
||||
@@ -1,302 +0,0 @@
|
||||
import java.io.InputStream;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.sql.Connection;
|
||||
import java.sql.DriverManager;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.Statement;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
import java.util.HashSet;
|
||||
|
||||
/** Applies the module cutover and runtime views with prerequisite and completion checks. */
|
||||
public final class ApplyModuleRuntimeViews {
|
||||
private static final List<String> REQUIRED_TABLES = List.of(
|
||||
"s_module",
|
||||
"s_module_page",
|
||||
"s_module_data",
|
||||
"s_module_report",
|
||||
"s_module_dashboard",
|
||||
"s_module_workflow",
|
||||
"s_function_node",
|
||||
"s_page_node",
|
||||
"s_module_profile",
|
||||
"s_module_field",
|
||||
"s_module_field_list",
|
||||
"s_module_field_form",
|
||||
"s_module_field_query",
|
||||
"s_module_action",
|
||||
"b_role",
|
||||
"b_user_role",
|
||||
"b_role_function_node",
|
||||
"b_role_page_node",
|
||||
"b_role_action",
|
||||
"b_user_function_node",
|
||||
"b_user_page_node",
|
||||
"b_user_action"
|
||||
);
|
||||
private static final List<String> REQUIRED_VIEWS = List.of(
|
||||
"v_s_function_node",
|
||||
"v_s_page_node",
|
||||
"v_s_module_profile",
|
||||
"v_s_module_runtime",
|
||||
"v_s_module_field_list",
|
||||
"v_s_module_field_form",
|
||||
"v_s_module_field_query",
|
||||
"v_s_module_action",
|
||||
"v_s_user_function_permission",
|
||||
"v_s_user_page_permission",
|
||||
"v_s_user_action_permission"
|
||||
);
|
||||
private static final List<String> INSPECTION_TABLES = List.of(
|
||||
"s_module",
|
||||
"s_module_profile",
|
||||
"s_function_node",
|
||||
"s_page_node",
|
||||
"s_module_field",
|
||||
"s_module_field_list",
|
||||
"s_module_field_edit",
|
||||
"s_module_field_query",
|
||||
"s_module_field_group",
|
||||
"s_module_power",
|
||||
"b_user_module",
|
||||
"b_user_power"
|
||||
);
|
||||
public static void main(String[] args) throws Exception {
|
||||
Path apiRoot = Path.of("").toAbsolutePath().normalize();
|
||||
boolean hasModeArgument = args.length > 0 && args[0].startsWith("--");
|
||||
String mode = hasModeArgument ? args[0] : "--views-only";
|
||||
int configIndex = hasModeArgument ? 1 : 0;
|
||||
Path configPath = args.length > configIndex
|
||||
? apiRoot.resolve(args[configIndex]).normalize()
|
||||
: apiRoot.resolve("config/dbconfigs/g3hd.properties");
|
||||
Path cutoverPath = apiRoot.resolve("config/migrations/033_create_module_structure.sql");
|
||||
Path migrationPath = apiRoot.resolve("config/migrations/034_module_runtime_views.sql");
|
||||
requirePathWithin(apiRoot, configPath);
|
||||
requirePathWithin(apiRoot, cutoverPath);
|
||||
requirePathWithin(apiRoot, migrationPath);
|
||||
|
||||
Properties properties = new Properties();
|
||||
try (InputStream input = Files.newInputStream(configPath)) {
|
||||
properties.load(input);
|
||||
}
|
||||
|
||||
try (Connection connection = DriverManager.getConnection(
|
||||
required(properties, "url"),
|
||||
required(properties, "username"),
|
||||
required(properties, "password")
|
||||
)) {
|
||||
if (!"FMS".equalsIgnoreCase(connection.getCatalog())) {
|
||||
throw new IllegalStateException("Refusing to migrate database: " + connection.getCatalog());
|
||||
}
|
||||
|
||||
if (mode.equals("--dry-run-cutover")) {
|
||||
List<String> cutoverTables = missingObjects(connection, "sys.tables", REQUIRED_TABLES);
|
||||
if (!cutoverTables.isEmpty()) {
|
||||
executeCutover(connection, cutoverPath, true);
|
||||
}
|
||||
System.out.println("PASS|033_create_module_structure.sql|dry_run=true|committed=false");
|
||||
return;
|
||||
}
|
||||
if (mode.equals("--apply-cutover")) {
|
||||
List<String> cutoverTables = missingObjects(connection, "sys.tables", REQUIRED_TABLES);
|
||||
if (cutoverTables.isEmpty()) {
|
||||
System.out.println("PASS|033_create_module_structure.sql|applied=false");
|
||||
} else {
|
||||
executeCutover(connection, cutoverPath, false);
|
||||
cutoverTables = missingObjects(connection, "sys.tables", REQUIRED_TABLES);
|
||||
if (!cutoverTables.isEmpty()) {
|
||||
throw new IllegalStateException(
|
||||
"Migration 033 did not complete; tables remain missing: "
|
||||
+ String.join(",", cutoverTables)
|
||||
);
|
||||
}
|
||||
System.out.println("APPLIED|033_create_module_structure.sql");
|
||||
}
|
||||
} else if (!mode.equals("--views-only")) {
|
||||
throw new IllegalArgumentException("Unknown mode: " + mode);
|
||||
}
|
||||
|
||||
List<String> missingTables = missingObjects(connection, "sys.tables", REQUIRED_TABLES);
|
||||
if (!missingTables.isEmpty()) {
|
||||
System.out.println("MISSING_PREREQUISITE_TABLES|" + String.join(",", missingTables));
|
||||
printPartialState(connection);
|
||||
throw new IllegalStateException("Run migration 033 before migration 034");
|
||||
}
|
||||
|
||||
List<String> missingBefore = missingViews(connection);
|
||||
if (missingBefore.isEmpty()) {
|
||||
System.out.println("PASS|required_module_views=present|applied=false");
|
||||
return;
|
||||
}
|
||||
System.out.println("MISSING|" + String.join(",", missingBefore));
|
||||
|
||||
connection.setAutoCommit(false);
|
||||
try {
|
||||
String migration = Files.readString(migrationPath, StandardCharsets.UTF_8);
|
||||
int batches = executeBatches(connection, migration);
|
||||
List<String> missingAfter = missingViews(connection);
|
||||
if (!missingAfter.isEmpty()) {
|
||||
throw new IllegalStateException(
|
||||
"Required views remain missing: " + String.join(",", missingAfter)
|
||||
);
|
||||
}
|
||||
connection.commit();
|
||||
System.out.println("APPLIED|034_module_runtime_views.sql|batches=" + batches);
|
||||
System.out.println("PASS|required_module_views=present|applied=true");
|
||||
} catch (Exception exception) {
|
||||
connection.rollback();
|
||||
throw exception;
|
||||
} finally {
|
||||
connection.setAutoCommit(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static List<String> missingViews(Connection connection) throws Exception {
|
||||
return missingObjects(connection, "sys.views", REQUIRED_VIEWS);
|
||||
}
|
||||
|
||||
private static List<String> missingObjects(
|
||||
Connection connection,
|
||||
String catalogView,
|
||||
List<String> requiredObjects
|
||||
) throws Exception {
|
||||
Set<String> existing = new HashSet<>();
|
||||
try (Statement statement = connection.createStatement(); ResultSet rows = statement.executeQuery(
|
||||
"SELECT name FROM " + catalogView + " WHERE schema_id = SCHEMA_ID(N'dbo')"
|
||||
)) {
|
||||
while (rows.next()) existing.add(rows.getString(1));
|
||||
}
|
||||
List<String> missing = new ArrayList<>();
|
||||
for (String required : requiredObjects) {
|
||||
if (!existing.contains(required)) missing.add(required);
|
||||
}
|
||||
return missing;
|
||||
}
|
||||
|
||||
private static int executeBatches(Connection connection, String migration) throws Exception {
|
||||
String[] batches = migration.split("(?im)^\\s*GO\\s*(?:--.*)?$");
|
||||
int executed = 0;
|
||||
for (String batch : batches) {
|
||||
if (batch.isBlank()) continue;
|
||||
try (Statement statement = connection.createStatement()) {
|
||||
boolean hasResult = statement.execute(batch);
|
||||
while (true) {
|
||||
if (hasResult) {
|
||||
try (ResultSet rows = statement.getResultSet()) {
|
||||
while (rows.next()) {
|
||||
// Drain server results so the complete SQL batch finishes.
|
||||
}
|
||||
}
|
||||
} else if (statement.getUpdateCount() == -1) {
|
||||
break;
|
||||
}
|
||||
hasResult = statement.getMoreResults();
|
||||
}
|
||||
}
|
||||
executed++;
|
||||
}
|
||||
return executed;
|
||||
}
|
||||
|
||||
private static void executeCutover(Connection connection, Path migrationPath, boolean dryRun)
|
||||
throws Exception {
|
||||
connection.setAutoCommit(false);
|
||||
String migration = Files.readString(migrationPath, StandardCharsets.UTF_8);
|
||||
migration = migration.replaceAll(
|
||||
"(?s)/\\* CUTOVER_INSTALLED_GUARD_START \\*/.*?"
|
||||
+ "/\\* CUTOVER_INSTALLED_GUARD_END \\*/",
|
||||
""
|
||||
);
|
||||
migration = migration.replaceAll(
|
||||
"(?s)/\\* RETURN in the first batch means the architecture was already installed\\. \\*/"
|
||||
+ "\\s*IF @@TRANCOUNT = 0\\s*RETURN;",
|
||||
""
|
||||
);
|
||||
migration = migration.replaceAll("(?im)^\\s*BEGIN TRANSACTION;\\s*$", "");
|
||||
migration = migration.replaceAll("(?im)^\\s*COMMIT TRANSACTION;\\s*$", "");
|
||||
try {
|
||||
printCutoverState(connection, "before");
|
||||
int batches = executeBatches(connection, migration);
|
||||
printCutoverState(connection, "after-sql");
|
||||
List<String> missingTables = missingObjects(connection, "sys.tables", REQUIRED_TABLES);
|
||||
if (!missingTables.isEmpty()) {
|
||||
throw new IllegalStateException(
|
||||
"Migration 033 did not create required tables: " + String.join(",", missingTables)
|
||||
);
|
||||
}
|
||||
if (dryRun) {
|
||||
connection.rollback();
|
||||
} else {
|
||||
connection.commit();
|
||||
}
|
||||
printCutoverState(connection, "after-jdbc");
|
||||
System.out.println("CUTOVER_SQL|dry_run=" + dryRun + "|batches=" + batches);
|
||||
} catch (Exception exception) {
|
||||
try (Statement statement = connection.createStatement()) {
|
||||
statement.execute("IF @@TRANCOUNT > 0 ROLLBACK TRANSACTION");
|
||||
}
|
||||
connection.rollback();
|
||||
throw exception;
|
||||
} finally {
|
||||
connection.setAutoCommit(true);
|
||||
}
|
||||
}
|
||||
|
||||
private static void printCutoverState(Connection connection, String phase) throws Exception {
|
||||
try (Statement statement = connection.createStatement(); ResultSet rows = statement.executeQuery(
|
||||
"SELECT @@TRANCOUNT, CASE WHEN OBJECT_ID(N'dbo.s_module_page', N'U') IS NULL THEN 0 ELSE 1 END"
|
||||
)) {
|
||||
rows.next();
|
||||
System.out.println("CUTOVER_STATE|" + phase + "|trancount=" + rows.getInt(1)
|
||||
+ "|s_module_page=" + (rows.getInt(2) == 1));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static void printPartialState(Connection connection) throws Exception {
|
||||
Set<String> existing = new HashSet<>();
|
||||
try (Statement statement = connection.createStatement(); ResultSet rows = statement.executeQuery(
|
||||
"SELECT name FROM sys.tables WHERE schema_id = SCHEMA_ID(N'dbo')"
|
||||
)) {
|
||||
while (rows.next()) existing.add(rows.getString(1));
|
||||
}
|
||||
for (String table : INSPECTION_TABLES) {
|
||||
if (!existing.contains(table)) continue;
|
||||
try (Statement statement = connection.createStatement(); ResultSet rows = statement.executeQuery(
|
||||
"SELECT COUNT_BIG(*) FROM dbo.[" + table.replace("]", "]]" ) + "]"
|
||||
)) {
|
||||
rows.next();
|
||||
System.out.println("TABLE_STATE|" + table + "|rows=" + rows.getLong(1));
|
||||
}
|
||||
List<String> columns = new ArrayList<>();
|
||||
try (Statement statement = connection.createStatement(); ResultSet rows = statement.executeQuery(
|
||||
"SELECT column_row.name, TYPE_NAME(column_row.user_type_id), column_row.is_nullable "
|
||||
+ "FROM sys.columns AS column_row "
|
||||
+ "WHERE column_row.object_id = OBJECT_ID(N'dbo.["
|
||||
+ table.replace("]", "]]" )
|
||||
+ "]') ORDER BY column_row.column_id"
|
||||
)) {
|
||||
while (rows.next()) {
|
||||
columns.add(rows.getString(1) + ":" + rows.getString(2)
|
||||
+ (rows.getBoolean(3) ? "?" : ""));
|
||||
}
|
||||
}
|
||||
System.out.println("TABLE_COLUMNS|" + table + "|" + String.join(",", columns));
|
||||
}
|
||||
}
|
||||
|
||||
private static String required(Properties properties, String key) {
|
||||
String value = properties.getProperty(key);
|
||||
if (value == null || value.isBlank()) throw new IllegalStateException("Missing property: " + key);
|
||||
return value.trim();
|
||||
}
|
||||
|
||||
private static void requirePathWithin(Path root, Path path) {
|
||||
if (!path.startsWith(root)) throw new IllegalArgumentException("Path is outside API root: " + path);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
import java.io.InputStream;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.sql.Connection;
|
||||
import java.sql.DriverManager;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.Statement;
|
||||
import java.util.Properties;
|
||||
|
||||
public final class ApplySimpleModuleRestore {
|
||||
public static void main(String[] args) throws Exception {
|
||||
Path apiRoot = Path.of("").toAbsolutePath().normalize();
|
||||
Path configPath = apiRoot.resolve("config/dbconfigs/g3hd.properties").normalize();
|
||||
Path migrationPath = apiRoot.resolve("config/migrations/035_restore_simple_module_tree.sql").normalize();
|
||||
|
||||
Properties properties = new Properties();
|
||||
try (InputStream input = Files.newInputStream(configPath)) {
|
||||
properties.load(input);
|
||||
}
|
||||
|
||||
try (Connection connection = DriverManager.getConnection(
|
||||
required(properties, "url"),
|
||||
required(properties, "username"),
|
||||
required(properties, "password"))) {
|
||||
if (!"FMS".equalsIgnoreCase(connection.getCatalog())) {
|
||||
throw new IllegalStateException("Refusing to restore database: " + connection.getCatalog());
|
||||
}
|
||||
if (args.length == 1 && "--verify-only".equals(args[0])) {
|
||||
verify(connection);
|
||||
return;
|
||||
}
|
||||
connection.setAutoCommit(false);
|
||||
try {
|
||||
String migration = Files.readString(migrationPath, StandardCharsets.UTF_8);
|
||||
int batches = executeBatches(connection, migration);
|
||||
verify(connection);
|
||||
connection.commit();
|
||||
System.out.println("APPLIED|035_restore_simple_module_tree.sql|batches=" + batches);
|
||||
} catch (Exception exception) {
|
||||
connection.rollback();
|
||||
throw exception;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static int executeBatches(Connection connection, String migration) throws Exception {
|
||||
String[] batches = migration.split("(?im)^\\s*GO\\s*(?:--.*)?$");
|
||||
int count = 0;
|
||||
for (String batch : batches) {
|
||||
if (batch.isBlank()) continue;
|
||||
try (Statement statement = connection.createStatement()) {
|
||||
statement.execute(batch);
|
||||
}
|
||||
count++;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
private static void verify(Connection connection) throws Exception {
|
||||
String sql = """
|
||||
SELECT
|
||||
CASE WHEN COL_LENGTH(N'dbo.s_module', N'b_parent_id') IS NULL THEN 0 ELSE 1 END,
|
||||
CASE WHEN OBJECT_ID(N'dbo.s_module_page', N'U') IS NULL THEN 0 ELSE 1 END,
|
||||
(SELECT COUNT(*) FROM dbo.s_module WHERE b_module_type = 'data_category'),
|
||||
(SELECT COUNT(*)
|
||||
FROM dbo.s_module child
|
||||
LEFT JOIN dbo.s_module parent ON parent.b_id = child.b_parent_id
|
||||
WHERE (child.b_module_type IN ('directory', 'page')
|
||||
AND child.b_parent_id IS NOT NULL
|
||||
AND ISNULL(parent.b_module_type, '') <> 'directory')
|
||||
OR (child.b_module_type IN ('data_category', 'data')
|
||||
AND ISNULL(parent.b_module_type, '') NOT IN ('page', 'data_category')))
|
||||
""";
|
||||
try (Statement statement = connection.createStatement(); ResultSet rows = statement.executeQuery(sql)) {
|
||||
rows.next();
|
||||
if (rows.getInt(1) != 1 || rows.getInt(2) != 0 || rows.getInt(4) != 0) {
|
||||
throw new IllegalStateException("Simple module tree verification failed");
|
||||
}
|
||||
System.out.println(
|
||||
"PASS|simple_module_tree|data_categories=" + rows.getInt(3) + "|invalid_parents=0");
|
||||
}
|
||||
}
|
||||
|
||||
private static String required(Properties properties, String key) {
|
||||
String value = properties.getProperty(key);
|
||||
if (value == null || value.isBlank()) throw new IllegalStateException("Missing property: " + key);
|
||||
return value;
|
||||
}
|
||||
}
|
||||
@@ -30,7 +30,7 @@ public final class GenerateBusinessMigrations {
|
||||
"dtproperties", "log_datas"
|
||||
);
|
||||
private static final Set<String> TREE_TABLES = lowerSet(
|
||||
"b_other_bmfl", "bc_pricelist_bmfl", "oa_title_bmfl"
|
||||
"bc_pricelist_bmfl", "oa_title_bmfl"
|
||||
);
|
||||
private static final Set<String> EXCLUDED_VIEWS = lowerSet(
|
||||
"v_autoidrule", "v_b_contact", "v_b_employee", "v_b_user_record"
|
||||
|
||||
@@ -1,163 +0,0 @@
|
||||
/* Read-only verification for the module architecture cutover. */
|
||||
SET NOCOUNT ON;
|
||||
|
||||
IF DB_NAME() <> N'FMS'
|
||||
THROW 53500, N'This verification can only run against the FMS database.', 1;
|
||||
|
||||
IF EXISTS (
|
||||
SELECT required.name
|
||||
FROM (VALUES
|
||||
(N's_module'), (N's_module_page'), (N's_module_data'), (N's_module_report'),
|
||||
(N's_module_dashboard'), (N's_module_workflow'), (N's_function_node'),
|
||||
(N's_page_node'), (N's_module_profile'), (N's_module_field'),
|
||||
(N's_module_field_list'), (N's_module_field_form'), (N's_module_field_query'),
|
||||
(N's_module_action'), (N's_module_relation'), (N'b_role'), (N'b_user_role'),
|
||||
(N'b_role_data_scope')
|
||||
) AS required(name)
|
||||
LEFT JOIN sys.tables AS actual ON actual.name = required.name AND actual.schema_id = SCHEMA_ID(N'dbo')
|
||||
WHERE actual.object_id IS NULL
|
||||
)
|
||||
THROW 53501, N'Required module architecture tables are missing.', 1;
|
||||
|
||||
IF EXISTS (
|
||||
SELECT required.name
|
||||
FROM (VALUES
|
||||
(N'v_s_function_node'), (N'v_s_page_node'), (N'v_s_module_runtime'),
|
||||
(N'v_s_module_profile'), (N'v_s_module_action'),
|
||||
(N'v_s_user_function_permission'), (N'v_s_user_page_permission'),
|
||||
(N'v_s_user_action_permission')
|
||||
) AS required(name)
|
||||
LEFT JOIN sys.views AS actual ON actual.name = required.name AND actual.schema_id = SCHEMA_ID(N'dbo')
|
||||
WHERE actual.object_id IS NULL
|
||||
)
|
||||
THROW 53502, N'Required module runtime views are missing.', 1;
|
||||
|
||||
IF EXISTS (
|
||||
SELECT 1
|
||||
FROM (VALUES
|
||||
(N's_module_field_edit'), (N's_module_power'), (N'b_user_module'),
|
||||
(N'b_user_power'), (N'b_other_bmfl')
|
||||
) AS legacy(name)
|
||||
INNER JOIN sys.tables AS actual ON actual.name = legacy.name AND actual.schema_id = SCHEMA_ID(N'dbo')
|
||||
)
|
||||
THROW 53503, N'Legacy module metadata tables still exist.', 1;
|
||||
|
||||
IF EXISTS (
|
||||
SELECT 1
|
||||
FROM dbo.s_module AS module_row
|
||||
LEFT JOIN dbo.s_module_page AS page_row ON page_row.b_module_id = module_row.b_id
|
||||
LEFT JOIN dbo.s_module_data AS data_row ON data_row.b_module_id = module_row.b_id
|
||||
LEFT JOIN dbo.s_module_report AS report_row ON report_row.b_module_id = module_row.b_id
|
||||
LEFT JOIN dbo.s_module_dashboard AS dashboard_row ON dashboard_row.b_module_id = module_row.b_id
|
||||
LEFT JOIN dbo.s_module_workflow AS workflow_row ON workflow_row.b_module_id = module_row.b_id
|
||||
WHERE (CASE WHEN page_row.b_module_id IS NULL THEN 0 ELSE 1 END
|
||||
+ CASE WHEN data_row.b_module_id IS NULL THEN 0 ELSE 1 END
|
||||
+ CASE WHEN report_row.b_module_id IS NULL THEN 0 ELSE 1 END
|
||||
+ CASE WHEN dashboard_row.b_module_id IS NULL THEN 0 ELSE 1 END
|
||||
+ CASE WHEN workflow_row.b_module_id IS NULL THEN 0 ELSE 1 END) <> 1
|
||||
OR (module_row.b_module_type = 'page' AND page_row.b_module_id IS NULL)
|
||||
OR (module_row.b_module_type = 'data' AND data_row.b_module_id IS NULL)
|
||||
OR (module_row.b_module_type = 'report' AND report_row.b_module_id IS NULL)
|
||||
OR (module_row.b_module_type = 'dashboard' AND dashboard_row.b_module_id IS NULL)
|
||||
OR (module_row.b_module_type = 'workflow' AND workflow_row.b_module_id IS NULL)
|
||||
)
|
||||
THROW 53504, N'Module subtype records are incomplete or conflicting.', 1;
|
||||
|
||||
IF EXISTS (
|
||||
SELECT 1
|
||||
FROM dbo.s_module AS module_row
|
||||
LEFT JOIN dbo.s_module_profile AS profile_row
|
||||
ON profile_row.b_module_id = module_row.b_id AND profile_row.b_default = 1
|
||||
WHERE module_row.b_module_type = 'data' AND profile_row.b_id IS NULL
|
||||
)
|
||||
THROW 53505, N'A data module has no default profile.', 1;
|
||||
|
||||
IF EXISTS (
|
||||
SELECT 1
|
||||
FROM dbo.s_module_profile AS profile_row
|
||||
INNER JOIN dbo.s_module AS module_row ON module_row.b_id = profile_row.b_module_id
|
||||
WHERE module_row.b_module_type <> 'data'
|
||||
)
|
||||
THROW 53506, N'A profile belongs to a non-data module.', 1;
|
||||
|
||||
IF EXISTS (
|
||||
SELECT 1
|
||||
FROM dbo.s_function_node AS child
|
||||
INNER JOIN dbo.s_function_node AS parent_row ON parent_row.b_id = child.b_parent_id
|
||||
WHERE parent_row.b_node_type <> 'directory'
|
||||
)
|
||||
THROW 53507, N'A function node is placed below a non-directory node.', 1;
|
||||
|
||||
IF EXISTS (
|
||||
SELECT 1
|
||||
FROM dbo.s_page_node AS child
|
||||
INNER JOIN dbo.s_page_node AS parent_row
|
||||
ON parent_row.b_page_module_id = child.b_page_module_id
|
||||
AND parent_row.b_id = child.b_parent_id
|
||||
WHERE parent_row.b_node_type = 'module_ref'
|
||||
)
|
||||
THROW 53508, N'A page node is placed below a module reference.', 1;
|
||||
|
||||
DECLARE @FunctionCycle bit = 0;
|
||||
;WITH function_tree AS (
|
||||
SELECT b_id AS origin_id, b_parent_id AS current_id,
|
||||
CAST(N'/' + CONVERT(nvarchar(30), b_id) + N'/' AS nvarchar(max)) AS visited
|
||||
FROM dbo.s_function_node
|
||||
WHERE b_parent_id IS NOT NULL
|
||||
UNION ALL
|
||||
SELECT tree.origin_id, parent_row.b_parent_id,
|
||||
tree.visited + CONVERT(nvarchar(30), parent_row.b_id) + N'/'
|
||||
FROM function_tree AS tree
|
||||
INNER JOIN dbo.s_function_node AS parent_row ON parent_row.b_id = tree.current_id
|
||||
WHERE tree.current_id IS NOT NULL
|
||||
AND tree.visited NOT LIKE N'%/' + CONVERT(nvarchar(30), parent_row.b_id) + N'/%'
|
||||
)
|
||||
SELECT TOP (1) @FunctionCycle = 1
|
||||
FROM function_tree WHERE current_id = origin_id
|
||||
OPTION (MAXRECURSION 32767);
|
||||
|
||||
IF @FunctionCycle = 1
|
||||
THROW 53509, N'The function tree contains a cycle.', 1;
|
||||
|
||||
DECLARE @PageCycle bit = 0;
|
||||
;WITH page_tree AS (
|
||||
SELECT b_page_module_id AS page_id, b_id AS origin_id, b_parent_id AS current_id,
|
||||
CAST(N'/' + CONVERT(nvarchar(30), b_id) + N'/' AS nvarchar(max)) AS visited
|
||||
FROM dbo.s_page_node
|
||||
WHERE b_parent_id IS NOT NULL
|
||||
UNION ALL
|
||||
SELECT tree.page_id, tree.origin_id, parent_row.b_parent_id,
|
||||
tree.visited + CONVERT(nvarchar(30), parent_row.b_id) + N'/'
|
||||
FROM page_tree AS tree
|
||||
INNER JOIN dbo.s_page_node AS parent_row
|
||||
ON parent_row.b_page_module_id = tree.page_id AND parent_row.b_id = tree.current_id
|
||||
WHERE tree.current_id IS NOT NULL
|
||||
AND tree.visited NOT LIKE N'%/' + CONVERT(nvarchar(30), parent_row.b_id) + N'/%'
|
||||
)
|
||||
SELECT TOP (1) @PageCycle = 1
|
||||
FROM page_tree WHERE current_id = origin_id
|
||||
OPTION (MAXRECURSION 32767);
|
||||
|
||||
IF @PageCycle = 1
|
||||
THROW 53510, N'The page tree contains a cycle.', 1;
|
||||
|
||||
IF EXISTS (SELECT 1 FROM dbo.s_module WHERE b_i18n <> 'meta.module.' + CONVERT(varchar(30), b_id))
|
||||
THROW 53511, N'Module i18n keys are not ID based.', 1;
|
||||
IF EXISTS (SELECT 1 FROM dbo.s_function_node WHERE b_i18n <> 'meta.node.' + CONVERT(varchar(30), b_id))
|
||||
THROW 53512, N'Function node i18n keys are not ID based.', 1;
|
||||
IF EXISTS (SELECT 1 FROM dbo.s_page_node WHERE b_i18n <> 'meta.node.' + CONVERT(varchar(30), b_id))
|
||||
THROW 53513, N'Page node i18n keys are not ID based.', 1;
|
||||
IF EXISTS (SELECT 1 FROM dbo.s_module_profile WHERE b_i18n <> 'meta.profile.' + CONVERT(varchar(30), b_id))
|
||||
THROW 53514, N'Profile i18n keys are not ID based.', 1;
|
||||
IF EXISTS (SELECT 1 FROM dbo.s_module_field WHERE b_i18n <> 'meta.field.' + CONVERT(varchar(30), b_id))
|
||||
THROW 53515, N'Field i18n keys are not ID based.', 1;
|
||||
IF EXISTS (SELECT 1 FROM dbo.s_module_action WHERE b_i18n <> 'meta.action.' + CONVERT(varchar(30), b_id))
|
||||
THROW 53516, N'Action i18n keys are not ID based.', 1;
|
||||
|
||||
SELECT
|
||||
(SELECT COUNT(*) FROM dbo.s_module) AS module_count,
|
||||
(SELECT COUNT(*) FROM dbo.s_function_node) AS function_node_count,
|
||||
(SELECT COUNT(*) FROM dbo.s_page_node) AS page_node_count,
|
||||
(SELECT COUNT(*) FROM dbo.s_module_profile) AS profile_count,
|
||||
(SELECT COUNT(*) FROM dbo.s_module_field) AS field_count,
|
||||
(SELECT COUNT(*) FROM dbo.s_module_action) AS action_count;
|
||||
@@ -6,9 +6,7 @@ import cn.g3soft.fmsapi.utils.ApiResponse;
|
||||
import cn.g3soft.fmsapi.utils.ParamUtils;
|
||||
import cn.g3soft.fmsapi.utils.snowflake.idgen.IdGenerator;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
@@ -57,8 +55,12 @@ public class DataController {
|
||||
return ApiResponse.success("保存成功", null);
|
||||
}
|
||||
|
||||
@GetMapping("/nextid")
|
||||
public ApiResponse<?> nextId(@RequestParam(required = false, defaultValue = "1") int count) {
|
||||
@PostMapping("/nextid")
|
||||
public ApiResponse<?> nextId(@RequestBody(required = false) Map<String, Object> params) {
|
||||
int count = 1;
|
||||
if (params != null && params.get("count") instanceof Number num) {
|
||||
count = num.intValue();
|
||||
}
|
||||
if (count <= 1) {
|
||||
return ApiResponse.success(IdGenerator.nextId());
|
||||
}
|
||||
@@ -69,11 +71,14 @@ public class DataController {
|
||||
return ApiResponse.success(ids);
|
||||
}
|
||||
|
||||
@GetMapping("/nextcode")
|
||||
public ApiResponse<?> nextCode(
|
||||
@RequestParam String moduleId,
|
||||
@RequestParam(required = false, defaultValue = "1") int count
|
||||
) throws SQLException {
|
||||
@PostMapping("/nextcode")
|
||||
public ApiResponse<?> nextCode(@RequestBody(required = false) Map<String, Object> params)
|
||||
throws SQLException {
|
||||
String moduleId = ParamUtils.getRequiredString(params, "moduleId");
|
||||
int count = 1;
|
||||
if (params != null && params.get("count") instanceof Number num) {
|
||||
count = num.intValue();
|
||||
}
|
||||
List<String> codes = dataSaveService.nextCode(moduleId, count);
|
||||
if (codes.size() == 1) {
|
||||
return ApiResponse.success(codes.get(0));
|
||||
|
||||
Binary file not shown.
Reference in new issue
Block a user