Imports System.Text
Imports UTS_Core.Database

Namespace UTSModule.DbTableModel.Customer
    ''' <summary>
    ''' 用户数据库同步总表
    ''' </summary>
    Public Class SyncListTable
        Enum ColNamesEnum
            ID
            ''' <summary>
            ''' 需要同步的数据表名
            ''' </summary>
            TableName
            ''' <summary>
            ''' 数据表版本编号
            ''' </summary>
            RevisionID
            ''' <summary>
            ''' 最近同步的本地时间
            ''' </summary>
            SyncTime
            ''' <summary>
            ''' 同步类型,如全表下载(all),或是增量下载（new）
            ''' </summary>
            SyncType
            ''' <summary>
            ''' 同步时需要更新的数据列
            ''' </summary>
            SyncCols
        End Enum

        Public Shared Property TableName() As String = "TBL_SyncList"


        ''' <summary>
        ''' 根据数据库类型,返回建表语句
        ''' </summary>
        ''' <param name="dbType">数据库类型</param>
        ''' <returns></returns>
        Public Shared Function CreateTableString(dbType As DbExecutor.DbTypeEnum) As String
            Dim createStr As New StringBuilder
            Select Case dbType
                Case DbExecutor.DbTypeEnum.Sqlite
                    createStr.Append($"Create Table If Not Exists `{TableName}`")
                    createStr.Append(" (")
                    createStr.Append($"`{ColNamesEnum.ID}` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL ,")
                    createStr.Append($"`{ColNamesEnum.TableName}` varchar(254) NOT NULL ,")
                    createStr.Append($"`{ColNamesEnum.RevisionID}` integer NOT NULL Default 0 ,")
                    createStr.Append($"`{ColNamesEnum.SyncTime}` dateTime NOT NULL DEFAULT '2000-01-01 00:00:00' ,")
                    createStr.Append($"`{ColNamesEnum.SyncType}` varchar(254) NOT NULL DEFAULT 'ALL' ,")
                    createStr.Append($"`{ColNamesEnum.SyncCols}` varchar(254) NOT NULL DEFAULT '*' ")
                    createStr.Append(" );")
                Case DbExecutor.DbTypeEnum.Mysql
                    createStr.Append($"Create Table If Not Exists `{TableName}`")
                    createStr.Append(" (")
                    createStr.Append($"`{ColNamesEnum.ID}` int(11) Not NULL AUTO_INCREMENT,")
                    createStr.Append($"`{ColNamesEnum.TableName}` varchar(254) Not NULL COMMENT '需同步的表名',")
                    createStr.Append($"`{ColNamesEnum.RevisionID}` int(11) Not NULL DEFAULT 0 COMMENT '表版本编号',")
                    createStr.Append($"`{ColNamesEnum.SyncType}` varchar(254) NOT NULL DEFAULT 'ALL' COMMENT '同步类型',")
                    createStr.Append($"`{ColNamesEnum.SyncCols}` varchar(254) NOT NULL DEFAULT '*' COMMENT '同步列名',")
                    createStr.Append($"PRIMARY KEY (`ID`)")
                    createStr.Append(" );")
                Case Else
                    Throw New Exception($"Invalid db type:{dbType}")
            End Select

            Return createStr.ToString()
        End Function

        Public Shared Function CreateTableString(dbName As String, Optional dbType As DbExecutor.DbTypeEnum = DbExecutor.DbTypeEnum.Mysql) As String
            Dim createStr As New StringBuilder
            Select Case dbType
                Case DbExecutor.DbTypeEnum.Sqlite
                    createStr.Append($"Create Table If Not Exists `{TableName}`")
                    createStr.Append(" (")
                    createStr.Append($"`{ColNamesEnum.ID}` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL ,")
                    createStr.Append($"`{ColNamesEnum.TableName}` varchar(254) NOT NULL ,")
                    createStr.Append($"`{ColNamesEnum.RevisionID}` integer NOT NULL Default 0 ,")
                    createStr.Append($"`{ColNamesEnum.SyncTime}` dateTime NOT NULL DEFAULT '2000-01-01 00:00:00' ,")
                    createStr.Append($"`{ColNamesEnum.SyncType}` varchar(254) NOT NULL DEFAULT 'ALL' ,")
                    createStr.Append($"`{ColNamesEnum.SyncCols}` varchar(254) NOT NULL DEFAULT '*' ")
                    createStr.Append(" );")
                Case DbExecutor.DbTypeEnum.Mysql
                    createStr.Append($"Create Table If Not Exists `{dbName}`.`{TableName}`")
                    createStr.Append(" (")
                    createStr.Append($"`{ColNamesEnum.ID}` int(11) Not NULL AUTO_INCREMENT,")
                    createStr.Append($"`{ColNamesEnum.TableName}` varchar(254) Not NULL COMMENT '需同步的表名',")
                    createStr.Append($"`{ColNamesEnum.RevisionID}` int(11) Not NULL DEFAULT 0 COMMENT '表版本编号',")
                    createStr.Append($"`{ColNamesEnum.SyncType}` varchar(254) NOT NULL DEFAULT 'ALL' COMMENT '同步类型',")
                    createStr.Append($"`{ColNamesEnum.SyncCols}` varchar(254) NOT NULL DEFAULT '*' COMMENT '同步列名',")
                    createStr.Append($"PRIMARY KEY (`ID`)")
                    createStr.Append(" );")
                Case Else
                    Throw New Exception($"Invalid db type:{dbType}")
            End Select

            Return createStr.ToString()
        End Function

        Public Shared Function SyncTrigger(dbName As String, tbName As String) As String
            Dim builder As New StringBuilder
            builder.Append(DbAfterDeleteDataTrigger(dbName, tbName))
            builder.Append(DbAfterInsertDataTrigger(dbName, tbName))
            ' builder.Append(DbAfterUpdateDataTrigger(dbName, tbName))
            builder.Append(DbBeforUpdateDataTrigger(dbName, tbName))
            Return builder.ToString()
        End Function

        ''' <summary>
        ''' 添加需要同步的数据表名至同步表中
        ''' </summary>
        ''' <param name="dbName">数据库名</param>
        ''' <param name="tbName">需要同步的数据表名</param>
        ''' <param name="syncType">同步类型,all为全表下载,new为增量下载</param>
        ''' <param name="syncCols">同步时下载的字段，默认为*全字段下载</param>
        ''' <returns></returns>
        Public Shared Function AddSyncTableString(dbName As String, tbName As String,Optional syncType As String = "all",Optional syncCols As String = "*") As String
            Dim builder As New StringBuilder
            builder.Append($"Delete from `{dbName}`.`{TableName}` where `{ColNamesEnum.TableName}` = '{tbName}';")
            builder.Append($"Insert Into `{dbName}`.`{TableName}` (`{ColNamesEnum.TableName}`,`{ColNamesEnum.SyncType}`,`{ColNamesEnum.SyncCols}`) values ('{tbName}','{syncType}','{syncCols}');")
            Return builder.ToString()
        End Function

        ''' <summary>
        ''' 数据库连接涉及多库操作时，新增数据后更新触发器
        ''' </summary>
        ''' <param name="dbName">数据库名</param>
        ''' <param name="tbName">数据表名</param>
        ''' <returns></returns>
        Public Shared Function DbAfterInsertDataTrigger(dbName As String, tbName As String) As String
            Dim triggerString As New StringBuilder
            triggerString.Append($"Create Trigger If Not Exists `{dbName}`.`{tbName}_AfterInsert` ")
            triggerString.Append($"After Insert On `{dbName}`.`{tbName}` ")
            triggerString.Append($"For Each Row ")
            triggerString.Append($"Begin ")

            triggerString.Append($"UPDATE `{dbName}`.`{TableName}` SET `{ColNamesEnum.RevisionID}` = (`{ColNamesEnum.RevisionID}` + 1) where `{ColNamesEnum.TableName}` = '{tbName}';")

            triggerString.Append($"End;")

            Return triggerString.ToString()
        End Function

        ''' <summary>
        ''' 数据库连接涉及多库操作时，更新数据后更新触发器
        ''' </summary>
        ''' <param name="dbName">数据库名</param>
        ''' <param name="tbName">数据表名</param>
        ''' <returns></returns>
        Public Shared Function DbAfterUpdateDataTrigger(dbName As String, tbName As String) As String
            Dim triggerString As New StringBuilder
            triggerString.Append($"Create Trigger If Not Exists `{dbName}`.`{tbName}_AfterUpdate` ")
            triggerString.Append($"After Update On `{dbName}`.`{tbName}` ")
            triggerString.Append($"For Each Row ")
            triggerString.Append($"Begin ")

            triggerString.Append($"Set NEW.UpdateTime = NOW();")
            triggerString.Append($"UPDATE `{dbName}`.`{TableName}` SET `{ColNamesEnum.RevisionID}` = (`{ColNamesEnum.RevisionID}` + 1) where `{ColNamesEnum.TableName}` = '{tbName}';")

            triggerString.Append($"End;")

            Return triggerString.ToString()
        End Function

        ''' <summary>
        ''' 数据库连接涉及多库操作时，更新数据后更新触发器
        ''' </summary>
        ''' <param name="dbName">数据库名</param>
        ''' <param name="tbName">数据表名</param>
        ''' <returns></returns>
        Public Shared Function DbBeforUpdateDataTrigger(dbName As String, tbName As String) As String
            Dim triggerString As New StringBuilder
            triggerString.Append($"Create Trigger If Not Exists `{dbName}`.`{tbName}_BeforeUpdate` ")
            triggerString.Append($"Before Update On `{dbName}`.`{tbName}` ")
            triggerString.Append($"For Each Row ")
            triggerString.Append($"Begin ")

            triggerString.Append($"Set NEW.UpdateTime = NOW();")
            triggerString.Append($"UPDATE `{dbName}`.`{TableName}` SET `{ColNamesEnum.RevisionID}` = (`{ColNamesEnum.RevisionID}` + 1) where `{ColNamesEnum.TableName}` = '{tbName}';")

            triggerString.Append($"End;")

            Return triggerString.ToString()
        End Function


        ''' <summary>
        ''' 数据库连接涉及多库操作时，删除后更新触发器
        ''' </summary>
        ''' <param name="dbName">数据库名</param>
        ''' <param name="tbName">数据表名</param>
        ''' <returns></returns>
        Public Shared Function DbAfterDeleteDataTrigger(dbName As String, tbName As String) As String
            Dim triggerString As New StringBuilder
            triggerString.Append($"Create Trigger If Not Exists `{dbName}`.`{tbName}_AfterDelete` ")
            triggerString.Append($"After Delete On `{dbName}`.`{tbName}` ")
            triggerString.Append($"For Each Row ")
            triggerString.Append($"Begin ")

            triggerString.Append($"UPDATE `{dbName}`.`{TableName}` SET `{ColNamesEnum.RevisionID}` = (`{ColNamesEnum.RevisionID}` + 1) where `{ColNamesEnum.TableName}` = '{tbName}';")

            triggerString.Append($"End;")

            Return triggerString.ToString()
        End Function



    End Class

End Namespace
