-- Copyright (c) 2025 Huawei Technologies Co., Ltd.
-- openUBMC is licensed under Mulan PSL v2.
-- You can use this software according to the terms and conditions of the Mulan PSL v2.
-- You may obtain a copy of Mulan PSL v2 at:
--          http://license.coscl.org.cn/MulanPSL2
-- THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
-- EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
-- MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
-- See the Mulan PSL v2 for more details.
local Databases = require 'database'
local Col = require 'database.column'

local def_types = require 'class.types.types'

---@class AccountServiceTable: Table
---@field AccountLockoutCounterResetAfter FieldBase
---@field AccountLockoutCounterResetEnabled FieldBase
---@field AuthFailureLoggingThreshold FieldBase
---@field MaxPasswordLength FieldBase
---@field MinPasswordLength FieldBase
---@field ServiceEnabled FieldBase
---@field PasswordComplexityEnable FieldBase
---@field InitialPasswordPromptEnable FieldBase
---@field InitialPasswordNeedModify FieldBase
---@field InitialAccountPrivilegeRestrictEnabled FieldBase
---@field MinPasswordValidDays FieldBase
---@field MaxPasswordValidDays FieldBase
---@field EmergencyLoginAccountId FieldBase
---@field SNMPv3TrapAccountId FieldBase
---@field InactiveDaysThreshold FieldBase
---@field WeakPasswordDictionaryEnabled FieldBase
---@field HistoryPasswordCount FieldBase
---@field MaxHistoryPasswordCount FieldBase
---@field HostUserManagementEnabled FieldBase
---@field OSAdministratorPrivilegeEnabled FieldBase
---@field SNMPv3TrapAccountLimitPolicy FieldBase
---@field UserNamePasswordPrefixCompareEnabled FieldBase
---@field UserNamePasswordPrefixCompareLength FieldBase
---@field SNMPv3TrapAccountChangePolicy FieldBase
---@field RequireChangePasswordAction FieldBase
---@field PasswordExpirationDays FieldBase
---@field AccountLockoutDuration FieldBase
---@field AccountLockoutThreshold FieldBase
---@field UserMgmtEnable FieldBase
---@field TimeSource FieldBase
---@field PasswordComplexityIsLock FieldBase
---@field PreviousPasswordsDisallowed FieldBase
---@field Id FieldBase

---@class ManagerAccountDBTable: Table
---@field AccountExpiration FieldBase
---@field Certificates FieldBase
---@field Enabled FieldBase
---@field Id FieldBase
---@field Locked FieldBase
---@field UserName FieldBase
---@field Deletable FieldBase
---@field Password FieldBase
---@field KDFPassword FieldBase
---@field PasswordChangeRequired FieldBase
---@field PasswordExpiration FieldBase
---@field RoleId FieldBase
---@field SshPublicKeyHash FieldBase
---@field IpmiPassword FieldBase
---@field IpmiPasswordBak FieldBase
---@field WithinMinPasswordDays FieldBase
---@field LoginRuleIds FieldBase
---@field InactUserRemainDays FieldBase
---@field LastLoginTime FieldBase
---@field LastLoginIP FieldBase
---@field LastLoginInterface FieldBase
---@field FirstLoginPolicy FieldBase
---@field AccountType FieldBase
---@field LoginInterface FieldBase
---@field PasswordValidStartTime FieldBase
---@field InactiveStartTime FieldBase
---@field PasswordWritable FieldBase
---@field UserNameWritable FieldBase
---@field LoginInterfaceWritable FieldBase
---@field RoleIdWritable FieldBase
---@field EnabledWritable FieldBase
---@field LoginRuleIdsWritable FieldBase
---@field AuthenticationProtocolWritable FieldBase
---@field EncryptionProtocolWritable FieldBase
---@field SNMPPasswordWritable FieldBase
---@field IsOnline FieldBase

---@class ManagerAccountBackupTable: Table
---@field Id FieldBase
---@field ManagerAccountData FieldBase
---@field IpmiAccountData FieldBase
---@field SnmpAccountData FieldBase
---@field IpmiChannelData FieldBase

---@class SNMPUserInfoTable: Table
---@field AccountId FieldBase
---@field AuthenticationKey FieldBase
---@field AuthenticationKeySet FieldBase
---@field AuthenticationProtocol FieldBase
---@field EncryptionKey FieldBase
---@field EncryptionKeySet FieldBase
---@field EncryptionProtocol FieldBase
---@field SNMPPassword FieldBase
---@field SNMPKDFPassword FieldBase
---@field SnmpEncryptionPasswordInitialStatus FieldBase

---@class IpmiUserInfoTable: Table
---@field AccountId FieldBase
---@field Use20BytesPasswd FieldBase
---@field IsCallin FieldBase
---@field IsEnableAuth FieldBase
---@field IsEnableIpmiMsg FieldBase
---@field IsEnableByPasswd FieldBase
---@field Privilege0 FieldBase
---@field Privilege1 FieldBase
---@field IsSynced FieldBase

---@class HistoryPasswordTable: Table
---@field AccountId FieldBase
---@field SequenceNumber FieldBase
---@field Password FieldBase
---@field KDFPassword FieldBase

---@class LoginRuleTable: Table
---@field RuleId FieldBase
---@field IpRule FieldBase
---@field Ipv6Rule FieldBase
---@field TimeRule FieldBase
---@field MacRule FieldBase
---@field Enabled FieldBase

---@class RolesTable: Table
---@field ExtendedCustomRoleEnabled FieldBase
---@field Id FieldBase

---@class RoleTable: Table
---@field RolePrivilege FieldBase
---@field Name FieldBase
---@field Id FieldBase
---@field RoleName FieldBase
---@field UserMgmt FieldBase
---@field BasicSetting FieldBase
---@field KVMMgmt FieldBase
---@field ReadOnly FieldBase
---@field VMMMgmt FieldBase
---@field SecurityMgmt FieldBase
---@field PowerMgmt FieldBase
---@field DiagnoseMgmt FieldBase
---@field ConfigureSelf FieldBase

---@class SnmpCommunityTable: Table
---@field LongCommunityEnabled FieldBase
---@field RwCommunityEnabled FieldBase
---@field Id FieldBase

---@class AccountBackupTable: Table
---@field Id FieldBase
---@field UserName FieldBase
---@field Password FieldBase
---@field RoleId FieldBase
---@field LoginInterface FieldBase
---@field Enabled FieldBase

---@class PasswordPolicyDBTable: Table
---@field AccountType FieldBase
---@field AccountTypeName FieldBase
---@field Policy FieldBase
---@field Pattern FieldBase
---@field MaxPasswordLength FieldBase

---@class AccountPolicyDBTable: Table
---@field AccountType FieldBase
---@field NamePattern FieldBase
---@field AllowedLoginInterfaces FieldBase
---@field Visible FieldBase
---@field Deletable FieldBase
---@field OnlineDeletable FieldBase

---@class IpmiChannelConfigTable: Table
---@field PrivilegeLimit FieldBase
---@field IpmiMessagingEnabled FieldBase
---@field LinkAuthenticationEnabled FieldBase
---@field CallbackRestriction FieldBase
---@field SessionLimit FieldBase
---@field AccountId FieldBase
---@field ChannelNumber FieldBase

---@class AccountDBDatabase
---@field db DataBase
---@field select fun(db:DataBase, table: any, ...): SelectStatement
---@field update fun(db:DataBase, table: any, ...): UpdateStatement
---@field insert fun(db:DataBase, table: any, ...): InsertStatement
---@field AccountService AccountServiceTable
---@field ManagerAccountDB ManagerAccountDBTable
---@field ManagerAccountBackup ManagerAccountBackupTable
---@field SNMPUserInfo SNMPUserInfoTable
---@field IpmiUserInfo IpmiUserInfoTable
---@field HistoryPassword HistoryPasswordTable
---@field LoginRule LoginRuleTable
---@field Roles RolesTable
---@field Role RoleTable
---@field SnmpCommunity SnmpCommunityTable
---@field AccountBackup AccountBackupTable
---@field PasswordPolicyDB PasswordPolicyDBTable
---@field AccountPolicyDB AccountPolicyDBTable
---@field IpmiChannelConfig IpmiChannelConfigTable
local AccountDBDatabase = {}
AccountDBDatabase.__index = AccountDBDatabase

function AccountDBDatabase.new(path, datas)
    local db = Databases(path)
    local obj = {db = db}

    obj.AccountService = db:Table('t_account_service', {
        AccountLockoutCounterResetAfter = Col.IntegerField():cid(1):null():max_length(32):default(0),
        AccountLockoutCounterResetEnabled = Col.BooleandField():cid(2):null():default(false),
        AuthFailureLoggingThreshold = Col.IntegerField():cid(3):null():max_length(32):default(0),
        MaxPasswordLength = Col.IntegerField():cid(4):persistence_key('protect_power_off'):null():max_length(32)
            :default(20),
        MinPasswordLength = Col.IntegerField():cid(5):persistence_key('protect_power_off'):null():max_length(32)
            :default(8),
        ServiceEnabled = Col.BooleandField():cid(6):null():default(true),
        PasswordComplexityEnable = Col.BooleandField():cid(7):persistence_key('protect_power_off'):null():default(true),
        InitialPasswordPromptEnable = Col.BooleandField():cid(8):persistence_key('protect_power_off'):null():default(
            true),
        InitialPasswordNeedModify = Col.BooleandField():cid(9):persistence_key('protect_power_off'):null():default(true),
        InitialAccountPrivilegeRestrictEnabled = Col.BooleandField():cid(10):persistence_key('protect_power_off'):null()
            :default(false),
        MinPasswordValidDays = Col.IntegerField():cid(11):persistence_key('protect_power_off'):null():max_length(32)
            :default(0),
        MaxPasswordValidDays = Col.IntegerField():cid(12):persistence_key('protect_power_off'):null():max_length(32)
            :default(0),
        EmergencyLoginAccountId = Col.IntegerField():cid(13):persistence_key('protect_power_off'):null():max_length(8)
            :default(0),
        SNMPv3TrapAccountId = Col.IntegerField():cid(14):persistence_key('protect_power_off'):null():max_length(8)
            :default(2),
        InactiveDaysThreshold = Col.IntegerField():cid(15):persistence_key('protect_power_off'):null():max_length(32)
            :default(0),
        WeakPasswordDictionaryEnabled = Col.BooleandField():cid(16):persistence_key('protect_power_off'):null():default(
            true),
        HistoryPasswordCount = Col.IntegerField():cid(17):persistence_key('protect_power_off'):null():max_length(8)
            :default(5),
        MaxHistoryPasswordCount = Col.IntegerField():cid(18):persistence_key('protect_temporary'):null():max_length(8)
            :default(5),
        HostUserManagementEnabled = Col.BooleandField():cid(19):persistence_key('protect_power_off'):null()
            :default(true),
        OSAdministratorPrivilegeEnabled = Col.BooleandField():cid(20):persistence_key('protect_power_off'):null()
            :default(true),
        SNMPv3TrapAccountLimitPolicy = Col.IntegerField():cid(21):null():max_length(8):default(2),
        UserNamePasswordPrefixCompareEnabled = Col.BooleandField():cid(22):persistence_key('protect_power_off'):null()
            :default(false),
        UserNamePasswordPrefixCompareLength = Col.IntegerField():cid(23):persistence_key('protect_power_off'):null()
            :max_length(8):default(4),
        SNMPv3TrapAccountChangePolicy = Col.IntegerField():cid(24):persistence_key('protect_power_off'):null()
            :max_length(8):default(0),
        RequireChangePasswordAction = Col.BooleandField():cid(25):persistence_key('protect_power_off'):null():default(
            false),
        PasswordExpirationDays = Col.IntegerField():cid(26):persistence_key('protect_power_off'):null():max_length(32)
            :default(4294967295),
        AccountLockoutDuration = Col.IntegerField():cid(27):null():max_length(32):default(300),
        AccountLockoutThreshold = Col.IntegerField():cid(28):null():max_length(32):default(5),
        UserMgmtEnable = Col.BooleandField():cid(29):persistence_key('protect_power_off'):null():default(true),
        TimeSource = Col.EnumField(def_types.TimeSource):cid(30):persistence_key('protect_power_off'):null():default(
            def_types.TimeSource.TS_NOT_NTP),
        PasswordComplexityIsLock = Col.BooleandField():cid(31):persistence_key('protect_power_off'):null()
            :default(false),
        PreviousPasswordsDisallowed = Col.IntegerField():cid(32):persistence_key('protect_power_off'):null():max_length(
            8):default(5),
        Id = Col.IntegerField():cid(33):primary_key():persistence_key('protect_power_off'):max_length(8)
    }, 'protect_power_off'):create_if_not_exist(datas and datas['t_account_service'])
    obj.ManagerAccountDB = db:Table('t_manager_account', {
        AccountExpiration = Col.TextField():cid(1):persistence_key('protect_power_off'):null():critical(),
        Certificates = Col.IntegerField():cid(2):persistence_key('protect_power_off'):null():max_length(16):critical(),
        Enabled = Col.BooleandField():cid(3):persistence_key('protect_power_off'):null():default(false):critical(),
        Id = Col.IntegerField():cid(4):primary_key():persistence_key('protect_power_off'):max_length(8):critical(),
        Locked = Col.BooleandField():cid(5):persistence_key('protect_power_off'):null():default(false):critical(),
        UserName = Col.TextField():cid(6):persistence_key('protect_power_off'):unique():null():critical(),
        Deletable = Col.BooleandField():cid(7):persistence_key('protect_power_off'):null():default(false):critical(),
        Password = Col.TextField():cid(8):persistence_key('protect_power_off'):critical(),
        KDFPassword = Col.TextField():cid(9):persistence_key('protect_power_off'):null():critical(),
        PasswordChangeRequired = Col.BooleandField():cid(10):persistence_key('protect_power_off'):null():default(true)
            :critical(),
        PasswordExpiration = Col.IntegerField():cid(11):persistence_key('protect_power_off'):null():max_length(32)
            :default(4294967295):critical(),
        RoleId = Col.IntegerField():cid(12):persistence_key('protect_power_off'):null():max_length(8):default(0)
            :critical(),
        SshPublicKeyHash = Col.TextField():cid(13):persistence_key('protect_power_off'):null():default('\'\'')
            :critical(),
        IpmiPassword = Col.TextField():cid(14):persistence_key('protect_power_off'):critical(),
        IpmiPasswordBak = Col.TextField():cid(15):persistence_key('protect_power_off'):null():critical(),
        WithinMinPasswordDays = Col.BooleandField():cid(16):persistence_key('protect_power_off'):null():default(false)
            :critical(),
        LoginRuleIds = Col.IntegerField():cid(17):persistence_key('protect_power_off'):null():max_length(8):default(0)
            :critical(),
        InactUserRemainDays = Col.IntegerField():cid(18):persistence_key('protect_power_off'):null():max_length(32)
            :default(4294967295):critical(),
        LastLoginTime = Col.IntegerField():cid(19):persistence_key('protect_power_off'):null():max_length(32):default(
            4294967295):critical(),
        LastLoginIP = Col.TextField():cid(20):persistence_key('protect_power_off'):null():default('\'\''):critical(),
        LastLoginInterface = Col.EnumField(def_types.LoginInterface):cid(21):persistence_key('protect_power_off'):null()
            :default(def_types.LoginInterface.Web):critical(),
        FirstLoginPolicy = Col.EnumField(def_types.FirstLoginPolicy):cid(22):persistence_key('protect_power_off'):null()
            :default(def_types.FirstLoginPolicy.ForcePasswordReset):critical(),
        AccountType = Col.EnumField(def_types.AccountType):cid(23):persistence_key('protect_power_off'):null():default(
            def_types.AccountType.Local):critical(),
        LoginInterface = Col.IntegerField():cid(24):persistence_key('protect_power_off'):null():max_length(32)
            :default(0):critical(),
        PasswordValidStartTime = Col.IntegerField():cid(25):persistence_key('protect_power_off'):null():max_length(32)
            :default(0):critical(),
        InactiveStartTime = Col.IntegerField():cid(26):persistence_key('protect_power_off'):null():max_length(32)
            :default(0):critical(),
        PasswordWritable = Col.BooleandField():cid(27):persistence_key('protect_power_off'):null():default(true)
            :critical(),
        UserNameWritable = Col.BooleandField():cid(28):persistence_key('protect_power_off'):null():default(true)
            :critical(),
        LoginInterfaceWritable = Col.BooleandField():cid(29):persistence_key('protect_power_off'):null():default(true)
            :critical(),
        RoleIdWritable = Col.BooleandField():cid(30):persistence_key('protect_power_off'):null():default(true)
            :critical(),
        EnabledWritable = Col.BooleandField():cid(31):persistence_key('protect_power_off'):null():default(true)
            :critical(),
        LoginRuleIdsWritable = Col.BooleandField():cid(32):persistence_key('protect_power_off'):null():default(true)
            :critical(),
        AuthenticationProtocolWritable = Col.BooleandField():cid(33):persistence_key('protect_power_off'):null()
            :default(true):critical(),
        EncryptionProtocolWritable = Col.BooleandField():cid(34):persistence_key('protect_power_off'):null():default(
            true):critical(),
        SNMPPasswordWritable = Col.BooleandField():cid(35):persistence_key('protect_power_off'):null():default(true)
            :critical(),
        IsOnline = Col.BooleandField():cid(36):persistence_key('protect_temporary'):null():default(false)
    }):create_if_not_exist(datas and datas['t_manager_account'])
    obj.ManagerAccountBackup = db:Table('t_manager_account_backup', {
        Id = Col.IntegerField():cid(1):primary_key():persistence_key('protect_power_off'):max_length(8),
        ManagerAccountData = Col.TextField():cid(2):persistence_key('protect_power_off'):null(),
        IpmiAccountData = Col.TextField():cid(3):persistence_key('protect_power_off'):null(),
        SnmpAccountData = Col.TextField():cid(4):persistence_key('protect_power_off'):null(),
        IpmiChannelData = Col.TextField():cid(5):persistence_key('protect_power_off'):null()
    }):create_if_not_exist(datas and datas['t_manager_account_backup'])
    obj.SNMPUserInfo = db:Table('t_snmp_user_info', {
        AccountId = Col.IntegerField():cid(1):primary_key():persistence_key('protect_power_off'):max_length(8),
        AuthenticationKey = Col.TextField():cid(2):persistence_key('protect_power_off'),
        AuthenticationKeySet = Col.BooleandField():cid(3):persistence_key('protect_power_off'):null():default(false),
        AuthenticationProtocol = Col.EnumField(def_types.SNMPAuthenticationProtocols):cid(4):persistence_key(
            'protect_power_off'):null():default(def_types.SNMPAuthenticationProtocols.SHA256),
        EncryptionKey = Col.TextField():cid(5):persistence_key('protect_power_off'),
        EncryptionKeySet = Col.BooleandField():cid(6):persistence_key('protect_power_off'):null():default(false),
        EncryptionProtocol = Col.EnumField(def_types.SNMPEncryptionProtocols):cid(7)
            :persistence_key('protect_power_off'):null():default(def_types.SNMPEncryptionProtocols.AES128),
        SNMPPassword = Col.TextField():cid(8):persistence_key('protect_power_off'),
        SNMPKDFPassword = Col.TextField():cid(9):persistence_key('protect_power_off'):null(),
        SnmpEncryptionPasswordInitialStatus = Col.BooleandField():cid(10):persistence_key('protect_power_off'):null()
            :default(true)
    }):create_if_not_exist(datas and datas['t_snmp_user_info'])
    obj.IpmiUserInfo = db:Table('t_ipmi_user_info', {
        AccountId = Col.IntegerField():cid(1):primary_key():persistence_key('protect_power_off'):max_length(8),
        Use20BytesPasswd = Col.IntegerField():cid(2):persistence_key('protect_power_off'):null():max_length(8)
            :default(1),
        IsCallin = Col.IntegerField():cid(3):persistence_key('protect_power_off'):null():max_length(8):default(0),
        IsEnableAuth = Col.IntegerField():cid(4):persistence_key('protect_power_off'):null():max_length(8):default(1),
        IsEnableIpmiMsg = Col.IntegerField():cid(5):persistence_key('protect_power_off'):null():max_length(8):default(1),
        IsEnableByPasswd = Col.EnumField(def_types.IpmiUserEnableByPassword):cid(6):persistence_key('protect_power_off')
            :null():default(def_types.IpmiUserEnableByPassword.Disable),
        Privilege0 = Col.EnumField(def_types.IpmiPrivilege):cid(7):persistence_key('protect_power_off'):null():default(
            def_types.IpmiPrivilege.RESERVED),
        Privilege1 = Col.EnumField(def_types.IpmiPrivilege):cid(8):persistence_key('protect_power_off'):null():default(
            def_types.IpmiPrivilege.RESERVED),
        IsSynced = Col.BooleandField():cid(9):persistence_key('protect_power_off'):null():default(false)
    }):create_if_not_exist(datas and datas['t_ipmi_user_info'])
    obj.HistoryPassword = db:Table('t_history_password', {
        AccountId = Col.IntegerField():cid(1):primary_key():persistence_key('protect_power_off'):max_length(8),
        SequenceNumber = Col.IntegerField():cid(2):primary_key():persistence_key('protect_power_off'):max_length(8),
        Password = Col.TextField():cid(3):persistence_key('protect_power_off'):null(),
        KDFPassword = Col.TextField():cid(4):persistence_key('protect_power_off'):null()
    }):create_if_not_exist(datas and datas['t_history_password'])
    obj.LoginRule = db:Table('t_login_rule', {
        RuleId = Col.IntegerField():cid(1):primary_key():persistence_key('protect_power_off'):max_length(8),
        IpRule = Col.TextField():cid(2):persistence_key('protect_power_off'):null(),
        Ipv6Rule = Col.TextField():cid(3):persistence_key('protect_power_off'):null():default('\'\''),
        TimeRule = Col.TextField():cid(4):persistence_key('protect_power_off'):null(),
        MacRule = Col.TextField():cid(5):persistence_key('protect_power_off'):null(),
        Enabled = Col.BooleandField():cid(6):persistence_key('protect_power_off'):null():default(false)
    }):create_if_not_exist(datas and datas['t_login_rule'])
    obj.Roles = db:Table('t_roles', {
        ExtendedCustomRoleEnabled = Col.BooleandField():cid(1):persistence_key('protect_power_off'):null(),
        Id = Col.IntegerField():cid(2):primary_key():persistence_key('protect_power_off'):max_length(8)
    }):create_if_not_exist(datas and datas['t_roles'])
    obj.Role = db:Table('t_role', {
        RolePrivilege = Col.JsonField():cid(1):null():default([['[]']]),
        Name = Col.TextField():cid(2):null(),
        Id = Col.EnumField(def_types.RoleType):cid(3):primary_key():persistence_key('protect_power_off'),
        RoleName = Col.TextField():cid(4):persistence_key('protect_power_off'):unique():null(),
        UserMgmt = Col.BooleandField():cid(5):persistence_key('protect_power_off'):null():default(false),
        BasicSetting = Col.BooleandField():cid(6):persistence_key('protect_power_off'):null():default(false),
        KVMMgmt = Col.BooleandField():cid(7):persistence_key('protect_power_off'):null():default(false),
        ReadOnly = Col.BooleandField():cid(8):persistence_key('protect_power_off'):null():default(false),
        VMMMgmt = Col.BooleandField():cid(9):persistence_key('protect_power_off'):null():default(false),
        SecurityMgmt = Col.BooleandField():cid(10):persistence_key('protect_power_off'):null():default(false),
        PowerMgmt = Col.BooleandField():cid(11):persistence_key('protect_power_off'):null():default(false),
        DiagnoseMgmt = Col.BooleandField():cid(12):persistence_key('protect_power_off'):null():default(false),
        ConfigureSelf = Col.BooleandField():cid(13):persistence_key('protect_power_off'):null():default(false)
    }):create_if_not_exist(datas and datas['t_role'])
    obj.SnmpCommunity = db:Table('t_snmp_community', {
        LongCommunityEnabled = Col.BooleandField():cid(1):persistence_key('protect_power_off'):null():default(true),
        RwCommunityEnabled = Col.BooleandField():cid(2):persistence_key('protect_power_off'):null():default(true),
        Id = Col.IntegerField():cid(3):primary_key():persistence_key('protect_power_off'):max_length(8)
    }):create_if_not_exist(datas and datas['t_snmp_community'])
    obj.AccountBackup = db:Table('t_account_backup', {
        Id = Col.IntegerField():cid(1):primary_key():persistence_key('protect_permanent'):max_length(8),
        UserName = Col.TextField():cid(2):persistence_key('protect_permanent'):unique():null(),
        Password = Col.TextField():cid(3):persistence_key('protect_permanent'),
        RoleId = Col.IntegerField():cid(4):persistence_key('protect_permanent'):null():max_length(8):default(0),
        LoginInterface = Col.IntegerField():cid(5):persistence_key('protect_permanent'):null():max_length(32):default(0),
        Enabled = Col.BooleandField():cid(6):persistence_key('protect_permanent'):null():default(false)
    }):create_if_not_exist(datas and datas['t_account_backup'])
    obj.PasswordPolicyDB = db:Table('t_password_policy', {
        AccountType = Col.IntegerField():cid(1):primary_key():persistence_key('protect_power_off'):max_length(8),
        AccountTypeName = Col.TextField():cid(2):null(),
        Policy = Col.IntegerField():cid(3):persistence_key('protect_power_off'):null():max_length(8):default(1),
        Pattern = Col.TextField():cid(4):persistence_key('protect_power_off'):null():default('\'\''),
        MaxPasswordLength = Col.IntegerField():cid(5):persistence_key('protect_temporary'):null():max_length(32)
    }):create_if_not_exist(datas and datas['t_password_policy'])
    obj.AccountPolicyDB = db:Table('t_account_policy', {
        AccountType = Col.IntegerField():cid(1):primary_key():persistence_key('protect_power_off'):max_length(8),
        NamePattern = Col.TextField():cid(2):persistence_key('protect_power_off'):null():default('\'\''),
        AllowedLoginInterfaces = Col.IntegerField():cid(3):persistence_key('protect_power_off'):null():max_length(32)
            :default(223),
        Visible = Col.BooleandField():cid(4):persistence_key('protect_power_off'):null():default(false),
        Deletable = Col.BooleandField():cid(5):persistence_key('protect_power_off'):null():default(false),
        OnlineDeletable = Col.BooleandField():cid(6):persistence_key('protect_temporary'):null():default(true)
    }):create_if_not_exist(datas and datas['t_account_policy'])
    obj.IpmiChannelConfig = db:Table('t_ipmi_channel_config', {
        PrivilegeLimit = Col.IntegerField():cid(1):persistence_key('protect_power_off'):null():max_length(8),
        IpmiMessagingEnabled = Col.BooleandField():cid(2):persistence_key('protect_power_off'):null():default(true),
        LinkAuthenticationEnabled = Col.BooleandField():cid(3):persistence_key('protect_power_off'):null():default(true),
        CallbackRestriction = Col.IntegerField():cid(4):persistence_key('protect_power_off'):null():max_length(8),
        SessionLimit = Col.IntegerField():cid(5):persistence_key('protect_power_off'):null():max_length(8),
        AccountId = Col.IntegerField():cid(6):primary_key():persistence_key('protect_power_off'):max_length(8),
        ChannelNumber = Col.IntegerField():cid(7):primary_key():persistence_key('protect_power_off'):max_length(8)
    }, 'protect_power_off'):create_if_not_exist(datas and datas['t_ipmi_channel_config'])

    obj.tables = db.tables
    return setmetatable(obj, AccountDBDatabase)
end

function AccountDBDatabase:select(table, ...)
    return self.db:select(table, ...)
end

function AccountDBDatabase:update(table, ...)
    return self.db:update(table, ...)
end

function AccountDBDatabase:insert(table, ...)
    return self.db:insert(table, ...)
end

function AccountDBDatabase:delete(table, ...)
    return self.db:delete(table, ...)
end

function AccountDBDatabase:exec(...)
    return self.db:exec(...)
end

return AccountDBDatabase.new
