diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 034cf88c..5245c43d 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -8,9 +8,9 @@ jobs: runs-on: ubuntu-latest steps: - name: Install Go - uses: actions/setup-go@v3 + uses: actions/setup-go@v4 with: - go-version: '1.21' + go-version: '1.22' - name: Code uses: actions/checkout@v3 - name: Check diff between gofmt and code @@ -20,10 +20,10 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - go-version: ['1.21'] + go-version: ['1.22'] steps: - name: Install Go - uses: actions/setup-go@v3 + uses: actions/setup-go@v4 with: go-version: ${{ matrix.go-version }} - name: Code @@ -37,11 +37,11 @@ jobs: runs-on: ubuntu-latest steps: - name: Install Go - uses: actions/setup-go@v3 + uses: actions/setup-go@v4 with: - go-version: '1.21' + go-version: '1.22' - name: Code - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Go vet run: | git submodule init @@ -53,4 +53,4 @@ jobs: with: only-new-issues: true skip-pkg-cache: true - skip-build-cache: true \ No newline at end of file + skip-build-cache: true diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 5b219949..2f3cb1b1 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -18,7 +18,7 @@ on: # The branches below must be a subset of the branches above branches: [ "main" ] schedule: - - cron: '33 15 * * 6' + - cron: '30 15 * * 6' jobs: analyze: @@ -40,11 +40,16 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 + + - name: Install Go + uses: actions/setup-go@v4 + with: + go-version-file: go.mod # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@v2 + uses: github/codeql-action/init@v3 with: # Run extended queries including queries using machine learning queries: security-extended @@ -61,7 +66,7 @@ jobs: # Autobuild attempts to build any compiled languages (C/C++, C#, Go, or Java). # If this step fails, then you should remove it and run the build manually (see below) - name: Autobuild - uses: github/codeql-action/autobuild@v2 + uses: github/codeql-action/autobuild@v3 # ℹ Command-line programs to run using the OS shell. # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun @@ -74,6 +79,6 @@ jobs: # ./location_of_script_within_repo/buildscript.sh - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v2 + uses: github/codeql-action/analyze@v3 with: category: "/language:${{matrix.language}}" diff --git a/.github/workflows/update_submodules.yml b/.github/workflows/update_submodules.yml deleted file mode 100644 index a3bb5c93..00000000 --- a/.github/workflows/update_submodules.yml +++ /dev/null @@ -1,41 +0,0 @@ -name: Update submodules -run-name: Update submodules -permissions: write-all -on: - schedule: - - cron: '0 0 * * *' - workflow_dispatch: - push: - branches: - - main - -jobs: - update_submodules: - name: Update submodules - runs-on: ubuntu-latest - env: - TZ: "Asia/Tokyo" - if: contains(github.event.head_commit.message, '[ci skip]') == false - steps: - - uses: actions/checkout@v2 - with: - submodules: recursive - - name: Update submodules - id: update - run: git submodule update --remote --recursive - - name: Run git status - id: status - run: echo "::set-output name=status::$(git status -s)" - - name: Add and commit files - run: | - git add . - git config --local user.email "action@github.com" - git config --local user.name "GitHub Action" - git commit -m "Update submodules at $(date "+DATE: %Y-%m-%d TIME: %H:%M:%S")" - if: ${{ steps.status.outputs.status }} - - name: Push changes - uses: ad-m/github-push-action@master - with: - github_token: ${{ secrets.GITHUB_TOKEN }} - branch: main - if: ${{ steps.status.outputs.status && github.event_name == 'push' }} diff --git a/.gitignore b/.gitignore index 63a06cf7..cdfffdee 100644 --- a/.gitignore +++ b/.gitignore @@ -20,8 +20,12 @@ gobot start.sh config.json gobot.json +gobot.yml __**__** logs/ dist/ + +.docusaurus +node_modules diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 00000000..6854d676 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,10 @@ +# デフォルトの無芖察象ファむル +/shelf/ +/workspace.xml +# ゚ディタヌベヌスの HTTP クラむアントリク゚スト +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml +# GitHub Copilot persisted chat sessions +/copilot/chatSessions diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml new file mode 100644 index 00000000..a55e7a17 --- /dev/null +++ b/.idea/codeStyles/codeStyleConfig.xml @@ -0,0 +1,5 @@ + + + + \ No newline at end of file diff --git a/.idea/dataSources.xml b/.idea/dataSources.xml new file mode 100644 index 00000000..42f47308 --- /dev/null +++ b/.idea/dataSources.xml @@ -0,0 +1,12 @@ + + + + + mariadb + true + org.mariadb.jdbc.Driver + jdbc:mariadb://localhost:3306/gobot_dev + $ProjectFileDir$ + + + \ No newline at end of file diff --git a/.idea/discord.xml b/.idea/discord.xml new file mode 100644 index 00000000..8cf359dc --- /dev/null +++ b/.idea/discord.xml @@ -0,0 +1,7 @@ + + + + + \ No newline at end of file diff --git a/.idea/gobot.iml b/.idea/gobot.iml new file mode 100644 index 00000000..5e764c4f --- /dev/null +++ b/.idea/gobot.iml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 00000000..ffb3dc0c --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 00000000..35eb1ddf --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/watcherTasks.xml b/.idea/watcherTasks.xml new file mode 100644 index 00000000..69c3c05b --- /dev/null +++ b/.idea/watcherTasks.xml @@ -0,0 +1,32 @@ + + + + + + + + + + \ No newline at end of file diff --git a/bot/bot.go b/bot/bot.go new file mode 100644 index 00000000..2ae1dfe7 --- /dev/null +++ b/bot/bot.go @@ -0,0 +1,183 @@ +/* + Copyright (C) 2022-2023 sabafly + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ +package bot + +import ( + "context" + "fmt" + "github.com/disgoorg/disgo/discord" + "github.com/disgoorg/disgo/events" + "io" + "log/slog" + "net/http" + "net/url" + "os" + "os/signal" + "syscall" + + "github.com/disgoorg/disgo" + "github.com/disgoorg/disgo/bot" + "github.com/disgoorg/disgo/cache" + "github.com/disgoorg/disgo/gateway" + "github.com/disgoorg/disgo/rest" + "github.com/disgoorg/disgo/sharding" + _ "github.com/go-sql-driver/mysql" + "github.com/joho/godotenv" + "github.com/sabafly/gobot/bot/commands/debug" + "github.com/sabafly/gobot/bot/commands/level" + "github.com/sabafly/gobot/bot/commands/message" + "github.com/sabafly/gobot/bot/commands/permission" + "github.com/sabafly/gobot/bot/commands/ping" + "github.com/sabafly/gobot/bot/commands/role" + "github.com/sabafly/gobot/bot/commands/setting" + userinfo "github.com/sabafly/gobot/bot/commands/user_info" + "github.com/sabafly/gobot/bot/components" + "github.com/sabafly/gobot/ent" + "github.com/sabafly/gobot/internal/translate" + "github.com/spf13/cobra" +) + +var cmd = &cobra.Command{ + Use: "bot", + Short: "botを起動する", + RunE: func(cmd *cobra.Command, args []string) error { + return run() + }, +} + +func Command() *cobra.Command { return cmd } + +var ( + version = "v1.0.0-alpha.0" +) + +func run() error { + slog.SetDefault(slog.New(slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{ + AddSource: true, + Level: slog.LevelInfo, + }))) + _ = godotenv.Load() + + config, err := components.Load("gobot.yml") + if err != nil { + return fmt.Errorf("蚭定ファむルを読み蟌めたせん: %w", err) + } + + db, err := ent.Open("mysql", config.MySQL) + if err != nil { + return fmt.Errorf("mysqlずの接続を開けたせん: %w", err) + } + defer func(db *ent.Client) { + err := db.Close() + if err != nil { + slog.Error("mysqlずの接続を閉じれたせん", slog.Any("error", err)) + } + }(db) + + // c, err := caches.Open(config.Redis...) + // if err != nil { + // return fmt.Errorf("cacheを開けたせん: %w", err) + // } + + if err := db.Schema.Create(context.Background()); err != nil { + return fmt.Errorf("スキヌマを定矩できたせん: %w", err) + } + + if _, err := translate.LoadDir(config.TranslateDir); err != nil { + return fmt.Errorf("翻蚳ファむルが読み蟌めたせん path=%s: %w", config.TranslateDir, err) + } + + component := components.New(db, *config) + component.Version = version + + component.AddCommands( + debug.Command(component), + ping.Command(component), + message.Command(component), + role.Command(component), + level.Command(component), + userinfo.Command(component), + permission.Command(component), + setting.Command(component), + role.ImportCommand(component), + ) + + ready := make(chan *events.Ready) + + token := os.Getenv("TOKEN") + if token == "" { + return fmt.Errorf("TOKEN が空です") + } + client, err := disgo.New(token, + bot.WithCacheConfigOpts(cache.WithCaches(cache.FlagsAll)), + bot.WithShardManagerConfigOpts( + sharding.WithAutoScaling(true), + sharding.WithGatewayConfigOpts( + gateway.WithAutoReconnect(true), + gateway.WithIntents(gateway.IntentsGuild, gateway.IntentsPrivileged), + ), + ), + bot.WithRestClientConfigOpts( + rest.WithUserAgent(fmt.Sprintf("DiscordBot (%s, %s)", disgo.GitHub, disgo.Version)), + ), + bot.WithEventManagerConfigOpts( + bot.WithAsyncEventsEnabled(), + bot.WithListeners( + bot.NewListenerChan(ready), + ), + ), + ) + if err != nil { + return fmt.Errorf("クラむアントを䜜成できたせん: %w", err) + } + + if err := component.Initialize(client); err != nil { + return fmt.Errorf("コンポヌネントを初期化できたせん: %w", err) + } + + if err := client.OpenShardManager(context.Background()); err != nil { + return fmt.Errorf("discord ゲヌトりェむを開けたせん: %w", err) + } + defer client.Close(context.Background()) + + <-ready + + // set default webhook + bot.WebhookDefaultName = "gobot-webhook" + self, ok := client.Caches().SelfUser() + if !ok { + return fmt.Errorf("cannot cache self user") + } + if avatarURL, err := url.Parse(self.EffectiveAvatarURL(discord.WithFormat(discord.FileFormatPNG))); err != nil { + resp, err := http.Get(avatarURL.String()) + if err != nil { + return fmt.Errorf("error on get: %w", err) + } + defer resp.Body.Close() + buf, err := io.ReadAll(resp.Body) + if err != nil { + return fmt.Errorf("error on read all: %w", err) + } + bot.WebhookDefaultAvatar = discord.NewIconRaw(discord.IconTypePNG, buf) + } + + s := make(chan os.Signal, 1) + signal.Notify(s, syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT, syscall.Signal(0x13), syscall.Signal(0x14)) + <-s + + return nil +} diff --git a/bot/client/client.go b/bot/client/client.go deleted file mode 100644 index ebb8c75b..00000000 --- a/bot/client/client.go +++ /dev/null @@ -1,157 +0,0 @@ -package client - -import ( - "fmt" - "os" - "sync" - - "github.com/disgoorg/snowflake/v2" - "github.com/sabafly/disgo/discord" - "github.com/sabafly/disgo/events" - "github.com/sabafly/gobot/bot/db" - botlib "github.com/sabafly/sabafly-lib/v2/bot" - "github.com/sabafly/sabafly-lib/v2/handler" - "github.com/sabafly/sabafly-lib/v2/logging" -) - -func New(cfg *Config, db db.DB) (*Client, error) { - if err := os.MkdirAll("./logs/messages", 0755); err != nil { - return nil, err - } - ml, err := logging.New(logging.Config{ - LogPath: "./logs/messages", - LogName: "message.log", - }) - if err != nil { - return nil, err - } - return &Client{ - Config: cfg, - DB: db, - Logger: &Logger{ - Message: ml, - DebugChannel: map[snowflake.ID]*DebugLog{}, - DebugGuild: map[snowflake.ID]*DebugLog{}, - }, - userDataLocks: make(map[snowflake.ID]*sync.Mutex), - guildDataLocks: make(map[snowflake.ID]*sync.Mutex), - }, nil -} - -func (c *Client) Close() (err error) { - defer func() { - e := c.Logger.Message.Close() - if e != nil { - err = fmt.Errorf("%w: %w", err, e) - } - }() - defer func() { - for _, l := range c.Logger.DebugChannel { - if l.Logger != nil { - e := l.Logger.Close() - if e != nil { - err = fmt.Errorf("%w: %w", err, e) - } - } - } - }() - defer func() { - for _, l := range c.Logger.DebugGuild { - if l.Logger != nil { - e := l.Logger.Close() - if e != nil { - err = fmt.Errorf("%w: %w", err, e) - } - } - } - }() - return -} - -type Client struct { - Config *Config - DB db.DB - MessagePin map[snowflake.ID]*db.GuildMessagePins - MessagePinSync sync.Mutex - Logger *Logger - userDataLock sync.Mutex - userDataLocks map[snowflake.ID]*sync.Mutex - guildDataLock sync.Mutex - guildDataLocks map[snowflake.ID]*sync.Mutex -} - -func (c *Client) GuildDataLock(gid snowflake.ID) *sync.Mutex { - c.guildDataLock.Lock() - defer c.guildDataLock.Unlock() - if c.guildDataLocks[gid] == nil { - c.guildDataLocks[gid] = new(sync.Mutex) - } - return c.guildDataLocks[gid] -} - -func (c *Client) UserDataLock(uid snowflake.ID) *sync.Mutex { - c.userDataLock.Lock() - defer c.userDataLock.Unlock() - if c.userDataLocks[uid] == nil { - c.userDataLocks[uid] = new(sync.Mutex) - } - return c.userDataLocks[uid] -} - -func (c *Client) CheckAutoCompletePermission(b *botlib.Bot[*Client], perm string, alt_perm discord.Permissions) handler.Check[*events.AutocompleteInteractionCreate] { - return func(ctx *events.AutocompleteInteractionCreate) bool { - if b.CheckDev(ctx.User().ID) { - return true - } - if ctx.Member() != nil && ctx.Member().Permissions.Has(alt_perm) { - return true - } - gd, err := c.DB.GuildData().Get(*ctx.GuildID()) - if err == nil { - if gd.UserPermissions[ctx.User().ID].Has(perm) { - return true - } - for _, id := range ctx.Member().RoleIDs { - if gd.RolePermissions[id].Has(perm) { - return true - } - } - } - return false - } -} - -func (c *Client) CheckCommandPermission(b *botlib.Bot[*Client], perm string, alt_perm discord.Permissions) handler.Check[*events.ApplicationCommandInteractionCreate] { - return func(ctx *events.ApplicationCommandInteractionCreate) bool { - if b.CheckDev(ctx.User().ID) { - return true - } - if ctx.Member() != nil && ctx.Member().Permissions.Has(alt_perm) { - return true - } - gd, err := c.DB.GuildData().Get(*ctx.GuildID()) - if err == nil { - if gd.UserPermissions[ctx.User().ID].Has(perm) { - return true - } - for _, id := range ctx.Member().RoleIDs { - if gd.RolePermissions[id].Has(perm) { - return true - } - } - } - _ = botlib.ReturnErrMessage(ctx, "error_no_permission", botlib.WithTranslateData(map[string]any{"Name": perm})) - return false - } -} - -type Logger struct { - Message *logging.Logging - DebugChannel map[snowflake.ID]*DebugLog - DebugGuild map[snowflake.ID]*DebugLog -} - -type DebugLog struct { - Logger *logging.Logging - LogChannel *snowflake.ID -} diff --git a/bot/client/config.go b/bot/client/config.go deleted file mode 100644 index 1af87db0..00000000 --- a/bot/client/config.go +++ /dev/null @@ -1,81 +0,0 @@ -package client - -import ( - "encoding/gob" - "encoding/json" - "encoding/xml" - "errors" - "os" - "path/filepath" - - "github.com/pelletier/go-toml/v2" - "github.com/sabafly/gobot/bot/db" - "gopkg.in/yaml.v2" -) - -type Config struct { - DBConfig db.DBConfig `json:"db_config"` - MessagePinAvatarURL string `json:"message_pin_avatar_url"` -} - -var defaultConfig = Config{ - DBConfig: db.DBConfig{ - Host: "localhost", - Port: "6379", - DB: 0, - }, - MessagePinAvatarURL: "", -} - -func LoadConfig(config_filepath string) (*Config, error) { - file, err := os.Open(config_filepath) - if os.IsNotExist(err) { - if file, err = os.Create(config_filepath); err != nil { - return nil, err - } - switch filepath.Ext(config_filepath) { - case ".json": - encoder := json.NewEncoder(file) - encoder.SetIndent("", "\t") - err = encoder.Encode(defaultConfig) - case ".yml", ".yaml": - err = yaml.NewEncoder(file).Encode(file) - case ".toml": - err = toml.NewEncoder(file).SetArraysMultiline(true).SetIndentSymbol("\t").SetIndentTables(true).Encode(defaultConfig) - case ".xml": - encoder := xml.NewEncoder(file) - encoder.Indent("", "\t") - err = encoder.Encode(defaultConfig) - case ".gob": - err = gob.NewEncoder(file).Encode(defaultConfig) - default: - panic("unknown config file type " + filepath.Ext(config_filepath)) - } - if err != nil { - return nil, err - } - return nil, errors.New("config file not found, created new one") - } else if err != nil { - return nil, err - } - - var cfg Config - switch filepath.Ext(config_filepath) { - case ".json": - err = json.NewDecoder(file).Decode(&cfg) - case ".yml", ".yaml": - err = yaml.NewDecoder(file).Decode(&cfg) - case ".tml", ".toml": - err = toml.NewDecoder(file).Decode(&cfg) - case ".xml": - err = xml.NewDecoder(file).Decode(&cfg) - case ".gob": - err = gob.NewDecoder(file).Decode(&cfg) - default: - panic("unknown config file type" + filepath.Ext(config_filepath)) - } - if err != nil { - return nil, err - } - return &cfg, nil -} diff --git a/bot/commands/about.go b/bot/commands/about.go deleted file mode 100644 index ad86d4a4..00000000 --- a/bot/commands/about.go +++ /dev/null @@ -1,94 +0,0 @@ -package commands - -import ( - "fmt" - "runtime" - "runtime/debug" - - "github.com/sabafly/disgo" - "github.com/sabafly/disgo/discord" - "github.com/sabafly/disgo/events" - "github.com/sabafly/gobot/bot/client" - lib "github.com/sabafly/sabafly-lib/v2" - botlib "github.com/sabafly/sabafly-lib/v2/bot" - "github.com/sabafly/sabafly-lib/v2/handler" - "github.com/sabafly/sabafly-lib/v2/translate" - "github.com/shirou/gopsutil/v3/mem" -) - -func About(b *botlib.Bot[*client.Client]) handler.Command { - return handler.Command{ - Create: discord.SlashCommandCreate{ - Name: "about", - Description: "show bot info", - DescriptionLocalizations: translate.MessageMap("about_command_description", false), - DMPermission: &b.Config.DMPermission, - }, - CommandHandlers: map[string]handler.CommandHandler{ - "": aboutCommandHandler(b), - }, - } -} - -func aboutCommandHandler(b *botlib.Bot[*client.Client]) handler.CommandHandler { - return func(event *events.ApplicationCommandInteractionCreate) error { - message := discord.NewMessageCreateBuilder() - embed := discord.NewEmbedBuilder() - embed.SetTitlef("%s Info", botlib.BotName) - embed.SetDescriptionf("### **version**\r- %s\r### **%s**\r- %s\r - %s\r### **%s**\r- %s\r - %s\r### **go version**\r- %s", - b.Version, - lib.Name, - lib.Module, - lib.Version, - disgo.Name, - disgo.Module, - disgo.Version, - runtime.Version(), - ) - gc_stat := new(debug.GCStats) - debug.ReadGCStats(gc_stat) - vm, err := mem.VirtualMemory() - var ms runtime.MemStats - runtime.ReadMemStats(&ms) - if err != nil { - embed.AddField("memory", fmt.Sprintf("Last GC:%v\r%s", discord.TimestampMention(gc_stat.LastGC.Unix()), err.Error()), true) - } else { - embed.AddField("memory", - fmt.Sprintf( - "Last GC:%v\rTotal: %dMB\rFree: %dMB\rUsed: %dMB\rUsed/Total: %.2f%%\rAlloc: %dMB\rTotalAlloc: %dMB\rHeapObjects: %d\rSys: %dMB", - discord.TimestampMention(gc_stat.LastGC.Unix()), - vm.Total/1024/1024, - vm.Free/1024/1024, - vm.Used/1024/1024, - float64(vm.Used)/float64(vm.Total)*100, - ms.Alloc/1024/1024, - ms.TotalAlloc/1024/1024, - ms.HeapObjects, - ms.Sys/1024/1024, - ), - false, - ) - } - embed.AddField("cpu", - fmt.Sprintf( - "NumCPU: %d\rNumGoroutine: %d\rGOMAXPROCS: %d", - runtime.NumCPU(), - runtime.NumGoroutine(), - runtime.GOMAXPROCS(0), - ), - false, - ) - embed.AddField( - "runtime", - fmt.Sprintf( - "GOOS: %s\rGOARCH: %s", - runtime.GOOS, - runtime.GOARCH, - ), - false, - ) - embed.Embed = botlib.SetEmbedProperties(embed.Embed) - message.SetEmbeds(embed.Build()) - return event.CreateMessage(message.Build()) - } -} diff --git a/bot/commands/admin.go b/bot/commands/admin.go deleted file mode 100644 index b4c81af4..00000000 --- a/bot/commands/admin.go +++ /dev/null @@ -1,751 +0,0 @@ -package commands - -import ( - "bytes" - "fmt" - "time" - - "github.com/disgoorg/json" - "github.com/disgoorg/snowflake/v2" - "github.com/sabafly/disgo/discord" - "github.com/sabafly/disgo/events" - "github.com/sabafly/gobot/bot/client" - botlib "github.com/sabafly/sabafly-lib/v2/bot" - "github.com/sabafly/sabafly-lib/v2/handler" - "github.com/sabafly/sabafly-lib/v2/logging" - "github.com/sabafly/sabafly-lib/v2/translate" -) - -func Admin(b *botlib.Bot[*client.Client]) handler.Command { - return handler.Command{ - Create: discord.SlashCommandCreate{ - Name: "admin", - Description: "admin only", - DMPermission: &b.Config.DMPermission, - Options: []discord.ApplicationCommandOption{ - discord.ApplicationCommandOptionSubCommandGroup{ - Name: "message", - Description: "about message", - Options: []discord.ApplicationCommandOptionSubCommand{ - { - Name: "get", - Description: "get channel message", - Options: []discord.ApplicationCommandOption{ - discord.ApplicationCommandOptionString{ - Name: "channel-id", - Description: "channel id", - Required: true, - }, - discord.ApplicationCommandOptionString{ - Name: "message-id", - Description: "message id", - Required: false, - }, - discord.ApplicationCommandOptionString{ - Name: "after-id", - Description: "message id", - Required: false, - }, - discord.ApplicationCommandOptionString{ - Name: "before-id", - Description: "message id", - Required: false, - }, - discord.ApplicationCommandOptionString{ - Name: "around-id", - Description: "message id", - Required: false, - }, - discord.ApplicationCommandOptionBool{ - Name: "create-message", - Description: "create message", - Required: false, - }, - }, - }, - }, - }, - discord.ApplicationCommandOptionSubCommandGroup{ - Name: "channel", - Description: "about channel", - Options: []discord.ApplicationCommandOptionSubCommand{ - { - Name: "get", - Description: "get guild channel", - Options: []discord.ApplicationCommandOption{ - discord.ApplicationCommandOptionString{ - Name: "guild-id", - Description: "guild id", - Required: true, - }, - discord.ApplicationCommandOptionString{ - Name: "channel-id", - Description: "channel id", - Required: false, - }, - }, - }, - }, - }, - discord.ApplicationCommandOptionSubCommandGroup{ - Name: "guild", - Description: "about guild", - Options: []discord.ApplicationCommandOptionSubCommand{ - { - Name: "get", - Description: "get guild", - Options: []discord.ApplicationCommandOption{ - discord.ApplicationCommandOptionString{ - Name: "guild-id", - Description: "guild id", - Required: false, - }, - }, - }, - { - Name: "leave", - Description: "leave guild", - Options: []discord.ApplicationCommandOption{ - discord.ApplicationCommandOptionString{ - Name: "guild-id", - Description: "guild id", - Required: true, - }, - }, - }, - }, - }, - discord.ApplicationCommandOptionSubCommandGroup{ - Name: "application", - Description: "about application", - Options: []discord.ApplicationCommandOptionSubCommand{ - { - Name: "command-get", - Description: "get application commands", - Options: []discord.ApplicationCommandOption{ - discord.ApplicationCommandOptionString{ - Name: "guild-id", - Description: "guild id", - Required: false, - }, - discord.ApplicationCommandOptionString{ - Name: "command-id", - Description: "command id", - Required: false, - }, - }, - }, - { - Name: "command-delete", - Description: "delete application commands", - Options: []discord.ApplicationCommandOption{ - discord.ApplicationCommandOptionString{ - Name: "command-id", - Description: "command id", - Required: true, - }, - discord.ApplicationCommandOptionString{ - Name: "guild-id", - Description: "guild id", - Required: false, - }, - }, - }, - }, - }, - discord.ApplicationCommandOptionSubCommandGroup{ - Name: "debug", - Description: "debug", - Options: []discord.ApplicationCommandOptionSubCommand{ - { - Name: "translate", - Description: "for debug translate module", - Options: []discord.ApplicationCommandOption{ - discord.ApplicationCommandOptionString{ - Name: "locale", - Description: "locale id", - Required: true, - }, - discord.ApplicationCommandOptionString{ - Name: "translate-key", - Description: "translate key", - Required: true, - }, - }, - }, - { - Name: "log", - Description: "log debug", - Options: []discord.ApplicationCommandOption{ - discord.ApplicationCommandOptionString{ - Name: "content", - Description: "content", - Required: true, - }, - discord.ApplicationCommandOptionInt{ - Name: "count", - Description: "count", - Required: true, - }, - }, - }, - { - Name: "add-hook", - Description: "add hook", - Options: []discord.ApplicationCommandOption{ - discord.ApplicationCommandOptionString{ - Name: "guild-id", - Description: "guild id", - Required: true, - }, - discord.ApplicationCommandOptionString{ - Name: "channel-id", - Description: "guild id", - Required: false, - }, - discord.ApplicationCommandOptionBool{ - Name: "write-file", - Description: "write file", - Required: false, - }, - }, - }, - }, - }, - }, - }, - CommandHandlers: map[string]handler.CommandHandler{ - "message/get": adminCommandMessageGetHandler(b), - "channel/get": adminCommandChannelGetHandler(b), - "guild/get": adminCommandGuildGetHandler(b), - "guild/leave": adminCommandGuildLeaveHandler(b), - "application/command-get": adminCommandApplicationCommandGet(b), - "application/command-delete": adminCommandApplicationCommandDelete(b), - "debug/translate": adminCommandDebugTranslateHandler(b), - "debug/log": adminCommandDebugLogHandler(b), - "debug/add-hook": adminCommandDebugAddHook(b), - }, - Check: func(ctx *events.ApplicationCommandInteractionCreate) bool { - if b.CheckDev(ctx.User().ID) { - return true - } - if ctx.GuildID() != nil && b.CheckDev(*ctx.GuildID()) && ctx.Member().Permissions.Has(discord.PermissionAdministrator) { - return true - } - return false - }, - DevOnly: false, - } -} - -func adminCommandGuildLeaveHandler(b *botlib.Bot[*client.Client]) handler.CommandHandler { - return func(event *events.ApplicationCommandInteractionCreate) error { - guildID := snowflake.MustParse(event.SlashCommandInteractionData().String("guild-id")) - if err := event.Client().Rest().LeaveGuild(guildID); err != nil { - return botlib.ReturnErr(event, err) - } - if err := event.CreateMessage(discord.NewMessageCreateBuilder().SetContent("OK").Build()); err != nil { - return botlib.ReturnErr(event, err) - } - return nil - } -} - -func adminCommandApplicationCommandDelete(b *botlib.Bot[*client.Client]) handler.CommandHandler { - return func(event *events.ApplicationCommandInteractionCreate) error { - commandID := snowflake.MustParse(event.SlashCommandInteractionData().String("command-id")) - var err error - if id, ok := event.SlashCommandInteractionData().OptString("guild-id"); ok { - err = event.Client().Rest().DeleteGuildCommand(event.ApplicationID(), snowflake.MustParse(id), commandID) - } else { - err = event.Client().Rest().DeleteGlobalCommand(event.ApplicationID(), commandID) - } - if err != nil { - return botlib.ReturnErr(event, err) - } - err = event.CreateMessage(discord.MessageCreate{ - Content: "OK", - }) - if err != nil { - return botlib.ReturnErr(event, err) - } - return nil - } -} - -func adminCommandApplicationCommandGet(b *botlib.Bot[*client.Client]) handler.CommandHandler { - return func(event *events.ApplicationCommandInteractionCreate) error { - if id, ok := event.SlashCommandInteractionData().OptString("command-id"); ok { - var err error - commandID := snowflake.MustParse(id) - var command discord.ApplicationCommand - if id, ok := event.SlashCommandInteractionData().OptString("guild-id"); ok { - command, err = event.Client().Rest().GetGuildCommand(event.ApplicationID(), snowflake.MustParse(id), commandID) - if err != nil { - return botlib.ReturnErr(event, err) - } - } else { - command, err = event.Client().Rest().GetGlobalCommand(event.ApplicationID(), commandID) - if err != nil { - return botlib.ReturnErr(event, err) - } - } - raw, err := json.MarshalIndent(command, "", " ") - if err != nil { - return botlib.ReturnErr(event, err) - } - err = event.CreateMessage(discord.MessageCreate{ - Files: []*discord.File{ - { - Name: fmt.Sprintf("command-%d.json", command.ID()), - Reader: bytes.NewReader(raw), - }, - }, - }) - if err != nil { - return botlib.ReturnErr(event, err) - } - } else { - channel := event.Channel() - var commands []discord.ApplicationCommand - var err error - if id, ok := event.SlashCommandInteractionData().OptString("guild-id"); ok { - commands, err = event.Client().Rest().GetGuildCommands(event.ApplicationID(), snowflake.MustParse(id), false) - } else { - commands, err = event.Client().Rest().GetGlobalCommands(event.ApplicationID(), false) - } - if err != nil { - return botlib.ReturnErr(event, err) - } - var description []string - var temp string - for _, ac := range commands { - s := fmt.Sprintf("id:%d name:%s type:%d\r", ac.ID(), ac.Name(), ac.Type()) - if len(s)+len(temp) >= 4096 { - description = append(description, temp) - temp = "" - } - temp += s - } - embeds := []discord.Embed{} - for _, v := range description { - embeds = append(embeds, discord.Embed{ - Description: v, - }) - } - embeds = append(embeds, discord.Embed{ - Description: temp, - }) - mEmbeds := [][]discord.Embed{} - for len(embeds) > 0 { - mEmbeds = append(mEmbeds, embeds[:func() int { - if len(embeds) < 1 { - return len(embeds) - } else { - return 1 - } - }()]) - if len(embeds) > 1 { - embeds = embeds[1:] - } else { - embeds = []discord.Embed{} - } - } - embeds = botlib.SetEmbedsProperties(mEmbeds[0]) - err = event.CreateMessage(discord.MessageCreate{ - Embeds: embeds, - }) - if err != nil { - return botlib.ReturnErr(event, err) - } - if len(mEmbeds) > 1 { - for i, v := range mEmbeds { - if i == 0 { - continue - } - v = botlib.SetEmbedsProperties(v) - _, err := botlib.SendWebhook(event.Client(), channel.ID(), discord.WebhookMessageCreate{Embeds: v}) - if err != nil { - return err - } - } - } - } - return nil - } -} - -func adminCommandGuildGetHandler(b *botlib.Bot[*client.Client]) handler.CommandHandler { - return func(event *events.ApplicationCommandInteractionCreate) error { - if id, ok := event.SlashCommandInteractionData().OptString("guild-id"); ok { - guildID := snowflake.MustParse(id) - guild, err := event.Client().Rest().GetGuild(guildID, true) - if err != nil { - return botlib.ReturnErr(event, err) - } - raw, err := json.MarshalIndent(guild, "", " ") - if err != nil { - return botlib.ReturnErr(event, err) - } - err = event.CreateMessage(discord.MessageCreate{ - Files: []*discord.File{ - { - Name: fmt.Sprintf("guild-%d.json", guild.ID), - Reader: bytes.NewReader(raw), - }, - }, - }) - if err != nil { - return botlib.ReturnErr(event, err) - } - } else { - channel := event.Channel() - var description []string - var temp string - event.Client().Caches().GuildsForEach(func(guild discord.Guild) { - s := fmt.Sprintf("id:%d members:%d name:%s join:%s\r", guild.ID, guild.MemberCount, guild.Name, guild.JoinedAt.Format(time.DateTime)) - if len(s)+len(temp) >= 4096 { - description = append(description, temp) - temp = "" - } - temp += s - }) - embeds := []discord.Embed{} - for _, v := range description { - embeds = append(embeds, discord.Embed{ - Description: v, - }) - } - embeds = append(embeds, discord.Embed{ - Description: temp, - }) - mEmbeds := [][]discord.Embed{} - for len(embeds) > 0 { - mEmbeds = append(mEmbeds, embeds[:func() int { - if len(embeds) < 1 { - return len(embeds) - } else { - return 1 - } - }()]) - if len(embeds) > 1 { - embeds = embeds[1:] - } else { - embeds = []discord.Embed{} - } - } - embeds = botlib.SetEmbedsProperties(mEmbeds[0]) - err := event.CreateMessage(discord.MessageCreate{ - Embeds: embeds, - }) - if err != nil { - return botlib.ReturnErr(event, err) - } - if len(mEmbeds) > 1 { - for i, v := range mEmbeds { - if i == 0 { - continue - } - v = botlib.SetEmbedsProperties(v) - _, err := botlib.SendWebhook(event.Client(), channel.ID(), discord.WebhookMessageCreate{Embeds: v}) - if err != nil { - return err - } - } - } - } - return nil - } -} - -func adminCommandChannelGetHandler(b *botlib.Bot[*client.Client]) handler.CommandHandler { - return func(event *events.ApplicationCommandInteractionCreate) error { - if id, ok := event.SlashCommandInteractionData().OptString("channel-id"); ok { - channelID := snowflake.MustParse(id) - channel, err := event.Client().Rest().GetChannel(channelID) - if err != nil { - return nil - } - raw, err := json.MarshalIndent(channel, "", " ") - if err != nil { - return botlib.ReturnErr(event, err) - } - err = event.CreateMessage(discord.MessageCreate{ - Files: []*discord.File{ - { - Name: fmt.Sprintf("channel-%d.json", channel.ID()), - Reader: bytes.NewReader(raw), - }, - }, - }) - if err != nil { - return botlib.ReturnErr(event, err) - } - } else { - channel := event.Channel() - guildID := snowflake.MustParse(event.SlashCommandInteractionData().String("guild-id")) - channels, err := event.Client().Rest().GetGuildChannels(guildID) - if err != nil { - return botlib.ReturnErr(event, err) - } - var description []string - var temp string - for _, gc := range channels { - s := fmt.Sprintf("ch-id:%d type:%d prt%d name:%s\r", gc.ID(), gc.Type(), gc.ParentID(), gc.Name()) - if len(s)+len(temp) >= 4096 { - description = append(description, temp) - temp = "" - } - temp += s - } - embeds := []discord.Embed{} - for _, v := range description { - embeds = append(embeds, discord.Embed{ - Description: v, - }) - } - embeds = append(embeds, discord.Embed{ - Description: temp, - }) - mEmbeds := [][]discord.Embed{} - for len(embeds) > 0 { - mEmbeds = append(mEmbeds, embeds[:func() int { - if len(embeds) < 1 { - return len(embeds) - } else { - return 1 - } - }()]) - if len(embeds) > 1 { - embeds = embeds[1:] - } else { - embeds = []discord.Embed{} - } - } - embeds = botlib.SetEmbedsProperties(mEmbeds[0]) - err = event.CreateMessage(discord.MessageCreate{ - Embeds: embeds, - }) - if err != nil { - return botlib.ReturnErr(event, err) - } - if len(mEmbeds) > 1 { - for i, v := range mEmbeds { - if i == 0 { - continue - } - v = botlib.SetEmbedsProperties(v) - _, err := event.Client().Rest().CreateMessage(channel.ID(), discord.MessageCreate{ - Embeds: v, - }) - if err != nil { - return err - } - } - } - } - return nil - } -} - -func adminCommandMessageGetHandler(b *botlib.Bot[*client.Client]) handler.CommandHandler { - return func(event *events.ApplicationCommandInteractionCreate) error { - channel := event.Channel() - channelID := snowflake.MustParse(event.SlashCommandInteractionData().String("channel-id")) - if messageID, ok := event.SlashCommandInteractionData().OptString("message-id"); ok { - mes, err := event.Client().Rest().GetMessage(channelID, snowflake.MustParse(messageID)) - if err != nil { - return botlib.ReturnErr(event, err) - } - raw, err := json.MarshalIndent(mes, "", " ") - if err != nil { - return botlib.ReturnErr(event, err) - } - embeds := []discord.Embed{ - { - Author: &discord.EmbedAuthor{ - Name: fmt.Sprintf("%s#%s", mes.Author.Username, mes.Author.Discriminator), - IconURL: mes.Author.EffectiveAvatarURL(), - URL: fmt.Sprintf("https://discord.com/users/%d", mes.Author.ID), - }, - Description: mes.Content, - }, - } - embeds = botlib.SetEmbedsProperties(embeds) - err = event.CreateMessage(discord.MessageCreate{ - Embeds: embeds, - Files: []*discord.File{ - { - Name: fmt.Sprintf("message-%d.json", mes.ID), - Reader: bytes.NewReader(raw), - }, - }, - }) - if err != nil { - return botlib.ReturnErr(event, err) - } - } else { - var after, before, around snowflake.ID - if str, ok := event.SlashCommandInteractionData().OptString("after-id"); ok { - after = snowflake.MustParse(str) - } - if str, ok := event.SlashCommandInteractionData().OptString("before-id"); ok { - before = snowflake.MustParse(str) - } - if str, ok := event.SlashCommandInteractionData().OptString("around-id"); ok { - around = snowflake.MustParse(str) - } - channelMes, err := event.Client().Rest().GetMessages(channelID, around, before, after, 100) - if err != nil { - return botlib.ReturnErr(event, err) - } - if event.SlashCommandInteractionData().Bool("create-message") { - go func() { - for i, j := 0, len(channelMes)-1; i < j; i, j = i+1, j-1 { - channelMes[i], channelMes[j] = channelMes[j], channelMes[i] - } - for _, m := range channelMes { - raw, err := json.MarshalIndent(m, "", " ") - if err != nil { - _, _ = botlib.SendWebhook(event.Client(), event.Channel().ID(), discord.WebhookMessageCreate{ - Content: err.Error(), - }) - continue - } - if _, err := botlib.SendWebhook(event.Client(), event.Channel().ID(), discord.WebhookMessageCreate{ - Content: m.Content, - Embeds: m.Embeds, - Username: m.Author.Tag(), - Components: m.Components, - AvatarURL: m.Author.EffectiveAvatarURL(), - Files: []*discord.File{ - { - Name: "message-" + m.ID.String() + ".json", - Reader: bytes.NewBuffer(raw), - }, - }, - }); err != nil { - b.Logger.Error(err) - } - } - }() - return event.CreateMessage(discord.NewMessageCreateBuilder().SetContent("OK").Build()) - } - var description []string - var temp string - for _, m := range channelMes { - s := fmt.Sprintf("%s#%s(%d) mes-id:%d[link](%s)\r", m.Author.Username, m.Author.Discriminator, m.Author.ID, m.ID, m.JumpURL()) - if len(s)+len(temp) >= 4000 { - description = append(description, temp) - temp = "" - } - temp += s - } - embeds := []discord.Embed{} - for _, v := range description { - embeds = append(embeds, discord.Embed{ - Description: v, - }) - } - embeds = append(embeds, discord.Embed{ - Description: temp, - }) - mEmbeds := [][]discord.Embed{} - for len(embeds) > 0 { - mEmbeds = append(mEmbeds, embeds[:func() int { - if len(embeds) < 1 { - return len(embeds) - } else { - return 1 - } - }()]) - if len(embeds) > 1 { - embeds = embeds[1:] - } else { - embeds = []discord.Embed{} - } - } - embeds = mEmbeds[0] - embeds = botlib.SetEmbedsProperties(embeds) - err = event.CreateMessage(discord.MessageCreate{ - Embeds: embeds, - }) - if err != nil { - return botlib.ReturnErr(event, err) - } - if len(mEmbeds) > 1 { - for i, v := range mEmbeds { - if i == 0 { - continue - } - v = botlib.SetEmbedsProperties(v) - _, err := event.Client().Rest().CreateMessage(channel.ID(), discord.MessageCreate{ - Embeds: v, - }) - if err != nil { - return err - } - } - } - } - return nil - } -} - -func adminCommandDebugTranslateHandler(b *botlib.Bot[*client.Client]) handler.CommandHandler { - return func(event *events.ApplicationCommandInteractionCreate) error { - if err := event.CreateMessage(discord.NewMessageCreateBuilder().SetContent(translate.Message(discord.Locale(event.SlashCommandInteractionData().String("locale")), event.SlashCommandInteractionData().String("translate-key"))).Build()); err != nil { - return botlib.ReturnErr(event, err) - } - return nil - } -} - -func adminCommandDebugLogHandler(b *botlib.Bot[*client.Client]) handler.CommandHandler { - return func(event *events.ApplicationCommandInteractionCreate) error { - go func() { - for i := 0; i < event.SlashCommandInteractionData().Int("count")+1; i++ { - b.Logger.Info(event.SlashCommandInteractionData().String("content")) - } - }() - return event.CreateMessage(discord.NewMessageCreateBuilder().SetContent("OK").Build()) - } -} - -func adminCommandDebugAddHook(b *botlib.Bot[*client.Client]) handler.CommandHandler { - return func(event *events.ApplicationCommandInteractionCreate) error { - isWriteFile := event.SlashCommandInteractionData().Bool("write-file") - guildID := snowflake.MustParse(event.SlashCommandInteractionData().String("guild-id")) - if channelIDOpt, ok := event.SlashCommandInteractionData().OptString("channel-id"); ok { - channelID := snowflake.MustParse(channelIDOpt) - b.Self.Logger.DebugChannel[channelID] = &client.DebugLog{ - LogChannel: json.Ptr(event.Channel().ID()), - } - if isWriteFile { - logger, err := logging.New(logging.Config{ - LogPath: "./logs/channels/" + guildID.String(), - LogName: channelID.String() + ".log", - }) - if err != nil { - return botlib.ReturnErr(event, err) - } - b.Self.Logger.DebugChannel[channelID].Logger = logger - } - } else { - b.Self.Logger.DebugGuild[guildID] = &client.DebugLog{ - LogChannel: json.Ptr(event.Channel().ID()), - } - if isWriteFile { - logger, err := logging.New(logging.Config{ - LogPath: "./logs/channels", - LogName: guildID.String() + ".log", - }) - if err != nil { - return botlib.ReturnErr(event, err) - } - b.Self.Logger.DebugChannel[guildID].Logger = logger - } - } - return event.CreateMessage(discord.NewMessageCreateBuilder().SetContent("OK").Build()) - } -} diff --git a/bot/commands/config.go b/bot/commands/config.go deleted file mode 100644 index 48813ccf..00000000 --- a/bot/commands/config.go +++ /dev/null @@ -1,742 +0,0 @@ -package commands - -import ( - "fmt" - "math/big" - "net/http" - - "github.com/disgoorg/json" - "github.com/disgoorg/snowflake/v2" - "github.com/sabafly/disgo/discord" - "github.com/sabafly/disgo/events" - "github.com/sabafly/gobot/bot/client" - "github.com/sabafly/gobot/bot/db" - botlib "github.com/sabafly/sabafly-lib/v2/bot" - "github.com/sabafly/sabafly-lib/v2/handler" - "github.com/sabafly/sabafly-lib/v2/translate" -) - -func Config(b *botlib.Bot[*client.Client]) handler.Command { - return handler.Command{ - Create: discord.SlashCommandCreate{ - Name: "config", - Description: "config", - DMPermission: &b.Config.DMPermission, - Options: []discord.ApplicationCommandOption{ - discord.ApplicationCommandOptionSubCommandGroup{ - Name: "bump", - Description: "bump", - Options: []discord.ApplicationCommandOptionSubCommand{ - { - Name: "on", - Description: "turn on", - DescriptionLocalizations: translate.MessageMap("config_bump_on_command_description", false), - }, - { - Name: "off", - Description: "turn off", - DescriptionLocalizations: translate.MessageMap("config_bump_off_command_description", false), - }, - { - Name: "message", - Description: "config message", - DescriptionLocalizations: translate.MessageMap("config_bump_message_command_description", false), - }, - { - Name: "mention", - Description: "set mention role", - DescriptionLocalizations: translate.MessageMap("config_bump_mention_command_description", false), - Options: []discord.ApplicationCommandOption{ - discord.ApplicationCommandOptionRole{ - Name: "role", - Description: "target role", - DescriptionLocalizations: translate.MessageMap("config_bump_mention_command_role_option_description", false), - }, - }, - }, - }, - }, - discord.ApplicationCommandOptionSubCommandGroup{ - Name: "up", - Description: "up", - Options: []discord.ApplicationCommandOptionSubCommand{ - { - Name: "on", - Description: "turn on", - DescriptionLocalizations: translate.MessageMap("config_up_on_command_description", false), - }, - { - Name: "off", - Description: "turn off", - DescriptionLocalizations: translate.MessageMap("config_up_off_message_description", false), - }, - { - Name: "message", - Description: "config message", - DescriptionLocalizations: translate.MessageMap("config_up_message_command_description", false), - }, - { - Name: "mention", - Description: "set mention role", - DescriptionLocalizations: translate.MessageMap("config_up_mention_command_description", false), - Options: []discord.ApplicationCommandOption{ - discord.ApplicationCommandOptionRole{ - Name: "role", - Description: "target role", - DescriptionLocalizations: translate.MessageMap("config_up_mention_command_role_option_description", false), - }, - }, - }, - }, - }, - discord.ApplicationCommandOptionSubCommandGroup{ - Name: "level", - Description: "level config", - Options: []discord.ApplicationCommandOptionSubCommand{ - { - Name: "notice-message", - Description: "set level up message", - DescriptionLocalizations: translate.MessageMap("config_level_notice_message_command_description", false), - }, - { - Name: "notice-channel", - Description: "set level up message channel to send", - DescriptionLocalizations: translate.MessageMap("config_level_notice_channel_command_description", false), - Options: []discord.ApplicationCommandOption{ - discord.ApplicationCommandOptionChannel{ - Name: "channel", - Description: "target channel", - DescriptionLocalizations: translate.MessageMap("config_level_notice_channel_command_channel_option_description", false), - ChannelTypes: []discord.ChannelType{ - discord.ChannelTypeGuildText, - }, - }, - }, - }, - { - Name: "exclude-add", - Description: "add exclude channel", - DescriptionLocalizations: translate.MessageMap("config_level_exclude_add_command_description", false), - Options: []discord.ApplicationCommandOption{ - discord.ApplicationCommandOptionChannel{ - Name: "channel", - Description: "target channel", - DescriptionLocalizations: translate.MessageMap("config_level_exclude_add_command_channel_option_description", false), - Required: true, - ChannelTypes: []discord.ChannelType{ - discord.ChannelTypeGuildText, - discord.ChannelTypeGuildPublicThread, - discord.ChannelTypeGuildPrivateThread, - discord.ChannelTypeGuildNewsThread, - }, - }, - }, - }, - { - Name: "exclude-remove", - Description: "remove exclude channel", - DescriptionLocalizations: translate.MessageMap("config_level_exclude_remove_command_description", false), - Options: []discord.ApplicationCommandOption{ - discord.ApplicationCommandOptionString{ - Name: "channel", - Description: "target channel", - DescriptionLocalizations: translate.MessageMap("config_level_exclude_remove_command_channel_option_description", false), - Required: true, - Autocomplete: true, - }, - }, - }, - { - Name: "import-mee6", - Description: "import level data from mee6 ⚠ all guild levels reset ⚠", - DescriptionLocalizations: translate.MessageMap("config_level_import_mee6_command_description", false), - }, - }, - }, - }, - }, - Check: b.Self.CheckCommandPermission(b, "guild.config.manage", discord.PermissionManageGuild), - CommandHandlers: map[string]handler.CommandHandler{ - "bump/on": configBumpOnCommandHandler(b), - "bump/off": configBumpOffCommandHandler(b), - "bump/message": configBumpMessageConfigHandler(b), - "bump/mention": configBumpMentionCommandHandler(b), - "up/on": configUpOnCommandHandler(b), - "up/off": configUpOffCommandHandler(b), - "up/message": configUpMessageConfigHandler(b), - "up/mention": configUpMentionCommandHandler(b), - "level/notice-message": configLevelNoticeMessageCommandHandler(b), - "level/notice-channel": configLevelNoticeChannelCommandHandler(b), - "level/exclude-add": configLevelExcludeAddCommandHandler(b), - "level/exclude-remove": configLevelExcludeRemoveHandler(b), - "level/import-mee6": configLevelImportMee6CommandHandler(b), - }, - AutocompleteCheck: func(ctx *events.AutocompleteInteractionCreate) bool { - if b.CheckDev(ctx.User().ID) { - return true - } - if ctx.Member() != nil && ctx.Member().Permissions.Has(discord.PermissionManageGuild) { - return true - } - gd, err := b.Self.DB.GuildData().Get(*ctx.GuildID()) - if err == nil { - if gd.UserPermissions[ctx.User().ID].Has("guild.config.manage") { - return true - } - for _, id := range ctx.Member().RoleIDs { - if gd.RolePermissions[id].Has("guild.config.manage") { - return true - } - } - } - return false - }, - AutocompleteHandlers: map[string]handler.AutocompleteHandler{ - "level/exclude-remove": configLevelExcludeAutocompleteHandler(b), - }, - } -} - -func configBumpOnCommandHandler(b *botlib.Bot[*client.Client]) handler.CommandHandler { - return func(event *events.ApplicationCommandInteractionCreate) error { - b.Self.GuildDataLock(*event.GuildID()).Lock() - defer b.Self.GuildDataLock(*event.GuildID()).Unlock() - gd, err := b.Self.DB.GuildData().Get(*event.GuildID()) - if err != nil { - return botlib.ReturnErr(event, err) - } - if gd.BumpStatus.BumpMessage == [2]string{} || gd.BumpStatus.BumpRemind == [2]string{} { - return botlib.ReturnErrMessage(event, "error_message_not_configured") - } - gd.BumpStatus.BumpEnabled = true - if err := b.Self.DB.GuildData().Set(gd.ID, gd); err != nil { - return botlib.ReturnErr(event, err) - } - embed := discord.NewEmbedBuilder() - embed.SetTitle(translate.Message(event.Locale(), "config_changed")) - embed.SetDescription(translate.Message(event.Locale(), "config_bump_on_description")) - embed.Embed = botlib.SetEmbedProperties(embed.Embed) - message := discord.NewMessageCreateBuilder().AddFlags(discord.MessageFlagEphemeral) - message.AddEmbeds(embed.Build()) - if err := event.CreateMessage(message.Build()); err != nil { - return err - } - return nil - } -} - -func configBumpOffCommandHandler(b *botlib.Bot[*client.Client]) handler.CommandHandler { - return func(event *events.ApplicationCommandInteractionCreate) error { - b.Self.GuildDataLock(*event.GuildID()).Lock() - defer b.Self.GuildDataLock(*event.GuildID()).Unlock() - gd, err := b.Self.DB.GuildData().Get(*event.GuildID()) - if err != nil { - return botlib.ReturnErr(event, err) - } - gd.BumpStatus.BumpEnabled = false - if err := b.Self.DB.GuildData().Set(gd.ID, gd); err != nil { - return botlib.ReturnErr(event, err) - } - embed := discord.NewEmbedBuilder() - embed.SetTitle(translate.Message(event.Locale(), "config_changed")) - embed.SetDescription(translate.Message(event.Locale(), "config_bump_off_description")) - embed.Embed = botlib.SetEmbedProperties(embed.Embed) - message := discord.NewMessageCreateBuilder().AddFlags(discord.MessageFlagEphemeral) - message.AddEmbeds(embed.Build()) - if err := event.CreateMessage(message.Build()); err != nil { - return err - } - return nil - } -} - -func configBumpMessageConfigHandler(b *botlib.Bot[*client.Client]) handler.CommandHandler { - return func(event *events.ApplicationCommandInteractionCreate) error { - b.Self.GuildDataLock(*event.GuildID()).Lock() - defer b.Self.GuildDataLock(*event.GuildID()).Unlock() - gd, err := b.Self.DB.GuildData().Get(*event.GuildID()) - if err != nil { - return botlib.ReturnErr(event, err) - } - modal := discord.NewModalCreateBuilder() - modal.SetCustomID("handler:config:bump-message") - modal.SetTitle("bump message") - modal.AddContainerComponents( - discord.NewActionRow(discord.TextInputComponent{ - Style: discord.TextInputStyleShort, - CustomID: "message-title", - Required: true, - MaxLength: 32, - Label: translate.Message(event.Locale(), "command_config_bump_message_modal_text_0_label"), - Value: gd.BumpStatus.BumpMessage[0], - }), - discord.NewActionRow(discord.TextInputComponent{ - Style: discord.TextInputStyleParagraph, - CustomID: "message-body", - Required: true, - MaxLength: 256, - Label: translate.Message(event.Locale(), "command_config_bump_message_modal_text_1_label"), - Value: gd.BumpStatus.BumpMessage[1], - }), - discord.NewActionRow(discord.TextInputComponent{ - Style: discord.TextInputStyleShort, - CustomID: "remind-title", - Required: true, - MaxLength: 32, - Label: translate.Message(event.Locale(), "command_config_bump_message_modal_text_2_label"), - Value: gd.BumpStatus.BumpRemind[0], - }), - discord.NewActionRow(discord.TextInputComponent{ - Style: discord.TextInputStyleParagraph, - CustomID: "remind-body", - Required: true, - MaxLength: 256, - Label: translate.Message(event.Locale(), "command_config_bump_message_modal_text_3_label"), - Value: gd.BumpStatus.BumpRemind[1], - }), - ) - if err := event.CreateModal(modal.Build()); err != nil { - return err - } - return nil - } -} - -func configBumpMentionCommandHandler(b *botlib.Bot[*client.Client]) handler.CommandHandler { - return func(event *events.ApplicationCommandInteractionCreate) error { - b.Self.GuildDataLock(*event.GuildID()).Lock() - defer b.Self.GuildDataLock(*event.GuildID()).Unlock() - gd, err := b.Self.DB.GuildData().Get(*event.GuildID()) - if err != nil { - return botlib.ReturnErr(event, err) - } - embed := discord.NewEmbedBuilder() - embed.SetTitle(translate.Message(event.Locale(), "config_changed")) - embed.Embed = botlib.SetEmbedProperties(embed.Embed) - if role, ok := event.SlashCommandInteractionData().OptRole("role"); ok { - gd.BumpStatus.BumpRole = json.Ptr(role.ID) - embed.SetDescription(translate.Message(event.Locale(), "config_bump_up_mention_set", translate.WithTemplate(map[string]any{"Mention": discord.RoleMention(role.ID)}))) - } else if gd.BumpStatus.BumpRole != nil { - embed.SetDescription(translate.Message(event.Locale(), "config_bump_up_mention_remove", translate.WithTemplate(map[string]any{"Mention": discord.RoleMention(*gd.BumpStatus.BumpRole)}))) - gd.BumpStatus.BumpRole = nil - } else { - gd.BumpStatus.BumpRole = nil - embed.SetDescription(translate.Message(event.Locale(), "config_bump_up_mention_none")) - } - if err := b.Self.DB.GuildData().Set(gd.ID, gd); err != nil { - return botlib.ReturnErr(event, err) - } - message := discord.NewMessageCreateBuilder().AddFlags(discord.MessageFlagEphemeral) - message.AddEmbeds(embed.Build()) - if err := event.CreateMessage(message.Build()); err != nil { - return err - } - return nil - } -} - -func configUpOnCommandHandler(b *botlib.Bot[*client.Client]) handler.CommandHandler { - return func(event *events.ApplicationCommandInteractionCreate) error { - b.Self.GuildDataLock(*event.GuildID()).Lock() - defer b.Self.GuildDataLock(*event.GuildID()).Unlock() - gd, err := b.Self.DB.GuildData().Get(*event.GuildID()) - if err != nil { - return botlib.ReturnErr(event, err) - } - if gd.BumpStatus.UpMessage == [2]string{} || gd.BumpStatus.UpRemind == [2]string{} { - return botlib.ReturnErrMessage(event, "error_message_not_configured") - } - gd.BumpStatus.UpEnabled = true - if err := b.Self.DB.GuildData().Set(gd.ID, gd); err != nil { - return botlib.ReturnErr(event, err) - } - embed := discord.NewEmbedBuilder() - embed.SetTitle(translate.Message(event.Locale(), "config_changed")) - embed.SetDescription(translate.Message(event.Locale(), "config_up_on_description")) - embed.Embed = botlib.SetEmbedProperties(embed.Embed) - message := discord.NewMessageCreateBuilder().AddFlags(discord.MessageFlagEphemeral) - message.AddEmbeds(embed.Build()) - if err := event.CreateMessage(message.Build()); err != nil { - return err - } - return nil - } -} - -func configUpOffCommandHandler(b *botlib.Bot[*client.Client]) handler.CommandHandler { - return func(event *events.ApplicationCommandInteractionCreate) error { - b.Self.GuildDataLock(*event.GuildID()).Lock() - defer b.Self.GuildDataLock(*event.GuildID()).Unlock() - gd, err := b.Self.DB.GuildData().Get(*event.GuildID()) - if err != nil { - return botlib.ReturnErr(event, err) - } - gd.BumpStatus.UpEnabled = false - if err := b.Self.DB.GuildData().Set(gd.ID, gd); err != nil { - return botlib.ReturnErr(event, err) - } - embed := discord.NewEmbedBuilder() - embed.SetTitle(translate.Message(event.Locale(), "config_changed")) - embed.SetDescription(translate.Message(event.Locale(), "config_up_off_description")) - embed.Embed = botlib.SetEmbedProperties(embed.Embed) - message := discord.NewMessageCreateBuilder().AddFlags(discord.MessageFlagEphemeral) - message.AddEmbeds(embed.Build()) - if err := event.CreateMessage(message.Build()); err != nil { - return err - } - return nil - } -} - -func configUpMessageConfigHandler(b *botlib.Bot[*client.Client]) handler.CommandHandler { - return func(event *events.ApplicationCommandInteractionCreate) error { - b.Self.GuildDataLock(*event.GuildID()).Lock() - defer b.Self.GuildDataLock(*event.GuildID()).Unlock() - gd, err := b.Self.DB.GuildData().Get(*event.GuildID()) - if err != nil { - return botlib.ReturnErr(event, err) - } - modal := discord.NewModalCreateBuilder() - modal.SetCustomID("handler:config:up-message") - modal.SetTitle("up message") - modal.AddContainerComponents( - discord.NewActionRow(discord.TextInputComponent{ - Style: discord.TextInputStyleShort, - CustomID: "message-title", - Required: true, - MaxLength: 32, - Label: translate.Message(event.Locale(), "command_config_bump_message_modal_text_0_label"), - Value: gd.BumpStatus.UpMessage[0], - }), - discord.NewActionRow(discord.TextInputComponent{ - Style: discord.TextInputStyleParagraph, - CustomID: "message-body", - Required: true, - MaxLength: 256, - Label: translate.Message(event.Locale(), "command_config_bump_message_modal_text_1_label"), - Value: gd.BumpStatus.UpMessage[1], - }), - discord.NewActionRow(discord.TextInputComponent{ - Style: discord.TextInputStyleShort, - CustomID: "remind-title", - Required: true, - MaxLength: 32, - Label: translate.Message(event.Locale(), "command_config_bump_message_modal_text_2_label"), - Value: gd.BumpStatus.UpRemind[0], - }), - discord.NewActionRow(discord.TextInputComponent{ - Style: discord.TextInputStyleParagraph, - CustomID: "remind-body", - Required: true, - MaxLength: 256, - Label: translate.Message(event.Locale(), "command_config_bump_message_modal_text_3_label"), - Value: gd.BumpStatus.UpRemind[1], - }), - ) - if err := event.CreateModal(modal.Build()); err != nil { - return err - } - return nil - } -} - -func configUpMentionCommandHandler(b *botlib.Bot[*client.Client]) handler.CommandHandler { - return func(event *events.ApplicationCommandInteractionCreate) error { - b.Self.GuildDataLock(*event.GuildID()).Lock() - defer b.Self.GuildDataLock(*event.GuildID()).Unlock() - gd, err := b.Self.DB.GuildData().Get(*event.GuildID()) - if err != nil { - return botlib.ReturnErr(event, err) - } - embed := discord.NewEmbedBuilder() - embed.SetTitle(translate.Message(event.Locale(), "config_changed")) - embed.Embed = botlib.SetEmbedProperties(embed.Embed) - if role, ok := event.SlashCommandInteractionData().OptRole("role"); ok { - gd.BumpStatus.UpRole = json.Ptr(role.ID) - embed.SetDescription(translate.Message(event.Locale(), "config_bump_up_mention_set", translate.WithTemplate(map[string]any{"Mention": discord.RoleMention(role.ID)}))) - } else if gd.BumpStatus.UpRole != nil { - embed.SetDescription(translate.Message(event.Locale(), "config_bump_up_mention_remove", translate.WithTemplate(map[string]any{"Mention": discord.RoleMention(*gd.BumpStatus.UpRole)}))) - gd.BumpStatus.UpRole = nil - } else { - gd.BumpStatus.UpRole = nil - embed.SetDescription(translate.Message(event.Locale(), "config_bump_up_mention_none")) - } - if err := b.Self.DB.GuildData().Set(gd.ID, gd); err != nil { - return botlib.ReturnErr(event, err) - } - message := discord.NewMessageCreateBuilder().AddFlags(discord.MessageFlagEphemeral) - message.AddEmbeds(embed.Build()) - if err := event.CreateMessage(message.Build()); err != nil { - return err - } - return nil - } -} - -func configLevelNoticeMessageCommandHandler(b *botlib.Bot[*client.Client]) handler.CommandHandler { - return func(event *events.ApplicationCommandInteractionCreate) error { - b.Self.GuildDataLock(*event.GuildID()).Lock() - defer b.Self.GuildDataLock(*event.GuildID()).Unlock() - gd, err := b.Self.DB.GuildData().Get(*event.GuildID()) - if err != nil { - return botlib.ReturnErr(event, err) - } - modal := discord.NewModalCreateBuilder() - modal.SetCustomID("handler:level:notice-message") - modal.SetTitle(translate.Message(event.Locale(), "modal_level_notice_message_title")) - modal.AddContainerComponents( - discord.NewActionRow( - discord.TextInputComponent{ - CustomID: "message", - Style: discord.TextInputStyleParagraph, - Label: translate.Message(event.Locale(), "modal_level_notice_message_text_input_0_label"), - MinLength: json.Ptr(1), - MaxLength: 512, - Required: true, - Value: gd.Config.LevelUpMessage, - Placeholder: translate.Message(event.Locale(), "modal_level_notice_message_text_input_0_placeholder"), - }, - ), - ) - if err := event.CreateModal(modal.Build()); err != nil { - return err - } - return nil - } -} - -func configLevelNoticeChannelCommandHandler(b *botlib.Bot[*client.Client]) handler.CommandHandler { - return func(event *events.ApplicationCommandInteractionCreate) error { - b.Self.GuildDataLock(*event.GuildID()).Lock() - defer b.Self.GuildDataLock(*event.GuildID()).Unlock() - gd, err := b.Self.DB.GuildData().Get(*event.GuildID()) - if err != nil { - return botlib.ReturnErr(event, err) - } - embed := discord.NewEmbedBuilder() - embed.SetTitle(translate.Message(event.Locale(), "config_changed")) - if channel, ok := event.SlashCommandInteractionData().OptChannel("channel"); ok { - gd.Config.LevelUpMessageChannel = &channel.ID - embed.SetDescription(translate.Message(event.Locale(), "config_level_notice_channel_set", translate.WithTemplate(map[string]any{"Mention": discord.ChannelMention(channel.ID)}))) - } else { - gd.Config.LevelUpMessageChannel = nil - embed.SetDescription(translate.Message(event.Locale(), "config_level_notice_channel_remove")) - } - if err := b.Self.DB.GuildData().Set(gd.ID, gd); err != nil { - return botlib.ReturnErr(event, err) - } - embed.Embed = botlib.SetEmbedProperties(embed.Embed) - message := discord.NewMessageCreateBuilder().SetFlags(discord.MessageFlagEphemeral) - message.AddEmbeds(embed.Build()) - if err := event.CreateMessage(message.Build()); err != nil { - return botlib.ReturnErr(event, err) - } - return nil - } -} - -func configLevelExcludeAddCommandHandler(b *botlib.Bot[*client.Client]) handler.CommandHandler { - return func(event *events.ApplicationCommandInteractionCreate) error { - b.Self.GuildDataLock(*event.GuildID()).Lock() - defer b.Self.GuildDataLock(*event.GuildID()).Unlock() - gd, err := b.Self.DB.GuildData().Get(*event.GuildID()) - if err != nil { - return botlib.ReturnErr(event, err) - } - channel := event.SlashCommandInteractionData().Channel("channel") - gd.UserLevelExcludeChannels[channel.ID] = channel.Name - if err := b.Self.DB.GuildData().Set(gd.ID, gd); err != nil { - return botlib.ReturnErr(event, err) - } - embed := discord.NewEmbedBuilder() - embed.SetTitle(translate.Message(event.Locale(), "config_changed")) - embed.SetDescription(translate.Message(event.Locale(), "config_level_exclude_add", translate.WithTemplate(map[string]any{"Mention": discord.ChannelMention(channel.ID)}))) - embed.Embed = botlib.SetEmbedProperties(embed.Embed) - message := discord.NewMessageCreateBuilder() - if err := event.CreateMessage(message.AddFlags(discord.MessageFlagEphemeral).Build()); err != nil { - return botlib.ReturnErr(event, err) - } - return nil - } -} - -func configLevelExcludeRemoveHandler(b *botlib.Bot[*client.Client]) handler.CommandHandler { - return func(event *events.ApplicationCommandInteractionCreate) error { - b.Self.GuildDataLock(*event.GuildID()).Lock() - defer b.Self.GuildDataLock(*event.GuildID()).Unlock() - gd, err := b.Self.DB.GuildData().Get(*event.GuildID()) - if err != nil { - return botlib.ReturnErr(event, err) - } - channel_id, err := snowflake.Parse(event.SlashCommandInteractionData().String("channel")) - if err != nil { - return botlib.ReturnErrMessage(event, "error_invalid_id") - } - delete(gd.UserLevelExcludeChannels, channel_id) - if err := b.Self.DB.GuildData().Set(gd.ID, gd); err != nil { - return botlib.ReturnErr(event, err) - } - embed := discord.NewEmbedBuilder() - embed.SetTitle(translate.Message(event.Locale(), "config_changed")) - embed.SetDescription(translate.Message(event.Locale(), "config_level_exclude_remove", translate.WithTemplate(map[string]any{"Mention": discord.ChannelMention(channel_id)}))) - embed.Embed = botlib.SetEmbedProperties(embed.Embed) - message := discord.NewMessageCreateBuilder() - if err := event.CreateMessage(message.AddFlags(discord.MessageFlagEphemeral).Build()); err != nil { - return botlib.ReturnErr(event, err) - } - return nil - } -} - -func configLevelExcludeAutocompleteHandler(b *botlib.Bot[*client.Client]) handler.AutocompleteHandler { - return func(event *events.AutocompleteInteractionCreate) error { - b.Self.GuildDataLock(*event.GuildID()).Lock() - defer b.Self.GuildDataLock(*event.GuildID()).Unlock() - gd, err := b.Self.DB.GuildData().Get(*event.GuildID()) - if err != nil { - return err - } - var choices []discord.AutocompleteChoice - for i, v := range gd.UserLevelExcludeChannels { - choices = append(choices, discord.AutocompleteChoiceString{ - Name: fmt.Sprintf("%s (%s)", v, i.String()), - Value: i.String(), - }) - } - if err := event.Result(choices); err != nil { - return err - } - return nil - } -} - -func configLevelImportMee6CommandHandler(b *botlib.Bot[*client.Client]) handler.CommandHandler { - return func(event *events.ApplicationCommandInteractionCreate) error { - if err := event.DeferCreateMessage(false); err != nil { - return botlib.ReturnErr(event, err) - } - url := fmt.Sprintf("https://mee6.xyz/api/plugins/levels/leaderboard/%s", event.GuildID().String()) - users := map[snowflake.ID]db.GuildDataUserLevel{} - for page := 0; true; page++ { - c, err := http.Get(fmt.Sprintf("%s?page=%d", url, page)) - if err != nil || c.StatusCode != http.StatusOK { - switch c.StatusCode { - case http.StatusUnauthorized: - _, _ = event.Client().Rest().UpdateInteractionResponse(event.ApplicationID(), event.Token(), discord.NewMessageUpdateBuilder().SetContent(fmt.Sprintf("# FAILED\r```| STATUS CODE | %d\r| RESPONSE | %v```%s", c.StatusCode, err, translate.Message(event.Locale(), "config_import_mee6_result_unauthorized", translate.WithTemplate(map[string]any{"GuildID": *event.GuildID()})))).Build()) - default: - _, _ = event.Client().Rest().UpdateInteractionResponse(event.ApplicationID(), event.Token(), discord.NewMessageUpdateBuilder().SetContent(fmt.Sprintf("# FAILED\r```| STATUS CODE | %d\r| RESPONSE | %v```", c.StatusCode, err)).Build()) - } - return err - } - var leaderboard db.Mee6LeaderBoard - if err := json.NewDecoder(c.Body).Decode(&leaderboard); err != nil { - _, _ = event.Client().Rest().UpdateInteractionResponse(event.ApplicationID(), event.Token(), discord.NewMessageUpdateBuilder().SetContent(fmt.Sprintf("# FAILED\r```| ERROR | %s```", err)).Build()) - return err - } - event.Client().Logger().Info(leaderboard) - if len(leaderboard.Players) < 1 { - break - } - for _, mp := range leaderboard.Players { - u := db.GuildDataUserLevel{ - MessageCount: mp.MessageCount, - UserDataLevel: db.UserDataLevel{ - Point: big.NewInt(mp.Xp), - }, - } - users[mp.ID] = u - } - } - b.Self.GuildDataLock(*event.GuildID()).Lock() - defer b.Self.GuildDataLock(*event.GuildID()).Unlock() - gd, err := b.Self.DB.GuildData().Get(*event.GuildID()) - if err != nil { - _, _ = event.Client().Rest().UpdateInteractionResponse(event.ApplicationID(), event.Token(), discord.NewMessageUpdateBuilder().SetContent(fmt.Sprintf("# FAILED\r```| ERROR | %s```", err)).Build()) - return err - } - gd.UserLevels = users - if err := b.Self.DB.GuildData().Set(gd.ID, gd); err != nil { - _, _ = event.Client().Rest().UpdateInteractionResponse(event.ApplicationID(), event.Token(), discord.NewMessageUpdateBuilder().SetContent(fmt.Sprintf("# FAILED\r```| ERROR | %s```", err)).Build()) - return err - } - if _, err := event.Client().Rest().UpdateInteractionResponse(event.ApplicationID(), event.Token(), discord.NewMessageUpdateBuilder().SetContentf("# DONE\r```%d users has been imported```", len(users)).Build()); err != nil { - _, _ = event.Client().Rest().UpdateInteractionResponse(event.ApplicationID(), event.Token(), discord.NewMessageUpdateBuilder().SetContent(fmt.Sprintf("# FAILED\r```| ERROR | %s```", err)).Build()) - return err - } - return nil - } -} - -func ConfigModal(b *botlib.Bot[*client.Client]) handler.Modal { - return handler.Modal{ - Name: "config", - Handler: map[string]handler.ModalHandler{ - "bump-message": configModalBumpMessageHandler(b), - "up-message": configModalUpMessageHandler(b), - }, - } -} - -func configModalBumpMessageHandler(b *botlib.Bot[*client.Client]) handler.ModalHandler { - return func(event *events.ModalSubmitInteractionCreate) error { - b.Self.GuildDataLock(*event.GuildID()).Lock() - defer b.Self.GuildDataLock(*event.GuildID()).Unlock() - gd, err := b.Self.DB.GuildData().Get(*event.GuildID()) - if err != nil { - return botlib.ReturnErr(event, err) - } - gd.BumpStatus.BumpMessage = [2]string{ - event.ModalSubmitInteraction.Data.Text("message-title"), - event.ModalSubmitInteraction.Data.Text("message-body"), - } - gd.BumpStatus.BumpRemind = [2]string{ - event.ModalSubmitInteraction.Data.Text("remind-title"), - event.ModalSubmitInteraction.Data.Text("remind-body"), - } - if err := b.Self.DB.GuildData().Set(gd.ID, gd); err != nil { - return botlib.ReturnErr(event, err) - } - embed := discord.NewEmbedBuilder() - embed.SetTitle(translate.Message(event.Locale(), "config_changed")) - embed.SetDescription(translate.Message(event.Locale(), "config_bump_message_changed")) - embed.Embed = botlib.SetEmbedProperties(embed.Embed) - message := discord.NewMessageCreateBuilder() - message.AddEmbeds(embed.Build()) - if err := event.CreateMessage(message.SetFlags(discord.MessageFlagEphemeral).Build()); err != nil { - return err - } - return nil - } -} - -func configModalUpMessageHandler(b *botlib.Bot[*client.Client]) handler.ModalHandler { - return func(event *events.ModalSubmitInteractionCreate) error { - b.Self.GuildDataLock(*event.GuildID()).Lock() - defer b.Self.GuildDataLock(*event.GuildID()).Unlock() - gd, err := b.Self.DB.GuildData().Get(*event.GuildID()) - if err != nil { - return botlib.ReturnErr(event, err) - } - gd.BumpStatus.UpMessage = [2]string{ - event.ModalSubmitInteraction.Data.Text("message-title"), - event.ModalSubmitInteraction.Data.Text("message-body"), - } - gd.BumpStatus.UpRemind = [2]string{ - event.ModalSubmitInteraction.Data.Text("remind-title"), - event.ModalSubmitInteraction.Data.Text("remind-body"), - } - if err := b.Self.DB.GuildData().Set(gd.ID, gd); err != nil { - return botlib.ReturnErr(event, err) - } - embed := discord.NewEmbedBuilder() - embed.SetTitle(translate.Message(event.Locale(), "config_changed")) - embed.SetDescription(translate.Message(event.Locale(), "config_up_message_changed")) - embed.Embed = botlib.SetEmbedProperties(embed.Embed) - message := discord.NewMessageCreateBuilder() - message.AddEmbeds(embed.Build()) - if err := event.CreateMessage(message.SetFlags(discord.MessageFlagEphemeral).Build()); err != nil { - return err - } - return nil - } -} diff --git a/bot/commands/debug/db/guild_data.go b/bot/commands/debug/db/guild_data.go new file mode 100644 index 00000000..5df39e42 --- /dev/null +++ b/bot/commands/debug/db/guild_data.go @@ -0,0 +1,91 @@ +package db + +import ( + "time" + + "github.com/disgoorg/json" + "github.com/disgoorg/snowflake/v2" + "github.com/google/uuid" +) + +type GuildData struct { + ID snowflake.ID `json:"id"` + RolePanel map[uuid.UUID]GuildDataRolePanel `json:"role_panel"` + RolePanelLimit int `json:"role_panel_limit"` + UserLevels map[snowflake.ID]GuildDataUserLevel `json:"user_levels"` + Config GuildDataConfig `json:"config"` + BumpStatus BumpStatus `json:"bump_status"` + + MCStatusPanel map[uuid.UUID]string `json:"mc_status_panel"` + MCStatusPanelName map[string]int `json:"mc_status_panel_name"` + MCStatusPanelMax int `json:"mc_status_panel_max"` + + UserLevelExcludeChannels map[snowflake.ID]string `json:"user_level_exclude_channels"` + + RolePanelV2 map[uuid.UUID]string `json:"role_panel_v2"` + RolePanelV2Name map[string]int `json:"role_panel_v2_name"` + RolePanelV2Placed map[string]uuid.UUID `json:"role_panel_v2_placed"` + RolePanelV2PlacedConfig map[string]RolePanelV2Config `json:"role_panel_v2_placed_config"` + RolePanelV2Limit int `json:"role_panel_v2_limit"` + + RolePanelV2Editing map[uuid.UUID]uuid.UUID `json:"role_panel_v2_editing"` + + RolePanelV2EditingEmoji map[uuid.UUID][2]snowflake.ID `json:"role_panel_v2_emoji"` + + DataVersion *int `json:"data_version,omitempty"` +} + +type MessageSuffix struct { + Target snowflake.ID `json:"target"` + Suffix string `json:"suffix"` + RuleType MessageSuffixRuleType `json:"rule_type"` +} + +type MessageSuffixRuleType int + +type BumpStatus struct { + BumpEnabled bool `json:"bump_enabled"` + BumpChannel *snowflake.ID `json:"bump_channel"` + BumpRole *snowflake.ID `json:"bump_role"` + BumpMessage [2]string `json:"bump_message"` + BumpRemind [2]string `json:"bump_remind"` + LastBump time.Time `json:"last_bump"` + LastBumpChannel *snowflake.ID `json:"last_bump_channel"` + UpEnabled bool `json:"up_enabled"` + UpChannel *snowflake.ID `json:"up_channel"` + UpRole *snowflake.ID `json:"up_role"` + UpMessage [2]string `json:"up_message"` + UpRemind [2]string `json:"up_remind"` + LastUp time.Time `json:"last_up"` + LastUpChannel *snowflake.ID `json:"last_up_channel"` + + BumpCountMap map[snowflake.ID]uint64 `json:"bump_count_map"` + UpCountMap map[snowflake.ID]uint64 `json:"up_count_map"` +} + +type GuildDataConfig struct { + LevelUpMessage string `json:"level_up_message"` + LevelUpMessageChannel *snowflake.ID `json:"level_up_message_channel"` +} + +type GuildDataUserLevel struct { + UserDataLevel + MessageCount int64 `json:"message_count"` + LastMessageTime time.Time `json:"last_message_time"` +} + +func (g *GuildData) UnmarshalJSON(b []byte) error { + type guildData GuildData + var v struct { + guildData + } + if err := json.Unmarshal(b, &v); err != nil { + return err + } + *g = GuildData(v.guildData) + return nil +} + +type GuildDataRolePanel struct { + OnList bool `json:"on_list"` +} diff --git a/bot/commands/debug/db/role_panel_v2.go b/bot/commands/debug/db/role_panel_v2.go new file mode 100644 index 00000000..6509234d --- /dev/null +++ b/bot/commands/debug/db/role_panel_v2.go @@ -0,0 +1,29 @@ +package db + +import ( + "github.com/disgoorg/disgo/discord" + "github.com/disgoorg/snowflake/v2" + "github.com/google/uuid" +) + +type RolePanelV2 struct { + ID uuid.UUID `json:"uuid"` + Name string `json:"name"` + Description string `json:"description"` + Roles []RolePanelV2Role `json:"roles"` +} + +type RolePanelV2Config struct { + PanelType RolePanelV2Type `json:"panel_type"` + ButtonStyle discord.ButtonStyle `json:"button_style"` + ButtonShowName bool `json:"show_name"` + SimpleSelectMenu bool `json:"simple_select_menu"` + HideNotice bool `json:"hide_notice"` + UseDisplayName bool `json:"use_display_name"` +} + +type RolePanelV2Role struct { + RoleID snowflake.ID `json:"role_id"` + RoleName string `json:"role_name"` + Emoji *discord.ComponentEmoji `json:"emoji"` +} diff --git a/bot/commands/debug/db/role_panel_v2_edit.go b/bot/commands/debug/db/role_panel_v2_edit.go new file mode 100644 index 00000000..ff66ace6 --- /dev/null +++ b/bot/commands/debug/db/role_panel_v2_edit.go @@ -0,0 +1,38 @@ +package db + +import ( + "time" + + "github.com/disgoorg/disgo/discord" + "github.com/disgoorg/snowflake/v2" + "github.com/google/uuid" +) + +type RolePanelV2EditDB interface { + Get(id uuid.UUID) (data *RolePanelV2Edit, err error) + Set(id uuid.UUID, data *RolePanelV2Edit) (err error) + Del(id uuid.UUID) (err error) +} + +type RolePanelV2Edit struct { + ID uuid.UUID `json:"id"` + CreatedAt time.Time `json:"created_at"` + + RolePanelID uuid.UUID `json:"role_panel_id"` + + GuildID snowflake.ID `json:"guild_id"` + ChannelID snowflake.ID `json:"channel_id"` + MessageID snowflake.ID `json:"message_id"` + EmojiMode bool `json:"emoji_mode"` + EmojiLocale discord.Locale `json:"emoji_locale"` + + SelectedID *snowflake.ID +} + +func (r RolePanelV2Edit) IsSelected(id snowflake.ID) bool { + return r.SelectedID != nil && *r.SelectedID == id +} + +func (r RolePanelV2Edit) HasSelectedRole() bool { + return r.SelectedID != nil +} diff --git a/bot/commands/debug/db/role_panel_v2_place.go b/bot/commands/debug/db/role_panel_v2_place.go new file mode 100644 index 00000000..b3c7eba2 --- /dev/null +++ b/bot/commands/debug/db/role_panel_v2_place.go @@ -0,0 +1,18 @@ +package db + +import ( + "time" + + "github.com/disgoorg/snowflake/v2" + "github.com/google/uuid" +) + +type RolePanelV2Place struct { + ID uuid.UUID `json:"id"` + CreatedAt time.Time `json:"created_at"` + GuildID snowflake.ID `json:"guild_id"` + PanelID uuid.UUID `json:"panel_id"` + Config RolePanelV2Config `json:"config"` +} + +type RolePanelV2Type string diff --git a/bot/commands/debug/db/userdata.go b/bot/commands/debug/db/userdata.go new file mode 100644 index 00000000..3d170007 --- /dev/null +++ b/bot/commands/debug/db/userdata.go @@ -0,0 +1,109 @@ +package db + +import ( + "encoding/json" + "math/big" + "math/rand" + "time" + + "github.com/disgoorg/disgo/discord" + "github.com/disgoorg/snowflake/v2" +) + +type UserData struct { + ID snowflake.ID `json:"id"` + + CreatedAt time.Time `json:"created_at"` + BirthDay [2]int `json:"birth_day"` + Location DataLocation `json:"location"` + Locale discord.Locale `json:"locale"` + + LastMessageTime time.Time `json:"last_message_time"` + MessageCount int64 `json:"message_count"` + GlobalLevel UserDataLevel `json:"global_level"` + GlobalMessageLevel UserDataLevel `json:"global_message_level"` + GlobalVoiceLevel UserDataLevel `json:"global_voice_level"` + + DataVersion int `json:"data_version"` +} + +func (u *UserData) UnmarshalJSON(b []byte) error { + type userData UserData + var v struct { + userData + } + if err := json.Unmarshal(b, &v); err != nil { + return err + } + *u = UserData(v.userData) + return nil +} + +type DataLocation struct { + *time.Location +} + +func (u *DataLocation) MarshalJSON() ([]byte, error) { + return json.Marshal(u.Location.String()) +} + +func (u *DataLocation) UnmarshalJSON(b []byte) error { + var data string + err := json.Unmarshal(b, &data) + if err != nil { + return err + } + lc, err := time.LoadLocation(data) + if err != nil { + return err + } + u.Location = lc + return nil +} + +type UserDataLevel struct { + Point *big.Int `json:"point"` +} + +var i = big.NewInt(10) +var a = big.NewInt(2) + +func (UserDataLevel) sumRequiredLevelPoint(n *big.Int) *big.Int { + n.Add(n, big.NewInt(3)) + return new(big.Int).Add(new(big.Int).Mul(i, new(big.Int).Div(new(big.Int).Sub(new(big.Int).Exp(a, n, nil), big.NewInt(1)), new(big.Int).Sub(a, big.NewInt(1)))), big.NewInt(0)) +} + +func (UserDataLevel) requiredLevelPoint(n *big.Int) *big.Int { + n.Add(n, big.NewInt(3)) + return new(big.Int).Add(new(big.Int).Mul(i, new(big.Int).Exp(a, n, nil)), big.NewInt(0)) +} + +func (u UserDataLevel) ReqPoint() *big.Int { + return u.requiredLevelPoint(u.Level()) +} + +func (u UserDataLevel) SumReqPoint() *big.Int { + return u.sumRequiredLevelPoint(u.Level()) +} + +func (u UserDataLevel) Level() *big.Int { + if u.Point == nil { + u.Point = big.NewInt(0) + } + for k := 0; k < 999; k++ { + lv := u.sumRequiredLevelPoint(big.NewInt(int64(k))) + if lv.Cmp(u.Point) == 1 { + return big.NewInt(int64(k)) + } + } + return big.NewInt(0) +} + +func (u *UserDataLevel) Add(i *big.Int) { + u.Point.Add(u.Point, i) +} + +func (u *UserDataLevel) AddRandom() { + r := rand.Intn(10) + u.Add(new(big.Int).Add(big.NewInt(int64(r)), big.NewInt(15))) +} diff --git a/bot/commands/debug/debug.go b/bot/commands/debug/debug.go new file mode 100644 index 00000000..21f5f72f --- /dev/null +++ b/bot/commands/debug/debug.go @@ -0,0 +1,269 @@ +package debug + +import ( + "fmt" + "log/slog" + "slices" + "strings" + + "github.com/disgoorg/disgo/discord" + "github.com/disgoorg/disgo/events" + "github.com/disgoorg/json" + "github.com/disgoorg/snowflake/v2" + "github.com/google/uuid" + "github.com/redis/go-redis/v9" + "github.com/sabafly/gobot/bot/commands/debug/db" + "github.com/sabafly/gobot/bot/commands/role" + "github.com/sabafly/gobot/bot/components" + "github.com/sabafly/gobot/bot/components/generic" + "github.com/sabafly/gobot/ent" + "github.com/sabafly/gobot/ent/rolepanelplaced" + "github.com/sabafly/gobot/ent/schema" + "github.com/sabafly/gobot/internal/builtin" + "github.com/sabafly/gobot/internal/errors" + "github.com/sabafly/gobot/internal/translate" +) + +func Command(c *components.Components) *generic.Command { + return (&generic.Command{ + Namespace: "debug", + Private: true, + CommandCreate: []discord.ApplicationCommandCreate{ + discord.SlashCommandCreate{ + Name: "debug", + Description: "debug", + DMPermission: builtin.Ptr(false), + Contexts: []discord.InteractionContextType{ + discord.InteractionContextTypeGuild, + }, + DefaultMemberPermissions: json.NewNullablePtr(discord.PermissionAdministrator), + Options: []discord.ApplicationCommandOption{ + discord.ApplicationCommandOptionSubCommandGroup{ + Name: "translate", + Description: "translate", + Options: []discord.ApplicationCommandOptionSubCommand{ + { + Name: "get", + Description: "get translate", + Options: []discord.ApplicationCommandOption{ + discord.ApplicationCommandOptionString{ + Name: "key", + Description: "translate key", + Required: true, + }, + discord.ApplicationCommandOptionString{ + Name: "locale", + Description: "locale", + Required: true, + }, + }, + }, + { + Name: "reload", + Description: "reload translate", + }, + }, + }, + discord.ApplicationCommandOptionSubCommandGroup{ + Name: "redis", + Description: "redis", + Options: []discord.ApplicationCommandOptionSubCommand{ + { + Name: "import", + Description: "import", + Options: []discord.ApplicationCommandOption{ + discord.ApplicationCommandOptionString{ + Name: "addr", + Description: "address", + Required: true, + }, + discord.ApplicationCommandOptionInt{ + Name: "db", + Description: "db", + Required: true, + }, + }, + }, + }, + }, + discord.ApplicationCommandOptionSubCommandGroup{ + Name: "guild", + Description: "guild", + Options: []discord.ApplicationCommandOptionSubCommand{ + { + Name: "leave", + Description: "leave", + Options: []discord.ApplicationCommandOption{ + discord.ApplicationCommandOptionString{ + Name: "guild", + Description: "guild", + Required: true, + }, + }, + }, + }, + }, + }, + }, + }, + CommandHandlers: map[string]generic.PermissionCommandHandler{ + "/debug/translate/get": generic.CommandHandler(func(c *components.Components, event *events.ApplicationCommandInteractionCreate) errors.Error { + key := event.SlashCommandInteractionData().String("key") + locale := discord.Locale(event.SlashCommandInteractionData().String("locale")) + if err := event.CreateMessage( + discord.NewMessageBuilder(). + SetContent(translate.Message(locale, key)). + BuildCreate(), + ); err != nil { + return errors.NewError(err) + } + return nil + }), + "/debug/translate/reload": generic.CommandHandler(func(c *components.Components, event *events.ApplicationCommandInteractionCreate) errors.Error { + if _, err := translate.LoadDir(c.Config().TranslateDir); err != nil { + slog.Error("翻蚳ファむルを読み蟌めたせん", "err", err) + return errors.NewError(err) + } + if err := event.CreateMessage( + discord.NewMessageBuilder(). + SetContent("OK"). + BuildCreate(), + ); err != nil { + return errors.NewError(err) + } + return nil + }), + "/debug/guild/leave": generic.CommandHandler(func(c *components.Components, event *events.ApplicationCommandInteractionCreate) errors.Error { + guildID := snowflake.MustParse(event.SlashCommandInteractionData().String("guild")) + if err := event.Client().Rest().LeaveGuild(guildID); err != nil { + return errors.NewError(err) + } + if err := event.CreateMessage( + discord.NewMessageBuilder(). + SetContent("OK"). + BuildCreate(), + ); err != nil { + return errors.NewError(err) + } + return nil + }), + "/debug/redis/import": generic.CommandHandler(func(c *components.Components, event *events.ApplicationCommandInteractionCreate) errors.Error { + client := redis.NewClient(&redis.Options{ + Addr: event.SlashCommandInteractionData().String("addr"), + DB: event.SlashCommandInteractionData().Int("db"), + }) + // GuildData + guildCmd := client.HGetAll(event, "guild-data") + if err := guildCmd.Err(); err != nil { + return errors.NewError(err) + } + + rpv2Cmd := client.HGetAll(event, "role-panel-v2") + if err := rpv2Cmd.Err(); err != nil { + return errors.NewError(err) + } + + rpv2List := map[uuid.UUID]db.RolePanelV2{} + + for _, v := range rpv2Cmd.Val() { + var rpv2 db.RolePanelV2 + if err := json.Unmarshal([]byte(v), &rpv2); err != nil { + slog.Error("unmarshalに倱敗", "err", err) + continue + } + rpv2List[rpv2.ID] = rpv2 + } + + for _, v := range guildCmd.Val() { + var guildData db.GuildData + if err := json.Unmarshal([]byte(v), &guildData); err != nil { + slog.Error("unmarshalに倱敗", "err", err) + continue + } + if guildData.DataVersion == nil || *guildData.DataVersion != 11 { + continue + } + + g, err := c.GuildCreateID(event, guildData.ID) + if err != nil { + slog.Error("guild取埗に倱敗", slog.Any("err", err)) + continue + } + + var createRolePanelBulk []*ent.RolePanelCreate + + for u := range guildData.RolePanelV2 { + rpv2, ok := rpv2List[u] + if !ok { + continue + } + + roles := make([]schema.Role, len(rpv2.Roles)) + + for i, r := range rpv2.Roles { + roles[i] = schema.Role{ + ID: r.RoleID, + Name: r.RoleName, + Emoji: r.Emoji, + } + } + + createRolePanelBulk = append(createRolePanelBulk, + c.DB().RolePanel.Create(). + SetID(rpv2.ID). + SetRoles(roles). + SetName(rpv2.Name). + SetGuild(g). + SetDescription(rpv2.Description), + ) + } + + rolePanels, err := c.DB().RolePanel.CreateBulk(createRolePanelBulk...).Save(event) + if err != nil { + return errors.NewError(err) + } + + placedIDMap := map[[2]snowflake.ID]uuid.UUID{} + for k, u := range guildData.RolePanelV2Placed { + ks := strings.Split(k, "/") + channelID, messageID := snowflake.MustParse(ks[0]), snowflake.MustParse(ks[1]) + placedIDMap[[2]snowflake.ID{channelID, messageID}] = u + } + + for k, u := range placedIDMap { + index := slices.IndexFunc(rolePanels, func(rp *ent.RolePanel) bool { return rp.ID == u }) + if index == -1 { + continue + } + + keyString := fmt.Sprintf("%d/%d", k[0], k[1]) + + placed := c.DB().RolePanelPlaced.Create(). + SetChannelID(k[0]). + SetMessageID(k[1]). + SetType(rolepanelplaced.Type(guildData.RolePanelV2PlacedConfig[keyString].PanelType)). + SetButtonType(builtin.Or(guildData.RolePanelV2PlacedConfig[keyString].ButtonStyle != 0, guildData.RolePanelV2PlacedConfig[keyString].ButtonStyle, 1)). + SetFoldingSelectMenu(guildData.RolePanelV2PlacedConfig[keyString].SimpleSelectMenu). + SetUseDisplayName(guildData.RolePanelV2PlacedConfig[keyString].UseDisplayName). + SetShowName(guildData.RolePanelV2PlacedConfig[keyString].ButtonShowName). + SetHideNotice(guildData.RolePanelV2PlacedConfig[keyString].HideNotice). + SetName(rolePanels[index].Name). + SetDescription(rolePanels[index].Description). + SetRoles(rolePanels[index].Roles). + SetRolePanel(rolePanels[index]). + SetGuild(g). + SaveX(event) + + role.UpdateRolePanel(event, placed, event.Locale(), event.Client()) + } + + } + + if err := event.RespondMessage(discord.NewMessageBuilder().SetContent("OK")); err != nil { + return errors.NewError(err) + } + return nil + }), + }, + }).SetComponent(c) +} diff --git a/bot/commands/level.go b/bot/commands/level.go deleted file mode 100644 index ab0fa9ff..00000000 --- a/bot/commands/level.go +++ /dev/null @@ -1,330 +0,0 @@ -package commands - -import ( - "fmt" - "math/big" - "slices" - - "github.com/disgoorg/json" - "github.com/disgoorg/snowflake/v2" - "github.com/sabafly/disgo/discord" - "github.com/sabafly/disgo/events" - "github.com/sabafly/gobot/bot/client" - "github.com/sabafly/gobot/bot/db" - botlib "github.com/sabafly/sabafly-lib/v2/bot" - "github.com/sabafly/sabafly-lib/v2/handler" - "github.com/sabafly/sabafly-lib/v2/translate" -) - -func Level(b *botlib.Bot[*client.Client]) handler.Command { - return handler.Command{ - Create: discord.SlashCommandCreate{ - Name: "level", - Description: "level", - DMPermission: &b.Config.DMPermission, - Options: []discord.ApplicationCommandOption{ - discord.ApplicationCommandOptionSubCommandGroup{ - Name: "user", - Description: "user", - Options: []discord.ApplicationCommandOptionSubCommand{ - { - Name: "move", - Description: "set user level", - DescriptionLocalizations: translate.MessageMap("level_user_move_command_description", false), - Options: []discord.ApplicationCommandOption{ - discord.ApplicationCommandOptionUser{ - Name: "target-from", - Description: "target user move level from", - DescriptionLocalizations: translate.MessageMap("level_user_move_command_target_from_option_description", false), - Required: true, - }, - discord.ApplicationCommandOptionUser{ - Name: "target-to", - Description: "target user move level to", - DescriptionLocalizations: translate.MessageMap("level_user_move_command_target_to_option_description", false), - Required: true, - }, - }, - }, - { - Name: "reset", - Description: "reset user level", - DescriptionLocalizations: translate.MessageMap("level_user_reset_command_description", false), - Options: []discord.ApplicationCommandOption{ - discord.ApplicationCommandOptionUser{ - Name: "target", - Description: "target user", - DescriptionLocalizations: translate.MessageMap("level_user_reset_command_target_option_description", false), - Required: true, - }, - }, - }, - }, - }, - discord.ApplicationCommandOptionSubCommand{ - Name: "leaderboard", - Description: "show guild member leaderboard", - DescriptionLocalizations: translate.MessageMap("level_leaderboard_command_description", false), - Options: []discord.ApplicationCommandOption{ - discord.ApplicationCommandOptionInt{ - Name: "page", - Description: "page number", - DescriptionLocalizations: translate.MessageMap("level_leaderboard_command_page_option_description", false), - MinValue: json.Ptr(1), - }, - }, - }, - discord.ApplicationCommandOptionSubCommand{ - Name: "point", - Description: "show yourself point", - DescriptionLocalizations: translate.MessageMap("level_point_command_description", false), - }, - }, - }, - Checks: map[string]handler.Check[*events.ApplicationCommandInteractionCreate]{ - "user/move": b.Self.CheckCommandPermission(b, "user.level.manage", discord.PermissionManageGuild), - "user/reset": b.Self.CheckCommandPermission(b, "user.level.manage", discord.PermissionManageGuild), - }, - CommandHandlers: map[string]handler.CommandHandler{ - "user/move": levelUserMoveCommandHandler(b), - "user/reset": levelUserResetCommandHandler(b), - "point": levelPointCommandHandler(b), - "leaderboard": levelLeaderBoard(b), - }, - } -} - -func levelUserMoveCommandHandler(b *botlib.Bot[*client.Client]) handler.CommandHandler { - return func(event *events.ApplicationCommandInteractionCreate) error { - mute := b.Self.GuildDataLock(*event.GuildID()) - if !mute.TryLock() { - return botlib.ReturnErrMessage(event, "error_busy") - } - defer mute.Unlock() - gd, err := b.Self.DB.GuildData().Get(*event.GuildID()) - if err != nil { - return botlib.ReturnErr(event, err) - } - user_from := event.SlashCommandInteractionData().User("target-from") - user_to := event.SlashCommandInteractionData().User("target-to") - if user_from.Bot || user_from.System || user_to.Bot || user_to.System { - return botlib.ReturnErrMessage(event, "error_is_bot") - } - gd.UserLevels[user_to.ID] = gd.UserLevels[user_from.ID] - tmp := gd.UserLevels[user_from.ID] - tmp.Point = big.NewInt(0) - gd.UserLevels[user_from.ID] = tmp - if err := b.Self.DB.GuildData().Set(gd.ID, gd); err != nil { - return botlib.ReturnErr(event, err) - } - message := discord.NewMessageCreateBuilder() - embed := discord.NewEmbedBuilder() - embed.SetTitle(translate.Message(event.Locale(), "command_level_move_result_embed_title")) - ul := gd.UserLevels[user_to.ID] - embed.SetDescriptionf( - "%s```0 lvl 0 xp```-> %s```%s lvl %s xp```", - user_from.Mention(), - user_to.Mention(), - ul.Level().String(), - ul.Point.String(), - ) - embed.Embed = botlib.SetEmbedProperties(embed.Embed) - message.AddEmbeds(embed.Build()) - if err := event.CreateMessage(message.Build()); err != nil { - return botlib.ReturnErr(event, err) - } - return nil - } -} - -func levelUserResetCommandHandler(b *botlib.Bot[*client.Client]) handler.CommandHandler { - return func(event *events.ApplicationCommandInteractionCreate) error { - if !b.Self.GuildDataLock(*event.GuildID()).TryLock() { - return botlib.ReturnErrMessage(event, "error_busy") - } - defer b.Self.GuildDataLock(*event.GuildID()).Unlock() - gd, err := b.Self.DB.GuildData().Get(*event.GuildID()) - if err != nil { - return botlib.ReturnErr(event, err) - } - target := event.SlashCommandInteractionData().User("target") - if target.Bot || target.System { - return botlib.ReturnErrMessage(event, "error_is_bot") - } - user_level := gd.UserLevels[target.ID] - ul := gd.UserLevels[target.ID] - ul.Point = big.NewInt(0) - gd.UserLevels[target.ID] = ul - if err := b.Self.DB.GuildData().Set(gd.ID, gd); err != nil { - return botlib.ReturnErr(event, err) - } - message := discord.NewMessageCreateBuilder() - embed := discord.NewEmbedBuilder() - embed.SetTitle(translate.Message(event.Locale(), "command_level_reset_result_embed_title")) - embed.SetDescriptionf( - "```%s: %s lvl %s xp -> 0 lvl 0 xp```", - target.EffectiveName(), - user_level.Level().String(), - user_level.Point.String(), - ) - embed.Embed = botlib.SetEmbedProperties(embed.Embed) - message.AddEmbeds(embed.Build()) - if err := event.CreateMessage(message.Build()); err != nil { - return botlib.ReturnErr(event, err) - } - return nil - } -} - -func levelPointCommandHandler(b *botlib.Bot[*client.Client]) handler.CommandHandler { - return func(event *events.ApplicationCommandInteractionCreate) error { - b.Self.UserDataLock(event.User().ID).Lock() - defer b.Self.UserDataLock(event.User().ID).Unlock() - b.Self.GuildDataLock(*event.GuildID()).Lock() - defer b.Self.GuildDataLock(*event.GuildID()).Unlock() - ud, err := b.Self.DB.UserData().Get(event.User().ID) - if err != nil { - return botlib.ReturnErr(event, err) - } - gd, err := b.Self.DB.GuildData().Get(*event.GuildID()) - if err != nil { - return botlib.ReturnErr(event, err) - } - message := discord.NewMessageCreateBuilder() - embed := discord.NewEmbedBuilder() - embed.Author = &discord.EmbedAuthor{ - Name: event.Member().EffectiveName(), - IconURL: event.Member().EffectiveAvatarURL(), - } - embed.SetTitle(translate.Message(event.Locale(), "command_level_rank_result_embed_title", translate.WithTemplate(map[string]any{"User": event.Member().EffectiveName()}))) - embed.SetDescriptionf("```%-6.6s:%16s``````%-6.6s:%16s/%s```", - "Level", ud.GlobalLevel.Level().String(), - "Point", ud.GlobalLevel.Point.String(), ud.GlobalLevel.SumReqPoint().String(), - ) - var guild discord.Guild - var ok bool - if guild, ok = event.Guild(); !ok { - g, err := b.Client.Rest().GetGuild(*event.GuildID(), true) - if err != nil { - return botlib.ReturnErr(event, err) - } - guild = g.Guild - } - ul, ok := gd.UserLevels[event.User().ID] - if !ok { - ul = db.NewGuildDataUserLevel() - } - embed.AddFields(discord.EmbedField{ - Name: guild.Name, - Value: fmt.Sprintf("```%-6.6s:%16s``````%-6.6s:%16s/%v```", - "Level", ul.Level().String(), - "Point", ul.Point.String(), ul.SumReqPoint().String(), - ), - }) - embed.Embed = botlib.SetEmbedProperties(embed.Embed) - message.AddEmbeds(embed.Build()) - if err := event.CreateMessage(message.Build()); err != nil { - return err - } - return nil - } -} - -func levelLeaderBoard(b *botlib.Bot[*client.Client]) handler.CommandHandler { - return func(event *events.ApplicationCommandInteractionCreate) error { - b.Self.UserDataLock(event.User().ID).Lock() - defer b.Self.UserDataLock(event.User().ID).Unlock() - b.Self.GuildDataLock(*event.GuildID()).Lock() - defer b.Self.GuildDataLock(*event.GuildID()).Unlock() - gd, err := b.Self.DB.GuildData().Get(*event.GuildID()) - if err != nil { - return botlib.ReturnErr(event, err) - } - type sortLevel struct { - user_id snowflake.ID - level db.UserDataLevel - } - sort_list := []sortLevel{} - for id, level := range gd.UserLevels { - sort_list = append(sort_list, sortLevel{ - user_id: id, - level: level.UserDataLevel, - }) - } - - page_number, ok := event.SlashCommandInteractionData().OptInt("page") - if !ok || page_number < 1 { - page_number = 1 - } - - max_page := len(sort_list)/25 + 1 - - if len(sort_list) < 1 || max_page < page_number { - return botlib.ReturnErrMessage(event, "error_unavailable_page") - } - - slices.SortFunc(sort_list, func(a, b sortLevel) int { - return a.level.Point.Cmp(b.level.Point) - }) - slices.Reverse(sort_list) - - sort_list = sort_list[25*(page_number-1) : min(25*page_number, len(sort_list))] - - var text_list_string string - for i, sl := range sort_list { - text_list_string += fmt.Sprintf( - "**#%d | ** %s **XP:** `%s` **Level:** `%s`\r", - (25*(page_number-1))+(i+1), discord.UserMention(sl.user_id), sl.level.Point.String(), sl.level.Level().String(), - ) - } - - embed := discord.NewEmbedBuilder() - embed.SetTitlef("💬%s(%d/%d)", translate.Message(event.Locale(), "level_leader_board_category_text"), page_number, max_page) - embed.SetDescription(text_list_string) - embed.SetAuthorNamef("🏆%s", translate.Message(event.Locale(), "level_leader_board_author_text")) - if guild, ok := event.Guild(); ok && guild.Icon != nil { - embed.SetAuthorIcon(*guild.IconURL()) - } - embed.Embed = botlib.SetEmbedProperties(embed.Embed) - message := discord.NewMessageCreateBuilder() - message.AddEmbeds(embed.Build()) - if err := event.CreateMessage(message.Build()); err != nil { - buf, _ := json.Marshal(message.Build()) - b.Logger.Debug(string(buf), len(sort_list)) - return botlib.ReturnErr(event, err) - } - b.Logger.Debug(len(sort_list)) - return nil - } -} - -func LevelModal(b *botlib.Bot[*client.Client]) handler.Modal { - return handler.Modal{ - Name: "level", - Handler: map[string]handler.ModalHandler{ - "notice-message": levelModalNoticeMessageHandler(b), - }, - } -} - -func levelModalNoticeMessageHandler(b *botlib.Bot[*client.Client]) handler.ModalHandler { - return func(event *events.ModalSubmitInteractionCreate) error { - b.Self.GuildDataLock(*event.GuildID()).Lock() - defer b.Self.GuildDataLock(*event.GuildID()).Unlock() - gd, err := b.Self.DB.GuildData().Get(*event.GuildID()) - if err != nil { - return botlib.ReturnErr(event, err) - } - gd.Config.LevelUpMessage = event.Data.Text("message") - if err := b.Self.DB.GuildData().Set(gd.ID, gd); err != nil { - return botlib.ReturnErr(event, err) - } - embed := discord.NewEmbedBuilder() - embed.SetTitle(translate.Message(event.Locale(), "config_changed")) - embed.SetDescription(translate.Message(event.Locale(), "config_level_notice_message_changed")) - if err := event.DeferUpdateMessage(); err != nil { - return err - } - return nil - } -} diff --git a/bot/commands/level/level.go b/bot/commands/level/level.go new file mode 100644 index 00000000..19e91657 --- /dev/null +++ b/bot/commands/level/level.go @@ -0,0 +1,1004 @@ +package level + +import ( + "cmp" + "context" + "encoding/json" + "fmt" + "log/slog" + "math/rand/v2" + "net/http" + "slices" + "strconv" + "strings" + "time" + + "entgo.io/ent/dialect/sql" + "github.com/disgoorg/disgo/bot" + "github.com/disgoorg/disgo/discord" + "github.com/disgoorg/disgo/events" + "github.com/disgoorg/snowflake/v2" + "github.com/sabafly/gobot/bot/components" + "github.com/sabafly/gobot/bot/components/generic" + "github.com/sabafly/gobot/ent" + "github.com/sabafly/gobot/ent/member" + "github.com/sabafly/gobot/internal/builtin" + "github.com/sabafly/gobot/internal/discordutil" + "github.com/sabafly/gobot/internal/embeds" + "github.com/sabafly/gobot/internal/errors" + "github.com/sabafly/gobot/internal/smap" + "github.com/sabafly/gobot/internal/translate" + "github.com/sabafly/gobot/internal/xppoint" +) + +func Command(c *components.Components) components.Command { + return (&generic.Command{ + Namespace: "level", + CommandCreate: []discord.ApplicationCommandCreate{ + discord.SlashCommandCreate{ + Name: "level", + Description: "level", + DMPermission: builtin.Ptr(false), + Contexts: []discord.InteractionContextType{ + discord.InteractionContextTypeGuild, + }, + Options: []discord.ApplicationCommandOption{ + discord.ApplicationCommandOptionSubCommand{ + Name: "rank", + Description: "view your level and points", + Options: []discord.ApplicationCommandOption{ + discord.ApplicationCommandOptionUser{ + Name: "target", + Description: "target user", + }, + }, + }, + discord.ApplicationCommandOptionSubCommand{ + Name: "leaderboard", + Description: "view guild rank leaderboard", + Options: []discord.ApplicationCommandOption{ + discord.ApplicationCommandOptionInt{ + Name: "page", + Description: "page number", + Required: false, + MinValue: builtin.Ptr(1), + }, + }, + }, + discord.ApplicationCommandOptionSubCommand{ + Name: "transfer", + Description: "transfer xp to someone", + Options: []discord.ApplicationCommandOption{ + discord.ApplicationCommandOptionUser{ + Name: "to", + Description: "who transfer xp to", + Required: true, + }, + discord.ApplicationCommandOptionUser{ + Name: "from", + Description: "who transfer xp from", + }, + }, + }, + discord.ApplicationCommandOptionSubCommandGroup{ + Name: "up", + Description: "up", + Options: []discord.ApplicationCommandOptionSubCommand{ + { + Name: "message", + Description: "set level up message", + }, + { + Name: "message-channel", + Description: "set level up message channel", + Options: []discord.ApplicationCommandOption{ + discord.ApplicationCommandOptionChannel{ + Name: "channel", + Description: "channel", + Required: false, + ChannelTypes: []discord.ChannelType{ + discord.ChannelTypeGuildText, + discord.ChannelTypeGuildNews, + }, + }, + }, + }, + }, + }, + discord.ApplicationCommandOptionSubCommandGroup{ + Name: "exclude-channel", + Description: "exclude-channel", + Options: []discord.ApplicationCommandOptionSubCommand{ + { + Name: "add", + Description: "add exclude channel", + Options: []discord.ApplicationCommandOption{ + discord.ApplicationCommandOptionChannel{ + Name: "channel", + Description: "channel", + Required: true, + ChannelTypes: []discord.ChannelType{ + discord.ChannelTypeGuildText, + discord.ChannelTypeGuildNews, + discord.ChannelTypeGuildVoice, + discord.ChannelTypeGuildForum, + discord.ChannelTypeGuildStageVoice, + }, + }, + }, + }, + { + Name: "remove", + Description: "remove exclude channel", + Options: []discord.ApplicationCommandOption{ + discord.ApplicationCommandOptionChannel{ + Name: "channel", + Description: "channel", + Required: true, + ChannelTypes: []discord.ChannelType{ + discord.ChannelTypeGuildText, + discord.ChannelTypeGuildNews, + discord.ChannelTypeGuildVoice, + discord.ChannelTypeGuildForum, + discord.ChannelTypeGuildStageVoice, + }, + }, + }, + }, + { + Name: "clear", + Description: "clear exclude channels", + }, + { + Name: "list", + Description: "list exclude channels", + }, + }, + }, + discord.ApplicationCommandOptionSubCommand{ + Name: "import-mee6", + Description: "import xp point from mee6", + }, + discord.ApplicationCommandOptionSubCommand{ + Name: "reset", + Description: "reset user xp", + Options: []discord.ApplicationCommandOption{ + discord.ApplicationCommandOptionUser{ + Name: "target", + Description: "target user", + Required: true, + }, + }, + }, + discord.ApplicationCommandOptionSubCommandGroup{ + Name: "role", + Description: "role", + Options: []discord.ApplicationCommandOptionSubCommand{ + { + Name: "set", + Description: "set level role", + Options: []discord.ApplicationCommandOption{ + discord.ApplicationCommandOptionInt{ + Name: "level", + Description: "level number", + Required: true, + MinValue: builtin.Ptr(1), + MaxValue: builtin.Ptr(1000), + }, + discord.ApplicationCommandOptionRole{ + Name: "role", + Description: "role", + Required: true, + }, + }, + }, + { + Name: "remove", + Description: "remove level role", + Options: []discord.ApplicationCommandOption{ + discord.ApplicationCommandOptionInt{ + Name: "level", + Description: "level number", + Required: true, + MinValue: builtin.Ptr(1), + MaxValue: builtin.Ptr(1000), + }, + }, + }, + { + Name: "list", + Description: "list level roles", + }, + }, + }, + discord.ApplicationCommandOptionSubCommand{ + Name: "required-point", + Description: "required point", + Options: []discord.ApplicationCommandOption{ + discord.ApplicationCommandOptionInt{ + Name: "level", + Description: "level number", + MinValue: builtin.Ptr(1), + }, + }, + }, + }, + }, + }, + CommandHandlers: map[string]generic.PermissionCommandHandler{ + "/level/required-point": generic.PCommandHandler{ + Permission: []generic.Permission{ + generic.PermissionDefaultString("level.required-point"), + }, + CommandHandler: func(c *components.Components, event *events.ApplicationCommandInteractionCreate) errors.Error { + mem, err := c.MemberCreate(event, event.User(), *event.GuildID()) + if err != nil { + return errors.NewError(err) + } + level := uint64(0) + l, ok := event.SlashCommandInteractionData().OptInt("level") + level = uint64(l) + if !ok { + level = mem.Xp.Level() + 1 + } + builder := discord.NewMessageBuilder() + builder.SetEmbeds( + embeds.SetEmbedProperties(discord.NewEmbedBuilder(). + SetTitle(translate.Message(event.Locale(), "components.level.required-point.embed.title", translate.WithTemplate(map[string]any{"Level": level}))). + SetDescriptionf("# `%d`xp\n%s\n%s", + xppoint.TotalPoint(level), + translate.Message(event.Locale(), "components.level.required-point.embed.description", translate.WithTemplate(map[string]any{"User": event.Member().EffectiveName(), "Xp": mem.Xp})), + translate.Message(event.Locale(), "components.level.required-point.embed.description.diff", translate.WithTemplate(map[string]any{"Xp": builtin.Or(xppoint.TotalPoint(level) > uint64(mem.Xp), xppoint.TotalPoint(level)-uint64(mem.Xp), 0)})), + ). + Build()), + ) + if err := event.CreateMessage(builder.BuildCreate()); err != nil { + return errors.NewError(err) + } + return nil + }, + }, + "/level/rank": generic.PCommandHandler{ + Permission: []generic.Permission{ + generic.PermissionDefaultString("level.rank"), + }, + CommandHandler: func(c *components.Components, event *events.ApplicationCommandInteractionCreate) errors.Error { + g, err := c.GuildCreateID(event, *event.GuildID()) + if err != nil { + return errors.NewError(err) + } + target, ok := event.SlashCommandInteractionData().OptMember("target") + if !ok { + target = *event.Member() + } + if target.User.Bot || target.User.System { + return errors.NewError(errors.ErrorMessage("errors.invalid.bot.target", event)) + } + m, err := c.MemberCreate(event, target.User, *event.GuildID()) + if err != nil { + return errors.NewError(err) + } + gl, err := c.GuildRequest(event.Client(), g.ID) + if err != nil { + return errors.NewError(err) + } + ids := g.QueryMembers().Order( + member.ByXp( + sql.OrderDesc(), + ), + ).IDsX(event) + index := slices.Index(ids, m.ID) + if err := event.CreateMessage( + discord.NewMessageBuilder(). + SetEmbeds( + embeds.SetEmbedProperties( + levelMessage(g, gl, m, index, target.Member, event), + ), + ). + BuildCreate(), + ); err != nil { + return errors.NewError(err) + } + return nil + }, + }, + "/level/leaderboard": generic.PCommandHandler{ + Permission: []generic.Permission{ + generic.PermissionDefaultString("level.leaderboard"), + }, + CommandHandler: func(c *components.Components, event *events.ApplicationCommandInteractionCreate) errors.Error { + const pageCount = 25 + g, err := c.GuildCreateID(event, *event.GuildID()) + if err != nil { + return errors.NewError(err) + } + gl, err := c.GuildRequest(event.Client(), g.ID) + if err != nil { + return errors.NewError(err) + } + page := event.SlashCommandInteractionData().Int("page") + page = builtin.Or(page > 0, page, 1) + count := g.QueryMembers().CountX(event) + if page > count/pageCount+1 { + return errors.NewError(errors.ErrorMessage("errors.invalid.page", event)) + } + members := g.QueryMembers(). + Order(member.ByXp(sql.OrderDesc())). + Offset((page - 1) * pageCount). + Limit(pageCount). + AllX(event) + var leaderboard string + for i, m := range members { + leaderboard += fmt.Sprintf("**#%d | %s XP: `%d` Level: `%d`**\n", + i+1+((page-1)*pageCount), + discord.UserMention(m.UserID), + m.Xp, m.Xp.Level(), + ) + } + if err := event.CreateMessage( + discord.NewMessageBuilder(). + SetEmbeds( + embeds.SetEmbedProperties( + discord.NewEmbedBuilder(). + SetEmbedAuthor( + &discord.EmbedAuthor{ + Name: g.Name, + IconURL: builtin.NonNil(gl.IconURL()), + }, + ). + SetTitlef("🏆%s(%d/%d)", + translate.Message(event.Locale(), "components.level.leaderboard.title"), + page, + count/pageCount+1, + ). + SetDescription(leaderboard). + Build(), + ), + ). + BuildCreate(), + ); err != nil { + return errors.NewError(err) + } + return nil + }, + }, + "/level/transfer": generic.PCommandHandler{ + Permission: []generic.Permission{ + generic.PermissionString("level.transfer"), + }, + DiscordPerm: discord.PermissionManageGuild.Add(discord.PermissionModerateMembers), + CommandHandler: func(c *components.Components, event *events.ApplicationCommandInteractionCreate) errors.Error { + g, err := c.GuildCreateID(event, *event.GuildID()) + if err != nil { + return errors.NewError(err) + } + gl, err := c.GuildRequest(event.Client(), g.ID) + if err != nil { + return errors.NewError(err) + } + + to := event.SlashCommandInteractionData().Member("to") + from, ok := event.SlashCommandInteractionData().OptMember("from") + if !ok { + from = *event.Member() + } + if from.User.Bot || from.User.System || to.User.Bot || to.User.System { + return errors.NewError(errors.ErrorMessage("errors.invalid.bot.target", event)) + } + if to.User.ID == from.User.ID { + return errors.NewError(errors.ErrorMessage("errors.invalid.self.target", event)) + } + + fromUser, err := c.MemberCreate(event, from.User, *event.GuildID()) + if err != nil { + return errors.NewError(err) + } + toUser, err := c.MemberCreate(event, to.User, *event.GuildID()) + if err != nil { + return errors.NewError(err) + } + movedXp := uint64(fromUser.Xp) + fromUser.Xp = xppoint.XP(0) + fromUser = fromUser.Update().SetXp(fromUser.Xp).SaveX(event) + if toUser, err = addXp(event, toUser.Update(), movedXp, event.Client(), toUser, g, event.Channel().ID(), to.EffectiveName()); err != nil { + return errors.NewError(err) + } + ids := g.QueryMembers().Order( + member.ByXp( + sql.OrderDesc(), + ), + ).IDsX(event) + fromIndex := slices.Index(ids, fromUser.ID) + toIndex := slices.Index(ids, toUser.ID) + if err := event.CreateMessage( + discord.NewMessageBuilder(). + SetEmbeds( + embeds.SetEmbedsProperties( + []discord.Embed{ + levelMessage(g, gl, fromUser, fromIndex, from.Member, event), + levelMessage(g, gl, toUser, toIndex, to.Member, event), + discord.NewEmbedBuilder(). + SetTitlef("`%d`xp 移動したした", movedXp). + Build(), + }, + )..., + ). + BuildCreate(), + ); err != nil { + return errors.NewError(err) + } + return nil + }, + }, + "/level/up/message": generic.PCommandHandler{ + Permission: []generic.Permission{ + generic.PermissionString("level.up.message"), + }, + DiscordPerm: discord.PermissionManageGuild, + CommandHandler: func(c *components.Components, event *events.ApplicationCommandInteractionCreate) errors.Error { + g, err := c.GuildCreateID(event, *event.GuildID()) + if err != nil { + return errors.NewError(err) + } + if err := event.Modal( + discord.NewModalCreateBuilder(). + SetTitle(translate.Message(event.Locale(), "components.level.up.message.modal.title")). + SetCustomID("level:up_message_modal"). + SetContainerComponents( + discord.NewActionRow( + discord.TextInputComponent{ + CustomID: "message", + Style: discord.TextInputStyleParagraph, + Label: translate.Message(event.Locale(), "components.level.up.message.modal.input.message"), + MinLength: builtin.Ptr(1), + MaxLength: 140, + Required: true, + Placeholder: translate.Message(event.Locale(), "components.level.up.message.modal.input.message.placeholder"), + Value: g.LevelUpMessage, + }, + ), + ). + Build(), + ); err != nil { + return errors.NewError(err) + } + return nil + }, + }, + "/level/up/message-channel": generic.PCommandHandler{ + Permission: []generic.Permission{ + generic.PermissionString("level.message-channel"), + }, + DiscordPerm: discord.PermissionManageGuild, + CommandHandler: func(c *components.Components, event *events.ApplicationCommandInteractionCreate) errors.Error { + g, err := c.GuildCreateID(event, *event.GuildID()) + if err != nil { + return errors.NewError(err) + } + if channel, ok := event.SlashCommandInteractionData().OptChannel("channel"); ok { + g = g.Update(). + SetLevelUpChannel(channel.ID). + SaveX(event) + } else { + g = g.Update(). + ClearLevelUpChannel(). + SaveX(event) + } + if err := event.CreateMessage( + discord.NewMessageBuilder(). + SetContent(translate.Message(event.Locale(), "components.level.up.message-channel.message", + translate.WithTemplate(map[string]any{ + "Channel": builtin.Or(g.LevelUpChannel != nil, + discord.ChannelMention(builtin.NonNil(g.LevelUpChannel)), + translate.Message(event.Locale(), "components.level.up.message-channel.default"), + ), + }), + )). + BuildCreate(), + ); err != nil { + return errors.NewError(err) + } + return nil + }, + }, + "/level/exclude-channel/add": generic.PCommandHandler{ + Permission: []generic.Permission{ + generic.PermissionString("level.exclude-channel.add"), + }, + DiscordPerm: discord.PermissionManageGuild, + CommandHandler: func(c *components.Components, event *events.ApplicationCommandInteractionCreate) errors.Error { + g, err := c.GuildCreateID(event, *event.GuildID()) + if err != nil { + return errors.NewError(err) + } + channel := event.SlashCommandInteractionData().Channel("channel") + if slices.Contains(g.LevelUpExcludeChannel, channel.ID) { + return errors.NewError(errors.ErrorMessage("errors.already_exist", event)) + } + g.LevelUpExcludeChannel = append(g.LevelUpExcludeChannel, channel.ID) + g.Update(). + SetLevelUpExcludeChannel(g.LevelUpExcludeChannel). + ExecX(event) + if err := event.CreateMessage( + discord.NewMessageBuilder(). + SetContent(translate.Message(event.Locale(), "components.level.exclude-channel.add.message", + translate.WithTemplate(map[string]any{"Channel": discord.ChannelMention(channel.ID)}), + )). + BuildCreate(), + ); err != nil { + return errors.NewError(err) + } + return nil + }, + }, + "/level/exclude-channel/remove": generic.PCommandHandler{ + Permission: []generic.Permission{ + generic.PermissionString("level.exclude-channel.remove"), + }, + DiscordPerm: discord.PermissionManageGuild, + CommandHandler: func(c *components.Components, event *events.ApplicationCommandInteractionCreate) errors.Error { + g, err := c.GuildCreateID(event, *event.GuildID()) + if err != nil { + return errors.NewError(err) + } + channel := event.SlashCommandInteractionData().Channel("channel") + index := slices.Index(g.LevelUpExcludeChannel, channel.ID) + if index == -1 { + return errors.NewError(errors.ErrorMessage("errors.not_exist", event)) + } + g.LevelUpExcludeChannel = slices.Delete(g.LevelUpExcludeChannel, index, index+1) + g.Update(). + SetLevelUpExcludeChannel(g.LevelUpExcludeChannel). + ExecX(event) + if err := event.CreateMessage( + discord.NewMessageBuilder(). + SetContent(translate.Message(event.Locale(), "components.level.exclude-channel.remove.message", + translate.WithTemplate(map[string]any{"Channel": discord.ChannelMention(channel.ID)}), + )). + BuildCreate(), + ); err != nil { + return errors.NewError(err) + } + return nil + }, + }, + "/level/exclude-channel/clear": generic.PCommandHandler{ + Permission: []generic.Permission{ + generic.PermissionString("level.exclude-channel.clear"), + }, + DiscordPerm: discord.PermissionManageGuild, + CommandHandler: func(c *components.Components, event *events.ApplicationCommandInteractionCreate) errors.Error { + g, err := c.GuildCreateID(event, *event.GuildID()) + if err != nil { + return errors.NewError(err) + } + g.Update(). + ClearLevelUpExcludeChannel(). + ExecX(event) + if err := event.CreateMessage( + discord.NewMessageBuilder(). + SetContent(translate.Message(event.Locale(), "components.level.exclude-channel.clear.message")). + BuildCreate(), + ); err != nil { + return errors.NewError(err) + } + return nil + }, + }, + "/level/import-mee6": generic.PCommandHandler{ + Permission: []generic.Permission{ + generic.PermissionString("level.import-mee6"), + }, + DiscordPerm: discord.PermissionManageGuild, + CommandHandler: func(c *components.Components, event *events.ApplicationCommandInteractionCreate) errors.Error { + g, err := c.GuildCreateID(event, *event.GuildID()) + if err != nil { + return errors.NewError(err) + } + + if g.LevelMee6Imported { + return errors.NewError(errors.ErrorMessage("components.level.import-mee6.message.already", event)) + } + + var members []discord.Member + memberCount := 1000 + afterID := snowflake.ID(0) + for memberCount == 1000 { + m, err := event.Client().Rest().GetMembers(*event.GuildID(), memberCount, afterID) + if err != nil { + return errors.NewError(err) + } + memberCount = len(m) + members = append(members, m...) + afterID = m[len(m)-1].User.ID + } + + slog.Info("mee6むンポヌト", slog.Any("gid", event.GuildID()), slog.Int("member_count", len(members))) + + memberCount = 0 + url := fmt.Sprintf("https://mee6.xyz/api/plugins/levels/leaderboard/%s", event.GuildID().String()) + for page := 0; true; page++ { + response, err := http.Get(fmt.Sprintf("%s?page=%d", url, page)) + if err != nil || response.StatusCode != http.StatusOK { + switch response.StatusCode { + case http.StatusUnauthorized: + if err := event.RespondMessage( + discord.NewMessageBuilder(). + SetContent( + fmt.Sprintf("# FAILED\n```| STATUS CODE | %d\n| RESPONSE | %v```%s", + response.StatusCode, + err, + translate.Message(event.Locale(), "components.level.import-mee6.message.unauthorized", + translate.WithTemplate(map[string]any{"GuildID": *event.GuildID()}), + ), + ), + ), + ); err != nil { + return errors.NewError(err) + } + return nil + default: + if err := event.RespondMessage( + discord.NewMessageBuilder(). + SetContent(fmt.Sprintf("# FAILED\n```| STATUS CODE | %d\n| RESPONSE | %v```", response.StatusCode, err)), + ); err != nil { + return errors.NewError(err) + } + return nil + } + } + var leaderboard mee6LeaderBoard + if err := json.NewDecoder(response.Body).Decode(&leaderboard); err != nil { + return errors.NewError(err) + } + _ = response.Body.Close() + if len(leaderboard.Players) < 1 { + break + } + for _, player := range leaderboard.Players { + index := slices.IndexFunc(members, func(m discord.Member) bool { return m.User.ID == player.ID }) + if index == -1 { + continue + } + slog.Info("mee6メンバヌむンポヌト", slog.Any("gid", event.GuildID()), slog.Any("member_id", player.ID)) + m, err := c.MemberCreate(event, members[index].User, *event.GuildID()) + if err != nil { + return errors.NewError(err) + } + m.Update().SetXp(xppoint.XP(player.Xp)).ExecX(event) + memberCount++ + } + } + + g.Update().SetLevelMee6Imported(true).ExecX(event) + + if err := event.RespondMessage( + discord.NewMessageBuilder(). + SetContent(fmt.Sprintf("# SUCCEED\n```| IMPORTED MEMBER COUNT | %d```", memberCount)), + ); err != nil { + return errors.NewError(err) + } + return nil + }, + }, + "/level/reset": generic.PCommandHandler{ + Permission: []generic.Permission{ + generic.PermissionString("level.reset"), + }, + DiscordPerm: discord.PermissionManageGuild, + CommandHandler: func(c *components.Components, event *events.ApplicationCommandInteractionCreate) errors.Error { + target := event.SlashCommandInteractionData().Member("target") + m, err := c.MemberCreate(event, target.User, *event.GuildID()) + if err != nil { + return errors.NewError(err) + } + m.Update().SetXp(xppoint.XP(0)).ExecX(event) + if err := event.CreateMessage( + discord.NewMessageBuilder(). + SetContent(translate.Message(event.Locale(), "components.level.reset.message", + translate.WithTemplate(map[string]any{"User": discord.UserMention(target.User.ID)}), + )). + BuildCreate(), + ); err != nil { + return errors.NewError(err) + } + return nil + }, + }, + "/level/exclude-channel/list": generic.PCommandHandler{ + Permission: []generic.Permission{ + generic.PermissionString("level.exclude-channel.list"), + }, + DiscordPerm: discord.PermissionManageGuild, + CommandHandler: func(c *components.Components, event *events.ApplicationCommandInteractionCreate) errors.Error { + g, err := c.GuildCreateID(event, *event.GuildID()) + if err != nil { + return errors.NewError(err) + } + var listStr string + for i, id := range g.LevelUpExcludeChannel { + listStr += fmt.Sprintf("%d. %s\n", i+1, discord.ChannelMention(id)) + } + if err := event.CreateMessage( + discord.NewMessageBuilder(). + SetEmbeds( + embeds.SetEmbedProperties( + discord.NewEmbedBuilder(). + SetTitle(translate.Message(event.Locale(), "components.level.exclude-channel.list.message")). + SetDescription( + builtin.Or(listStr != "", + listStr, + "- "+translate.Message(event.Locale(), "components.level.exclude-channel.list.message.none"), + ), + ). + Build(), + ), + ). + BuildCreate(), + ); err != nil { + return errors.NewError(err) + } + return nil + }, + }, + "/level/role/set": generic.PCommandHandler{ + Permission: []generic.Permission{ + generic.PermissionString("level.role.set"), + }, + DiscordPerm: discord.PermissionManageGuild, + CommandHandler: func(c *components.Components, event *events.ApplicationCommandInteractionCreate) errors.Error { + g, err := c.GuildCreateID(event, *event.GuildID()) + if err != nil { + return errors.NewError(err) + } + if len(g.LevelRole) >= 20 { + return errors.NewError(errors.ErrorMessage("errors.create.reach_max", event)) + } + level := event.SlashCommandInteractionData().Int("level") + role := event.SlashCommandInteractionData().Role("role") + g.LevelRole = builtin.NonNilMap(g.LevelRole) + g.LevelRole[level] = role.ID + self, valid := event.Client().Caches().SelfMember(*event.GuildID()) + if !valid { + return errors.NewError(errors.ErrorMessage("errors.invalid.self", event)) + } + var roles []discord.Role + for _, id := range self.RoleIDs { + role, ok := event.Client().Caches().Role(*event.GuildID(), id) + if !ok { + continue + } + roles = append(roles, role) + } + highestRole := discordutil.GetHighestRole(roles) + if highestRole == nil { + return errors.NewError(errors.ErrorMessage("errors.invalid.self", event)) + } + + if role.Managed || role.Compare(*highestRole) != -1 || role.ID == *event.GuildID() { + return errors.NewError(errors.ErrorMessage("errors.invalid.role", event)) + } + + g.Update(). + SetLevelRole(g.LevelRole). + ExecX(event) + + if err := event.CreateMessage( + discord.NewMessageBuilder(). + SetEmbeds( + embeds.SetEmbedProperties( + discord.NewEmbedBuilder(). + SetTitle(translate.Message(event.Locale(), "components.level.role.set.message.embed.title")). + SetDescription( + translate.Message(event.Locale(), "components.level.role.set.message.embed.description", + translate.WithTemplate(map[string]any{ + "Level": strconv.Itoa(level), + "Role": discord.RoleMention(role.ID), + }), + ), + ). + Build(), + ), + ). + BuildCreate(), + ); err != nil { + return errors.NewError(err) + } + return nil + }, + }, + "/level/role/list": generic.PCommandHandler{ + Permission: []generic.Permission{ + generic.PermissionString("level.role.list"), + }, + DiscordPerm: discord.PermissionManageGuild, + CommandHandler: func(c *components.Components, event *events.ApplicationCommandInteractionCreate) errors.Error { + g, err := c.GuildCreateID(event, *event.GuildID()) + if err != nil { + return errors.NewError(err) + } + g.LevelRole = builtin.NonNilMap(g.LevelRole) + var listStr string + smap.MakeSortMap(g.LevelRole).Range(cmp.Compare[int], + func(k int, v snowflake.ID) { + listStr += "- " + translate.Message(event.Locale(), "components.level.role.list.message", + translate.WithTemplate(map[string]any{ + "Level": strconv.Itoa(k), + "Role": discord.RoleMention(v), + }), + ) + "\n" + }, + ) + if err := event.RespondMessage( + discord.NewMessageBuilder(). + SetEmbeds( + embeds.SetEmbedProperties( + discord.NewEmbedBuilder(). + SetTitle(translate.Message(event.Locale(), "components.level.role.list.message.embed.title")). + SetDescription( + builtin.Or(listStr != "", + listStr, + translate.Message(event.Locale(), "components.level.role.list.message.none"), + ), + ). + Build(), + ), + ), + ); err != nil { + return errors.NewError(err) + } + return nil + }, + }, + "/level/role/remove": generic.PCommandHandler{ + Permission: []generic.Permission{ + generic.PermissionString("level.role.remove"), + }, + DiscordPerm: discord.PermissionManageGuild, + CommandHandler: func(c *components.Components, event *events.ApplicationCommandInteractionCreate) errors.Error { + g, err := c.GuildCreateID(event, *event.GuildID()) + if err != nil { + return errors.NewError(err) + } + g.LevelRole = builtin.NonNilMap(g.LevelRole) + level := event.SlashCommandInteractionData().Int("level") + r, ok := g.LevelRole[level] + if !ok { + return errors.NewError(errors.ErrorMessage("errors.not_exist", event)) + } + delete(g.LevelRole, level) + + g.Update(). + SetLevelRole(g.LevelRole). + ExecX(event) + + if err := event.CreateMessage( + discord.NewMessageBuilder(). + SetEmbeds( + embeds.SetEmbedProperties( + discord.NewEmbedBuilder(). + SetTitle(translate.Message(event.Locale(), "components.level.role.remove.message.embed.title")). + SetDescription( + translate.Message(event.Locale(), "components.level.role.remove.message.embed.description", + translate.WithTemplate(map[string]any{ + "Level": strconv.Itoa(level), + "Role": discord.RoleMention(r), + }), + ), + ). + Build(), + ), + ). + BuildCreate(), + ); err != nil { + return errors.NewError(err) + } + return nil + }, + }, + }, + ModalHandlers: map[string]generic.ModalHandler{ + "level:up_message_modal": func(c *components.Components, event *events.ModalSubmitInteractionCreate) errors.Error { + g, err := c.GuildCreateID(event, *event.GuildID()) + if err != nil { + return errors.NewError(err) + } + g = g.Update(). + SetLevelUpMessage(event.ModalSubmitInteraction.Data.Text("message")). + SaveX(event) + if err := event.CreateMessage( + discord.NewMessageBuilder(). + SetEmbeds( + embeds.SetEmbedProperties( + discord.NewEmbedBuilder(). + SetTitle(translate.Message(event.Locale(), "components.level.up.message.message")). + SetDescription(g.LevelUpMessage). + Build(), + ), + ). + BuildCreate(), + ); err != nil { + return nil + } + return nil + }, + }, + EventHandler: func(c *components.Components, event bot.Event) errors.Error { + switch event := event.(type) { + case *events.GuildMessageCreate: + if event.Message.Author.Bot || event.Message.Author.System || event.Message.Type.System() { + return nil + } + if event.Message.Type != discord.MessageTypeDefault && event.Message.Type != discord.MessageTypeReply { + return nil + } + g, err := c.GuildCreateID(event, event.GuildID) + if err != nil { + return errors.NewError(err) + } + if slices.Contains(g.LevelUpExcludeChannel, event.ChannelID) { + return nil + } + m, err := c.MemberCreate(event, event.Message.Author, event.GuildID) + if err != nil { + return errors.NewError(err) + } + if _, err = addXp(event, m.Update(), rand.N[uint64](16)+15, event.Client(), m, g, event.ChannelID, event.Message.Author.EffectiveName()); err != nil { + return errors.NewError(err) + } + } + return nil + }, + }).SetComponent(c) +} + +func addXp(ctx context.Context, memberUpdate *ent.MemberUpdateOne, xp uint64, client bot.Client, m *ent.Member, g *ent.Guild, channelID snowflake.ID, username string) (*ent.Member, error) { + before := builtin.NonNilOrDefault(m.LastNotifiedLevel, m.Xp.Level()) + if time.Now().After(m.LastXp.Add(time.Minute * 3)) { + m.Xp.Add(xp) + memberUpdate. + SetXp(m.Xp). + SetLastXp(time.Now()) + } + after := m.Xp.Level() + m = memberUpdate. + SetLastNotifiedLevel(after). + SetMessageCount(m.MessageCount + 1). + SaveX(ctx) + if before < after { + for i := range after - before { + if err := levelUp(g, before+i+1, client, g.ID, builtin.NonNilOrDefault(g.LevelUpChannel, channelID), m, username, before+i); err != nil { + return m, err + } + } + } + return m, nil +} + +func levelUp(g *ent.Guild, after uint64, client bot.Client, guildID, channelID snowflake.ID, m *ent.Member, username string, before uint64) error { + // レベルロヌル + r, ok := g.LevelRole[int(after)] + if ok { + if err := client.Rest().AddMemberRole(guildID, m.UserID, r); err != nil { + slog.Error("レベルロヌル付䞎に倱敗", slog.Any("err", err)) + } + } + + // レベルアップ通知 + content := g.LevelUpMessage + content = strings.ReplaceAll(content, "{user}", discord.UserMention(m.UserID)) + content = strings.ReplaceAll(content, "{username}", username) + content = strings.ReplaceAll(content, "{before_level}", strconv.FormatUint(before, 10)) + content = strings.ReplaceAll(content, "{after_level}", strconv.FormatUint(after, 10)) + content = strings.ReplaceAll(content, "{xp}", strconv.FormatUint(uint64(m.Xp), 10)) + if _, err := client.Rest(). + CreateMessage( + builtin.Or(builtin.NonNil(g.LevelUpChannel) != 0, builtin.NonNil(g.LevelUpChannel), channelID), + discord.NewMessageBuilder(). + SetContent(content). + BuildCreate(), + ); err != nil { + return err + } + return nil +} diff --git a/bot/commands/level/level_message.go b/bot/commands/level/level_message.go new file mode 100644 index 00000000..65ccb2ce --- /dev/null +++ b/bot/commands/level/level_message.go @@ -0,0 +1,65 @@ +package level + +import ( + "fmt" + + "github.com/disgoorg/disgo/discord" + "github.com/sabafly/gobot/ent" + "github.com/sabafly/gobot/internal/builtin" + "github.com/sabafly/gobot/internal/translate" + "github.com/sabafly/gobot/internal/xppoint" +) + +func levelMessage( + g *ent.Guild, + gl *discord.Guild, + m *ent.Member, + index int, + member discord.Member, + event interface { + Locale() discord.Locale + }, +) discord.Embed { + return discord.NewEmbedBuilder(). + SetEmbedAuthor( + &discord.EmbedAuthor{ + Name: g.Name, + IconURL: builtin.NonNil(gl.IconURL()), + }, + ). + SetThumbnail(member.EffectiveAvatarURL()). + SetTitle( + translate.Message( + event.Locale(), "components.level.rank.embed.title", + translate.WithTemplate( + map[string]any{ + "User": member.EffectiveName(), + }, + ), + ), + ). + SetDescription("## "+translate.Message(event.Locale(), "components.level.rank.embed.description", + translate.WithTemplate(map[string]any{ + "Level": m.Xp.Level(), + "Xp": m.Xp, + }), + )). + SetFields( + discord.EmbedField{ + Name: translate.Message(event.Locale(), "components.level.rank.embed.fields.place"), + Value: fmt.Sprintf("**#%d**", index+1), + Inline: builtin.Ptr(true), + }, + discord.EmbedField{ + Name: translate.Message(event.Locale(), "components.level.rank.embed.fields.next_level", + translate.WithTemplate(map[string]any{"NextLevel": m.Xp.Level() + 1}), + ), + Value: fmt.Sprintf("`%d`xp / `%d`xp", + xppoint.RequiredPoint(m.Xp.Level())-(xppoint.TotalPoint(m.Xp.Level()+1)-uint64(m.Xp)), + xppoint.RequiredPoint(m.Xp.Level()), + ), + Inline: builtin.Ptr(true), + }, + ). + Build() +} diff --git a/bot/db/mee6.go b/bot/commands/level/mee6.go similarity index 83% rename from bot/db/mee6.go rename to bot/commands/level/mee6.go index 17564920..a790849e 100644 --- a/bot/db/mee6.go +++ b/bot/commands/level/mee6.go @@ -1,24 +1,24 @@ -package db +package level import "github.com/disgoorg/snowflake/v2" -type Mee6LeaderBoard struct { +type mee6LeaderBoard struct { Admin bool `json:"admin"` BannerURL *string `json:"banner_url"` Country string `json:"country"` - Guild Mee6Guild `json:"guild"` + Guild mee6Guild `json:"guild"` IsMember bool `json:"is_member"` - MonetizeOptions Mee6MonetizeOptions `json:"monetize_options"` + MonetizeOptions mee6MonetizeOptions `json:"monetize_options"` Page int `json:"page"` - Player *Mee6Player `json:"player"` - Players []Mee6Player `json:"players"` + Player *mee6Player `json:"player"` + Players []mee6Player `json:"players"` RoleRewards []any `json:"role_rewards"` UserGuildSettings any `json:"user_guild_settings"` XpPerMessage []int `json:"xp_per_message"` XpRate float64 `json:"xp_rate"` } -type Mee6Guild struct { +type mee6Guild struct { AllowJoin bool `json:"allow_join"` ApplicationCommandsEnabled bool `json:"application_commands_enabled"` CommandsPrefix string `json:"commands_prefix"` @@ -30,12 +30,12 @@ type Mee6Guild struct { Premium bool `json:"premium"` } -type Mee6MonetizeOptions struct { +type mee6MonetizeOptions struct { DisplayPlans bool `json:"display_plans"` ShowcaseSubscribers bool `json:"showcase_subscribers"` } -type Mee6Player struct { +type mee6Player struct { Avatar string `json:"avatar"` DetailedXp []int64 `json:"detailed_xp"` Discriminator string `json:"discriminator"` diff --git a/bot/commands/message.go b/bot/commands/message.go deleted file mode 100644 index 78e0d5c8..00000000 --- a/bot/commands/message.go +++ /dev/null @@ -1,460 +0,0 @@ -package commands - -import ( - "fmt" - "strings" - - "slices" - - "github.com/disgoorg/snowflake/v2" - "github.com/google/uuid" - "github.com/sabafly/disgo/discord" - "github.com/sabafly/disgo/events" - "github.com/sabafly/gobot/bot/client" - "github.com/sabafly/gobot/bot/db" - botlib "github.com/sabafly/sabafly-lib/v2/bot" - "github.com/sabafly/sabafly-lib/v2/handler" - "github.com/sabafly/sabafly-lib/v2/handler/interactions" - "github.com/sabafly/sabafly-lib/v2/translate" -) - -func Message(b *botlib.Bot[*client.Client]) handler.Command { - return handler.Command{ - Create: discord.SlashCommandCreate{ - Name: "message", - Description: "message", - DMPermission: &b.Config.DMPermission, - Options: []discord.ApplicationCommandOption{ - discord.ApplicationCommandOptionSubCommandGroup{ - Name: "pin", - Description: "pin", - Options: []discord.ApplicationCommandOptionSubCommand{ - { - Name: "create", - Description: "create pinned message", - DescriptionLocalizations: translate.MessageMap("message_pin_create_command_description", false), - Options: []discord.ApplicationCommandOption{ - discord.ApplicationCommandOptionBool{ - Name: "use-embed", - Description: "wither uses embed creator", - DescriptionLocalizations: translate.MessageMap("message_pin_create_command_user_embed_option_description", false), - Required: false, - }, - }, - }, - { - Name: "delete", - Description: "delete pinned message", - DescriptionLocalizations: translate.MessageMap("message_pin_delete_command_description", false), - }, - }, - }, - discord.ApplicationCommandOptionSubCommandGroup{ - Name: "suffix", - Description: "suffix", - Options: []discord.ApplicationCommandOptionSubCommand{ - { - Name: "set", - Description: "set user message suffix", - DescriptionLocalizations: translate.MessageMap("message_suffix_set_command_description", false), - Options: []discord.ApplicationCommandOption{ - discord.ApplicationCommandOptionUser{ - Name: "target", - Description: "target user", - DescriptionLocalizations: translate.MessageMap("message_suffix_set_command_target_option_description", false), - Required: true, - }, - discord.ApplicationCommandOptionString{ - Name: "suffix", - Description: "suffix text", - DescriptionLocalizations: translate.MessageMap("message_suffix_set_command_suffix_option_description", false), - Required: true, - }, - discord.ApplicationCommandOptionInt{ - Name: "rule-type", - Description: "force suffix rule type", - DescriptionLocalizations: translate.MessageMap("message_suffix_set_command_rule_type_option_description", false), - Required: true, - Choices: []discord.ApplicationCommandOptionChoiceInt{ - { - Name: "send warning message", - NameLocalizations: translate.MessageMap("message_suffix_set_command_rule_type_option_send_warn", false), - Value: db.MessageSuffixRuleTypeWarning, - }, - { - Name: "delete message", - NameLocalizations: translate.MessageMap("message_suffix_set_command_rule_type_option_delete", false), - Value: db.MessageSuffixRuleTypeDelete, - }, - { - Name: "webhook replace", - NameLocalizations: translate.MessageMap("message_suffix_set_command_rule_type_webhook", false), - Value: db.MessageSuffixRuleTypeWebhook, - }, - }, - }, - }, - }, - { - Name: "remove", - Description: "remove suffix rule from target", - DescriptionLocalizations: translate.MessageMap("message_suffix_remove_command_description", false), - Options: []discord.ApplicationCommandOption{ - discord.ApplicationCommandOptionUser{ - Name: "target", - Description: "target user", - DescriptionLocalizations: translate.MessageMap("message_suffix_remove_command_target_option_description", false), - Required: true, - }, - }, - }, - }, - }, - }, - }, - Check: b.Self.CheckCommandPermission(b, "message.manage", discord.PermissionManageChannels.Add(discord.PermissionManageMessages)), - CommandHandlers: map[string]handler.CommandHandler{ - "pin/create": messagePinCreateCommandHandler(b), - "pin/delete": messagePinDeleteCommandHandler(b), - "suffix/set": messageSuffixSetCommandHandler(b), - "suffix/remove": messageSuffixRemoveCommandHandler(b), - }, - } -} - -func messagePinCreateCommandHandler(b *botlib.Bot[*client.Client]) handler.CommandHandler { - return func(event *events.ApplicationCommandInteractionCreate) error { - if event.SlashCommandInteractionData().Bool("use-embed") { - interaction_token := interactions.New(event.Token(), event.ID().Time()) - embed_dialog := db.NewEmbedDialog("message:p-e-create", interaction_token, event.Locale()) - if err := b.Self.DB.EmbedDialog().Set(embed_dialog.ID, *embed_dialog); err != nil { - return botlib.ReturnErr(event, err, botlib.WithEphemeral(true)) - } - embed_dialog.SetDescription("default message") - if err := event.DeferCreateMessage(true); err != nil { - return botlib.ReturnErr(event, err) - } - if _, err := event.Client().Rest().UpdateInteractionResponse(event.ApplicationID(), event.Token(), embed_dialog.BaseMenu()); err != nil { - return err - } - return nil - } else { - if err := event.CreateModal(discord.ModalCreate{ - Title: translate.Message(event.Locale(), "command_message_pin_create_modal_title"), - CustomID: "handler:message:pin-create", - Components: []discord.ContainerComponent{ - discord.NewActionRow( - discord.TextInputComponent{ - CustomID: "content", - Style: discord.TextInputStyle(discord.TextInputStyleParagraph), - Label: translate.Message(event.Locale(), "command_message_pin_create_modal_action_row_0_label"), - MaxLength: 2000, - Placeholder: translate.Message(event.Locale(), "command_message_create_modal_action_row_0_placeholder"), - Required: true, - }, - ), - }, - }); err != nil { - return botlib.ReturnErr(event, err) - } - return nil - } - } -} - -func messagePinDeleteCommandHandler(b *botlib.Bot[*client.Client]) handler.CommandHandler { - return func(event *events.ApplicationCommandInteractionCreate) error { - if !b.Self.MessagePinSync.TryLock() { - return botlib.ReturnErrMessage(event, "error_busy", botlib.WithEphemeral(true)) - } - defer b.Self.MessagePinSync.Unlock() - m, ok := b.Self.MessagePin[*event.GuildID()] - if !ok { - return botlib.ReturnErrMessage(event, "error_not_found", botlib.WithEphemeral(true)) - } - mp, ok := m.Pins[event.Channel().ID()] - b.Logger.Debug(*event.GuildID(), event.Channel().ID()) - if !ok { - return botlib.ReturnErrMessage(event, "error_not_found", botlib.WithEphemeral(true)) - } - if mp.LastMessageID != nil { - _ = event.Client().Rest().DeleteMessage(mp.ChannelID, *mp.LastMessageID) - } - delete(m.Pins, event.Channel().ID()) - if err := b.Self.DB.MessagePin().Set(*event.GuildID(), m); err != nil { - return botlib.ReturnErr(event, err, botlib.WithEphemeral(true)) - } - m.Pins[event.Channel().ID()] = mp - b.Self.MessagePin[*event.GuildID()] = m - embed := discord.NewEmbedBuilder() - embed.SetDescription(translate.Message(event.Locale(), "message_pin_delete")) - embed.Embed = botlib.SetEmbedProperties(embed.Embed) - message := discord.NewMessageCreateBuilder() - message.AddEmbeds(embed.Build()) - return event.CreateMessage(message.SetFlags(discord.MessageFlagEphemeral).Build()) - } -} - -func messageSuffixSetCommandHandler(b *botlib.Bot[*client.Client]) handler.CommandHandler { - return func(event *events.ApplicationCommandInteractionCreate) error { - b.Self.GuildDataLock(*event.GuildID()).Lock() - defer b.Self.GuildDataLock(*event.GuildID()).Unlock() - gd, err := b.Self.DB.GuildData().Get(*event.GuildID()) - if err != nil { - return botlib.ReturnErr(event, err) - } - target := event.SlashCommandInteractionData().User("target") - if target.Bot || target.System { - return botlib.ReturnErrMessage(event, "error_is_bot") - } - suffix_string := event.SlashCommandInteractionData().String("suffix") - suffix_type := event.SlashCommandInteractionData().Int("rule-type") - suffix := db.NewMessageSuffix(target.ID, suffix_string, db.MessageSuffixRuleType(suffix_type)) - gd.MessageSuffix[target.ID] = suffix - if err := b.Self.DB.GuildData().Set(gd.ID, gd); err != nil { - return botlib.ReturnErr(event, err) - } - message := discord.NewMessageCreateBuilder() - message.SetContentf("%sの語尟を「%s」に匷制したす", target.Mention(), suffix_string) - if err := event.CreateMessage(message.Build()); err != nil { - return err - } - return nil - } -} - -func messageSuffixRemoveCommandHandler(b *botlib.Bot[*client.Client]) handler.CommandHandler { - return func(event *events.ApplicationCommandInteractionCreate) error { - b.Self.GuildDataLock(*event.GuildID()).Lock() - defer b.Self.GuildDataLock(*event.GuildID()).Unlock() - gd, err := b.Self.DB.GuildData().Get(*event.GuildID()) - if err != nil { - return botlib.ReturnErr(event, err) - } - target := event.SlashCommandInteractionData().User("target") - if _, ok := gd.MessageSuffix[target.ID]; !ok { - return botlib.ReturnErrMessage(event, "error_already_deleted") - } - delete(gd.MessageSuffix, target.ID) - if err := b.Self.DB.GuildData().Set(gd.ID, gd); err != nil { - return botlib.ReturnErr(event, err) - } - message := discord.NewMessageCreateBuilder() - message.SetContentf("%sの語尟を解陀したした", target.Mention()) - if err := event.CreateMessage(message.Build()); err != nil { - return err - } - return nil - } -} - -func MessageComponent(b *botlib.Bot[*client.Client]) handler.Component { - return handler.Component{ - Name: "message", - Handler: map[string]handler.ComponentHandler{ - "p-e-create": messageComponentPECreate(b), - }, - } -} - -func messageComponentPECreate(b *botlib.Bot[*client.Client]) handler.ComponentHandler { - return func(event *events.ComponentInteractionCreate) error { - args := strings.Split(event.Data.CustomID(), ":") - ed_id, err := uuid.Parse(args[3]) - if err != nil { - return botlib.ReturnErrMessage(event, "error_invalid_id") - } - ed, err := b.Self.DB.EmbedDialog().Get(ed_id) - if err != nil { - return botlib.ReturnErrMessage(event, "error_timeout") - } - mp, err := b.Self.DB.MessagePin().Get(*event.GuildID()) - if err != nil { - mp = db.NewMessagePin() - } - if token, err := ed.InteractionToken.Get(); err == nil { - _ = event.Client().Rest().DeleteInteractionResponse(event.ApplicationID(), token) - } - if err := event.DeferUpdateMessage(); err != nil { - return botlib.ReturnErr(event, err) - } - wmc := discord.WebhookMessageCreate{ - Embeds: []discord.Embed{ed.SetColor(botlib.Color).Build()}, - Username: translate.Message(event.Locale(), "command_message_pin_create_pinned_message"), - AvatarURL: b.Self.Config.MessagePinAvatarURL, - } - m, err := botlib.SendWebhook(event.Client(), event.Channel().ID(), wmc) - if err != nil { - return err - } - mp.Pins[event.Channel().ID()] = db.MessagePin{ - WebhookMessageCreate: wmc, - ChannelID: m.ChannelID, - LastMessageID: &m.ID, - } - if err := b.Self.DB.MessagePin().Set(*event.GuildID(), mp); err != nil { - return err - } - b.Self.MessagePin[*event.GuildID()] = mp - return nil - } -} - -func MessageModal(b *botlib.Bot[*client.Client]) handler.Modal { - return handler.Modal{ - Name: "message", - Handler: map[string]handler.ModalHandler{ - "pin-create": messageModalPinCreate(b), - }, - } -} - -func messageModalPinCreate(b *botlib.Bot[*client.Client]) handler.ModalHandler { - return func(event *events.ModalSubmitInteractionCreate) error { - content := event.ModalSubmitInteraction.Data.Text("content") - mp, err := b.Self.DB.MessagePin().Get(*event.GuildID()) - if err != nil { - mp = db.NewMessagePin() - } - if err := event.DeferUpdateMessage(); err != nil { - return botlib.ReturnErr(event, err) - } - wmc := discord.WebhookMessageCreate{ - Content: content, - Username: translate.Message(event.Locale(), "command_message_pin_create_pinned_message"), - AvatarURL: b.Self.Config.MessagePinAvatarURL, - } - m, err := botlib.SendWebhook(event.Client(), event.Channel().ID(), wmc) - if err != nil { - return err - } - mp.Pins[event.Channel().ID()] = db.MessagePin{ - WebhookMessageCreate: wmc, - ChannelID: m.ChannelID, - LastMessageID: &m.ID, - } - if err := b.Self.DB.MessagePin().Set(*event.GuildID(), mp); err != nil { - return err - } - b.Self.MessagePin[*event.GuildID()] = mp - return nil - } -} - -func MessagePinMessageCreateHandler(b *botlib.Bot[*client.Client]) handler.Message { - return handler.Message{ - Handler: func(event *events.GuildMessageCreate) error { - if !b.Self.MessagePinSync.TryLock() { - return nil - } - defer b.Self.MessagePinSync.Unlock() - m, ok := b.Self.MessagePin[event.GuildID] - if !ok || !m.Enabled { - return nil - } - mp, ok := m.Pins[event.ChannelID] - if !ok { - return nil - } - if mp.CheckLimit() { - id, _, err := botlib.GetWebhook(event.Client(), event.ChannelID) - if err != nil { - b.Logger.Error(err) - return err - } - if event.Message.WebhookID != nil && id == *event.Message.WebhookID { - return nil - } - if err := mp.Update(event.Client()); err != nil { - return err - } - } - m.Pins[event.ChannelID] = mp - b.Self.MessagePin[event.GuildID] = m - if err := b.Self.DB.MessagePin().Set(event.GuildID, m); err != nil { - return err - } - return nil - }, - } -} - -func MessageSuffixMessageCreateHandler(b *botlib.Bot[*client.Client]) handler.Message { - return handler.Message{ - Handler: func(event *events.GuildMessageCreate) error { - if event.Message.Author.Bot || event.Message.Author.System || event.Message.Type.System() || !event.Message.Type.Deleteable() { - return nil - } - if event.Message.Type != discord.MessageTypeDefault && event.Message.Type != discord.MessageTypeReply { - return nil - } - b.Self.GuildDataLock(event.GuildID).Lock() - defer b.Self.GuildDataLock(event.GuildID).Unlock() - gd, err := b.Self.DB.GuildData().Get(event.GuildID) - if err != nil { - return err - } - suffix, ok := gd.MessageSuffix[event.Message.Author.ID] - if !ok { - return nil - } - has_suffix := strings.HasSuffix(event.Message.Content, suffix.Suffix) - switch suffix.RuleType { - case db.MessageSuffixRuleTypeWarning: - if has_suffix { - break - } - message := discord.NewMessageCreateBuilder() - message.SetContent(fmt.Sprintf("語尟が぀いおないよ\r「%s」を忘れないで(笑)", suffix.Suffix)) - message.SetAllowedMentions(&discord.AllowedMentions{ - RepliedUser: true, - }) - message.SetMessageReferenceByID(event.MessageID) - if _, err := event.Client().Rest().CreateMessage(event.ChannelID, message.Build()); err != nil { - return err - } - case db.MessageSuffixRuleTypeDelete: - if has_suffix { - break - } - if err := event.Client().Rest().DeleteMessage(event.ChannelID, event.MessageID); err != nil { - return err - } - case db.MessageSuffixRuleTypeWebhook: - if !has_suffix { - event.Message.Content += suffix.Suffix - } - if err := event.Client().Rest().DeleteMessage(event.ChannelID, event.MessageID); err != nil { - return err - } - message := discord.NewWebhookMessageCreateBuilder() - message.Content = event.Message.Content - message.SetAvatarURL(event.Message.Member.EffectiveAvatarURL()) - message.SetUsername(event.Message.Author.EffectiveName()) - mention_users := make([]snowflake.ID, len(event.Message.Mentions)) - for i, u := range event.Message.Mentions { - mention_users[i] = u.ID - } - replied_user := false - if event.Message.MessageReference != nil && event.Message.MessageReference.ChannelID != nil && event.Message.MessageReference.MessageID != nil { - reply_message, err := event.Client().Rest().GetMessage(*event.Message.MessageReference.ChannelID, *event.Message.MessageReference.MessageID) - if err == nil { - replied_user = slices.Index(mention_users, reply_message.Author.ID) != -1 - } - } - message.SetAllowedMentions(&discord.AllowedMentions{ - Users: mention_users, - Roles: event.Message.MentionRoles, - RepliedUser: replied_user, - }) - - // うヌヌん むりぜ¯\_(ツ)_/¯ - - if _, err := botlib.SendWebhook(event.Client(), event.ChannelID, message.Build()); err != nil { - return err - } - } - return nil - }, - } -} diff --git a/bot/commands/message/message.go b/bot/commands/message/message.go new file mode 100644 index 00000000..a765b25b --- /dev/null +++ b/bot/commands/message/message.go @@ -0,0 +1,957 @@ +package message + +import ( + "context" + "fmt" + "github.com/disgoorg/disgo/rest" + "log/slog" + "net/http" + "slices" + "strconv" + "strings" + "time" + + "github.com/disgoorg/disgo/bot" + "github.com/disgoorg/disgo/discord" + "github.com/disgoorg/disgo/events" + "github.com/disgoorg/snowflake/v2" + "github.com/sabafly/gobot/bot/components" + "github.com/sabafly/gobot/bot/components/generic" + "github.com/sabafly/gobot/ent" + "github.com/sabafly/gobot/ent/guild" + "github.com/sabafly/gobot/ent/messagepin" + "github.com/sabafly/gobot/ent/messageremind" + "github.com/sabafly/gobot/ent/wordsuffix" + "github.com/sabafly/gobot/internal/builtin" + "github.com/sabafly/gobot/internal/errors" + "github.com/sabafly/gobot/internal/parse" + "github.com/sabafly/gobot/internal/translate" +) + +func Command(c *components.Components) *generic.Command { + return (&generic.Command{ + Namespace: "message", + CommandCreate: []discord.ApplicationCommandCreate{ + discord.SlashCommandCreate{ + Name: "message", + Description: "message", + DMPermission: builtin.Ptr(false), + Contexts: []discord.InteractionContextType{ + discord.InteractionContextTypeGuild, + }, + Options: []discord.ApplicationCommandOption{ + discord.ApplicationCommandOptionSubCommandGroup{ + Name: "suffix", + Description: "suffix", + Options: []discord.ApplicationCommandOptionSubCommand{ + { + Name: "set", + Description: "set member's suffix", + DescriptionLocalizations: translate.MessageMap("components.message.suffix.set.command.description", false), + Options: []discord.ApplicationCommandOption{ + discord.ApplicationCommandOptionUser{ + Name: "target", + NameLocalizations: translate.MessageMap("components.message.suffix.set.command.options.target.name", false), + Description: "target", + DescriptionLocalizations: translate.MessageMap("components.message.suffix.set.command.options.target.description", false), + Required: true, + }, + discord.ApplicationCommandOptionString{ + Name: "suffix", + NameLocalizations: translate.MessageMap("components.message.suffix.set.command.options.suffix.name", false), + Description: "suffix", + DescriptionLocalizations: translate.MessageMap("components.message.suffix.set.command.options.suffix.description", false), + Required: true, + MaxLength: builtin.Ptr(512), + }, + discord.ApplicationCommandOptionString{ + Name: "rule", + NameLocalizations: translate.MessageMap("components.message.suffix.set.command.options.rule.name", false), + Description: "rule", + DescriptionLocalizations: translate.MessageMap("components.message.suffix.set.command.options.rule.description", false), + Required: true, + Choices: []discord.ApplicationCommandOptionChoiceString{ + { + Name: "webhook", + NameLocalizations: translate.MessageMap("components.message.suffix.set.command.options.rule.webhook", false), + Value: wordsuffix.RuleWebhook.String(), + }, + { + Name: "warn", + NameLocalizations: translate.MessageMap("components.message.suffix.set.command.options.rule.warn", false), + Value: wordsuffix.RuleWarn.String(), + }, + { + Name: "delete", + NameLocalizations: translate.MessageMap("components.message.suffix.set.command.options.rule.delete", false), + Value: wordsuffix.RuleDelete.String(), + }, + }, + }, + discord.ApplicationCommandOptionInt{ + Name: "duration", + NameLocalizations: translate.MessageMap("components.message.suffix.set.command.options.duration.name", false), + Description: "duration", + DescriptionLocalizations: translate.MessageMap("components.message.suffix.set.command.options.duration.description", false), + Required: false, + Choices: []discord.ApplicationCommandOptionChoiceInt{ + { + Name: "1m", + NameLocalizations: translate.MessageMap("components.message.suffix.set.command.options.duration.1m", false), + Value: 0, + }, + { + Name: "1h", + NameLocalizations: translate.MessageMap("components.message.suffix.set.command.options.duration.1h", false), + Value: 1, + }, + { + Name: "3h", + NameLocalizations: translate.MessageMap("components.message.suffix.set.command.options.duration.3h", false), + Value: 2, + }, + { + Name: "6h", + NameLocalizations: translate.MessageMap("components.message.suffix.set.command.options.duration.6h", false), + Value: 3, + }, + { + Name: "1d", + NameLocalizations: translate.MessageMap("components.message.suffix.set.command.options.duration.1d", false), + Value: 4, + }, + { + Name: "3d", + NameLocalizations: translate.MessageMap("components.message.suffix.set.command.options.duration.3d", false), + Value: 5, + }, + { + Name: "1w", + NameLocalizations: translate.MessageMap("components.message.suffix.set.command.options.duration.1w", false), + Value: 6, + }, + }, + }, + }, + }, + { + Name: "remove", + Description: "remove member's suffix", + DescriptionLocalizations: translate.MessageMap("components.message.suffix.remove.command.description", false), + Options: []discord.ApplicationCommandOption{ + discord.ApplicationCommandOptionUser{ + Name: "target", + NameLocalizations: translate.MessageMap("components.message.suffix.remove.command.options.target.name", false), + Description: "target", + DescriptionLocalizations: translate.MessageMap("components.message.suffix.remove.command.options.target.description", false), + Required: true, + }, + }, + }, + { + Name: "check", + Description: "check member's suffix", + Options: []discord.ApplicationCommandOption{ + discord.ApplicationCommandOptionUser{ + Name: "target", + Description: "target", + Required: false, + }, + }, + }, + }, + }, + discord.ApplicationCommandOptionSubCommandGroup{ + Name: "pin", + Description: "pin", + Options: []discord.ApplicationCommandOptionSubCommand{ + { + Name: "create", + Description: "create pinned message", + }, + { + Name: "delete", + Description: "delete pinned message", + }, + }, + }, + discord.ApplicationCommandOptionSubCommandGroup{ + Name: "remind", + Description: "remind", + Options: []discord.ApplicationCommandOptionSubCommand{ + { + Name: "set", + Description: "set remind", + Options: []discord.ApplicationCommandOption{ + discord.ApplicationCommandOptionString{ + Name: "time", + Description: "format 2023-01-23 15:16", + MinLength: builtin.Ptr(1), + MaxLength: builtin.Ptr(16), + Required: true, + }, + }, + }, + { + Name: "cancel", + Description: "cancel remind", + Options: []discord.ApplicationCommandOption{ + discord.ApplicationCommandOptionString{ + Name: "remind", + Description: "remind name", + Autocomplete: true, + Required: true, + }, + }, + }, + }, + }, + }, + }, + }, + + CommandHandlers: map[string]generic.PermissionCommandHandler{ + "/message/suffix/set": generic.PCommandHandler{ + Permission: []generic.Permission{ + generic.PermissionString("message.suffix.set"), + }, + DiscordPerm: discord.PermissionManageMessages, + CommandHandler: func(c *components.Components, event *events.ApplicationCommandInteractionCreate) errors.Error { + if u := event.SlashCommandInteractionData().User("target"); u.Bot || u.System { + return errors.NewError(errors.ErrorMessage("errors.invalid.bot.target", event)) + } + + g, err := c.GuildCreateID(event, *event.GuildID()) + if err != nil { + slog.Error("ナヌザヌ取埗に倱敗", "err", err, "command", event.SlashCommandInteractionData().CommandPath()) + return errors.NewError(err) + } + u, err := c.UserCreate(event, event.SlashCommandInteractionData().User("target")) + if err != nil { + slog.Error("ナヌザヌ取埗に倱敗", "err", err, "command", event.SlashCommandInteractionData().CommandPath()) + return errors.NewError(err) + } + var expired *time.Time + if duration, ok := event.SlashCommandInteractionData().OptInt("duration"); ok { + var d time.Duration + switch duration { + case 0: + d = time.Minute + case 1: + d = time.Hour + case 2: + d = time.Hour * 3 + case 3: + d = time.Hour * 6 + case 4: + d = time.Hour * 24 + case 5: + d = time.Hour * 24 * 3 + case 6: + d = time.Hour * 24 * 7 + } + expired = builtin.Or(d != 0, builtin.Ptr(time.Now().Add(d)), nil) + } + var w *ent.WordSuffix + if u.QueryWordSuffix().Where(wordsuffix.GuildID(g.ID)).ExistX(event) { + w = u.QueryWordSuffix().Where(wordsuffix.GuildID(g.ID)).OnlyX(event) + w.Update(). + SetSuffix(event.SlashCommandInteractionData().String("suffix")). + SetOwner(u). + SetRule(wordsuffix.Rule(event.SlashCommandInteractionData().String("rule"))). + SetNillableExpired(expired). + SaveX(event) + } else { + w = c.DB().WordSuffix. + Create(). + SetGuild(g). + SetSuffix(event.SlashCommandInteractionData().String("suffix")). + SetOwner(u). + SetRule(wordsuffix.Rule(event.SlashCommandInteractionData().String("rule"))). + SetNillableExpired(expired). + SaveX(event) + } + var durationString string + if expired != nil { + durationString = discord.FormattedTimestampMention(expired.Unix(), discord.TimestampStyleRelative) + } else { + durationString = translate.Message(event.Locale(), "components.message.suffix.duration.none") + } + if err := event.CreateMessage( + discord.NewMessageBuilder(). + SetContentf("%s\n%s", + translate.Message( + event.Locale(), + "components.message.suffix.set.message", + translate.WithTemplate(map[string]any{"User": discord.UserMention(u.ID), "Suffix": w.Suffix}), + ), + translate.Message( + event.Locale(), + "components.message.suffix.duration.message", + translate.WithTemplate(map[string]any{"Duration": durationString}), + ), + ). + BuildCreate(), + ); err != nil { + return errors.NewError(err) + } + + return nil + }, + }, + "/message/suffix/remove": generic.PCommandHandler{ + Permission: []generic.Permission{ + generic.PermissionString("message.suffix.remove"), + }, + DiscordPerm: discord.PermissionManageMessages, + CommandHandler: func(c *components.Components, event *events.ApplicationCommandInteractionCreate) errors.Error { + if u := event.SlashCommandInteractionData().User("target"); u.Bot || u.System { + return errors.NewError(errors.ErrorMessage("errors.invalid.bot.target", event)) + } + + g, err := c.GuildCreateID(event, *event.GuildID()) + if err != nil { + slog.Error("ナヌザヌ取埗に倱敗", "err", err, "command", event.SlashCommandInteractionData().CommandPath()) + return errors.NewError(err) + } + u, err := c.UserCreate(event, event.SlashCommandInteractionData().User("target")) + if err != nil { + slog.Error("ナヌザヌ取埗に倱敗", "err", err, "command", event.SlashCommandInteractionData().CommandPath()) + return errors.NewError(err) + } + + if !u.QueryWordSuffix().Where(wordsuffix.GuildID(g.ID)).ExistX(event) { + if err := event.CreateMessage( + discord.NewMessageBuilder(). + SetContent(translate.Message(event.Locale(), "components.message.suffix.remove.message.no_suffix", translate.WithTemplate(map[string]any{"User": discord.UserMention(u.ID)}))). + SetAllowedMentions(&discord.AllowedMentions{}). + SetFlags(discord.MessageFlagEphemeral). + BuildCreate(), + ); err != nil { + return errors.NewError(err) + } + return nil + } + + c.DB().WordSuffix.DeleteOneID(u.QueryWordSuffix().Where(wordsuffix.GuildID(g.ID)).FirstIDX(event)).ExecX(event) + if err := event.CreateMessage( + discord.NewMessageBuilder(). + SetContent(translate.Message(event.Locale(), "components.message.suffix.remove.message", translate.WithTemplate(map[string]any{"User": discord.UserMention(u.ID)}))). + BuildCreate(), + ); err != nil { + return errors.NewError(err) + } + + return nil + }, + }, + "/message/suffix/check": generic.PCommandHandler{ + Permission: []generic.Permission{ + generic.PermissionString("message.suffix.check"), + }, + DiscordPerm: discord.PermissionManageMessages, + CommandHandler: func(c *components.Components, event *events.ApplicationCommandInteractionCreate) errors.Error { + m, ok := event.SlashCommandInteractionData().OptMember("target") + if !ok { + m = *event.Member() + } + if m.User.Bot || m.User.System { + return errors.NewError(errors.ErrorMessage("errors.invalid.bot.target", event)) + } + + g, err := c.GuildCreateID(event, *event.GuildID()) + if err != nil { + slog.Error("ナヌザヌ取埗に倱敗", "err", err, "command", event.SlashCommandInteractionData().CommandPath()) + return errors.NewError(err) + } + u, err := c.UserCreate(event, m.User) + if err != nil { + slog.Error("ナヌザヌ取埗に倱敗", "err", err, "command", event.SlashCommandInteractionData().CommandPath()) + return errors.NewError(err) + } + + messageStr := translate.Message(event.Locale(), "components.message.suffix.check.message.none", + translate.WithTemplate(map[string]any{"User": discord.UserMention(u.ID)}), + ) + if u.QueryWordSuffix().Where( + wordsuffix.GuildID(g.ID), + ).ExistX(event) { + w := u.QueryWordSuffix().Where( + wordsuffix.GuildID(g.ID), + ).FirstX(event) + messageStr = translate.Message(event.Locale(), "components.message.suffix.check.message", + translate.WithTemplate( + map[string]any{ + "Duration": builtin.Or(w.Expired != nil, + discord.FormattedTimestampMention(builtin.NonNil(w.Expired).Unix(), discord.TimestampStyleRelative), + translate.Message(event.Locale(), "components.message.suffix.duration.none"), + ), + "User": discord.UserMention(u.ID), + "Suffix": w.Suffix, + "Rule": translate.Message(event.Locale(), "components.message.suffix.set.command.options.rule."+w.Rule.String()), + }, + ), + ) + } + if err := event.CreateMessage( + discord.NewMessageBuilder(). + SetContent(messageStr). + SetAllowedMentions(&discord.AllowedMentions{}). + BuildCreate(), + ); err != nil { + return errors.NewError(err) + } + return nil + }, + }, + "/message/pin/create": generic.PCommandHandler{ + Permission: []generic.Permission{ + generic.PermissionString("message.pin.create"), + }, + DiscordPerm: discord.PermissionManageMessages, + CommandHandler: func(c *components.Components, event *events.ApplicationCommandInteractionCreate) errors.Error { + if err := event.Modal( + discord.NewModalCreateBuilder(). + SetTitle(translate.Message(event.Locale(), "components.message.pin.create.modal.title")). + SetCustomID("message:pin_create_modal"). + SetContainerComponents( + discord.NewActionRow( + discord.TextInputComponent{ + CustomID: "content", + Style: discord.TextInputStyleParagraph, + Label: translate.Message(event.Locale(), "components.message.pin.create.modal.input.1.label"), + MaxLength: 1000, + Required: true, + }, + ), + ). + Build(), + ); err != nil { + return errors.NewError(err) + } + return nil + }, + }, + "/message/pin/delete": generic.PCommandHandler{ + Permission: []generic.Permission{ + generic.PermissionString("message.pin.delete"), + }, + DiscordPerm: discord.PermissionManageMessages, + CommandHandler: func(c *components.Components, event *events.ApplicationCommandInteractionCreate) errors.Error { + g, err := c.GuildCreateID(event, *event.GuildID()) + if err != nil { + return errors.NewError(err) + } + + if !g.QueryMessagePins().Where(messagepin.ChannelID(event.Channel().ID())).ExistX(event) { + return errors.NewError(errors.ErrorMessage("errors.unavailable.message.pin", event)) + } + if beforeID := g.QueryMessagePins().Where(messagepin.ChannelID(event.Channel().ID())).FirstX(event).BeforeID; beforeID != nil { + _ = event.Client().Rest().DeleteMessage(event.Channel().ID(), *beforeID) + } + + c.DB().MessagePin.Delete().Where(messagepin.ChannelID(event.Channel().ID())).ExecX(event) + + if err := event.CreateMessage( + discord.NewMessageBuilder(). + SetContent(translate.Message(event.Locale(), "components.message.pin.delete.message")). + SetFlags(discord.MessageFlagEphemeral). + BuildCreate(), + ); err != nil { + return errors.NewError(err) + } + + return nil + }, + }, + "/message/remind/set": generic.PCommandHandler{ + Permission: []generic.Permission{ + generic.PermissionString("message.remind.set"), + }, + DiscordPerm: discord.PermissionManageMessages, + CommandHandler: func(c *components.Components, event *events.ApplicationCommandInteractionCreate) errors.Error { + g, err := c.GuildCreateID(event, *event.GuildID()) + if err != nil { + return errors.NewError(err) + } + tm := time.Now().Add(time.Hour) + if timeStr, ok := event.SlashCommandInteractionData().OptString("time"); ok { + t, err := parse.TimeFuture(timeStr) + if err != nil { + return errors.NewError(errors.ErrorMessage("errors.invalid.time.format", event)) + } + if t.Before(time.Now()) { + return errors.NewError(errors.ErrorMessage("errors.invalid.time.before", event)) + } + tm = t + } + + if err := event.Modal( + discord.NewModalCreateBuilder(). + SetTitle(translate.Message(event.Locale(), "components.message.remind.add.modal.title")). + SetCustomID(fmt.Sprintf("message:remind_create_modal:%d", tm.Unix())). + SetContainerComponents( + discord.NewActionRow( + discord.TextInputComponent{ + CustomID: "content", + Style: discord.TextInputStyleParagraph, + Label: translate.Message(event.Locale(), "components.message.remind.add.modal.input.content.label"), + MinLength: builtin.Ptr(1), + MaxLength: 1000, + Required: true, + }, + ), + discord.NewActionRow( + discord.TextInputComponent{ + CustomID: "name", + Style: discord.TextInputStyleShort, + Label: translate.Message(event.Locale(), "components.message.remind.add.modal.input.name.label"), + MinLength: builtin.Ptr(1), + MaxLength: 64, + Required: true, + Value: fmt.Sprintf("%s#%d", + translate.Message(event.Locale(), "components.message.remind.add.modal.input.name.value"), + g.RemindCount+1, + ), + }, + ), + ). + Build(), + ); err != nil { + return errors.NewError(err) + } + return nil + }, + }, + "/message/remind/cancel": generic.PCommandHandler{ + Permission: []generic.Permission{ + generic.PermissionString("message.remind.cancel"), + }, + DiscordPerm: discord.PermissionManageMessages, + CommandHandler: func(c *components.Components, event *events.ApplicationCommandInteractionCreate) errors.Error { + count := c.DB().MessageRemind.Delete().Where( + messageremind.HasGuildWith(guild.ID(*event.GuildID())), + messageremind.NameContains(event.SlashCommandInteractionData().String("remind")), + ).ExecX(event) + if err := event.CreateMessage( + discord.NewMessageBuilder(). + SetContent(translate.Message(event.Locale(), "components.message.remind.cancel.message", + translate.WithTemplate(map[string]any{ + "Count": strconv.Itoa(count), + }), + )). + BuildCreate(), + ); err != nil { + return errors.NewError(err) + } + return nil + }, + }, + }, + + AutocompleteHandlers: map[string]generic.PermissionAutocompleteHandler{ + "/message/remind/cancel:remind": generic.PAutocompleteHandler{ + Permission: []generic.Permission{ + generic.PermissionString("message.remind.cancel"), + }, + DiscordPerm: discord.PermissionManageMessages, + AutocompleteHandler: func(c *components.Components, event *events.AutocompleteInteractionCreate) errors.Error { + reminds := c.DB().MessageRemind.Query().Where( + messageremind.HasGuildWith(guild.ID(*event.GuildID())), + messageremind.NameContains(event.Data.String("remind")), + ). + Limit(25). + AllX(event) + + choices := make([]discord.AutocompleteChoice, len(reminds)) + for i, mr := range reminds { + choices[i] = discord.AutocompleteChoiceString{ + Name: fmt.Sprintf("%s - %s", mr.Name, mr.Time.Local().Format("2006-01-02 15:04 MST")), + Value: mr.Name, + } + } + if err := event.AutocompleteResult(choices); err != nil { + return errors.NewError(err) + } + return nil + }, + }, + }, + + ModalHandlers: map[string]generic.ModalHandler{ + "message:pin_create_modal": func(component *components.Components, event *events.ModalSubmitInteractionCreate) errors.Error { + g, err := component.GuildCreateID(event, *event.GuildID()) + if err != nil { + return errors.NewError(err) + } + + // もし既にあったら抹消する + if g.QueryMessagePins().Where(messagepin.ChannelID(event.Channel().ID())).ExistX(event) { + if beforeID := g.QueryMessagePins().Where(messagepin.ChannelID(event.Channel().ID())).FirstX(event).BeforeID; beforeID != nil { + _ = event.Client().Rest().DeleteMessage(event.Channel().ID(), *beforeID) + } + + component.DB().MessagePin.Delete().Where(messagepin.ChannelID(event.Channel().ID())).ExecX(event) + } + + m := component.DB().MessagePin.Create(). + SetChannelID(event.Channel().ID()). + SetContent(event.Data.Text("content")). + SetGuild(g). + SaveX(event) + channel, err := event.Client().Rest().GetChannel(m.ChannelID) + if err != nil { + return errors.NewError(err) + } + + webhook, err := event.Client().WebhookManager().GetMessenger(channel) + if err != nil { + return errors.NewError(err) + } + message, err := webhook.SendWebhook( + discord.NewMessageBuilder(). + SetContent(m.Content). + SetEmbeds(m.Embeds...), + translate.Message(g.Locale, "components.message.pin.username"), + component.Config().Message.PinIconImage, + "", + ) + if err != nil { + return errors.NewError(err) + } + + m.Update().SetBeforeID(message.ID).SaveX(event) + + if err := event.CreateMessage( + discord.NewMessageBuilder(). + SetContent(translate.Message(event.Locale(), "components.message.pin.create.message")). + SetFlags(discord.MessageFlagEphemeral). + BuildCreate(), + ); err != nil { + return errors.NewError(err) + } + return nil + }, + "message:remind_create_modal": func(c *components.Components, event *events.ModalSubmitInteractionCreate) errors.Error { + g, err := c.GuildCreateID(event, *event.GuildID()) + if err != nil { + return errors.NewError(err) + } + args := strings.Split(event.Data.CustomID, ":") + tm := time.Unix(builtin.Must(strconv.ParseInt(args[2], 10, 64)), 0) + if time.Now().After(tm) { + return errors.NewError(errors.ErrorMessage("errors.invalid.time.before", event)) + } + c.DB().MessageRemind.Create(). + SetGuild(g). + SetTime(tm). + SetContent(event.Data.Text("content")). + SetChannelID(event.Channel().ID()). + SetAuthorID(event.Member().User.ID). + SetName(event.Data.Text("name")). + ExecX(event) + g.Update().AddRemindCount(1).ExecX(event) + + if err := event.CreateMessage( + discord.NewMessageBuilder(). + SetContent(translate.Message(event.Locale(), "components.message.remind.add.message", + translate.WithTemplate(map[string]any{ + "Time": discord.FormattedTimestampMention(tm.Unix(), discord.TimestampStyleLongDateTime), + }), + )). + BuildCreate(), + ); err != nil { + return errors.NewError(err) + } + return nil + }, + }, + + Schedulers: []components.Scheduler{ + { + Duration: time.Minute, + Worker: func(c *components.Components, client bot.Client) error { + reminds := c.DB().MessageRemind.Query(). + Where( + messageremind.TimeLT(time.Now()), + ). + AllX(context.Background()) + for _, remind := range reminds { + if _, err := client.Rest().CreateMessage(remind.ChannelID, + discord.NewMessageBuilder(). + SetContent(remind.Content). + BuildCreate(), + ); err != nil { + return err + } + } + + c.DB().MessageRemind.Delete(). + Where( + messageremind.TimeLT(time.Now()), + ). + ExecX(context.Background()) + return nil + }, + }, + }, + + EventHandler: func(c *components.Components, e bot.Event) errors.Error { + switch e := e.(type) { + case *events.GuildMessageCreate: + + err, shouldContinue := doTextCommand(e, e) + if err != nil { + return errors.NewError(err) + } + if !shouldContinue { + return nil + } + + // 語尟の凊理 + if err := messageSuffixMessageCreateHandler(e, c); err != nil { + return err + } + + if ok := c.GetLock("message_pin").Mutex(e.ChannelID).TryLock(); !ok { + return nil + } + defer c.GetLock("message_pin").Mutex(e.ChannelID).Unlock() + + // ピン留めメッセヌゞの凊理 + if err := func(event *events.GuildMessageCreate, c *components.Components) errors.Error { + var channel discord.Channel + channel, ok := event.Channel() + if !ok { + channel, err = event.Client().Rest().GetChannel(event.ChannelID) + if err != nil { + return errors.NewError(err) + } + } + + webhook, err := event.Client().WebhookManager().GetMessenger(channel) + if err != nil { + err1 := rest.Error{} + if errors.As(err, &err1) && err1.Response.StatusCode == http.StatusForbidden { + return errors.NewError(event.Client().Rest().LeaveGuild(event.GuildID)) + } + return errors.NewError(err) + } + if event.Message.WebhookID != nil && webhook.Webhook().ID() == *event.Message.WebhookID { + return nil + } + + g, err := c.GuildCreateID(event, event.GuildID) + if err != nil { + return errors.NewError(err) + } + if !g.QueryMessagePins().Where(messagepin.ChannelID(event.ChannelID)).ExistX(event) { + return nil + } + m := g.QueryMessagePins().Where(messagepin.ChannelID(event.ChannelID)).FirstX(event) + + if m.RateLimit.CheckLimit() { + if m.BeforeID != nil { + if err := event.Client().Rest().DeleteMessage(event.ChannelID, *m.BeforeID); err != nil { + slog.Error("削陀に倱敗", "err", err) + m.BeforeID = nil + } + } + + var channel discord.Channel + channel, ok := event.Channel() + if !ok { + channel, err = event.Client().Rest().GetChannel(event.ChannelID) + if err != nil { + return errors.NewError(err) + } + } + webhook, err := event.Client().WebhookManager().GetMessenger(channel) + if err != nil { + return errors.NewError(err) + } + + message, err := webhook.SendWebhook( + discord.NewMessageBuilder(). + SetContent(m.Content). + SetEmbeds(m.Embeds...), + translate.Message(g.Locale, "components.message.pin.username"), + c.Config().Message.PinIconImage, + "", + ) + if err != nil { + return errors.NewError(err) + } + + m.Update().SetBeforeID(message.ID).SetRateLimit(m.RateLimit).ExecX(event) + slog.Info("ピン留め曎新", "cid", event.ChannelID, "mid", event.MessageID) + } else { + m.Update().SetRateLimit(m.RateLimit).ExecX(event) + } + return nil + }(e, c); err != nil { + return err + } + case *events.GuildMessageDelete: + if ok := c.GetLock("message_pin").Mutex(e.ChannelID).TryLock(); !ok { + return nil + } + defer c.GetLock("message_pin").Mutex(e.ChannelID).Unlock() + if e.Message.WebhookID == nil { + return nil + } + + var channel discord.Channel + var err error + channel, ok := e.Channel() + if !ok { + channel, err = e.Client().Rest().GetChannel(e.ChannelID) + if err != nil { + return errors.NewError(err) + } + } + + webhook, err := e.Client().WebhookManager().GetMessenger(channel) + if err != nil { + return errors.NewError(err) + } + if e.Message.WebhookID != nil && webhook.Webhook().ID() != *e.Message.WebhookID { + return nil + } + + g, err := c.GuildCreateID(e, e.GuildID) + if err != nil { + return errors.NewError(err) + } + if !g.QueryMessagePins().Where(messagepin.ChannelID(e.ChannelID)).ExistX(e) { + return nil + } + m := g.QueryMessagePins().Where(messagepin.ChannelID(e.ChannelID)).FirstX(e) + + if m.BeforeID != nil && *m.BeforeID == e.MessageID { + slog.Info("ピン留め削陀", "cid", e.ChannelID, "mid", e.MessageID) + c.DB().MessagePin.DeleteOneID(m.ID).ExecX(e) + } + } + return nil + }, + }).SetComponent(c) +} + +func messageSuffixMessageCreateHandler(e *events.GuildMessageCreate, c *components.Components) errors.Error { + slog.Debug("メッセヌゞ䜜成") + if e.Message.Content == "" { + return nil + } + if e.Message.Type.System() || e.Message.Author.System || e.Message.Author.Bot { + return nil + } + if e.Message.Type != discord.MessageTypeDefault && e.Message.Type != discord.MessageTypeReply { + return nil + } + + u, err := c.UserCreate(e, e.Message.Author) + if err != nil { + slog.Error("メッセヌゞ著者取埗に倱敗", "err", err, "uid", e.Message.Author.ID) + return errors.NewError(err) + } + + var w *ent.WordSuffix + + if u.QueryWordSuffix().Where(wordsuffix.GuildID(e.GuildID)).ExistX(e) { + // Guild + w = u.QueryWordSuffix().Where(wordsuffix.GuildID(e.GuildID)).FirstX(e) + } else { + // Global + if !u.QueryWordSuffix().Where(wordsuffix.GuildIDIsNil()).ExistX(e) { + slog.Debug("語尟が存圚したせん") + return nil + } + w = u.QueryWordSuffix().Where(wordsuffix.GuildIDIsNil()).FirstX(e) + } + if w.Expired != nil && time.Now().Compare(*w.Expired) == 1 { + c.DB().WordSuffix.DeleteOneID(w.ID).ExecX(e) + return nil + } + switch w.Rule { + case wordsuffix.RuleDelete: + if strings.HasSuffix(e.Message.Content, w.Suffix) { + return nil + } + if err := e.Client().Rest().DeleteMessage(e.ChannelID, e.MessageID); err != nil { + slog.Error("メッセヌゞを削陀できたせん", "err", err) + return errors.NewError(err) + } + case wordsuffix.RuleWarn: + if strings.HasSuffix(e.Message.Content, w.Suffix) { + return nil + } + if _, err := e.Client().Rest().CreateMessage(e.ChannelID, + discord.NewMessageBuilder(). + SetContentf("%s\n%s", + translate.Message(u.Locale, "components.message.suffix.warn.message.1"), + translate.Message(u.Locale, "components.message.suffix.warn.message.2", translate.WithTemplate(map[string]any{"Suffix": w.Suffix})), + ). + SetMessageReferenceByID(e.MessageID). + BuildCreate(), + ); err != nil { + slog.Error("メッセヌゞを䜜成できたせん", "err", err) + return errors.NewError(err) + } + case wordsuffix.RuleWebhook: + content := e.Message.Content + if !strings.HasSuffix(e.Message.Content, w.Suffix) { + content += w.Suffix + } + if err := e.Client().Rest().DeleteMessage(e.ChannelID, e.MessageID); err != nil { + return errors.NewError(err) + } + member, err := e.Client().Rest().GetMember(e.GuildID, e.Message.Author.ID) + if err != nil { + return errors.NewError(err) + } + mentionUsers := make([]snowflake.ID, len(e.Message.Mentions)) + for i, u := range e.Message.Mentions { + mentionUsers[i] = u.ID + } + repliedUser := false + if e.Message.MessageReference != nil && e.Message.MessageReference.ChannelID != nil && e.Message.MessageReference.MessageID != nil { + replyMessage, err := e.Client().Rest().GetMessage(*e.Message.MessageReference.ChannelID, *e.Message.MessageReference.MessageID) + if err == nil { + repliedUser = slices.Index(mentionUsers, replyMessage.Author.ID) != -1 + } + } + + var channel discord.Channel + channel, ok := e.Channel() + if !ok { + channel, err = e.Client().Rest().GetChannel(e.ChannelID) + if err != nil { + return errors.NewError(err) + } + } + + webhook, err := e.Client().WebhookManager().GetMessenger(channel) + if err != nil { + return errors.NewError(err) + } + + if _, err := webhook.SendWebhook( + discord.NewMessageBuilder(). + SetContent(content). + SetAllowedMentions( + &discord.AllowedMentions{ + Users: mentionUsers, + Roles: e.Message.MentionRoles, + RepliedUser: repliedUser, + }, + ), + member.EffectiveName(), + e.Message.Author.EffectiveAvatarURL(), + "", + ); err != nil { + return errors.NewError(err) + } + } + return nil +} diff --git a/bot/commands/message/text_command.go b/bot/commands/message/text_command.go new file mode 100644 index 00000000..edcb0ef8 --- /dev/null +++ b/bot/commands/message/text_command.go @@ -0,0 +1,59 @@ +package message + +import ( + "context" + "github.com/disgoorg/disgo/discord" + "github.com/disgoorg/disgo/events" + "math/rand/v2" + "regexp" + "strconv" + "strings" +) + +func doTextCommand(ctx context.Context, event *events.GuildMessageCreate) (err error, shouldContinue bool) { + c, ok := strings.CutPrefix(event.Message.Content, discord.UserMention(event.Client().ApplicationID())) + if !ok { + return nil, true + } + content := strings.Split(strings.TrimSpace(c), " ") + + switch { + case diceRollRegex.MatchString(content[0]): + subMatch := diceRollRegex.FindStringSubmatch(content[0]) + diceCount, err := strconv.Atoi(subMatch[1]) + if err != nil || diceCount < 1 || diceCount > 1000 { + return nil, true + } + diceSize, err := strconv.Atoi(subMatch[2]) + if err != nil || diceSize < 1 || diceSize > 1000 { + return nil, true + } + content := "Dice Roll: " + sum := 0 + for i := 0; i < diceCount; i++ { + roll := diceRoll(diceSize) + sum += roll + content += strconv.Itoa(roll) + " " + } + + content += "\nSum: " + strconv.Itoa(sum) + + _, err = event.Client().Rest().CreateMessage(event.ChannelID, discord.NewMessageBuilder(). + SetContent(content). + SetMessageReferenceByID(event.Message.ID). + BuildCreate(), + ) + if err != nil { + return err, false + } + } + return nil, true +} + +func diceRoll(size int) int { + return rand.N(size) + 1 +} + +var ( + diceRollRegex = regexp.MustCompile(`^(\d+)[d](\d+)$`) +) diff --git a/bot/commands/message_other.go b/bot/commands/message_other.go deleted file mode 100644 index 9004f90b..00000000 --- a/bot/commands/message_other.go +++ /dev/null @@ -1,90 +0,0 @@ -package commands - -import ( - "fmt" - "regexp" - "strings" - - "github.com/disgoorg/snowflake/v2" - "github.com/sabafly/disgo/discord" - "github.com/sabafly/disgo/events" - "github.com/sabafly/gobot/bot/client" - botlib "github.com/sabafly/sabafly-lib/v2/bot" - "github.com/sabafly/sabafly-lib/v2/handler" - "github.com/sabafly/sabafly-lib/v2/translate" -) - -func MessageOther(b *botlib.Bot[*client.Client]) handler.Command { - return handler.Command{ - Create: discord.MessageCommandCreate{ - Name: "message other", - NameLocalizations: translate.MessageMap("message_other_command_name", false), - DMPermission: &b.Config.DMPermission, - }, - CommandHandlers: map[string]handler.CommandHandler{ - "": messageOtherHandler(b), - }, - } -} - -func messageOtherHandler(b *botlib.Bot[*client.Client]) handler.CommandHandler { - return func(event *events.ApplicationCommandInteractionCreate) error { - result_message := discord.NewMessageCreateBuilder() - message := event.MessageCommandInteractionData().TargetMessage() - switch { - case rolePanelConvertCheck(b, message): - result_message.AddContainerComponents( - discord.NewActionRow( - discord.ButtonComponent{ - Style: discord.ButtonStyleSuccess, - Label: translate.Message(event.Locale(), "message_other_panel_convert_button"), - CustomID: fmt.Sprintf("handler:rp-v2:convert:%s:%s", event.Channel().ID(), message.ID), - }, - ), - ) - default: - embed := discord.NewEmbedBuilder() - embed.SetTitle(translate.Message(event.Locale(), "message_other_command_not_eligible_title")) - embed.SetDescription(translate.Message(event.Locale(), "message_other_command_not_eligible_description")) - embed.Embed = botlib.SetEmbedProperties(embed.Embed) - result_message.AddEmbeds(embed.Build()) - } - result_message.SetFlags(discord.MessageFlagEphemeral) - if err := event.CreateMessage(result_message.Build()); err != nil { - return botlib.ReturnErr(event, err) - } - return nil - } -} - -func rolePanelConvertCheck(b *botlib.Bot[*client.Client], message discord.Message) bool { - var wid snowflake.ID - if message.WebhookID != nil { - wh, err := b.Client.Rest().GetWebhook(*message.WebhookID) - if err != nil { - b.Logger.Error(err) - } else if wh.Type() == discord.WebhookTypeIncoming && wh.(discord.IncomingWebhook).User.ID == 716496407212589087 { - wid = message.Author.ID - } - } - switch message.Author.ID { - case 895912135039803402, 1138119538190340146, 1137367652482957313, 971523089550671953 /*圹職パネルv3*/, 917780792032251904 /*圹職ボット*/, 669817785932578826 /*陜菜*/, 716496407212589087, wid /*RT*/, 718760319207473152 /*SevenBot*/, 832614051514417202 /*Glow-bot*/ : - if len(message.Embeds) < 1 { - return false - } - lines := strings.Split(message.Embeds[0].Description, "\r") - valid_lines := 0 - for _, v := range lines { - if !role_regexp.MatchString(v) { - continue - } - valid_lines++ - } - return valid_lines > 0 - default: - return false - } -} - -var role_regexp = regexp.MustCompile("<@&([0-9]{18,20})>") -var role_id_regexp = regexp.MustCompile("[0-9]{18,20}") diff --git a/bot/commands/minecraft.go b/bot/commands/minecraft.go deleted file mode 100644 index 3e0c9d8b..00000000 --- a/bot/commands/minecraft.go +++ /dev/null @@ -1,393 +0,0 @@ -package commands - -import ( - "bytes" - "encoding/base64" - "fmt" - "regexp" - "strings" - "time" - - "github.com/disgoorg/json" - "github.com/go-redis/redis/v8" - "github.com/google/uuid" - "github.com/sabafly/disgo/discord" - "github.com/sabafly/disgo/events" - "github.com/sabafly/gobot/bot/client" - "github.com/sabafly/gobot/bot/db" - botlib "github.com/sabafly/sabafly-lib/v2/bot" - "github.com/sabafly/sabafly-lib/v2/handler" - "github.com/sabafly/sabafly-lib/v2/translate" -) - -func Minecraft(b *botlib.Bot[*client.Client]) handler.Command { - return handler.Command{ - Create: discord.SlashCommandCreate{ - Name: "minecraft", - Description: "minecraft", - DMPermission: &b.Config.DMPermission, - Options: []discord.ApplicationCommandOption{ - discord.ApplicationCommandOptionSubCommandGroup{ - Name: "status-panel", - Description: "status-panel", - Options: []discord.ApplicationCommandOptionSubCommand{ - { - Name: "create", - Description: "create status panel", - DescriptionLocalizations: translate.MessageMap("minecraft_status_panel_create_command_description", false), - Options: []discord.ApplicationCommandOption{ - discord.ApplicationCommandOptionString{ - Name: "server-name", - Description: "name of server", - DescriptionLocalizations: translate.MessageMap("minecraft_status_panel_create_command_server_name_option_description", false), - Required: true, - MaxLength: json.Ptr(100), - }, - discord.ApplicationCommandOptionString{ - Name: "address", - Description: "address of server", - DescriptionLocalizations: translate.MessageMap("minecraft_status_panel_create_command_address_option_description", false), - Required: true, - MaxLength: json.Ptr(32), - }, - discord.ApplicationCommandOptionString{ - Name: "edition", - Description: "edition of server", - DescriptionLocalizations: translate.MessageMap("minecraft_status_panel_create_command_hide_address_option_description", false), - Required: true, - Choices: []discord.ApplicationCommandOptionChoiceString{ - { - Name: "java", - Value: "java", - }, - { - Name: "bedrock", - Value: "bedrock", - }, - }, - }, - discord.ApplicationCommandOptionBool{ - Name: "hide-address", - Description: "hide address", - DescriptionLocalizations: translate.MessageMap("minecraft_status_panel_create_command_hide_address_option_description", false), - }, - }, - }, - { - Name: "delete", - Description: "delete panel", - DescriptionLocalizations: translate.MessageMap("minecraft_status_panel_delete_command_description", false), - Options: []discord.ApplicationCommandOption{ - discord.ApplicationCommandOptionString{ - Name: "panel", - Description: "target panel", - DescriptionLocalizations: translate.MessageMap("minecraft_status_panel_delete_command_panel_option", false), - Autocomplete: true, - Required: true, - }, - }, - }, - { - Name: "list", - Description: "show list of panels", - DescriptionLocalizations: translate.MessageMap("minecraft_status_panel_list_command_description", false), - }, - }, - }, - }, - }, - AutocompleteHandlers: map[string]handler.AutocompleteHandler{ - "status-panel/delete": minecraftStatusPanelAutocomplete(b), - }, - AutocompleteCheck: func(ctx *events.AutocompleteInteractionCreate) bool { - if b.CheckDev(ctx.User().ID) { - return true - } - if ctx.Member() != nil && ctx.Member().Permissions.Has(discord.PermissionManageGuild) { - return true - } - gd, err := b.Self.DB.GuildData().Get(*ctx.GuildID()) - if err == nil { - if gd.UserPermissions[ctx.User().ID].Has("mc.panel.manage") { - return true - } - for _, id := range ctx.Member().RoleIDs { - if gd.RolePermissions[id].Has("mc.panel.manage") { - return true - } - } - } - _ = ctx.Result(nil) - return false - }, - Checks: map[string]handler.Check[*events.ApplicationCommandInteractionCreate]{ - "status-panel/create": b.Self.CheckCommandPermission(b, "mc.panel.manage", discord.PermissionManageGuild), - "status-panel/delete": b.Self.CheckCommandPermission(b, "mc.panel.manage", discord.PermissionManageGuild), - "status-panel/list": b.Self.CheckCommandPermission(b, "mc.panel.manage", discord.PermissionManageGuild), - }, - CommandHandlers: map[string]handler.CommandHandler{ - "status-panel/create": minecraftStatusPanelCreateCommandHandler(b), - "status-panel/delete": minecraftStatusPanelDeleteCommandHandler(b), - "status-panel/list": minecraftStatusPanelListCommandHandler(b), - }, - } -} - -var numIp = regexp.MustCompile(`[\d\D]{1,3}\.[\d\D]{1,3}\.[\d\D]{1,3}\.[\d\D]{1,3}`) -var invalidAddress = regexp.MustCompile(`[^\w\d\.\-_]`) - -func minecraftStatusPanelCreateCommandHandler(b *botlib.Bot[*client.Client]) handler.CommandHandler { - return func(event *events.ApplicationCommandInteractionCreate) error { - b.Self.GuildDataLock(*event.GuildID()).Lock() - defer b.Self.GuildDataLock(*event.GuildID()).Unlock() - gd, err := b.Self.DB.GuildData().Get(*event.GuildID()) - if err != nil { - return botlib.ReturnErr(event, err) - } - if len(gd.MCStatusPanel) >= gd.MCStatusPanelMax { - return botlib.ReturnErrMessage(event, "error_guild_max_count_limit_has_reached") - } - var port uint16 - var s_type db.MinecraftServerType - switch event.SlashCommandInteractionData().String("edition") { - case "java": - port = 25565 - s_type = db.MinecraftServerTypeJava - case "bedrock": - port = 19132 - s_type = db.MinecraftServerTypeBedrock - } - address := event.SlashCommandInteractionData().String("address") - if numIp.MatchString(address) || invalidAddress.MatchString(address) { - return botlib.ReturnErrMessage(event, "error_invalid_command_argument") - } - hash, err := db.Address2Hash(address, int(port)) - if err != nil { - return botlib.ReturnErr(event, err) - } - server, err := b.Self.DB.MinecraftServer().Get(hash) - if err != nil { - if err != redis.Nil { - return botlib.ReturnErr(event, err) - } - server = db.NewMinecraftServer(hash, address, port, s_type) - err := b.Self.DB.MinecraftServer().Set(server.Hash, server) - if err != nil { - return botlib.ReturnErr(event, err) - } - } - resp := server.LastResponse - if resp == nil || server.LastResponseTime.Before(time.Now().Add(-5*time.Minute)) { - resp, err = server.Fetch() - if err != nil { - return botlib.ReturnErrMessage(event, "error_failed_to_connect_server", botlib.WithTranslateData(map[string]any{"Err": err})) - } - } - if err := b.Self.DB.MinecraftServer().Set(server.Hash, server); err != nil { - return botlib.ReturnErr(event, err) - } - - name := event.SlashCommandInteractionData().String("server-name") - show_address := !event.SlashCommandInteractionData().Bool("hide-address") - mcp := db.NewMinecraftStatusPanel(name, *event.GuildID(), event.Channel().ID(), 0, hash, show_address) - message := discord.NewMessageCreateBuilder() - message.AddEmbeds(mcp.Embed(address, resp)) - thumb := strings.ReplaceAll(resp.Favicon, "data:image/png;base64,", "") - res, _ := base64.RawStdEncoding.DecodeString(thumb) - if resp.Favicon != "" { - message.AddFiles(discord.NewFile("favicon.png", "", bytes.NewBuffer(res))) - } - message.AddContainerComponents(mcp.Components()...) - mes, err := event.Client().Rest().CreateMessage(mcp.ChannelID, message.Build()) - if err != nil { - return botlib.ReturnErr(event, err) - } - mcp.MessageID = mes.ID - if err := b.Self.DB.MinecraftStatusPanel().Set(mcp.ID, mcp); err != nil { - return botlib.ReturnErr(event, err) - } - - gd.MCStatusPanelName[mcp.Name]++ - gd.MCStatusPanel[mcp.ID] = mcp.Name - - if err := b.Self.DB.GuildData().Set(gd.ID, gd); err != nil { - return botlib.ReturnErr(event, err) - } - embed := discord.NewEmbedBuilder() - embed.SetDescription(translate.Message(event.Locale(), "minecraft_status_panel_created")) - embed.Embed = botlib.SetEmbedProperties(embed.Embed) - result_message := discord.NewMessageCreateBuilder() - result_message.AddEmbeds(embed.Build()) - if err := event.CreateMessage(result_message.SetFlags(discord.MessageFlagEphemeral).Build()); err != nil { - return err - } - return nil - } -} - -func minecraftStatusPanelDeleteCommandHandler(b *botlib.Bot[*client.Client]) handler.CommandHandler { - return func(event *events.ApplicationCommandInteractionCreate) error { - panel_id, err := uuid.Parse(event.SlashCommandInteractionData().String("panel")) - if err != nil { - return botlib.ReturnErrMessage(event, "error_invalid_id") - } - b.Self.GuildDataLock(*event.GuildID()).Lock() - defer b.Self.GuildDataLock(*event.GuildID()).Unlock() - gd, err := b.Self.DB.GuildData().Get(*event.GuildID()) - if err != nil { - return botlib.ReturnErr(event, err) - } - panel, err := b.Self.DB.MinecraftStatusPanel().Get(panel_id) - if err != nil { - return botlib.ReturnErr(event, err) - } - server, err := b.Self.DB.MinecraftServer().Get(panel.Hash) - if err != nil { - return botlib.ReturnErr(event, err) - } - gd.MCStatusPanelName[panel.Name]-- - delete(gd.MCStatusPanel, panel.ID) - if err := b.Self.DB.GuildData().Set(gd.ID, gd); err != nil { - return botlib.ReturnErr(event, err) - } - _ = event.Client().Rest().DeleteMessage(panel.ChannelID, panel.MessageID) - if err := b.Self.DB.MinecraftStatusPanel().Del(panel.ID); err != nil { - return botlib.ReturnErr(event, err) - } - message := discord.NewMessageCreateBuilder() - message.SetFlags(discord.MessageFlagEphemeral) - embed := discord.NewEmbedBuilder() - embed.SetTitlef("Successfully deleted") - embed.SetDescriptionf("```\rName: %s\rAddress: %s:%d ```", panel.Name, server.Address, server.Port) - embed.Embed = botlib.SetEmbedProperties(embed.Embed) - message.AddEmbeds(embed.Build()) - if err := event.CreateMessage(message.Build()); err != nil { - return err - } - return nil - } -} - -func minecraftStatusPanelListCommandHandler(b *botlib.Bot[*client.Client]) handler.CommandHandler { - return func(event *events.ApplicationCommandInteractionCreate) error { - b.Self.GuildDataLock(*event.GuildID()).Lock() - defer b.Self.GuildDataLock(*event.GuildID()).Unlock() - gd, err := b.Self.DB.GuildData().Get(*event.GuildID()) - if err != nil { - return err - } - var res string - event.Client().Logger().Debug(gd.MCStatusPanel) - for k := range gd.MCStatusPanel { - panel, err := b.Self.DB.MinecraftStatusPanel().Get(k) - if err != nil { - continue - } - server, err := b.Self.DB.MinecraftServer().Get(panel.Hash) - if err != nil { - continue - } - res += fmt.Sprintf("- `%s` `%s:%d` %s\r", panel.Name, server.Address, server.Port, discord.MessageURL(panel.GuildID, panel.ChannelID, panel.MessageID)) - } - res = fmt.Sprintf("## There are (%d/%d) panels\r%s", len(gd.MCStatusPanel), gd.MCStatusPanelMax, res) - message := discord.NewMessageCreateBuilder().SetContent(res) - if err := event.CreateMessage(message.Build()); err != nil { - return err - } - return nil - } -} - -func minecraftStatusPanelAutocomplete(b *botlib.Bot[*client.Client]) handler.AutocompleteHandler { - return func(event *events.AutocompleteInteractionCreate) error { - if !event.AutocompleteInteraction.Data.Options["panel"].Focused { - _ = event.Result(nil) - return nil - } - b.Self.GuildDataLock(*event.GuildID()).Lock() - defer b.Self.GuildDataLock(*event.GuildID()).Unlock() - gd, err := b.Self.DB.GuildData().Get(*event.GuildID()) - if err != nil { - return err - } - var choices []discord.AutocompleteChoice - for u, v := range gd.MCStatusPanel { - if !strings.HasPrefix(v, event.AutocompleteInteraction.Data.String("panel")) { - continue - } - panel, err := b.Self.DB.MinecraftStatusPanel().Get(u) - if err != nil { - continue - } - server, err := b.Self.DB.MinecraftServer().Get(panel.Hash) - if err != nil { - continue - } - name := panel.Name - if gd.MCStatusPanelName[v] > 1 { - name += fmt.Sprintf(" (%s:%d)", server.Address, server.Port) - } - choices = append(choices, discord.AutocompleteChoiceString{ - Name: name, - Value: panel.ID.String(), - }) - } - if err := event.Result(choices); err != nil { - return err - } - return nil - } -} - -func MinecraftComponent(b *botlib.Bot[*client.Client]) handler.Component { - return handler.Component{ - Name: "minecraft", - Handler: map[string]handler.ComponentHandler{ - "status-refresh": minecraftComponentStatusRefreshHandler(b), - }, - } -} - -func minecraftComponentStatusRefreshHandler(b *botlib.Bot[*client.Client]) handler.ComponentHandler { - return func(event *events.ComponentInteractionCreate) error { - args := strings.Split(event.ButtonInteractionData().CustomID(), ":") - panel_id, err := uuid.Parse(args[3]) - if err != nil { - return botlib.ReturnErr(event, err, botlib.WithEphemeral(true)) - } - panel, err := b.Self.DB.MinecraftStatusPanel().Get(panel_id) - if err != nil { - return botlib.ReturnErr(event, err, botlib.WithEphemeral(true)) - } - server, err := b.Self.DB.MinecraftServer().Get(panel.Hash) - if err != nil { - return botlib.ReturnErr(event, err, botlib.WithEphemeral(true)) - } - resp := server.LastResponse - if resp == nil || server.LastResponseTime.Before(time.Now().Add(-5*time.Minute)) { - resp, err = server.Fetch() - if err != nil { - return botlib.ReturnErrMessage(event, "error_failed_to_connect_server", botlib.WithTranslateData(map[string]any{"Err": err}), botlib.WithEphemeral(true)) - } - } - if err := b.Self.DB.MinecraftServer().Set(server.Hash, server); err != nil { - return botlib.ReturnErr(event, err) - } - message := discord.NewMessageUpdateBuilder() - message.AddEmbeds(panel.Embed(server.Address, resp)) - thumb := strings.ReplaceAll(resp.Favicon, "data:image/png;base64,", "") - res, _ := base64.RawStdEncoding.DecodeString(thumb) - if resp.Favicon != "" { - message.AddFiles(discord.NewFile("favicon.png", "", bytes.NewBuffer(res))) - } - message.AddContainerComponents(panel.Components()...) - if _, err := event.Client().Rest().UpdateMessage(panel.ChannelID, panel.MessageID, message.Build()); err != nil { - return botlib.ReturnErr(event, err, botlib.WithEphemeral(true)) - } - - if err := event.DeferUpdateMessage(); err != nil { - return err - } - return nil - } -} diff --git a/bot/commands/permission.go b/bot/commands/permission.go deleted file mode 100644 index 79aff730..00000000 --- a/bot/commands/permission.go +++ /dev/null @@ -1,218 +0,0 @@ -package commands - -import ( - "github.com/disgoorg/json" - "github.com/sabafly/disgo/discord" - "github.com/sabafly/disgo/events" - "github.com/sabafly/gobot/bot/client" - botlib "github.com/sabafly/sabafly-lib/v2/bot" - "github.com/sabafly/sabafly-lib/v2/handler" - "github.com/sabafly/sabafly-lib/v2/permissions" - "github.com/sabafly/sabafly-lib/v2/translate" -) - -func Permission(b *botlib.Bot[*client.Client]) handler.Command { - return handler.Command{ - Create: discord.SlashCommandCreate{ - Name: "permission", - Description: "permission", - Options: []discord.ApplicationCommandOption{ - discord.ApplicationCommandOptionSubCommand{ - Name: "add", - Description: "add permission to target", - DescriptionLocalizations: translate.MessageMap("permission_add_command_description", false), - Options: []discord.ApplicationCommandOption{ - discord.ApplicationCommandOptionMentionable{ - Name: "target", - Description: "target to add permission", - DescriptionLocalizations: translate.MessageMap("permission_add_command_target_option_description", false), - Required: true, - }, - discord.ApplicationCommandOptionString{ - Name: "permission", - Description: "permission string", - DescriptionLocalizations: translate.MessageMap("permission_add_command_permission_option_description", false), - Required: true, - Autocomplete: true, - MaxLength: json.Ptr(32), - }, - }, - }, - discord.ApplicationCommandOptionSubCommand{ - Name: "remove", - Description: "remove permission to target", - DescriptionLocalizations: translate.MessageMap("permission_remove_command_description", false), - Options: []discord.ApplicationCommandOption{ - discord.ApplicationCommandOptionMentionable{ - Name: "target", - Description: "target to add permission", - DescriptionLocalizations: translate.MessageMap("permission_remove_command_target_option", false), - Required: true, - }, - discord.ApplicationCommandOptionString{ - Name: "permission", - Description: "permission string", - DescriptionLocalizations: translate.MessageMap("permission_remove_command_permission_option", false), - Required: true, - Autocomplete: true, - MaxLength: json.Ptr(32), - }, - }, - }, - discord.ApplicationCommandOptionSubCommand{ - Name: "list", - Description: "show list os target permission", - DescriptionLocalizations: translate.MessageMap("permission_list_command_description", false), - Options: []discord.ApplicationCommandOption{ - discord.ApplicationCommandOptionMentionable{ - Name: "target", - Description: "target to show permissions", - DescriptionLocalizations: translate.MessageMap("permission_list_command_target_option", false), - Required: true, - }, - }, - }, - }, - DMPermission: &b.Config.DMPermission, - }, - Checks: map[string]handler.Check[*events.ApplicationCommandInteractionCreate]{ - "add": b.Self.CheckCommandPermission(b, "guild.permissions.manage", discord.PermissionManageGuild), - "remove": b.Self.CheckCommandPermission(b, "guild.permissions.manage", discord.PermissionManageGuild), - "list": b.Self.CheckCommandPermission(b, "guild.permissions.manage", discord.PermissionManageGuild), - }, - CommandHandlers: map[string]handler.CommandHandler{ - "add": permissionAddCommandHandler(b), - "remove": permissionRemoveCommandHandler(b), - "list": permissionListCommandHandler(b), - }, - } -} - -func permissionAddCommandHandler(b *botlib.Bot[*client.Client]) handler.CommandHandler { - return func(event *events.ApplicationCommandInteractionCreate) error { - b.Self.GuildDataLock(*event.GuildID()).Lock() - defer b.Self.GuildDataLock(*event.GuildID()).Unlock() - gd, err := b.Self.DB.GuildData().Get(*event.GuildID()) - if err != nil { - return botlib.ReturnErr(event, err) - } - perm := event.SlashCommandInteractionData().String("permission") - var mention string - if user, ok := event.SlashCommandInteractionData().OptUser("target"); ok { - if user.Bot || user.System { - return botlib.ReturnErrMessage(event, "error_is_bot") - } - if gd.UserPermissions[user.ID] == nil { - gd.UserPermissions[user.ID] = permissions.New() - } - gd.UserPermissions[user.ID].Add(perm) - mention = discord.UserMention(user.ID) - } else if role, ok := event.SlashCommandInteractionData().OptRole("target"); ok { - if role.Managed { - return botlib.ReturnErrMessage(event, "error_invalid_role") - } - if gd.RolePermissions[role.ID] == nil { - gd.RolePermissions[role.ID] = permissions.New() - } - gd.RolePermissions[role.ID].Add(perm) - mention = discord.RoleMention(role.ID) - } else { - return botlib.ReturnErrMessage(event, "error_invalid_command_argument") - } - if err := b.Self.DB.GuildData().Set(gd.ID, gd); err != nil { - return botlib.ReturnErr(event, err) - } - embed := discord.NewEmbedBuilder() - embed.SetTitlef("Permission added") - embed.SetDescriptionf("To %s ```diff\r+ %s```", mention, perm) - embed.Embed = botlib.SetEmbedProperties(embed.Embed) - message := discord.NewMessageCreateBuilder() - message.AddEmbeds(embed.Build()) - if err := event.CreateMessage(message.Build()); err != nil { - return err - } - return nil - } -} - -func permissionRemoveCommandHandler(b *botlib.Bot[*client.Client]) handler.CommandHandler { - return func(event *events.ApplicationCommandInteractionCreate) error { - b.Self.GuildDataLock(*event.GuildID()).Lock() - defer b.Self.GuildDataLock(*event.GuildID()).Unlock() - gd, err := b.Self.DB.GuildData().Get(*event.GuildID()) - if err != nil { - return botlib.ReturnErr(event, err) - } - perm := event.SlashCommandInteractionData().String("permission") - var mention string - if user, ok := event.SlashCommandInteractionData().OptUser("target"); ok { - if user.Bot || user.System { - return botlib.ReturnErrMessage(event, "error_is_bot") - } - gd.UserPermissions[user.ID].Del(perm) - mention = discord.UserMention(user.ID) - } else if role, ok := event.SlashCommandInteractionData().OptRole("target"); ok { - if role.Managed { - return botlib.ReturnErrMessage(event, "error_invalid_role") - } - gd.RolePermissions[role.ID].Del(perm) - mention = discord.RoleMention(role.ID) - } else { - return botlib.ReturnErrMessage(event, "error_invalid_command_argument") - } - if err := b.Self.DB.GuildData().Set(gd.ID, gd); err != nil { - return botlib.ReturnErr(event, err) - } - embed := discord.NewEmbedBuilder() - embed.SetTitlef("Permission removed") - embed.SetDescriptionf("From %s ```diff\r- %s```", mention, perm) - embed.Embed = botlib.SetEmbedProperties(embed.Embed) - message := discord.NewMessageCreateBuilder() - message.AddEmbeds(embed.Build()) - if err := event.CreateMessage(message.Build()); err != nil { - return err - } - return nil - } -} - -func permissionListCommandHandler(b *botlib.Bot[*client.Client]) handler.CommandHandler { - return func(event *events.ApplicationCommandInteractionCreate) error { - b.Self.GuildDataLock(*event.GuildID()).Lock() - defer b.Self.GuildDataLock(*event.GuildID()).Unlock() - gd, err := b.Self.DB.GuildData().Get(*event.GuildID()) - if err != nil { - return botlib.ReturnErr(event, err) - } - var mention string - var permissions []string - if user, ok := event.SlashCommandInteractionData().OptUser("target"); ok { - if user.Bot || user.System { - return botlib.ReturnErrMessage(event, "error_is_bot") - } - permissions = gd.UserPermissions[user.ID].List() - mention = user.EffectiveName() - } else if role, ok := event.SlashCommandInteractionData().OptRole("target"); ok { - if role.Managed { - return botlib.ReturnErrMessage(event, "error_invalid_role") - } - permissions = gd.RolePermissions[role.ID].List() - mention = role.Name - } else { - return botlib.ReturnErrMessage(event, "error_invalid_command_argument") - } - embed := discord.NewEmbedBuilder() - embed.SetTitlef("%s's Permissions", mention) - for _, v := range permissions { - embed.Description += v + "\r" - } - embed.SetDescriptionf("```%s ```", embed.Description) - embed.Embed = botlib.SetEmbedProperties(embed.Embed) - message := discord.NewMessageCreateBuilder() - message.AddEmbeds(embed.Build()) - if err := event.CreateMessage(message.Build()); err != nil { - return err - } - return nil - } -} diff --git a/bot/commands/permission/permission.go b/bot/commands/permission/permission.go new file mode 100644 index 00000000..b30201b7 --- /dev/null +++ b/bot/commands/permission/permission.go @@ -0,0 +1,305 @@ +package permission + +import ( + "fmt" + + "github.com/disgoorg/disgo/discord" + "github.com/disgoorg/disgo/events" + "github.com/disgoorg/snowflake/v2" + "github.com/sabafly/gobot/bot/components" + "github.com/sabafly/gobot/bot/components/generic" + "github.com/sabafly/gobot/internal/builtin" + "github.com/sabafly/gobot/internal/embeds" + "github.com/sabafly/gobot/internal/errors" + "github.com/sabafly/gobot/internal/translate" +) + +func Command(c *components.Components) components.Command { + return (&generic.Command{ + Namespace: "permission", + CommandCreate: []discord.ApplicationCommandCreate{ + discord.SlashCommandCreate{ + Name: "permission", + Description: "permission", + DMPermission: builtin.Ptr(false), + Contexts: []discord.InteractionContextType{ + discord.InteractionContextTypeGuild, + }, + Options: []discord.ApplicationCommandOption{ + discord.ApplicationCommandOptionSubCommand{ + Name: "set", + Description: "set member/role permission", + Options: []discord.ApplicationCommandOption{ + discord.ApplicationCommandOptionMentionable{ + Name: "target", + Description: "target member/role", + Required: true, + }, + discord.ApplicationCommandOptionString{ + Name: "permission", + Description: "permission text", + Required: true, + MinLength: builtin.Ptr(1), + MaxLength: builtin.Ptr(100), + }, + discord.ApplicationCommandOptionBool{ + Name: "value", + Description: "the value of permission default is true", + }, + }, + }, + discord.ApplicationCommandOptionSubCommand{ + Name: "unset", + Description: "unset member/role permission", + Options: []discord.ApplicationCommandOption{ + discord.ApplicationCommandOptionMentionable{ + Name: "target", + Description: "target member/role", + Required: true, + }, + discord.ApplicationCommandOptionString{ + Name: "permission", + Description: "permission text", + Required: true, + MinLength: builtin.Ptr(1), + MaxLength: builtin.Ptr(100), + }, + }, + }, + discord.ApplicationCommandOptionSubCommand{ + Name: "check", + Description: "check member/role permission", + Options: []discord.ApplicationCommandOption{ + discord.ApplicationCommandOptionMentionable{ + Name: "target", + Description: "target member/role", + Required: true, + }, + discord.ApplicationCommandOptionString{ + Name: "permission", + Description: "permission text", + Required: true, + MinLength: builtin.Ptr(1), + MaxLength: builtin.Ptr(100), + }, + }, + }, + discord.ApplicationCommandOptionSubCommand{ + Name: "list", + Description: "list member/role permission", + Options: []discord.ApplicationCommandOption{ + discord.ApplicationCommandOptionMentionable{ + Name: "target", + Description: "target member/role", + Required: true, + }, + }, + }, + }, + }, + }, + CommandHandlers: map[string]generic.PermissionCommandHandler{ + "/permission/set": generic.PCommandHandler{ + Permission: []generic.Permission{ + generic.PermissionString("permission.set"), + }, + DiscordPerm: discord.PermissionAdministrator, + CommandHandler: func(c *components.Components, event *events.ApplicationCommandInteractionCreate) errors.Error { + perm := event.SlashCommandInteractionData().String("permission") + value, ok := event.SlashCommandInteractionData().OptBool("value") + if !ok { + value = true + } + var mention string + if target, ok := event.SlashCommandInteractionData().OptMember("target"); ok { + if target.User.Bot || target.User.System { + return errors.NewError(errors.ErrorMessage("errors.invalid.bot.target", event)) + } + t, err := c.MemberCreate(event, target.User, *event.GuildID()) + if err != nil { + return errors.NewError(err) + } + t.Permission.Set(perm, value) + t = t.Update(). + SetPermission(t.Permission). + SaveX(event) + mention = discord.UserMention(t.UserID) + } else { + role := event.SlashCommandInteractionData().Role("target") + g, err := c.GuildCreateID(event, *event.GuildID()) + if err != nil { + return errors.NewError(err) + } + p := g.Permissions[role.ID] + p.Set(perm, value) + g.Permissions[role.ID] = p + g.Update().SetPermissions(g.Permissions).ExecX(event) + mention = discord.RoleMention(role.ID) + } + if err := event.CreateMessage( + discord.NewMessageBuilder(). + SetEmbeds( + embeds.SetEmbedProperties( + discord.NewEmbedBuilder(). + SetTitle(translate.Message(event.Locale(), "components.permission.set.message.embed.title")). + SetDescriptionf("%s```yaml\n%s: %t\n```", + mention, perm, value, + ). + Build(), + ), + ). + BuildCreate(), + ); err != nil { + return errors.NewError(err) + } + return nil + }, + }, + "/permission/unset": generic.PCommandHandler{ + Permission: []generic.Permission{ + generic.PermissionString("permission.unset"), + }, + DiscordPerm: discord.PermissionAdministrator, + CommandHandler: func(c *components.Components, event *events.ApplicationCommandInteractionCreate) errors.Error { + var mention string + perm := event.SlashCommandInteractionData().String("permission") + if target, ok := event.SlashCommandInteractionData().OptMember("target"); ok { + if target.User.Bot || target.User.System { + return errors.NewError(errors.ErrorMessage("errors.invalid.bot.target", event)) + } + t, err := c.MemberCreate(event, target.User, *event.GuildID()) + if err != nil { + return errors.NewError(err) + } + t.Permission.UnSet(perm) + t = t.Update(). + SetPermission(t.Permission). + SaveX(event) + mention = discord.UserMention(t.UserID) + } else { + role := event.SlashCommandInteractionData().Role("target") + g, err := c.GuildCreateID(event, *event.GuildID()) + if err != nil { + return errors.NewError(err) + } + p := g.Permissions[role.ID] + p.UnSet(perm) + g.Permissions[role.ID] = p + g.Update().SetPermissions(g.Permissions).ExecX(event) + mention = discord.RoleMention(role.ID) + } + if err := event.CreateMessage( + discord.NewMessageBuilder(). + SetEmbeds( + embeds.SetEmbedProperties( + discord.NewEmbedBuilder(). + SetTitle(translate.Message(event.Locale(), "components.permission.unset.message.embed.title")). + SetDescriptionf("%s```yaml\n%s\n```", + mention, perm, + ). + Build(), + ), + ). + BuildCreate(), + ); err != nil { + return errors.NewError(err) + } + return nil + }, + }, + "/permission/check": generic.PCommandHandler{ + Permission: []generic.Permission{ + generic.PermissionString("permission.check"), + }, + DiscordPerm: discord.PermissionAdministrator, + CommandHandler: func(c *components.Components, event *events.ApplicationCommandInteractionCreate) errors.Error { + g, err := c.GuildCreateID(event, *event.GuildID()) + if err != nil { + return errors.NewError(err) + } + var mention string + var p bool + perm := event.SlashCommandInteractionData().String("permission") + if target, ok := event.SlashCommandInteractionData().OptMember("target"); ok { + if target.User.Bot || target.User.System { + return errors.NewError(errors.ErrorMessage("errors.invalid.bot.target", event)) + } + t, err := c.MemberCreate(event, target.User, *event.GuildID()) + if err != nil { + return errors.NewError(err) + } + mention = discord.UserMention(t.UserID) + p = generic.PermissionCheck(event, c, g, event.Client(), target, *event.GuildID(), []generic.Permission{generic.PermissionString(perm)}) + } else { + role := event.SlashCommandInteractionData().Role("target") + mention = discord.RoleMention(role.ID) + p = generic.RolePermissionCheck(g, *event.GuildID(), event.Client(), []snowflake.ID{role.ID}, []generic.Permission{generic.PermissionString(perm)}) + } + if err := event.CreateMessage( + discord.NewMessageBuilder(). + SetEmbeds( + embeds.SetEmbedProperties( + discord.NewEmbedBuilder(). + SetTitle(translate.Message(event.Locale(), "components.permission.check.message.embed.title")). + SetDescriptionf("%s```yaml\n%s: %t\n```", + mention, perm, p, + ). + Build(), + ), + ). + BuildCreate(), + ); err != nil { + return errors.NewError(err) + } + return nil + }, + }, + "/permission/list": generic.PCommandHandler{ + Permission: []generic.Permission{ + generic.PermissionString("permission.check"), + }, + DiscordPerm: discord.PermissionAdministrator, + CommandHandler: func(c *components.Components, event *events.ApplicationCommandInteractionCreate) errors.Error { + var str, mention string + if target, ok := event.SlashCommandInteractionData().OptMember("target"); ok { + if target.User.Bot || target.User.System { + return errors.NewError(errors.ErrorMessage("errors.invalid.bot.target", event)) + } + t, err := c.MemberCreate(event, target.User, *event.GuildID()) + if err != nil { + return errors.NewError(err) + } + mention, str = discord.UserMention(t.UserID), t.Permission.String() + } else { + role := event.SlashCommandInteractionData().Role("target") + g, err := c.GuildCreateID(event, *event.GuildID()) + if err != nil { + return errors.NewError(err) + } + mention, str = discord.RoleMention(role.ID), g.Permissions[role.ID].String() + } + if err := event.CreateMessage( + discord.NewMessageBuilder(). + SetEmbeds( + embeds.SetEmbedProperties( + discord.NewEmbedBuilder(). + SetTitle(translate.Message(event.Locale(), "components.permission.list.message.embed.title")). + SetDescriptionf( + fmt.Sprintf("%s```yaml\n%s```", + mention, + builtin.Or(str != "", str, "Empty"), + ), + ). + Build(), + ), + ). + BuildCreate(), + ); err != nil { + return errors.NewError(err) + } + return nil + }, + }, + }, + }).SetComponent(c) +} diff --git a/bot/commands/ping.go b/bot/commands/ping.go deleted file mode 100644 index 06e29762..00000000 --- a/bot/commands/ping.go +++ /dev/null @@ -1,49 +0,0 @@ -package commands - -import ( - "fmt" - - "github.com/sabafly/disgo/discord" - "github.com/sabafly/disgo/events" - "github.com/sabafly/gobot/bot/client" - botlib "github.com/sabafly/sabafly-lib/v2/bot" - "github.com/sabafly/sabafly-lib/v2/handler" - "github.com/sabafly/sabafly-lib/v2/translate" -) - -func Ping(b *botlib.Bot[*client.Client]) handler.Command { - return handler.Command{ - Create: discord.SlashCommandCreate{ - Name: "ping", - Description: "pong!", - DescriptionLocalizations: translate.MessageMap("ping_command_description", false), - DMPermission: &b.Config.DMPermission, - }, - CommandHandlers: map[string]handler.CommandHandler{ - "": pingHandler(b), - }, - } -} - -func pingHandler(b *botlib.Bot[*client.Client]) handler.CommandHandler { - return func(e *events.ApplicationCommandInteractionCreate) error { - embeds := []discord.Embed{} - embeds = append(embeds, discord.Embed{ - Title: "🏓 " + translate.Message(e.Locale(), "command_text_ping_response_embed_title"), - Fields: []discord.EmbedField{ - { - Name: fmt.Sprintf("DiscordAPI(#%d)", e.ShardID()), - Value: e.Client().ShardManager().Shard(e.ShardID()).Latency().String(), - }, - }, - }) - embeds = botlib.SetEmbedsProperties(embeds) - err := e.CreateMessage(discord.MessageCreate{ - Embeds: embeds, - }) - if err != nil { - return err - } - return nil - } -} diff --git a/bot/commands/ping/ping.go b/bot/commands/ping/ping.go new file mode 100644 index 00000000..1dad6184 --- /dev/null +++ b/bot/commands/ping/ping.go @@ -0,0 +1,53 @@ +package ping + +import ( + "fmt" + + "github.com/disgoorg/disgo/discord" + "github.com/disgoorg/disgo/events" + "github.com/sabafly/gobot/bot/components" + "github.com/sabafly/gobot/bot/components/generic" + "github.com/sabafly/gobot/internal/builtin" + "github.com/sabafly/gobot/internal/embeds" + "github.com/sabafly/gobot/internal/errors" + "github.com/sabafly/gobot/internal/translate" +) + +func Command(c *components.Components) *generic.Command { + return (&generic.Command{ + Namespace: "ping", + CommandCreate: []discord.ApplicationCommandCreate{ + discord.SlashCommandCreate{ + Name: "ping", + Description: "pong!", + DescriptionLocalizations: translate.MessageMap("components.ping.command.description", false), + DMPermission: builtin.Ptr(false), + Contexts: []discord.InteractionContextType{ + discord.InteractionContextTypeGuild, + }, + }, + }, + CommandHandlers: map[string]generic.PermissionCommandHandler{ + "/ping": generic.CommandHandler(func(_ *components.Components, event *events.ApplicationCommandInteractionCreate) errors.Error { + if err := event.CreateMessage( + discord.NewMessageBuilder(). + SetEmbeds( + embeds.SetEmbedProperties(discord.NewEmbedBuilder(). + SetTitlef("🏓 %s", translate.Message(event.Locale(), "components.ping.pong")). + SetFields( + discord.EmbedField{ + Name: fmt.Sprintf("**Discord API(#%d)**", event.ShardID()), + Value: event.Client().ShardManager().Shard(event.ShardID()).Latency().String(), + }, + ). + Build()), + ). + BuildCreate(), + ); err != nil { + return errors.NewError(err) + } + return nil + }), + }, + }).SetComponent(c) +} diff --git a/bot/commands/poll.go b/bot/commands/poll.go deleted file mode 100644 index fe0ce6ce..00000000 --- a/bot/commands/poll.go +++ /dev/null @@ -1,1936 +0,0 @@ -package commands - -import ( - "context" - "fmt" - "sort" - "strings" - "time" - - "github.com/disgoorg/json" - "github.com/disgoorg/snowflake/v2" - "github.com/google/uuid" - "github.com/sabafly/disgo/discord" - "github.com/sabafly/disgo/events" - "github.com/sabafly/gobot/bot/client" - "github.com/sabafly/gobot/bot/db" - botlib "github.com/sabafly/sabafly-lib/v2/bot" - "github.com/sabafly/sabafly-lib/v2/emoji" - "github.com/sabafly/sabafly-lib/v2/handler" - "github.com/sabafly/sabafly-lib/v2/translate" -) - -// TODO: V2 - -func Poll(b *botlib.Bot[*client.Client]) handler.Command { - return handler.Command{ - Create: discord.SlashCommandCreate{ - Name: "poll", - Description: "create, and manage poll", - DMPermission: &b.Config.DMPermission, - Options: []discord.ApplicationCommandOption{ - discord.ApplicationCommandOptionSubCommand{ - Name: "create", - Description: "create a new poll", - Options: []discord.ApplicationCommandOption{ - discord.ApplicationCommandOptionString{ - Name: "title", - Description: "title of poll", - Required: true, - MaxLength: json.Ptr(54), - }, - discord.ApplicationCommandOptionString{ - Name: "description", - Description: "description of poll", - Required: true, - MaxLength: json.Ptr(2048), - }, - discord.ApplicationCommandOptionInt{ - Name: "timeyear", - Description: "year of end time", - Required: true, - MinValue: json.Ptr(time.Now().Year()), - MaxValue: json.Ptr(time.Now().Year() + 1), - }, - discord.ApplicationCommandOptionInt{ - Name: "timemonth", - Description: "month of end time", - Required: true, - MinValue: json.Ptr(1), - MaxValue: json.Ptr(12), - }, - discord.ApplicationCommandOptionInt{ - Name: "timeday", - Description: "day of end time", - Required: true, - MinValue: json.Ptr(1), - MaxValue: json.Ptr(31), - }, - discord.ApplicationCommandOptionInt{ - Name: "timehour", - Description: "hour of end time", - Required: true, - MinValue: json.Ptr(0), - MaxValue: json.Ptr(23), - }, - discord.ApplicationCommandOptionInt{ - Name: "timeminute", - Description: "minute of end time", - Required: true, - MinValue: json.Ptr(0), - MaxValue: json.Ptr(59), - }, - discord.ApplicationCommandOptionInt{ - Name: "timezone", - Description: "timezone of end time", - Required: true, - MinValue: json.Ptr(-12), - MaxValue: json.Ptr(+14), - }, - discord.ApplicationCommandOptionInt{ - Name: "maxchoice", - Description: "Maximum number of votes a user can have", - Required: true, - MinValue: json.Ptr(1), - MaxValue: json.Ptr(25), - }, - discord.ApplicationCommandOptionInt{ - Name: "minchoice", - Description: "Minimum number of votes a user can have", - Required: false, - MinValue: json.Ptr(1), - MaxValue: json.Ptr(25), - }, - }, - }, - }, - }, - Check: b.Self.CheckCommandPermission(b, "poll.manage", discord.PermissionManageGuild), - CommandHandlers: map[string]handler.CommandHandler{ - "create": pollCreateHandler(b), - }, - } -} - -func pollCreateHandler(b *botlib.Bot[*client.Client]) func(e *events.ApplicationCommandInteractionCreate) error { - return func(e *events.ApplicationCommandInteractionCreate) error { - timeLimit := time.Date(e.SlashCommandInteractionData().Int("timeyear"), time.Month(e.SlashCommandInteractionData().Int("timemonth")), e.SlashCommandInteractionData().Int("timeday"), e.SlashCommandInteractionData().Int("timehour"), e.SlashCommandInteractionData().Int("timeminute"), 0, 0, time.FixedZone("", e.SlashCommandInteractionData().Int("timezone")*60*60)) - if time.Now().After(timeLimit) { - timeLimit = time.Now().Add(time.Hour) - } - min, ok := e.SlashCommandInteractionData().OptInt("minchoice") - if !ok { - min = 1 - } - v := db.PollCreate{ - ID: uuid.New(), - Title: e.SlashCommandInteractionData().String("title"), - Description: e.SlashCommandInteractionData().String("description"), - EndAt: timeLimit.Unix(), - MaxChoice: e.SlashCommandInteractionData().Int("maxchoice"), - MinChoice: min, - Choices: make(map[uuid.UUID]db.PollCreateChoice), - Locale: e.Locale(), - } - embeds := v.ConfigEmbed() - embeds = botlib.SetEmbedsProperties(embeds) - err := e.CreateMessage(discord.MessageCreate{ - Embeds: embeds, - Components: v.Components(), - }) - if err != nil { - return err - } - if err := b.Self.DB.PollCreate().Set(v.ID, v); err != nil { - return err - } - if err := b.Self.DB.Interactions().Set(v.ID, e.Token()); err != nil { - return err - } - return nil - } -} - -func PollComponent(b *botlib.Bot[*client.Client]) handler.Component { - return handler.Component{ - Name: "poll", - Handler: map[string]handler.ComponentHandler{ - "addchoice": pollComponentAddChoice(b), - "editchoice": pollComponentEditChoice(b), - "editsettings": pollComponentEditSettings(b), - "backmenu": pollComponentBackMenu(b), - "deletechoice": pollComponentDeleteChoice(b), - "changechoiceinfo": pollComponentChangeChoiceInfo(b), - "changechoiceemoji": pollComponentChangeChoiceEmoji(b), - "changesettingsmenu": pollComponentChangeSettingsMenu(b), - "changesettings": pollComponentChangeSettings(b), - "create": pollComponentCreate(b), - "createdo": pollComponentCreateDo(b), - "vote": pollComponentVote(b), - "votedo": pollComponentVoteDo(b), - "seeinfo": pollComponentSeeInfo(b), - "seeinfodo": pollComponentSeeInfoDo(b), - "seeresult": pollComponentSeeResult(b), - "seeresultdo": pollComponentSeeResultDo(b), - "changepollinfo": pollComponentChangePollInfo(b), - }, - } -} - -func pollComponentChangePollInfo(b *botlib.Bot[*client.Client]) func(e *events.ComponentInteractionCreate) error { - return func(e *events.ComponentInteractionCreate) error { - args := strings.Split(e.Data.CustomID(), ":") - id, err := uuid.Parse(args[3]) - if err != nil { - return err - } - v, err := b.Self.DB.PollCreate().Get(id) - if err != nil { - embeds := botlib.ErrorTraceEmbed(e.Locale(), err) - if err := e.CreateMessage(discord.MessageCreate{ - Embeds: embeds, - Flags: discord.MessageFlagEphemeral, - }); err != nil { - return err - } - return err - } - err = e.CreateModal(discord.ModalCreate{ - CustomID: e.Data.CustomID(), - Title: translate.Message(e.Locale(), "command_text_poll_create_modal_change_poll_info_modal_title"), - Components: []discord.ContainerComponent{ - discord.ActionRowComponent{ - discord.TextInputComponent{ - CustomID: "title", - Style: discord.TextInputStyle(discord.TextInputStyleShort), - Label: translate.Message(e.Locale(), "command_text_poll_create_modal_change_poll_info_modal_component_title"), - Placeholder: translate.Message(e.Locale(), "command_text_poll_create_modal_change_poll_info_modal_component_title_placeholder"), - Required: true, - MaxLength: 54, - Value: v.Title, - }, - }, - discord.ActionRowComponent{ - discord.TextInputComponent{ - CustomID: "description", - Style: discord.TextInputStyle(discord.TextInputStyleParagraph), - Label: translate.Message(e.Locale(), "command_text_poll_create_modal_change_poll_info_modal_component_description"), - Placeholder: translate.Message(e.Locale(), "command_text_poll_create_modal_change_poll_info_modal_component_description_placeholder"), - Required: false, - MaxLength: 2048, - Value: v.Description, - }, - }, - }, - }) - if err != nil { - return err - } - return nil - } -} - -func pollComponentSeeResultDo(b *botlib.Bot[*client.Client]) func(e *events.ComponentInteractionCreate) error { - return func(e *events.ComponentInteractionCreate) error { - args := strings.Split(e.Data.CustomID(), ":") - id, err := uuid.Parse(args[3]) - if err != nil { - return err - } - p, err := b.Self.DB.Poll().Get(id) - if err != nil { - embeds := botlib.ErrorTraceEmbed(e.Locale(), err) - if err := e.CreateMessage(discord.MessageCreate{ - Embeds: embeds, - Flags: discord.MessageFlagEphemeral, - }); err != nil { - return err - } - return err - } - token, err := b.Self.DB.Interactions().Get(uuid.MustParse(args[4])) - if err != nil { - embeds := botlib.ErrorTraceEmbed(e.Locale(), err) - if err := e.CreateMessage(discord.MessageCreate{ - Embeds: embeds, - Flags: discord.MessageFlagEphemeral, - }); err != nil { - return err - } - return err - } - choiceID := uuid.MustParse(e.StringSelectMenuInteractionData().Values[0]) - choice, ok := p.Choices[choiceID] - if !ok { - return nil - } - fields := []discord.EmbedField{} - fields = append(fields, discord.EmbedField{ - Name: translate.Message(e.Locale(), "poll_embed_field_number_of_votes"), - Value: fmt.Sprintf("%d", len(choice.Users)), - }) - if p.Settings.ShowUserInResult { - var str string - for i := range choice.Users { - str += discord.UserMention(i) + "\r" - } - fields = append(fields, discord.EmbedField{ - Name: translate.Message(e.Locale(), "poll_component_voter"), - Value: str, - }) - } - embeds := []discord.Embed{ - { - Title: translate.Message(e.Locale(), "poll_component_see_info_response_embed_title", translate.WithTemplate(map[string]any{"Name": choice.Name})), - Fields: fields, - }, - } - embeds = botlib.SetEmbedsProperties(embeds) - _, err = e.Client().Rest().UpdateInteractionResponse(e.ApplicationID(), token, discord.MessageUpdate{ - Embeds: &embeds, - }) - if err != nil { - embeds := botlib.ErrorTraceEmbed(e.Locale(), err) - if err := e.CreateMessage(discord.MessageCreate{ - Embeds: embeds, - Flags: discord.MessageFlagEphemeral, - }); err != nil { - return err - } - return err - } - err = e.DeferUpdateMessage() - if err != nil { - return err - } - return nil - } -} - -func pollComponentSeeResult(b *botlib.Bot[*client.Client]) func(e *events.ComponentInteractionCreate) error { - return func(e *events.ComponentInteractionCreate) error { - args := strings.Split(e.Data.CustomID(), ":") - id, err := uuid.Parse(args[3]) - if err != nil { - return err - } - p, err := b.Self.DB.Poll().Get(id) - if err != nil { - embeds := botlib.ErrorTraceEmbed(e.Locale(), err) - if err := e.CreateMessage(discord.MessageCreate{ - Embeds: embeds, - Flags: discord.MessageFlagEphemeral, - }); err != nil { - return err - } - return err - } - tokenID := uuid.New() - err = b.Self.DB.Interactions().Set(tokenID, e.Token()) - if err != nil { - embeds := botlib.ErrorTraceEmbed(e.Locale(), err) - if err := e.CreateMessage(discord.MessageCreate{ - Embeds: embeds, - Flags: discord.MessageFlagEphemeral, - }); err != nil { - return err - } - return err - } - component := p.SeeResultComponent(tokenID) - err = e.CreateMessage(discord.MessageCreate{ - Flags: discord.MessageFlagEphemeral, - Components: component, - }) - if err != nil { - return err - } - return nil - } -} - -func pollComponentSeeInfoDo(b *botlib.Bot[*client.Client]) func(e *events.ComponentInteractionCreate) error { - return func(e *events.ComponentInteractionCreate) error { - args := strings.Split(e.Data.CustomID(), ":") - id, err := uuid.Parse(args[3]) - if err != nil { - return err - } - p, err := b.Self.DB.Poll().Get(id) - if err != nil { - embeds := botlib.ErrorTraceEmbed(e.Locale(), err) - if err := e.CreateMessage(discord.MessageCreate{ - Embeds: embeds, - Flags: discord.MessageFlagEphemeral, - }); err != nil { - return err - } - return err - } - token, err := b.Self.DB.Interactions().Get(uuid.MustParse(args[4])) - if err != nil { - embeds := botlib.ErrorTraceEmbed(e.Locale(), err) - if err := e.CreateMessage(discord.MessageCreate{ - Embeds: embeds, - Flags: discord.MessageFlagEphemeral, - }); err != nil { - return err - } - return err - } - choiceID := uuid.MustParse(e.StringSelectMenuInteractionData().Values[0]) - choice, ok := p.Choices[choiceID] - if !ok { - return nil - } - fields := []discord.EmbedField{} - var isUser bool - var isCount bool - if _, ok := p.Users[e.User().ID]; p.Settings.ShowUser == db.PollSettingShowTypeAfterVote && ok || p.Settings.ShowUser == db.PollSettingShowTypeAlways { - isUser = true - } - if _, ok := p.Users[e.User().ID]; p.Settings.ShowCount == db.PollSettingShowTypeAfterVote && ok || p.Settings.ShowCount == db.PollSettingShowTypeAlways { - isCount = true - } - if isCount { - fields = append(fields, discord.EmbedField{ - Name: translate.Message(e.Locale(), "poll_embed_field_number_of_votes"), - Value: fmt.Sprintf("%d", len(choice.Users)), - }) - } - if isUser { - var str string - for i := range choice.Users { - str += discord.UserMention(i) + "\r" - } - fields = append(fields, discord.EmbedField{ - Name: translate.Message(e.Locale(), "poll_component_voter"), - Value: str, - }) - } - embeds := []discord.Embed{ - { - Title: translate.Message(e.Locale(), "poll_component_see_info_response_embed_title", translate.WithTemplate(map[string]any{"Name": choice.Name})), - Fields: fields, - }, - } - embeds = botlib.SetEmbedsProperties(embeds) - _, err = e.Client().Rest().UpdateInteractionResponse(e.ApplicationID(), token, discord.MessageUpdate{ - Embeds: &embeds, - }) - if err != nil { - embeds := botlib.ErrorTraceEmbed(e.Locale(), err) - if err := e.CreateMessage(discord.MessageCreate{ - Embeds: embeds, - Flags: discord.MessageFlagEphemeral, - }); err != nil { - return err - } - return err - } - err = e.DeferUpdateMessage() - if err != nil { - return err - } - return nil - } -} - -func pollComponentSeeInfo(b *botlib.Bot[*client.Client]) func(e *events.ComponentInteractionCreate) error { - return func(e *events.ComponentInteractionCreate) error { - args := strings.Split(e.Data.CustomID(), ":") - id, err := uuid.Parse(args[3]) - if err != nil { - return err - } - p, err := b.Self.DB.Poll().Get(id) - if err != nil { - embeds := botlib.ErrorTraceEmbed(e.Locale(), err) - if err := e.CreateMessage(discord.MessageCreate{ - Embeds: embeds, - Flags: discord.MessageFlagEphemeral, - }); err != nil { - return err - } - return err - } - if p.Settings.ShowCount != db.PollSettingShowTypeAlways && p.Settings.ShowUser != db.PollSettingShowTypeAlways { - if p.Settings.ShowCount == db.PollSettingShowTypeNever && p.Settings.ShowUser == db.PollSettingShowTypeNever { - embeds := []discord.Embed{ - { - Title: translate.Message(e.Locale(), "poll_component_cannot_use_this"), - Color: 0xff0000, - }, - } - embeds = botlib.SetEmbedsProperties(embeds) - err := e.CreateMessage(discord.MessageCreate{ - Flags: discord.MessageFlagEphemeral, - Embeds: embeds, - }) - if err != nil { - return err - } - return nil - } - } - tokenID := uuid.New() - err = b.Self.DB.Interactions().Set(tokenID, e.Token()) - if err != nil { - embeds := botlib.ErrorTraceEmbed(e.Locale(), err) - if err := e.CreateMessage(discord.MessageCreate{ - Embeds: embeds, - Flags: discord.MessageFlagEphemeral, - }); err != nil { - return err - } - return err - } - component := p.SeeInfoComponent(tokenID) - err = e.CreateMessage(discord.MessageCreate{ - Flags: discord.MessageFlagEphemeral, - Components: component, - }) - if err != nil { - return err - } - return nil - } -} - -func pollComponentVoteDo(b *botlib.Bot[*client.Client]) func(e *events.ComponentInteractionCreate) error { - return func(e *events.ComponentInteractionCreate) error { - args := strings.Split(e.Data.CustomID(), ":") - id, err := uuid.Parse(args[3]) - if err != nil { - return err - } - p, err := b.Self.DB.Poll().Get(id) - if err != nil { - embeds := botlib.ErrorTraceEmbed(e.Locale(), err) - if err := e.CreateMessage(discord.MessageCreate{ - Embeds: embeds, - Flags: discord.MessageFlagEphemeral, - }); err != nil { - return err - } - return err - } - p.Users[e.User().ID] = true - for k, pc := range p.Choices { - delete(pc.Users, e.User().ID) - p.Choices[k] = pc - } - var voted string - for _, v := range e.StringSelectMenuInteractionData().Values { - choiceID := uuid.MustParse(v) - choice, ok := p.Choices[choiceID] - if !ok { - err := e.CreateMessage(discord.MessageCreate{ - Content: "an critical error has occurred", - }) - if err != nil { - return err - } - return nil - } - choice.Users[e.User().ID] = true - p.Choices[choiceID] = choice - voted += fmt.Sprintf("%s | %s\r", botlib.FormatComponentEmoji(*choice.Emoji), choice.Name) - } - err = b.Self.DB.Poll().Del(p.ID) - if err != nil { - embeds := botlib.ErrorTraceEmbed(e.Locale(), err) - if err := e.CreateMessage(discord.MessageCreate{ - Embeds: embeds, - Flags: discord.MessageFlagEphemeral, - }); err != nil { - return err - } - return err - } - err = b.Self.DB.Poll().Set(p.ID, p) - if err != nil { - embeds := botlib.ErrorTraceEmbed(e.Locale(), err) - if err := e.CreateMessage(discord.MessageCreate{ - Embeds: embeds, - Flags: discord.MessageFlagEphemeral, - }); err != nil { - return err - } - return err - } - token, err := b.Self.DB.Interactions().Get(uuid.MustParse(args[4])) - if err != nil { - b.Logger.Error(err) - } - err = e.Client().Rest().DeleteInteractionResponse(e.ApplicationID(), token) - if err != nil { - b.Logger.Error(err) - } - embeds := p.MessageEmbed() - embeds = botlib.SetEmbedsProperties(embeds) - components := p.MessageComponent() - _, err = e.Client().Rest().UpdateMessage(p.ChannelID, p.MessageID, discord.MessageUpdate{ - Embeds: &embeds, - Components: &components, - }) - if err != nil { - b.Logger.Error(err) - } - embeds = []discord.Embed{ - { - Title: translate.Message(e.Locale(), "poll_component_select_menu_vote_do_response_title"), - Description: voted, - }, - } - embeds = botlib.SetEmbedsProperties(embeds) - err = e.CreateMessage(discord.MessageCreate{ - Flags: discord.MessageFlagEphemeral, - Embeds: embeds, - }) - if err != nil { - return err - } - return nil - } -} - -func pollComponentVote(b *botlib.Bot[*client.Client]) func(e *events.ComponentInteractionCreate) error { - return func(e *events.ComponentInteractionCreate) error { - args := strings.Split(e.Data.CustomID(), ":") - id, err := uuid.Parse(args[3]) - if err != nil { - return err - } - p, err := b.Self.DB.Poll().Get(id) - if err != nil { - embeds := botlib.ErrorTraceEmbed(e.Locale(), err) - if err := e.CreateMessage(discord.MessageCreate{ - Embeds: embeds, - Flags: discord.MessageFlagEphemeral, - }); err != nil { - return err - } - return err - } - tokenID := uuid.New() - if !p.Settings.CanChangeTarget { - _, ok := p.Users[e.User().ID] - if ok { - var voted string - for _, v := range p.Choices { - _, ok := v.Users[e.User().ID] - if !ok { - continue - } - voted += fmt.Sprintf("%s | %s\r", botlib.FormatComponentEmoji(*v.Emoji), v.Name) - } - embeds := []discord.Embed{ - { - Title: translate.Message(e.Locale(), "poll_component_button_vote_response_already_voted"), - Fields: []discord.EmbedField{ - { - Name: translate.Message(e.Locale(), "poll_component_button_vote_response_already_voted_field_votes_name"), - Value: voted, - }, - }, - }, - } - embeds = botlib.SetEmbedsProperties(embeds) - err := e.CreateMessage(discord.MessageCreate{ - Flags: discord.MessageFlagEphemeral, - Embeds: embeds, - }) - if err != nil { - return err - } - return nil - } - } - components := p.VoteComponent(tokenID) - err = e.CreateMessage(discord.MessageCreate{ - Flags: discord.MessageFlagEphemeral, - Components: components, - }) - if err != nil { - return err - } - if err := b.Self.DB.Interactions().Set(tokenID, e.Token()); err != nil { - return err - } - return nil - } -} - -func pollComponentCreate(b *botlib.Bot[*client.Client]) func(e *events.ComponentInteractionCreate) error { - return func(e *events.ComponentInteractionCreate) error { - args := strings.Split(e.Data.CustomID(), ":") - id, err := uuid.Parse(args[3]) - if err != nil { - return err - } - v, err := b.Self.DB.PollCreate().Get(id) - if err != nil { - embeds := botlib.ErrorTraceEmbed(e.Locale(), err) - if err := e.CreateMessage(discord.MessageCreate{ - Embeds: embeds, - Flags: discord.MessageFlagEphemeral, - }); err != nil { - return err - } - return err - } - token, err := b.Self.DB.Interactions().Get(id) - if err != nil { - embeds := botlib.ErrorTraceEmbed(e.Locale(), err) - if err := e.CreateMessage(discord.MessageCreate{ - Embeds: embeds, - Flags: discord.MessageFlagEphemeral, - }); err != nil { - return err - } - return err - } - embeds := []discord.Embed{ - { - Title: translate.Message(e.Locale(), "command_text_poll_create_embed_create_title"), - Description: translate.Message(e.Locale(), "command_text_poll_create_embed_create_description"), - }, - } - components := []discord.ContainerComponent{ - discord.ActionRowComponent{ - discord.ChannelSelectMenuComponent{ - CustomID: fmt.Sprintf("handler:poll:createdo:%s", v.ID), - ChannelTypes: []discord.ChannelType{ - discord.ChannelTypeGuildText, - }, - }, - }, - discord.ActionRowComponent{ - discord.ButtonComponent{ - Style: discord.ButtonStyle(discord.ButtonStyleSecondary), - CustomID: fmt.Sprintf("handler:poll:backmenu:%s", v.ID), - Emoji: &discord.ComponentEmoji{ - ID: snowflake.ID(1081932944739938414), - Name: "left", - }, - }, - }, - } - embeds = botlib.SetEmbedsProperties(embeds) - _, err = e.Client().Rest().UpdateInteractionResponse(e.ApplicationID(), token, discord.MessageUpdate{ - Embeds: &embeds, - Components: &components, - }) - if err != nil { - embeds := botlib.ErrorTraceEmbed(e.Locale(), err) - if err := e.CreateMessage(discord.MessageCreate{ - Embeds: embeds, - Flags: discord.MessageFlagEphemeral, - }); err != nil { - return err - } - return err - } - err = e.DeferUpdateMessage() - if err != nil { - return err - } - return nil - } -} - -func pollComponentCreateDo(b *botlib.Bot[*client.Client]) func(e *events.ComponentInteractionCreate) error { - return func(e *events.ComponentInteractionCreate) error { - args := strings.Split(e.Data.CustomID(), ":") - id, err := uuid.Parse(args[3]) - if err != nil { - return err - } - v, err := b.Self.DB.PollCreate().Get(id) - if err != nil { - embeds := botlib.ErrorTraceEmbed(e.Locale(), err) - if err := e.CreateMessage(discord.MessageCreate{ - Embeds: embeds, - Flags: discord.MessageFlagEphemeral, - }); err != nil { - return err - } - return err - } - token, err := b.Self.DB.Interactions().Get(id) - if err != nil { - embeds := botlib.ErrorTraceEmbed(e.Locale(), err) - if err := e.CreateMessage(discord.MessageCreate{ - Embeds: embeds, - Flags: discord.MessageFlagEphemeral, - }); err != nil { - return err - } - return err - } - poll := v.CreatePoll(e.Member().User) - poll.GuildId = *e.GuildID() - embeds := poll.MessageEmbed() - embeds = botlib.SetEmbedsProperties(embeds) - components := poll.MessageComponent() - val := e.ChannelSelectMenuInteractionData().Values[0] - poll.ChannelID = val - if poll.MaxChoice > len(poll.Choices) { - poll.MaxChoice = len(poll.Choices) - } - if poll.MaxChoice < poll.MinChoice { - poll.MinChoice = poll.MaxChoice - } - m, err := e.Client().Rest().CreateMessage(val, discord.MessageCreate{ - Embeds: embeds, - Components: components, - }) - if err != nil { - return err - } - poll.MessageID = m.ID - err = b.Self.DB.Poll().Set(poll.ID, poll) - if err != nil { - return err - } - go End(b, poll) - err = e.Client().Rest().DeleteInteractionResponse(e.ApplicationID(), token) - if err != nil { - return err - } - err = e.DeferUpdateMessage() - if err != nil { - return err - } - return nil - } -} - -func pollComponentAddChoice(b *botlib.Bot[*client.Client]) func(e *events.ComponentInteractionCreate) error { - return func(e *events.ComponentInteractionCreate) error { - args := strings.Split(e.Data.CustomID(), ":") - id, err := uuid.Parse(args[3]) - if err != nil { - return err - } - v, err := b.Self.DB.PollCreate().Get(id) - if err != nil { - embeds := botlib.ErrorTraceEmbed(e.Locale(), err) - if err := e.CreateMessage(discord.MessageCreate{ - Embeds: embeds, - Flags: discord.MessageFlagEphemeral, - }); err != nil { - return err - } - return err - } - err = e.CreateModal(discord.ModalCreate{ - CustomID: fmt.Sprintf("handler:poll:addchoice:%s", v.ID), - Title: translate.Message(e.Locale(), "command_text_poll_create_modal_add_choice_title"), - Components: []discord.ContainerComponent{ - discord.ActionRowComponent{ - discord.TextInputComponent{ - CustomID: "name", - Style: discord.TextInputStyle(discord.TextInputStyleShort), - Label: translate.Message(e.Locale(), "command_text_poll_create_modal_add_choice_component_name_label"), - Placeholder: translate.Message(e.Locale(), "command_text_poll_create_modal_add_choice_component_name_placeholder"), - Required: true, - MaxLength: 100, - }, - }, - discord.ActionRowComponent{ - discord.TextInputComponent{ - CustomID: "description", - Style: discord.TextInputStyle(discord.TextInputStyleShort), - Label: translate.Message(e.Locale(), "command_text_poll_create_modal_add_choice_component_description_label"), - Placeholder: translate.Message(e.Locale(), "command_text_poll_create_modal_add_choice_component_description_placeholder"), - Required: false, - MaxLength: 100, - }, - }, - }, - }) - if err != nil { - return err - } - return nil - } -} - -func pollComponentEditSettings(b *botlib.Bot[*client.Client]) func(e *events.ComponentInteractionCreate) error { - return func(e *events.ComponentInteractionCreate) error { - args := strings.Split(e.Data.CustomID(), ":") - id, err := uuid.Parse(args[3]) - if err != nil { - return err - } - v, err := b.Self.DB.PollCreate().Get(id) - if err != nil { - embeds := botlib.ErrorTraceEmbed(e.Locale(), err) - if err := e.CreateMessage(discord.MessageCreate{ - Embeds: embeds, - Flags: discord.MessageFlagEphemeral, - }); err != nil { - return err - } - return err - } - token, err := b.Self.DB.Interactions().Get(id) - if err != nil { - embeds := botlib.ErrorTraceEmbed(e.Locale(), err) - if err := e.CreateMessage(discord.MessageCreate{ - Embeds: embeds, - Flags: discord.MessageFlagEphemeral, - }); err != nil { - return err - } - return err - } - embeds := v.EditSettingsEmbed() - embeds = botlib.SetEmbedsProperties(embeds) - components := v.EditSettingsComponent() - _, err = e.Client().Rest().UpdateInteractionResponse(e.ApplicationID(), token, discord.MessageUpdate{ - Embeds: &embeds, - Components: &components, - }) - if err != nil { - embeds := botlib.ErrorTraceEmbed(e.Locale(), err) - if err := e.CreateMessage(discord.MessageCreate{ - Embeds: embeds, - Flags: discord.MessageFlagEphemeral, - }); err != nil { - return err - } - return err - } - err = e.DeferUpdateMessage() - if err != nil { - return err - } - return nil - } -} - -func pollComponentChangeSettingsMenu(b *botlib.Bot[*client.Client]) func(e *events.ComponentInteractionCreate) error { - return func(e *events.ComponentInteractionCreate) error { - args := strings.Split(e.Data.CustomID(), ":") - id, err := uuid.Parse(args[3]) - if err != nil { - return err - } - v, err := b.Self.DB.PollCreate().Get(id) - if err != nil { - embeds := botlib.ErrorTraceEmbed(e.Locale(), err) - if err := e.CreateMessage(discord.MessageCreate{ - Embeds: embeds, - Flags: discord.MessageFlagEphemeral, - }); err != nil { - return err - } - return err - } - token, err := b.Self.DB.Interactions().Get(id) - if err != nil { - embeds := botlib.ErrorTraceEmbed(e.Locale(), err) - if err := e.CreateMessage(discord.MessageCreate{ - Embeds: embeds, - Flags: discord.MessageFlagEphemeral, - }); err != nil { - return err - } - return err - } - val := e.StringSelectMenuInteractionData().Values[0] - embeds := v.EditSettingsEmbed() - embeds = botlib.SetEmbedsProperties(embeds) - switch val { - case "1": - components := v.ChangeSettingsMenuComponent(db.PollSettingsTypeShowUser) - _, err = e.Client().Rest().UpdateInteractionResponse(e.ApplicationID(), token, discord.MessageUpdate{ - Embeds: &embeds, - Components: &components, - }) - if err != nil { - return err - } - case "2": - components := v.ChangeSettingsMenuComponent(db.PollSettingsTypeShowCount) - _, err = e.Client().Rest().UpdateInteractionResponse(e.ApplicationID(), token, discord.MessageUpdate{ - Embeds: &embeds, - Components: &components, - }) - if err != nil { - return err - } - case "3": - components := v.ChangeSettingsMenuComponent(db.PollSettingsTypeShowTotalCount) - _, err = e.Client().Rest().UpdateInteractionResponse(e.ApplicationID(), token, discord.MessageUpdate{ - Embeds: &embeds, - Components: &components, - }) - if err != nil { - return err - } - case "4": - components := v.ChangeSettingsMenuComponent(db.PollSettingsTypeShowUserInResult) - _, err = e.Client().Rest().UpdateInteractionResponse(e.ApplicationID(), token, discord.MessageUpdate{ - Embeds: &embeds, - Components: &components, - }) - if err != nil { - return err - } - case "5": - components := v.ChangeSettingsMenuComponent(db.PollSettingsTypeCanChangeTarget) - _, err = e.Client().Rest().UpdateInteractionResponse(e.ApplicationID(), token, discord.MessageUpdate{ - Embeds: &embeds, - Components: &components, - }) - if err != nil { - return err - } - default: - b.Logger.Warn("䞍明な遞択") - return nil - } - err = e.DeferUpdateMessage() - if err != nil { - return err - } - return nil - } -} - -func pollComponentChangeSettings(b *botlib.Bot[*client.Client]) func(e *events.ComponentInteractionCreate) error { - return func(e *events.ComponentInteractionCreate) error { - args := strings.Split(e.Data.CustomID(), ":") - id, err := uuid.Parse(args[3]) - if err != nil { - return err - } - v, err := b.Self.DB.PollCreate().Get(id) - if err != nil { - embeds := botlib.ErrorTraceEmbed(e.Locale(), err) - if err := e.CreateMessage(discord.MessageCreate{ - Embeds: embeds, - Flags: discord.MessageFlagEphemeral, - }); err != nil { - return err - } - return err - } - token, err := b.Self.DB.Interactions().Get(id) - if err != nil { - embeds := botlib.ErrorTraceEmbed(e.Locale(), err) - if err := e.CreateMessage(discord.MessageCreate{ - Embeds: embeds, - Flags: discord.MessageFlagEphemeral, - }); err != nil { - return err - } - return err - } - switch args[4] { - case "showuser": - var val db.PollSettingShowType - switch args[5] { - case "0": - val = db.PollSettingShowTypeAlways - case "1": - val = db.PollSettingShowTypeNever - case "2": - val = db.PollSettingShowTypeAfterVote - } - v.Settings.ShowUser = val - case "showcount": - var val db.PollSettingShowType - switch args[5] { - case "0": - val = db.PollSettingShowTypeAlways - case "1": - val = db.PollSettingShowTypeNever - case "2": - val = db.PollSettingShowTypeAfterVote - } - v.Settings.ShowCount = val - case "showtotalcount": - var val db.PollSettingsBool - switch args[5] { - case "true": - val = true - case "false": - val = false - } - v.Settings.ShowTotalCount = val - case "showuserinresult": - var val db.PollSettingsBool - switch args[5] { - case "true": - val = true - case "false": - val = false - } - v.Settings.ShowUserInResult = val - case "canchangetarget": - var val db.PollSettingsBool - switch args[5] { - case "true": - val = true - case "false": - val = false - } - v.Settings.CanChangeTarget = val - } - embeds := v.EditSettingsEmbed() - embeds = botlib.SetEmbedsProperties(embeds) - components := v.EditSettingsComponent() - _, err = e.Client().Rest().UpdateInteractionResponse(e.ApplicationID(), token, discord.MessageUpdate{ - Embeds: &embeds, - Components: &components, - }) - if err != nil { - return err - } - if err := b.Self.DB.PollCreate().Del(id); err != nil { - embeds := botlib.ErrorTraceEmbed(e.Locale(), err) - if err := e.CreateMessage(discord.MessageCreate{ - Embeds: embeds, - Flags: discord.MessageFlagEphemeral, - }); err != nil { - return err - } - return err - } - if err := b.Self.DB.PollCreate().Set(id, v); err != nil { - embeds := botlib.ErrorTraceEmbed(e.Locale(), err) - if err := e.CreateMessage(discord.MessageCreate{ - Embeds: embeds, - Flags: discord.MessageFlagEphemeral, - }); err != nil { - return err - } - return err - } - return nil - } -} - -func pollComponentEditChoice(b *botlib.Bot[*client.Client]) func(e *events.ComponentInteractionCreate) error { - return func(e *events.ComponentInteractionCreate) error { - args := strings.Split(e.Data.CustomID(), ":") - id, err := uuid.Parse(args[3]) - if err != nil { - return err - } - v, err := b.Self.DB.PollCreate().Get(id) - if err != nil { - embeds := botlib.ErrorTraceEmbed(e.Locale(), err) - if err := e.CreateMessage(discord.MessageCreate{ - Embeds: embeds, - Flags: discord.MessageFlagEphemeral, - }); err != nil { - return err - } - return err - } - token, err := b.Self.DB.Interactions().Get(id) - if err != nil { - embeds := botlib.ErrorTraceEmbed(e.Locale(), err) - if err := e.CreateMessage(discord.MessageCreate{ - Embeds: embeds, - Flags: discord.MessageFlagEphemeral, - }); err != nil { - return err - } - return err - } - choiceID := uuid.MustParse(e.StringSelectMenuInteractionData().Values[0]) - choice, ok := v.Choices[choiceID] - if !ok { - return fmt.Errorf("poll choice not found err") - } - embeds := v.EditChoiceEmbed(choice.ID) - botlib.SetEmbedsProperties(embeds) - components := v.EditChoiceComponent(choice.ID) - _, err = e.Client().Rest().UpdateInteractionResponse(e.ApplicationID(), token, discord.MessageUpdate{ - Embeds: &embeds, - Components: &components, - }) - if err != nil { - embeds := botlib.ErrorTraceEmbed(e.Locale(), err) - if err := e.CreateMessage(discord.MessageCreate{ - Embeds: embeds, - Flags: discord.MessageFlagEphemeral, - }); err != nil { - return err - } - return err - } - err = e.DeferUpdateMessage() - if err != nil { - return err - } - return nil - } -} - -func pollComponentDeleteChoice(b *botlib.Bot[*client.Client]) func(e *events.ComponentInteractionCreate) error { - return func(e *events.ComponentInteractionCreate) error { - args := strings.Split(e.Data.CustomID(), ":") - id, err := uuid.Parse(args[3]) - if err != nil { - return err - } - v, err := b.Self.DB.PollCreate().Get(id) - if err != nil { - embeds := botlib.ErrorTraceEmbed(e.Locale(), err) - if err := e.CreateMessage(discord.MessageCreate{ - Embeds: embeds, - Flags: discord.MessageFlagEphemeral, - }); err != nil { - return err - } - return err - } - choiceID := uuid.MustParse(args[4]) - delete(v.Choices, choiceID) - if err := b.Self.DB.PollCreate().Del(id); err != nil { - embeds := botlib.ErrorTraceEmbed(e.Locale(), err) - if err := e.CreateMessage(discord.MessageCreate{ - Embeds: embeds, - Flags: discord.MessageFlagEphemeral, - }); err != nil { - return err - } - return err - } - if err := b.Self.DB.PollCreate().Set(id, v); err != nil { - embeds := botlib.ErrorTraceEmbed(e.Locale(), err) - if err := e.CreateMessage(discord.MessageCreate{ - Embeds: embeds, - Flags: discord.MessageFlagEphemeral, - }); err != nil { - return err - } - return err - } - err = pollComponentBackMenu(b)(e) - if err != nil { - return err - } - return nil - } -} - -func pollComponentChangeChoiceInfo(b *botlib.Bot[*client.Client]) func(e *events.ComponentInteractionCreate) error { - return func(e *events.ComponentInteractionCreate) error { - args := strings.Split(e.Data.CustomID(), ":") - id, err := uuid.Parse(args[3]) - if err != nil { - return err - } - v, err := b.Self.DB.PollCreate().Get(id) - if err != nil { - embeds := botlib.ErrorTraceEmbed(e.Locale(), err) - if err := e.CreateMessage(discord.MessageCreate{ - Embeds: embeds, - Flags: discord.MessageFlagEphemeral, - }); err != nil { - return err - } - return err - } - choiceID := uuid.MustParse(args[4]) - err = e.CreateModal(discord.ModalCreate{ - CustomID: e.Data.CustomID(), - Title: translate.Message(e.Locale(), "command_text_poll_create_modal_change_choice_info_title"), - Components: []discord.ContainerComponent{ - discord.ActionRowComponent{ - discord.TextInputComponent{ - CustomID: "name", - Style: discord.TextInputStyle(discord.TextInputStyleShort), - Label: translate.Message(e.Locale(), "command_text_poll_create_modal_add_choice_component_name_label"), - Placeholder: translate.Message(e.Locale(), "command_text_poll_create_modal_add_choice_component_name_placeholder"), - Required: true, - MaxLength: 100, - Value: v.Choices[choiceID].Name, - }, - }, - discord.ActionRowComponent{ - discord.TextInputComponent{ - CustomID: "description", - Style: discord.TextInputStyle(discord.TextInputStyleShort), - Label: translate.Message(e.Locale(), "command_text_poll_create_modal_add_choice_component_description_label"), - Placeholder: translate.Message(e.Locale(), "command_text_poll_create_modal_add_choice_component_description_placeholder"), - Required: false, - MaxLength: 100, - Value: v.Choices[choiceID].Description, - }, - }, - }, - }) - if err != nil { - return err - } - return nil - } -} - -func pollComponentChangeChoiceEmoji(b *botlib.Bot[*client.Client]) func(e *events.ComponentInteractionCreate) error { - return func(e *events.ComponentInteractionCreate) error { - args := strings.Split(e.Data.CustomID(), ":") - id, err := uuid.Parse(args[3]) - if err != nil { - return err - } - choiceID := uuid.MustParse(args[4]) - v, err := b.Self.DB.PollCreate().Get(id) - if err != nil { - embeds := botlib.ErrorTraceEmbed(e.Locale(), err) - if err := e.CreateMessage(discord.MessageCreate{ - Embeds: embeds, - Flags: discord.MessageFlagEphemeral, - }); err != nil { - return err - } - return err - } - token, err := b.Self.DB.Interactions().Get(id) - if err != nil { - embeds := botlib.ErrorTraceEmbed(e.Locale(), err) - if err := e.CreateMessage(discord.MessageCreate{ - Embeds: embeds, - Flags: discord.MessageFlagEphemeral, - }); err != nil { - return err - } - return err - } - - embeds := []discord.Embed{ - { - Title: translate.Message(e.Locale(), "command_text_poll_create_modal_change_choice_emoji_title"), - Description: translate.Message(e.Locale(), "command_text_poll_create_modal_change_choice_emoji_description"), - }, - } - channel := e.Channel() - embeds = botlib.SetEmbedsProperties(embeds) - customID := uuid.NewString() - ctx, cancel := context.WithTimeout(context.Background(), time.Minute*3) - var remove func() - var removeButton func() - remove = b.Handler.AddMessage(handler.Message{ - ChannelID: json.Ptr(channel.ID()), - AuthorID: json.Ptr(e.User().ID), - Check: func(ctx *events.GuildMessageCreate) bool { - b.Logger.Debug("check") - return emoji.MatchString(ctx.Message.Content) - }, - Handler: func(event *events.GuildMessageCreate) error { - b.Logger.Debug("called message") - emoji := botlib.ParseComponentEmoji(event.Message.Content) - choice := v.Choices[choiceID] - choice.Emoji = &emoji - v.Choices[choiceID] = choice - err := event.Client().Rest().DeleteMessage(event.ChannelID, event.MessageID) - if err != nil { - return err - } - // むンタラクショントヌクンを取埗 - token, err = b.Self.DB.Interactions().Get(id) - if err != nil { - return err - } - - defer cancel() - - embeds = []discord.Embed{} - embeds = v.EditChoiceEmbed(choice.ID) - botlib.SetEmbedsProperties(embeds) - components := v.EditChoiceComponent(choice.ID) - _, err = event.Client().Rest().UpdateInteractionResponse(event.Client().ApplicationID(), token, discord.MessageUpdate{ - Embeds: &embeds, - Components: &components, - }) - if err != nil { - return err - } - if err := b.Self.DB.PollCreate().Del(id); err != nil { - return err - } - if err := b.Self.DB.PollCreate().Set(id, v); err != nil { - return err - } - return nil - }, - }) - removeButton = b.Handler.AddComponent(handler.Component{ - Name: fmt.Sprintf("poll%s", customID), - Handler: map[string]handler.ComponentHandler{ - "changechoiceemojicancel": func(event *events.ComponentInteractionCreate) error { - b.Logger.Debug("called cancel button") - defer cancel() - // むンタラクショントヌクンを取埗 - token, err := b.Self.DB.Interactions().Get(id) - if err != nil { - embeds := botlib.ErrorTraceEmbed(event.Locale(), err) - if err := event.CreateMessage(discord.MessageCreate{ - Embeds: embeds, - Flags: discord.MessageFlagEphemeral, - }); err != nil { - return err - } - return err - } - - choice := v.Choices[choiceID] - - embeds = []discord.Embed{} - embeds = v.EditChoiceEmbed(choice.ID) - botlib.SetEmbedsProperties(embeds) - components := v.EditChoiceComponent(choice.ID) - _, err = event.Client().Rest().UpdateInteractionResponse(event.ApplicationID(), token, discord.MessageUpdate{ - Embeds: &embeds, - Components: &components, - }) - if err != nil { - embeds := botlib.ErrorTraceEmbed(event.Locale(), err) - if err := event.CreateMessage(discord.MessageCreate{ - Embeds: embeds, - Flags: discord.MessageFlagEphemeral, - }); err != nil { - return err - } - return err - } - err = event.DeferUpdateMessage() - if err != nil { - return err - } - return nil - }, - }, - }) - _, err = e.Client().Rest().UpdateInteractionResponse(e.ApplicationID(), token, discord.MessageUpdate{ - Embeds: &embeds, - Components: &[]discord.ContainerComponent{ - discord.ActionRowComponent{ - discord.ButtonComponent{ - CustomID: fmt.Sprintf("handler:poll%s:changechoiceemojicancel", customID), - Style: discord.ButtonStyle(discord.ButtonStyleDanger), - Emoji: &discord.ComponentEmoji{ - ID: snowflake.ID(1082319994211270686), - Name: "cancel", - }, - }, - }, - }, - }) - if err != nil { - return err - } - err = e.DeferUpdateMessage() - if err != nil { - b.Logger.Debug(err) - } - b.Logger.Debug("waiting context...") - go func() { - defer remove() - defer removeButton() - <-ctx.Done() - b.Logger.Debug("resume") - }() - return nil - } -} - -func pollComponentBackMenu(b *botlib.Bot[*client.Client]) func(e *events.ComponentInteractionCreate) error { - return func(e *events.ComponentInteractionCreate) error { - args := strings.Split(e.Data.CustomID(), ":") - id, err := uuid.Parse(args[3]) - if err != nil { - return err - } - v, err := b.Self.DB.PollCreate().Get(id) - if err != nil { - embeds := botlib.ErrorTraceEmbed(e.Locale(), err) - if err := e.CreateMessage(discord.MessageCreate{ - Embeds: embeds, - Flags: discord.MessageFlagEphemeral, - }); err != nil { - return err - } - return err - } - token, err := b.Self.DB.Interactions().Get(id) - if err != nil { - embeds := botlib.ErrorTraceEmbed(e.Locale(), err) - if err := e.CreateMessage(discord.MessageCreate{ - Embeds: embeds, - Flags: discord.MessageFlagEphemeral, - }); err != nil { - return err - } - return err - } - - embeds := v.ConfigEmbed() - embeds = botlib.SetEmbedsProperties(embeds) - components := v.Components() - _, err = e.Client().Rest().UpdateInteractionResponse(e.ApplicationID(), token, discord.MessageUpdate{ - Embeds: &embeds, - Components: &components, - }) - if err != nil { - embeds := botlib.ErrorTraceEmbed(e.Locale(), err) - if err := e.CreateMessage(discord.MessageCreate{ - Embeds: embeds, - Flags: discord.MessageFlagEphemeral, - }); err != nil { - return err - } - return err - } - err = e.DeferUpdateMessage() - if err != nil { - return err - } - return nil - } -} - -func PollModal(b *botlib.Bot[*client.Client]) handler.Modal { - return handler.Modal{ - Name: "poll", - Handler: map[string]handler.ModalHandler{ - "addchoice": pollModalAddChoice(b), - "changechoiceinfo": pollModalChangeChoiceInfo(b), - "changepollinfo": pollModalChangePollInfo(b), - }, - } -} - -func pollModalAddChoice(b *botlib.Bot[*client.Client]) func(*events.ModalSubmitInteractionCreate) error { - return func(e *events.ModalSubmitInteractionCreate) error { - // IDを取り出す - args := strings.Split(e.Data.CustomID, ":") - id, err := uuid.Parse(args[3]) - if err != nil { - embeds := botlib.ErrorTraceEmbed(e.Locale(), err) - if err := e.CreateMessage(discord.MessageCreate{ - Embeds: embeds, - Flags: discord.MessageFlagEphemeral, - }); err != nil { - return err - } - return err - } - // デヌタベヌスから取埗 - v, err := b.Self.DB.PollCreate().Get(id) - if err != nil { - embeds := botlib.ErrorTraceEmbed(e.Locale(), err) - if err := e.CreateMessage(discord.MessageCreate{ - Embeds: embeds, - Flags: discord.MessageFlagEphemeral, - }); err != nil { - return err - } - return err - } - // むンタラクショントヌクンを取埗 - token, err := b.Self.DB.Interactions().Get(id) - if err != nil { - embeds := botlib.ErrorTraceEmbed(e.Locale(), err) - if err := e.CreateMessage(discord.MessageCreate{ - Embeds: embeds, - Flags: discord.MessageFlagEphemeral, - }); err != nil { - return err - } - return err - } - - choiceID := uuid.New() - v.Choices[choiceID] = db.PollCreateChoice{ - ID: choiceID, - Name: e.ModalSubmitInteraction.Data.Text("name"), - Description: e.ModalSubmitInteraction.Data.Text("description"), - Position: len(v.Choices) + 1, - Emoji: &discord.ComponentEmoji{ - Name: botlib.Number2Emoji(len(v.Choices) + 1), - }, - } - - // 䜜成パネルを曎新 - embeds := v.ConfigEmbed() - embeds = botlib.SetEmbedsProperties(embeds) - components := v.Components() - _, err = e.Client().Rest().UpdateInteractionResponse(e.Client().ApplicationID(), token, discord.MessageUpdate{ - Embeds: &embeds, - Components: &components, - }) - if err != nil { - embeds := botlib.ErrorTraceEmbed(e.Locale(), err) - if err := e.CreateMessage(discord.MessageCreate{ - Embeds: embeds, - Flags: discord.MessageFlagEphemeral, - }); err != nil { - return err - } - return err - } - if err := b.Self.DB.PollCreate().Del(id); err != nil { - embeds := botlib.ErrorTraceEmbed(e.Locale(), err) - if err := e.CreateMessage(discord.MessageCreate{ - Embeds: embeds, - Flags: discord.MessageFlagEphemeral, - }); err != nil { - return err - } - return err - } - if err := b.Self.DB.PollCreate().Set(id, v); err != nil { - embeds := botlib.ErrorTraceEmbed(e.Locale(), err) - if err := e.CreateMessage(discord.MessageCreate{ - Embeds: embeds, - Flags: discord.MessageFlagEphemeral, - }); err != nil { - return err - } - return err - } - - // 远加内容をレスポンド - embeds = []discord.Embed{} - embeds = append(embeds, discord.Embed{ - Title: translate.Message(e.Locale(), "command_text_poll_create_modal_add_choice_component_response_title"), - Fields: []discord.EmbedField{ - { - Name: translate.Message(e.Locale(), "command_text_poll_create_modal_add_choice_component_name_label"), - Value: e.ModalSubmitInteraction.Data.Text("name"), - }, - }, - }) - if description, ok := e.ModalSubmitInteraction.Data.OptText("description"); ok { - embeds[0].Fields = append(embeds[0].Fields, discord.EmbedField{ - Name: translate.Message(e.Locale(), "command_text_poll_create_modal_add_choice_component_description_label"), - Value: description, - }) - } - botlib.SetEmbedsProperties(embeds) - if err := e.CreateMessage(discord.MessageCreate{ - Embeds: embeds, - Flags: discord.MessageFlagEphemeral, - }); err != nil { - return err - } - // 3秒埌に削陀 - time.Sleep(time.Second * 3) - if err := e.Client().Rest().DeleteInteractionResponse(e.Client().ApplicationID(), e.Token()); err != nil { - return err - } - return nil - } -} - -func pollModalChangeChoiceInfo(b *botlib.Bot[*client.Client]) func(*events.ModalSubmitInteractionCreate) error { - return func(e *events.ModalSubmitInteractionCreate) error { - // IDを取り出す - args := strings.Split(e.Data.CustomID, ":") - id, err := uuid.Parse(args[3]) - if err != nil { - embeds := botlib.ErrorTraceEmbed(e.Locale(), err) - if err := e.CreateMessage(discord.MessageCreate{ - Embeds: embeds, - Flags: discord.MessageFlagEphemeral, - }); err != nil { - return err - } - return err - } - // デヌタベヌスから取埗 - v, err := b.Self.DB.PollCreate().Get(id) - if err != nil { - embeds := botlib.ErrorTraceEmbed(e.Locale(), err) - if err := e.CreateMessage(discord.MessageCreate{ - Embeds: embeds, - Flags: discord.MessageFlagEphemeral, - }); err != nil { - return err - } - return err - } - // むンタラクショントヌクンを取埗 - token, err := b.Self.DB.Interactions().Get(id) - if err != nil { - embeds := botlib.ErrorTraceEmbed(e.Locale(), err) - if err := e.CreateMessage(discord.MessageCreate{ - Embeds: embeds, - Flags: discord.MessageFlagEphemeral, - }); err != nil { - return err - } - return err - } - - choiceID := uuid.MustParse(args[4]) - choice := v.Choices[choiceID] - choice.Name = e.ModalSubmitInteraction.Data.Text("name") - choice.Description = e.ModalSubmitInteraction.Data.Text("description") - v.Choices[choiceID] = choice - - embeds := v.EditChoiceEmbed(choice.ID) - botlib.SetEmbedsProperties(embeds) - components := v.EditChoiceComponent(choice.ID) - _, err = e.Client().Rest().UpdateInteractionResponse(e.ApplicationID(), token, discord.MessageUpdate{ - Embeds: &embeds, - Components: &components, - }) - if err != nil { - embeds := botlib.ErrorTraceEmbed(e.Locale(), err) - if err := e.CreateMessage(discord.MessageCreate{ - Embeds: embeds, - Flags: discord.MessageFlagEphemeral, - }); err != nil { - return err - } - return err - } - if err := b.Self.DB.PollCreate().Del(id); err != nil { - embeds := botlib.ErrorTraceEmbed(e.Locale(), err) - if err := e.CreateMessage(discord.MessageCreate{ - Embeds: embeds, - Flags: discord.MessageFlagEphemeral, - }); err != nil { - return err - } - return err - } - if err := b.Self.DB.PollCreate().Set(id, v); err != nil { - embeds := botlib.ErrorTraceEmbed(e.Locale(), err) - if err := e.CreateMessage(discord.MessageCreate{ - Embeds: embeds, - Flags: discord.MessageFlagEphemeral, - }); err != nil { - return err - } - return err - } - - // 远加内容をレスポンド - embeds = []discord.Embed{} - embeds = append(embeds, discord.Embed{ - Title: translate.Message(e.Locale(), "command_text_poll_create_modal_change_choice_info_component_response_title"), - Fields: []discord.EmbedField{ - { - Name: translate.Message(e.Locale(), "command_text_poll_create_modal_add_choice_component_name_label"), - Value: e.ModalSubmitInteraction.Data.Text("name"), - }, - }, - }) - if description, ok := e.ModalSubmitInteraction.Data.OptText("description"); ok { - embeds[0].Fields = append(embeds[0].Fields, discord.EmbedField{ - Name: translate.Message(e.Locale(), "command_text_poll_create_modal_add_choice_component_description_label"), - Value: description, - }) - } - botlib.SetEmbedsProperties(embeds) - if err := e.CreateMessage(discord.MessageCreate{ - Embeds: embeds, - Flags: discord.MessageFlagEphemeral, - }); err != nil { - return err - } - // 3秒埌に削陀 - time.Sleep(time.Second * 3) - if err := e.Client().Rest().DeleteInteractionResponse(e.Client().ApplicationID(), e.Token()); err != nil { - return err - } - return nil - } -} - -func pollModalChangePollInfo(b *botlib.Bot[*client.Client]) func(*events.ModalSubmitInteractionCreate) error { - return func(e *events.ModalSubmitInteractionCreate) error { - // IDを取り出す - args := strings.Split(e.Data.CustomID, ":") - id, err := uuid.Parse(args[3]) - if err != nil { - embeds := botlib.ErrorTraceEmbed(e.Locale(), err) - if err := e.CreateMessage(discord.MessageCreate{ - Embeds: embeds, - Flags: discord.MessageFlagEphemeral, - }); err != nil { - return err - } - return err - } - // デヌタベヌスから取埗 - v, err := b.Self.DB.PollCreate().Get(id) - if err != nil { - embeds := botlib.ErrorTraceEmbed(e.Locale(), err) - if err := e.CreateMessage(discord.MessageCreate{ - Embeds: embeds, - Flags: discord.MessageFlagEphemeral, - }); err != nil { - return err - } - return err - } - // むンタラクショントヌクンを取埗 - token, err := b.Self.DB.Interactions().Get(id) - if err != nil { - embeds := botlib.ErrorTraceEmbed(e.Locale(), err) - if err := e.CreateMessage(discord.MessageCreate{ - Embeds: embeds, - Flags: discord.MessageFlagEphemeral, - }); err != nil { - return err - } - return err - } - - v.Title = e.ModalSubmitInteraction.Data.Text("title") - v.Description = e.ModalSubmitInteraction.Data.Text("description") - embeds := v.ConfigEmbed() - botlib.SetEmbedsProperties(embeds) - components := v.Components() - _, err = e.Client().Rest().UpdateInteractionResponse(e.ApplicationID(), token, discord.MessageUpdate{ - Embeds: &embeds, - Components: &components, - }) - if err != nil { - embeds := botlib.ErrorTraceEmbed(e.Locale(), err) - if err := e.CreateMessage(discord.MessageCreate{ - Embeds: embeds, - Flags: discord.MessageFlagEphemeral, - }); err != nil { - return err - } - return err - } - if err := b.Self.DB.PollCreate().Del(id); err != nil { - embeds := botlib.ErrorTraceEmbed(e.Locale(), err) - if err := e.CreateMessage(discord.MessageCreate{ - Embeds: embeds, - Flags: discord.MessageFlagEphemeral, - }); err != nil { - return err - } - return err - } - if err := b.Self.DB.PollCreate().Set(id, v); err != nil { - embeds := botlib.ErrorTraceEmbed(e.Locale(), err) - if err := e.CreateMessage(discord.MessageCreate{ - Embeds: embeds, - Flags: discord.MessageFlagEphemeral, - }); err != nil { - return err - } - return err - } - - // 远加内容をレスポンド - embeds = []discord.Embed{} - embeds = append(embeds, discord.Embed{ - Title: translate.Message(e.Locale(), "command_text_poll_create_modal_change_choice_info_component_response_title"), - Fields: []discord.EmbedField{ - { - Name: translate.Message(e.Locale(), "command_text_poll_create_modal_change_poll_info_modal_component_title"), - Value: e.ModalSubmitInteraction.Data.Text("name"), - }, - }, - }) - if description, ok := e.ModalSubmitInteraction.Data.OptText("description"); ok { - embeds[0].Fields = append(embeds[0].Fields, discord.EmbedField{ - Name: translate.Message(e.Locale(), "command_text_poll_create_modal_change_poll_info_modal_component_description"), - Value: description, - }) - } - botlib.SetEmbedsProperties(embeds) - if err := e.CreateMessage(discord.MessageCreate{ - Embeds: embeds, - Flags: discord.MessageFlagEphemeral, - }); err != nil { - return err - } - // 3秒埌に削陀 - time.Sleep(time.Second * 3) - if err := e.Client().Rest().DeleteInteractionResponse(e.Client().ApplicationID(), e.Token()); err != nil { - return err - } - return nil - } -} - -func End(b *botlib.Bot[*client.Client], p db.Poll) { - if p.Finished { - return - } - time.Sleep(time.Until(time.Unix(p.EndAt, 0))) - b.Logger.Debug("finish vote") - p, err := b.Self.DB.Poll().Get(p.ID) - if err != nil { - b.Logger.Error(err) - return - } - embeds := p.MessageEmbed() - embeds = botlib.SetEmbedsProperties(embeds) - components := p.MessageComponent() - _, err = b.Client.Rest().UpdateMessage(p.ChannelID, p.MessageID, discord.MessageUpdate{ - Embeds: &embeds, - Components: &components, - }) - if err != nil { - b.Logger.Error(err) - return - } - var ranking []discord.EmbedField - choices := []db.PollChoice{} - for _, pc := range p.Choices { - choices = append(choices, pc) - } - sort.SliceStable(choices, func(i, j int) bool { - return len(choices[i].Users) > len(choices[j].Users) - }) - inline := true - rank := 1 - for i, pc := range choices { - if i > 0 && len(choices[i-1].Users) > len(pc.Users) { - rank = i + 1 - } - ranking = append(ranking, discord.EmbedField{ - Name: fmt.Sprintf("%s %s %s", botlib.FormatComponentEmoji(*pc.Emoji), pc.Name, translate.Message(p.Locale, "poll_message_result_title", translate.WithTemplate(map[string]any{"Rank": rank}))), - Value: translate.Message(p.Locale, "poll_message_result_description", translate.WithTemplate(map[string]any{"Count": len(pc.Users)})), - Inline: &inline, - }) - } - embeds = []discord.Embed{ - { - Title: translate.Message(p.Locale, "poll_message_result_embed_title"), - Description: fmt.Sprintf("**%s**\r%s", translate.Message(p.Locale, "joined_people"), translate.Message(p.Locale, "people", translate.WithTemplate(map[string]any{"Count": len(p.Users)}))), - Fields: ranking, - }, - } - embeds = botlib.SetEmbedsProperties(embeds) - _, err = b.Client.Rest().CreateMessage(p.ChannelID, discord.MessageCreate{ - Embeds: embeds, - MessageReference: &discord.MessageReference{ - MessageID: &p.MessageID, - ChannelID: &p.ChannelID, - GuildID: &p.GuildId, - }, - }) - if err != nil { - b.Logger.Error(err) - return - } - p.Finished = true - if err := b.Self.DB.Poll().Del(p.ID); err != nil { - b.Logger.Error(err) - } - if err := b.Self.DB.Poll().Set(p.ID, p); err != nil { - b.Logger.Error(err) - } -} diff --git a/bot/commands/role.go b/bot/commands/role.go deleted file mode 100644 index fc6cc380..00000000 --- a/bot/commands/role.go +++ /dev/null @@ -1,1913 +0,0 @@ -package commands - -import ( - "fmt" - "slices" - "strings" - "time" - - "github.com/disgoorg/json" - "github.com/disgoorg/snowflake/v2" - "github.com/google/uuid" - "github.com/sabafly/disgo/discord" - "github.com/sabafly/disgo/events" - "github.com/sabafly/gobot/bot/client" - "github.com/sabafly/gobot/bot/db" - botlib "github.com/sabafly/sabafly-lib/v2/bot" - "github.com/sabafly/sabafly-lib/v2/emoji" - "github.com/sabafly/sabafly-lib/v2/handler" - "github.com/sabafly/sabafly-lib/v2/handler/interactions" - "github.com/sabafly/sabafly-lib/v2/translate" -) - -func Role(b *botlib.Bot[*client.Client]) handler.Command { - return handler.Command{ - Create: discord.SlashCommandCreate{ - Name: "role", - Description: "require manage role permission", - DMPermission: &b.Config.DMPermission, - Options: []discord.ApplicationCommandOption{ - discord.ApplicationCommandOptionSubCommandGroup{ - Name: "panel-v2", - Description: "panel version 2", - Options: []discord.ApplicationCommandOptionSubCommand{ - { - Name: "create", - Description: "create a new role panel", - DescriptionLocalizations: translate.MessageMap("role_panel_v2_create_command_description", false), - }, - // TODO: Listコマンドを実装する - // { - // Name: "list", - // Description: "show list of role panels", - // }, - { - Name: "delete", - Description: "deletes a role panel", - DescriptionLocalizations: translate.MessageMap("role_panel_v2_delete_command_description", false), - Options: []discord.ApplicationCommandOption{ - discord.ApplicationCommandOptionString{ - Name: "panel", - Description: "panel identify", - DescriptionLocalizations: translate.MessageMap("role_panel_v2_delete_command_panel_option_description", false), - Autocomplete: true, - Required: true, - }, - }, - }, - { - Name: "edit", - Description: "edit a role panel", - DescriptionLocalizations: translate.MessageMap("role_panel_v2_edit_command_description", false), - Options: []discord.ApplicationCommandOption{ - discord.ApplicationCommandOptionString{ - Name: "panel", - Description: "panel identify", - DescriptionLocalizations: translate.MessageMap("role_panel_v2_edit_command_panel_option_description", false), - Autocomplete: true, - Required: true, - }, - }, - }, - { - Name: "place", - Description: "place panel to the channel", - DescriptionLocalizations: translate.MessageMap("role_panel_v2_place_command_description", false), - Options: []discord.ApplicationCommandOption{ - discord.ApplicationCommandOptionString{ - Name: "panel", - Description: "panel identify", - DescriptionLocalizations: translate.MessageMap("role_panel_v2_place_command_panel_description", false), - Autocomplete: true, - Required: true, - }, - }, - }, - }, - }, - }, - }, - Check: b.Self.CheckCommandPermission(b, "guild.role.manage", discord.PermissionManageRoles), - AutocompleteCheck: b.Self.CheckAutoCompletePermission(b, "guild.role.manage", discord.PermissionManageRoles), - AutocompleteHandlers: map[string]handler.AutocompleteHandler{ - "panel-v2/edit": rolePanelV2PanelAutoCompleteHandler(b), - "panel-v2/delete": rolePanelV2PanelAutoCompleteHandler(b), - "panel-v2/place": rolePanelV2PanelAutoCompleteHandler(b), - }, - CommandHandlers: map[string]handler.CommandHandler{ - "panel-v2/create": rolePanelV2Create(b), - "panel-v2/edit": rolePanelV2Edit(b), - "panel-v2/place": rolePanelV2Place(b), - "panel-v2/delete": rolePanelV2Delete(b), - }, - } -} - -func rolePanelV2PanelAutoCompleteHandler(b *botlib.Bot[*client.Client]) handler.AutocompleteHandler { - return func(event *events.AutocompleteInteractionCreate) error { - b.Self.GuildDataLock(*event.GuildID()).Lock() - defer b.Self.GuildDataLock(*event.GuildID()).Unlock() - gd, err := b.Self.DB.GuildData().Get(*event.GuildID()) - if err != nil { - return err - } - choices := []discord.AutocompleteChoice{} - for u, v := range gd.RolePanelV2 { - if !strings.HasPrefix(v, event.Data.String("panel")) { - continue - } - if gd.RolePanelV2Name[v] > 1 { - v = fmt.Sprintf("%s(%s)", v, u.String()) - } - choices = append(choices, discord.AutocompleteChoiceString{ - Name: v, - Value: u.String(), - }) - } - if err := event.Result(choices); err != nil { - return err - } - return nil - } -} - -func rolePanelV2Create(b *botlib.Bot[*client.Client]) handler.CommandHandler { - return func(event *events.ApplicationCommandInteractionCreate) error { - modal := discord.NewModalCreateBuilder() - modal.SetCustomID("handler:rp-v2:create-modal") - modal.SetTitle(translate.Message(event.Locale(), "rp_v2_create_modal_title")) - modal.AddActionRow(discord.TextInputComponent{ - CustomID: "name", - Style: discord.TextInputStyleShort, - Label: translate.Message(event.Locale(), "rp_v2_create_modal_label_0"), - Value: translate.Message(event.Locale(), "rp_v2_default_panel_name"), - MaxLength: 32, - Required: true, - }) - modal.AddActionRow(discord.TextInputComponent{ - CustomID: "description", - Style: discord.TextInputStyleParagraph, - Label: translate.Message(event.Locale(), "rp_v2_create_modal_label_1"), - MaxLength: 140, - Required: false, - }) - if err := event.CreateModal(modal.Build()); err != nil { - return err - } - return nil - } -} - -func rolePanelV2Edit(b *botlib.Bot[*client.Client]) handler.CommandHandler { - return func(event *events.ApplicationCommandInteractionCreate) error { - b.Self.GuildDataLock(*event.GuildID()).Lock() - defer b.Self.GuildDataLock(*event.GuildID()).Unlock() - - role_panel_id, err := uuid.Parse(event.SlashCommandInteractionData().String("panel")) - if err != nil { - return botlib.ReturnErrMessage(event, "error_invalid_id") - } - - gd, err := b.Self.DB.GuildData().Get(*event.GuildID()) - if err != nil { - return botlib.ReturnErr(event, err) - } - - if _, ok := gd.RolePanelV2[role_panel_id]; !ok { - return botlib.ReturnErrMessage(event, "error_unsearchable") - } - - rp, err := b.Self.DB.RolePanelV2().Get(role_panel_id) - if err != nil { - return botlib.ReturnErr(event, err) - } - - edit := db.NewRolePanelV2Edit(rp.ID, *event.GuildID(), event.Channel().ID(), interactions.New(event.Token(), event.CreatedAt())) - - if id, ok := gd.RolePanelV2Editing[role_panel_id]; ok { - old_edit, err := b.Self.DB.RolePanelV2Edit().Get(id) - if err != nil { - delete(gd.RolePanelV2Editing, role_panel_id) - delete(gd.RolePanelV2EditingEmoji, role_panel_id) - } else if old_edit.InteractionToken.IsValid() { - token, _ := old_edit.InteractionToken.Get() - message := discord.MessageUpdate{ - Content: json.Ptr(translate.Message(event.Locale(), "rp_v2_expired_content")), - Embeds: &[]discord.Embed{}, - Components: &[]discord.ContainerComponent{}, - } - _, _ = event.Client().Rest().UpdateInteractionResponse(event.ApplicationID(), token, message) - if err := b.Self.DB.RolePanelV2Edit().Del(old_edit.ID); err != nil { - return botlib.ReturnErr(event, err) - } - } - } - gd.RolePanelV2Editing[role_panel_id] = edit.ID - - mes := discord.NewMessageCreateBuilder() - mes = db.RolePanelV2EditMenuEmbed(rp, event.Locale(), edit, mes) - mes.SetFlags(discord.MessageFlagEphemeral) - - if err := b.Self.DB.RolePanelV2Edit().Set(edit.ID, edit); err != nil { - return botlib.ReturnErr(event, err) - } - if err := b.Self.DB.GuildData().Set(gd.ID, gd); err != nil { - return botlib.ReturnErr(event, err) - } - - if err := event.CreateMessage(mes.Build()); err != nil { - return botlib.ReturnErr(event, err) - } - return nil - } -} - -func rolePanelV2Place(b *botlib.Bot[*client.Client]) handler.CommandHandler { - return func(event *events.ApplicationCommandInteractionCreate) error { - b.Self.GuildDataLock(*event.GuildID()).Lock() - defer b.Self.GuildDataLock(*event.GuildID()).Unlock() - - role_panel_id, err := uuid.Parse(event.SlashCommandInteractionData().String("panel")) - if err != nil { - return botlib.ReturnErrMessage(event, "error_invalid_id", botlib.WithEphemeral(true)) - } - - gd, err := b.Self.DB.GuildData().Get(*event.GuildID()) - if err != nil { - return botlib.ReturnErr(event, err, botlib.WithEphemeral(true)) - } - - if _, ok := gd.RolePanelV2[role_panel_id]; !ok { - return botlib.ReturnErrMessage(event, "error_unsearchable", botlib.WithEphemeral(true)) - } - - rp, err := b.Self.DB.RolePanelV2().Get(role_panel_id) - if err != nil { - return botlib.ReturnErr(event, err, botlib.WithEphemeral(true)) - } - - place := db.NewRolePanelV2Place(*event.GuildID(), rp.ID, interactions.New(event.Token(), event.CreatedAt())) - if err := b.Self.DB.RolePanelV2Place().Set(place.ID, place); err != nil { - return botlib.ReturnErr(event, err) - } - - message := discord.NewMessageCreateBuilder() - message = db.RolePanelV2PlaceMenuEmbed(rp, event.Locale(), place, message) - message.SetFlags(discord.MessageFlagEphemeral) - - if err := event.CreateMessage(message.Build()); err != nil { - return botlib.ReturnErr(event, err, botlib.WithEphemeral(true)) - } - return nil - } -} - -func rolePanelV2Delete(b *botlib.Bot[*client.Client]) handler.CommandHandler { - return func(event *events.ApplicationCommandInteractionCreate) error { - b.Self.GuildDataLock(*event.GuildID()).Lock() - defer b.Self.GuildDataLock(*event.GuildID()).Unlock() - - role_panel_id, err := uuid.Parse(event.SlashCommandInteractionData().String("panel")) - if err != nil { - return botlib.ReturnErrMessage(event, "error_invalid_id") - } - - gd, err := b.Self.DB.GuildData().Get(*event.GuildID()) - if err != nil { - return botlib.ReturnErr(event, err) - } - - if _, ok := gd.RolePanelV2[role_panel_id]; !ok { - return botlib.ReturnErrMessage(event, "error_unsearchable") - } - - panel, err := b.Self.DB.RolePanelV2().Get(role_panel_id) - if err != nil { - return botlib.ReturnErr(event, err) - } - - edit_id, ok := gd.RolePanelV2Editing[panel.ID] - if ok { - delete(gd.RolePanelV2EditingEmoji, edit_id) - } - delete(gd.RolePanelV2Editing, panel.ID) - gd.RolePanelV2Name[panel.Name]-- - delete(gd.RolePanelV2, panel.ID) - - if err := b.Self.DB.GuildData().Set(gd.ID, gd); err != nil { - return botlib.ReturnErr(event, err, botlib.WithEphemeral(true)) - } - if err := b.Self.DB.RolePanelV2().Del(panel.ID); err != nil { - return botlib.ReturnErr(event, err, botlib.WithEphemeral(true)) - } - - go rolePanelV2MessageDelete(b, *event.GuildID(), panel, event.Locale()) - - embed := discord.NewEmbedBuilder() - embed.SetTitle(translate.Message(event.Locale(), "rp_v2_delete_success_embed_title")) - embed.SetDescription(translate.Message(event.Locale(), "rp_v2_delete_success_embed_description")) - embed.Embed = botlib.SetEmbedProperties(embed.Embed) - message := discord.NewMessageCreateBuilder() - message.AddEmbeds(embed.Build()) - if err := event.CreateMessage(message.Build()); err != nil { - return botlib.ReturnErr(event, err, botlib.WithEphemeral(true)) - } - return nil - } -} - -func RolePanelV2Component(b *botlib.Bot[*client.Client]) handler.Component { - return handler.Component{ - Name: "rp-v2", - Handler: map[string]handler.ComponentHandler{ - "edit-rsm": rolePanelV2EditRoleSelectMenuHandler(b), - "edit_name": rolePanelV2EditPanelInfoHandler(b), - "edit_description": rolePanelV2EditPanelInfoHandler(b), - "edit_roles": rolePanelV2EditRolesComponentHandler(b), - "back_edit_roles": rolePanelV2BackEditRolesComponentHandler(b), - "edit_role_select": rolePanelV2EditRoleSelectComponentHandler(b), - "edit_role_name": rolePanelV2EditRoleNameComponentHandler(b), - "edit_role_delete": rolePanelV2EditRoleDeleteComponent(b), - "edit_role_emoji": rolePanelV2EditRoleEmojiComponentHandler(b), - "place_type": rolePanelV2PlaceTypeComponentHandler(b), - "place": rolePanelV2PlaceComponentHandler(b), - "use_select_menu": rolePanelV2UseSelectMenuComponentHandler(b), - "use_button": rolePanelV2UseButtonComponentHandler(b), - "place_simple_select_menu": rolePanelV2PlaceSimpleSelectMenuComponentHandler(b), - "place_button_show_name": rolePanelV2PlaceButtonShowNameComponentHandler(b), - "place_button_color": rolePanelV2PlaceButtonColorComponentHandler(b), - "call_select_menu": rolePanelV2CallSelectMenuComponentHandler(b), - "convert": rolePanelV2ConvertComponentHandler(b), - }, - } -} - -func rolePanelV2EditRoleSelectMenuHandler(b *botlib.Bot[*client.Client]) handler.ComponentHandler { - return func(event *events.ComponentInteractionCreate) error { - args := strings.Split(event.Data.CustomID(), ":") - edit_id, err := uuid.Parse(args[3]) - if err != nil { - return botlib.ReturnErrMessage(event, "error_invalid_id") - } - - edit, err := b.Self.DB.RolePanelV2Edit().Get(edit_id) - if err != nil { - return botlib.ReturnErrMessage(event, "error_timeout", botlib.WithEphemeral(true)) - } - - if len(event.StringSelectMenuInteractionData().Values) < 1 { - edit.SelectedID = nil - } else { - selected_role, err := snowflake.Parse(event.StringSelectMenuInteractionData().Values[0]) - if err != nil { - return botlib.ReturnErr(event, err, botlib.WithEphemeral(true)) - } - edit.SelectedID = &selected_role - } - - if err := b.Self.DB.RolePanelV2Edit().Set(edit.ID, edit); err != nil { - return botlib.ReturnErr(event, err, botlib.WithEphemeral(true)) - } - rp, err := b.Self.DB.RolePanelV2().Get(edit.RolePanelID) - if err != nil { - return botlib.ReturnErr(event, err, botlib.WithEphemeral(true)) - } - - message := discord.NewMessageUpdateBuilder() - message = db.RolePanelV2EditMenuEmbed(rp, event.Locale(), edit, message) - - token, err := edit.InteractionToken.Get() - if err != nil { - return botlib.ReturnErrMessage(event, "error_timeout") - } - if _, err := event.Client().Rest().UpdateInteractionResponse(event.ApplicationID(), token, message.Build()); err != nil { - return botlib.ReturnErr(event, err, botlib.WithEphemeral(true)) - } - - if err := event.DeferUpdateMessage(); err != nil { - return botlib.ReturnErr(event, err, botlib.WithEphemeral(true)) - } - return nil - } -} - -func rolePanelV2EditPanelInfoHandler(b *botlib.Bot[*client.Client]) handler.ComponentHandler { - return func(event *events.ComponentInteractionCreate) error { - args := strings.Split(event.Data.CustomID(), ":") - edit_id, err := uuid.Parse(args[3]) - if err != nil { - return botlib.ReturnErr(event, err, botlib.WithEphemeral(true)) - } - edit, err := b.Self.DB.RolePanelV2Edit().Get(edit_id) - if err != nil { - return botlib.ReturnErrMessage(event, "error_timeout", botlib.WithEphemeral(true)) - } - panel, err := b.Self.DB.RolePanelV2().Get(edit.RolePanelID) - if err != nil { - return botlib.ReturnErr(event, err, botlib.WithEphemeral(true)) - } - modal := discord.NewModalCreateBuilder() - switch args[2] { - case "edit_name": - modal.SetTitle(translate.Message(event.Locale(), "rp_v2_edit_embed_edit_name_modal_title")) - modal.SetCustomID(event.Data.CustomID()) - modal.AddActionRow( - discord.TextInputComponent{ - CustomID: "value", - Style: discord.TextInputStyleShort, - Label: translate.Message(event.Locale(), "rp_v2_create_modal_label_0"), - Value: panel.Name, - MaxLength: 32, - Required: true, - }, - ) - case "edit_description": - modal.SetTitle(translate.Message(event.Locale(), "rp_v2_edit_embed_edit_description_modal_title")) - modal.SetCustomID(event.Data.CustomID()) - modal.AddActionRow( - discord.TextInputComponent{ - CustomID: "value", - Style: discord.TextInputStyleParagraph, - Label: translate.Message(event.Locale(), "rp_v2_create_modal_label_1"), - Value: panel.Description, - MaxLength: 140, - Required: false, - }, - ) - } - if err := event.CreateModal(modal.Build()); err != nil { - return botlib.ReturnErr(event, err, botlib.WithEphemeral(true)) - } - return nil - } -} - -func rolePanelV2EditRolesComponentHandler(b *botlib.Bot[*client.Client]) handler.ComponentHandler { - return func(event *events.ComponentInteractionCreate) error { - b.Self.GuildDataLock(*event.GuildID()).Lock() - defer b.Self.GuildDataLock(*event.GuildID()).Unlock() - args := strings.Split(event.Data.CustomID(), ":") - edit_id, err := uuid.Parse(args[3]) - if err != nil { - return botlib.ReturnErrMessage(event, "error_invalid_id", botlib.WithEphemeral(true)) - } - edit, err := b.Self.DB.RolePanelV2Edit().Get(edit_id) - if err != nil { - return botlib.ReturnErrMessage(event, "error_timeout", botlib.WithEphemeral(true)) - } - panel, err := b.Self.DB.RolePanelV2().Get(edit.RolePanelID) - if err != nil { - return botlib.ReturnErr(event, err, botlib.WithEphemeral(true)) - } - - embed := discord.NewEmbedBuilder() - embed.SetTitle(translate.Message(event.Locale(), "rp_v2_edit_roles_embed_title")) - embed.SetDescription(translate.Message(event.Locale(), "rp_v2_edit_roles_embed_description")) - embed.Embed = botlib.SetEmbedProperties(embed.Embed) - message := discord.NewMessageUpdateBuilder() - message.AddEmbeds(embed.Build()) - max_values := 20 - len(panel.Roles) - disabled := false - if max_values < 1 { - max_values = 1 - disabled = true - } - message.AddContainerComponents( - discord.NewActionRow( - discord.ButtonComponent{ - Style: discord.ButtonStyleSecondary, - Label: translate.Message(event.Locale(), "rp_v2_edit_back_button"), - CustomID: fmt.Sprintf("handler:rp-v2:back_edit_roles:%s", edit.ID.String()), - }, - ), - discord.NewActionRow( - discord.RoleSelectMenuComponent{ - CustomID: fmt.Sprintf("handler:rp-v2:edit_role_select:%s", edit.ID.String()), - Placeholder: translate.Message(event.Locale(), "rp_v2_edit_roles_select_menu_placeholder"), - MaxValues: max_values, - MinValues: json.Ptr(0), - Disabled: disabled, - }, - ), - ) - - token, err := edit.InteractionToken.Get() - if err != nil { - return botlib.ReturnErrMessage(event, "error_timeout", botlib.WithEphemeral(true)) - } - if _, err := event.Client().Rest().UpdateInteractionResponse(event.ApplicationID(), token, message.Build()); err != nil { - return botlib.ReturnErr(event, err, botlib.WithEphemeral(true)) - } - if err := event.DeferUpdateMessage(); err != nil { - return botlib.ReturnErr(event, err, botlib.WithEphemeral(true)) - } - return nil - } -} - -func rolePanelV2BackEditRolesComponentHandler(b *botlib.Bot[*client.Client]) handler.ComponentHandler { - return func(event *events.ComponentInteractionCreate) error { - b.Self.GuildDataLock(*event.GuildID()).Lock() - defer b.Self.GuildDataLock(*event.GuildID()).Unlock() - args := strings.Split(event.Data.CustomID(), ":") - edit_id, err := uuid.Parse(args[3]) - if err != nil { - return botlib.ReturnErrMessage(event, "error_invalid_id", botlib.WithEphemeral(true)) - } - edit, err := b.Self.DB.RolePanelV2Edit().Get(edit_id) - if err != nil { - return botlib.ReturnErrMessage(event, "error_timeout", botlib.WithEphemeral(true)) - } - panel, err := b.Self.DB.RolePanelV2().Get(edit.RolePanelID) - if err != nil { - return botlib.ReturnErr(event, err, botlib.WithEphemeral(true)) - } - - if edit.EmojiMode { - gd, err := b.Self.DB.GuildData().Get(*event.GuildID()) - if err != nil { - return botlib.ReturnErr(event, err, botlib.WithEphemeral(true)) - } - delete(gd.RolePanelV2EditingEmoji, panel.ID) - edit.EmojiMode = false - if err := b.Self.DB.GuildData().Set(gd.ID, gd); err != nil { - return botlib.ReturnErr(event, err, botlib.WithEphemeral(true)) - } - } - - token, err := edit.InteractionToken.Get() - if err != nil { - return botlib.ReturnErrMessage(event, "error_timeout", botlib.WithEphemeral(true)) - } - message := discord.NewMessageUpdateBuilder() - message = db.RolePanelV2EditMenuEmbed(panel, event.Locale(), edit, message) - if _, err := event.Client().Rest().UpdateInteractionResponse(event.ApplicationID(), token, message.Build()); err != nil { - return botlib.ReturnErr(event, err, botlib.WithEphemeral(true)) - } - if err := event.DeferUpdateMessage(); err != nil { - return botlib.ReturnErr(event, err, botlib.WithEphemeral(true)) - } - return nil - } -} - -func rolePanelV2EditRoleSelectComponentHandler(b *botlib.Bot[*client.Client]) handler.ComponentHandler { - return func(event *events.ComponentInteractionCreate) error { - b.Self.GuildDataLock(*event.GuildID()).Lock() - defer b.Self.GuildDataLock(*event.GuildID()).Unlock() - args := strings.Split(event.Data.CustomID(), ":") - edit_id, err := uuid.Parse(args[3]) - if err != nil { - return botlib.ReturnErrMessage(event, "error_invalid_id", botlib.WithEphemeral(true)) - } - edit, err := b.Self.DB.RolePanelV2Edit().Get(edit_id) - if err != nil { - return botlib.ReturnErrMessage(event, "error_timeout", botlib.WithEphemeral(true)) - } - panel, err := b.Self.DB.RolePanelV2().Get(edit.RolePanelID) - if err != nil { - return botlib.ReturnErr(event, err, botlib.WithEphemeral(true)) - } - - selected_role := event.RoleSelectMenuInteractionData().Resolved.Roles - - self, valid := event.Client().Caches().SelfMember(*event.GuildID()) - if !valid { - return botlib.ReturnErrMessage(event, "error_bot_member_not_found", botlib.WithEphemeral(true)) - } - role_map := map[snowflake.ID]discord.Role{} - for _, id := range self.RoleIDs { - role, ok := event.Client().Caches().Role(*event.GuildID(), id) - if !ok { - continue - } - role_map[id] = role - } - hi, _ := botlib.GetHighestRolePosition(role_map) - deleted_role := []snowflake.ID{} - for i, r := range selected_role { - if r.Managed || r.Position >= hi { - delete(selected_role, i) - deleted_role = append(deleted_role, i) - continue - } - var emoji *discord.ComponentEmoji - if r.Emoji != nil { - e := botlib.ParseComponentEmoji(*r.Emoji) - emoji = &e - } - if !panel.AddRole(r.ID, r.Name, emoji) { - delete(selected_role, i) - deleted_role = append(deleted_role, i) - } - } - - token, err := edit.InteractionToken.Get() - if err != nil { - return botlib.ReturnErrMessage(event, "error_timeout", botlib.WithEphemeral(true)) - } - - message_update := discord.NewMessageUpdateBuilder() - message_update = db.RolePanelV2EditMenuEmbed(panel, event.Locale(), edit, message_update) - if _, err := event.Client().Rest().UpdateInteractionResponse(event.ApplicationID(), token, message_update.Build()); err != nil { - return botlib.ReturnErr(event, err, botlib.WithEphemeral(true)) - } - - if err := b.Self.DB.RolePanelV2().Set(panel.ID, panel); err != nil { - return botlib.ReturnErr(event, err, botlib.WithEphemeral(true)) - } - - go rolePanelV2Update(b, *event.GuildID(), panel, event.Locale()) - - if len(deleted_role) < 1 { - if err := event.DeferUpdateMessage(); err != nil { - return botlib.ReturnErr(event, err, botlib.WithEphemeral(true)) - } - return nil - } - - var deleted_role_string string - for _, id := range deleted_role { - deleted_role_string += fmt.Sprintf("- %s\r", discord.RoleMention(id)) - } - - embed := discord.NewEmbedBuilder() - embed.SetTitle(translate.Message(event.Locale(), "rp_v2_edit_role_add_select_deleted_embed_title")) - embed.SetDescriptionf("%s\r%s", - translate.Message(event.Locale(), "rp_v2_edit_role_add_select_deleted_embed_description"), - deleted_role_string, - ) - embed.Embed = botlib.SetEmbedProperties(embed.Embed) - message := discord.NewMessageCreateBuilder() - message.AddEmbeds(embed.Build()) - message.SetFlags(discord.MessageFlagEphemeral) - if err := event.CreateMessage(message.Build()); err != nil { - return botlib.ReturnErr(event, err, botlib.WithEphemeral(true)) - } - - return nil - } -} - -func rolePanelV2EditRoleNameComponentHandler(b *botlib.Bot[*client.Client]) handler.ComponentHandler { - return func(event *events.ComponentInteractionCreate) error { - b.Self.GuildDataLock(*event.GuildID()).Lock() - defer b.Self.GuildDataLock(*event.GuildID()).Unlock() - args := strings.Split(event.Data.CustomID(), ":") - edit_id, err := uuid.Parse(args[3]) - if err != nil { - return botlib.ReturnErrMessage(event, "error_invalid_id", botlib.WithEphemeral(true)) - } - edit, err := b.Self.DB.RolePanelV2Edit().Get(edit_id) - if err != nil { - return botlib.ReturnErrMessage(event, "error_timeout", botlib.WithEphemeral(true)) - } - panel, err := b.Self.DB.RolePanelV2().Get(edit.RolePanelID) - if err != nil { - return botlib.ReturnErr(event, err, botlib.WithEphemeral(true)) - } - - if edit.SelectedID == nil { - return botlib.ReturnErrMessage(event, "error_unavailable", botlib.WithEphemeral(true)) - } - role_index := slices.IndexFunc(panel.Roles, func(rpvr db.RolePanelV2Role) bool { - return rpvr.RoleID == *edit.SelectedID - }) - if role_index == -1 { - return botlib.ReturnErrMessage(event, "error_unavailable", botlib.WithEphemeral(true)) - } - - modal := discord.NewModalCreateBuilder() - modal.SetTitle(translate.Message(event.Locale(), "rp_v2_edit_role_name_modal_title")) - modal.SetCustomID(fmt.Sprintf("handler:rp-v2:edit_role_name:%s", edit.ID)) - modal.AddActionRow( - discord.TextInputComponent{ - CustomID: "name", - Style: discord.TextInputStyleShort, - Label: translate.Message(event.Locale(), "rp_v2_edit_role_name_modal_label"), - MaxLength: 32, - Value: panel.Roles[role_index].RoleName, - Required: true, - }, - ) - - if err := event.CreateModal(modal.Build()); err != nil { - return botlib.ReturnErr(event, err, botlib.WithEphemeral(true)) - } - return nil - } -} - -func rolePanelV2EditRoleDeleteComponent(b *botlib.Bot[*client.Client]) handler.ComponentHandler { - return func(event *events.ComponentInteractionCreate) error { - b.Self.GuildDataLock(*event.GuildID()).Lock() - defer b.Self.GuildDataLock(*event.GuildID()).Unlock() - args := strings.Split(event.Data.CustomID(), ":") - edit_id, err := uuid.Parse(args[3]) - if err != nil { - return botlib.ReturnErrMessage(event, "error_invalid_id", botlib.WithEphemeral(true)) - } - edit, err := b.Self.DB.RolePanelV2Edit().Get(edit_id) - if err != nil { - return botlib.ReturnErrMessage(event, "error_timeout", botlib.WithEphemeral(true)) - } - panel, err := b.Self.DB.RolePanelV2().Get(edit.RolePanelID) - if err != nil { - return botlib.ReturnErr(event, err, botlib.WithEphemeral(true)) - } - - if edit.SelectedID == nil { - return botlib.ReturnErrMessage(event, "error_unavailable", botlib.WithEphemeral(true)) - } - role_index := slices.IndexFunc(panel.Roles, func(rpvr db.RolePanelV2Role) bool { - return rpvr.RoleID == *edit.SelectedID - }) - if role_index == -1 { - return botlib.ReturnErrMessage(event, "error_unavailable", botlib.WithEphemeral(true)) - } - - panel.Roles = slices.Delete(panel.Roles, role_index, role_index+1) - edit.SelectedID = nil - - if err := b.Self.DB.RolePanelV2().Set(panel.ID, panel); err != nil { - return botlib.ReturnErr(event, err, botlib.WithEphemeral(true)) - } - if err := b.Self.DB.RolePanelV2Edit().Set(edit.ID, edit); err != nil { - return botlib.ReturnErr(event, err, botlib.WithEphemeral(true)) - } - - token, err := edit.InteractionToken.Get() - if err != nil { - return botlib.ReturnErrMessage(event, "error_timeout", botlib.WithEphemeral(true)) - } - - go rolePanelV2Update(b, *event.GuildID(), panel, event.Locale()) - - message := db.RolePanelV2EditMenuEmbed(panel, event.Locale(), edit, discord.NewMessageUpdateBuilder()) - if _, err := event.Client().Rest().UpdateInteractionResponse(event.ApplicationID(), token, message.Build()); err != nil { - return botlib.ReturnErr(event, err, botlib.WithEphemeral(true)) - } - - if err := event.DeferUpdateMessage(); err != nil { - return botlib.ReturnErr(event, err, botlib.WithEphemeral(true)) - } - - return nil - } -} - -func rolePanelV2EditRoleEmojiComponentHandler(b *botlib.Bot[*client.Client]) handler.ComponentHandler { - return func(event *events.ComponentInteractionCreate) error { - b.Self.GuildDataLock(*event.GuildID()).Lock() - defer b.Self.GuildDataLock(*event.GuildID()).Unlock() - args := strings.Split(event.Data.CustomID(), ":") - edit_id, err := uuid.Parse(args[3]) - if err != nil { - return botlib.ReturnErrMessage(event, "error_invalid_id", botlib.WithEphemeral(true)) - } - edit, err := b.Self.DB.RolePanelV2Edit().Get(edit_id) - if err != nil { - return botlib.ReturnErrMessage(event, "error_timeout", botlib.WithEphemeral(true)) - } - panel, err := b.Self.DB.RolePanelV2().Get(edit.RolePanelID) - if err != nil { - return botlib.ReturnErr(event, err, botlib.WithEphemeral(true)) - } - gd, err := b.Self.DB.GuildData().Get(*event.GuildID()) - if err != nil { - return botlib.ReturnErr(event, err, botlib.WithEphemeral(true)) - } - - gd.RolePanelV2EditingEmoji[panel.ID] = [2]snowflake.ID{ - event.Channel().ID(), - event.User().ID, - } - edit.EmojiMode = true - edit.EmojiLocale = event.Locale() - - if err := b.Self.DB.RolePanelV2Edit().Set(edit.ID, edit); err != nil { - return botlib.ReturnErr(event, err, botlib.WithEphemeral(true)) - } - if err := b.Self.DB.GuildData().Set(gd.ID, gd); err != nil { - return botlib.ReturnErr(event, err, botlib.WithEphemeral(true)) - } - - embed := discord.NewEmbedBuilder() - embed.SetTitle(translate.Message(event.Locale(), "rp_v2_edit_role_emoji_embed_title")) - embed.SetDescription(translate.Message(event.Locale(), "rp_v2_edit_role_emoji_embed_description")) - embed.Embed = botlib.SetEmbedProperties(embed.Embed) - - message := discord.NewMessageUpdateBuilder() - message.AddEmbeds(embed.Build()) - - message.AddContainerComponents( - discord.NewActionRow( - discord.ButtonComponent{ - Style: discord.ButtonStyleSecondary, - Label: translate.Message(event.Locale(), "rp_v2_edit_back_button"), - CustomID: fmt.Sprintf("handler:rp-v2:back_edit_roles:%s", edit.ID.String()), - }, - ), - ) - - token, err := edit.InteractionToken.Get() - if err != nil { - return botlib.ReturnErrMessage(event, "error_timeout", botlib.WithEphemeral(true)) - } - if _, err := event.Client().Rest().UpdateInteractionResponse(event.ApplicationID(), token, message.Build()); err != nil { - return botlib.ReturnErr(event, err, botlib.WithEphemeral(true)) - } - - if err := event.DeferUpdateMessage(); err != nil { - return botlib.ReturnErr(event, err, botlib.WithEphemeral(true)) - } - - return nil - } -} - -func rolePanelV2PlaceTypeComponentHandler(b *botlib.Bot[*client.Client]) handler.ComponentHandler { - return func(event *events.ComponentInteractionCreate) error { - b.Self.GuildDataLock(*event.GuildID()).Lock() - defer b.Self.GuildDataLock(*event.GuildID()).Unlock() - - args := strings.Split(event.Data.CustomID(), ":") - place_id, err := uuid.Parse(args[3]) - if err != nil { - return botlib.ReturnErrMessage(event, "error_invalid_id") - } - place, err := b.Self.DB.RolePanelV2Place().Get(place_id) - if err != nil { - return botlib.ReturnErr(event, err, botlib.WithEphemeral(true)) - } - panel, err := b.Self.DB.RolePanelV2().Get(place.PanelID) - if err != nil { - return botlib.ReturnErr(event, err, botlib.WithEphemeral(true)) - } - - place.Config.PanelType = db.RolePanelV2Type(event.StringSelectMenuInteractionData().Values[0]) - - if err := b.Self.DB.RolePanelV2Place().Set(place.ID, place); err != nil { - return botlib.ReturnErr(event, err, botlib.WithEphemeral(true)) - } - - message := discord.NewMessageUpdateBuilder() - message = db.RolePanelV2PlaceMenuEmbed(panel, event.Locale(), place, message) - - token, err := place.InteractionToken.Get() - if err != nil { - return botlib.ReturnErrMessage(event, "error_timeout", botlib.WithEphemeral(true)) - } - - if _, err := event.Client().Rest().UpdateInteractionResponse(event.ApplicationID(), token, message.Build()); err != nil { - return botlib.ReturnErr(event, err, botlib.WithEphemeral(true)) - } - if err := event.DeferUpdateMessage(); err != nil { - return botlib.ReturnErr(event, err, botlib.WithEphemeral(true)) - } - - return nil - } -} - -func rolePanelV2PlaceSimpleSelectMenuComponentHandler(b *botlib.Bot[*client.Client]) handler.ComponentHandler { - return func(event *events.ComponentInteractionCreate) error { - b.Self.GuildDataLock(*event.GuildID()).Lock() - defer b.Self.GuildDataLock(*event.GuildID()).Unlock() - - args := strings.Split(event.Data.CustomID(), ":") - place_id, err := uuid.Parse(args[3]) - if err != nil { - return botlib.ReturnErrMessage(event, "error_invalid_id") - } - place, err := b.Self.DB.RolePanelV2Place().Get(place_id) - if err != nil { - return botlib.ReturnErr(event, err, botlib.WithEphemeral(true)) - } - panel, err := b.Self.DB.RolePanelV2().Get(place.PanelID) - if err != nil { - return botlib.ReturnErr(event, err, botlib.WithEphemeral(true)) - } - - place.Config.SimpleSelectMenu = !place.Config.SimpleSelectMenu - - if err := b.Self.DB.RolePanelV2Place().Set(place.ID, place); err != nil { - return botlib.ReturnErr(event, err, botlib.WithEphemeral(true)) - } - - message := discord.NewMessageUpdateBuilder() - message = db.RolePanelV2PlaceMenuEmbed(panel, event.Locale(), place, message) - - token, err := place.InteractionToken.Get() - if err != nil { - return botlib.ReturnErrMessage(event, "error_timeout", botlib.WithEphemeral(true)) - } - - if _, err := event.Client().Rest().UpdateInteractionResponse(event.ApplicationID(), token, message.Build()); err != nil { - return botlib.ReturnErr(event, err, botlib.WithEphemeral(true)) - } - if err := event.DeferUpdateMessage(); err != nil { - return botlib.ReturnErr(event, err, botlib.WithEphemeral(true)) - } - - return nil - } -} - -func rolePanelV2PlaceButtonShowNameComponentHandler(b *botlib.Bot[*client.Client]) handler.ComponentHandler { - return func(event *events.ComponentInteractionCreate) error { - b.Self.GuildDataLock(*event.GuildID()).Lock() - defer b.Self.GuildDataLock(*event.GuildID()).Unlock() - - args := strings.Split(event.Data.CustomID(), ":") - place_id, err := uuid.Parse(args[3]) - if err != nil { - return botlib.ReturnErrMessage(event, "error_invalid_id") - } - place, err := b.Self.DB.RolePanelV2Place().Get(place_id) - if err != nil { - return botlib.ReturnErr(event, err, botlib.WithEphemeral(true)) - } - panel, err := b.Self.DB.RolePanelV2().Get(place.PanelID) - if err != nil { - return botlib.ReturnErr(event, err, botlib.WithEphemeral(true)) - } - - place.Config.ButtonShowName = !place.Config.ButtonShowName - - if err := b.Self.DB.RolePanelV2Place().Set(place.ID, place); err != nil { - return botlib.ReturnErr(event, err, botlib.WithEphemeral(true)) - } - - message := discord.NewMessageUpdateBuilder() - message = db.RolePanelV2PlaceMenuEmbed(panel, event.Locale(), place, message) - - token, err := place.InteractionToken.Get() - if err != nil { - return botlib.ReturnErrMessage(event, "error_timeout", botlib.WithEphemeral(true)) - } - - if _, err := event.Client().Rest().UpdateInteractionResponse(event.ApplicationID(), token, message.Build()); err != nil { - return botlib.ReturnErr(event, err, botlib.WithEphemeral(true)) - } - if err := event.DeferUpdateMessage(); err != nil { - return botlib.ReturnErr(event, err, botlib.WithEphemeral(true)) - } - - return nil - } -} - -func rolePanelV2PlaceButtonColorComponentHandler(b *botlib.Bot[*client.Client]) handler.ComponentHandler { - return func(event *events.ComponentInteractionCreate) error { - b.Self.GuildDataLock(*event.GuildID()).Lock() - defer b.Self.GuildDataLock(*event.GuildID()).Unlock() - - args := strings.Split(event.Data.CustomID(), ":") - place_id, err := uuid.Parse(args[3]) - if err != nil { - return botlib.ReturnErrMessage(event, "error_invalid_id") - } - place, err := b.Self.DB.RolePanelV2Place().Get(place_id) - if err != nil { - return botlib.ReturnErr(event, err, botlib.WithEphemeral(true)) - } - panel, err := b.Self.DB.RolePanelV2().Get(place.PanelID) - if err != nil { - return botlib.ReturnErr(event, err, botlib.WithEphemeral(true)) - } - - value := event.StringSelectMenuInteractionData().Values[0] - - switch value { - case "red": - place.Config.ButtonStyle = discord.ButtonStyleDanger - case "green": - place.Config.ButtonStyle = discord.ButtonStyleSuccess - case "blue": - place.Config.ButtonStyle = discord.ButtonStylePrimary - case "gray": - place.Config.ButtonStyle = discord.ButtonStyleSecondary - } - - if err := b.Self.DB.RolePanelV2Place().Set(place.ID, place); err != nil { - return botlib.ReturnErr(event, err, botlib.WithEphemeral(true)) - } - - message := discord.NewMessageUpdateBuilder() - message = db.RolePanelV2PlaceMenuEmbed(panel, event.Locale(), place, message) - - token, err := place.InteractionToken.Get() - if err != nil { - return botlib.ReturnErrMessage(event, "error_timeout", botlib.WithEphemeral(true)) - } - - if _, err := event.Client().Rest().UpdateInteractionResponse(event.ApplicationID(), token, message.Build()); err != nil { - return botlib.ReturnErr(event, err, botlib.WithEphemeral(true)) - } - if err := event.DeferUpdateMessage(); err != nil { - return botlib.ReturnErr(event, err, botlib.WithEphemeral(true)) - } - - return nil - } -} - -func rolePanelV2PlaceComponentHandler(b *botlib.Bot[*client.Client]) handler.ComponentHandler { - return func(event *events.ComponentInteractionCreate) error { - b.Self.GuildDataLock(*event.GuildID()).Lock() - defer b.Self.GuildDataLock(*event.GuildID()).Unlock() - - args := strings.Split(event.Data.CustomID(), ":") - place_id, err := uuid.Parse(args[3]) - if err != nil { - return botlib.ReturnErrMessage(event, "error_invalid_id", botlib.WithEphemeral(true)) - } - place, err := b.Self.DB.RolePanelV2Place().Get(place_id) - if err != nil { - return botlib.ReturnErr(event, err, botlib.WithEphemeral(true)) - } - panel, err := b.Self.DB.RolePanelV2().Get(place.PanelID) - if err != nil { - return botlib.ReturnErr(event, err, botlib.WithEphemeral(true)) - } - gd, err := b.Self.DB.GuildData().Get(*event.GuildID()) - if err != nil { - return botlib.ReturnErr(event, err, botlib.WithEphemeral(true)) - } - - if len(panel.Roles) < 1 { - return botlib.ReturnErrMessage(event, "error_has_no_data", botlib.WithEphemeral(true)) - } - - token, err := place.InteractionToken.Get() - if err != nil { - return botlib.ReturnErrMessage(event, "error_timeout", botlib.WithEphemeral(true)) - } - if err := event.Client().Rest().DeleteInteractionResponse(event.ApplicationID(), token); err != nil { - return botlib.ReturnErr(event, err, botlib.WithEphemeral(true)) - } - - if err := panelPlace(b, panel, place, &gd, event.Locale(), event.Channel().ID()); err != nil { - return botlib.ReturnErr(event, err, botlib.WithEphemeral(true)) - } - - if err := event.DeferUpdateMessage(); err != nil { - return botlib.ReturnErr(event, err, botlib.WithEphemeral(true)) - } - return nil - } -} - -func rolePanelV2UseSelectMenuComponentHandler(b *botlib.Bot[*client.Client]) handler.ComponentHandler { - return func(event *events.ComponentInteractionCreate) error { - b.Self.GuildDataLock(*event.GuildID()).Lock() - defer b.Self.GuildDataLock(*event.GuildID()).Unlock() - gd, err := b.Self.DB.GuildData().Get(*event.GuildID()) - if err != nil { - return botlib.ReturnErr(event, err, botlib.WithEphemeral(true)) - } - - key := fmt.Sprintf("%s/%s", event.Message.ChannelID, event.Message.ID) - panel_id, ok := gd.RolePanelV2Placed[key] - if !ok && !event.Message.Flags.Has(discord.MessageFlagEphemeral) { - return botlib.ReturnErrMessage(event, "error_not_found", botlib.WithEphemeral(true)) - } - if event.Message.Flags.Has(discord.MessageFlagEphemeral) { - panel_id = uuid.MustParse(strings.Split(event.Data.CustomID(), ":")[3]) - } - panel, err := b.Self.DB.RolePanelV2().Get(panel_id) - if err != nil { - return botlib.ReturnErr(event, err, botlib.WithEphemeral(true)) - } - - selected_roles := []snowflake.ID{} - for _, v := range event.StringSelectMenuInteractionData().Values { - selected_roles = append(selected_roles, snowflake.MustParse(v)) - } - - if err := event.DeferCreateMessage(true); err != nil { - return botlib.ReturnErr(event, err) - } - - add_roles := []snowflake.ID{} - removed_roles := []snowflake.ID{} - unchanged_role := []snowflake.ID{} - for _, role := range panel.Roles { - if slices.Index(selected_roles, role.RoleID) != -1 { - // 遞ばれたずき - if slices.Index(event.Member().RoleIDs, role.RoleID) != -1 { - // 持っおたなら - unchanged_role = append(unchanged_role, role.RoleID) - continue - } else { - // 持っおないなら - add_roles = append(add_roles, role.RoleID) - - if err := event.Client().Rest().AddMemberRole(*event.GuildID(), event.User().ID, role.RoleID); err != nil { - embed := discord.NewEmbedBuilder(). - SetTitle(translate.Message(event.Locale(), "rp_v2_add_role_failed_embed_title")). - SetDescription(translate.Message(event.Locale(), "rp_v2_add_role_failed_embed_description")) - embed.Embed = botlib.SetEmbedProperties(embed.Embed) - if _, err := event.Client().Rest().UpdateInteractionResponse( - event.ApplicationID(), - event.Token(), - discord.MessageUpdate{ - Embeds: &[]discord.Embed{ - embed.Build(), - }, - }); err != nil { - return botlib.ReturnErr(event, err, botlib.WithEphemeral(true), botlib.WithUpdate(true, event.Client())) - } - return err - } - } - } else { - // 遞ばれおないずき - if slices.Index(event.Member().RoleIDs, role.RoleID) != -1 { - // 持っおたなら - removed_roles = append(removed_roles, role.RoleID) - - if err := event.Client().Rest().RemoveMemberRole(*event.GuildID(), event.User().ID, role.RoleID); err != nil { - embed := discord.NewEmbedBuilder(). - SetTitle(translate.Message(event.Locale(), "rp_v2_remove_role_failed_embed_title")). - SetDescription(translate.Message(event.Locale(), "rp_v2_remove_role_failed_embed_description")) - embed.Embed = botlib.SetEmbedProperties(embed.Embed) - if _, err := event.Client().Rest().UpdateInteractionResponse( - event.ApplicationID(), - event.Token(), - discord.MessageUpdate{ - Embeds: &[]discord.Embed{ - embed.Build(), - }, - }); err != nil { - return botlib.ReturnErr(event, err, botlib.WithEphemeral(true), botlib.WithUpdate(true, event.Client())) - } - return err - } - } else { - // 持っおないなら - continue - } - } - } - - embed := discord.NewEmbedBuilder() - embed.SetTitle(translate.Message(event.Locale(), "rp_v2_select_menu_used")) - if len(add_roles) > 0 { - var add_roles_string string - for _, id := range add_roles { - add_roles_string += fmt.Sprintf("%s\r", discord.RoleMention(id)) - } - embed.AddFields( - discord.EmbedField{ - Name: translate.Message(event.Locale(), "rp_v2_add_role"), - Value: add_roles_string, - }, - ) - } - if len(unchanged_role) > 0 { - var unchanged_role_string string - for _, id := range unchanged_role { - unchanged_role_string += fmt.Sprintf("%s\r", discord.RoleMention(id)) - } - embed.AddFields( - discord.EmbedField{ - Name: translate.Message(event.Locale(), "rp_v2_unchanged_role"), - Value: unchanged_role_string, - }, - ) - } - if len(removed_roles) > 0 { - var removed_roles_string string - for _, id := range removed_roles { - removed_roles_string += fmt.Sprintf("%s\r", discord.RoleMention(id)) - } - embed.AddFields( - discord.EmbedField{ - Name: translate.Message(event.Locale(), "rp_v2_removed_role"), - Value: removed_roles_string, - }, - ) - } - embed.Embed = botlib.SetEmbedProperties(embed.Embed) - message := discord.NewMessageUpdateBuilder() - message.AddEmbeds(embed.Build()) - message.SetFlags(discord.MessageFlagEphemeral) - if _, err := event.Client().Rest().UpdateInteractionResponse(event.ApplicationID(), event.Token(), message.Build()); err != nil { - return botlib.ReturnErr(event, err, botlib.WithEphemeral(true), botlib.WithUpdate(true, event.Client())) - } - return nil - } -} - -func rolePanelV2UseButtonComponentHandler(b *botlib.Bot[*client.Client]) handler.ComponentHandler { - return func(event *events.ComponentInteractionCreate) error { - b.Self.GuildDataLock(*event.GuildID()).Lock() - defer b.Self.GuildDataLock(*event.GuildID()).Unlock() - - args := strings.Split(event.ButtonInteractionData().CustomID(), ":") - - role_id, err := snowflake.Parse(args[4]) - if err != nil { - return botlib.ReturnErrMessage(event, "error_timeout", botlib.WithEphemeral(true)) - } - - if slices.Index(event.Member().RoleIDs, role_id) == -1 { - if err := event.Client().Rest().AddMemberRole(*event.GuildID(), event.User().ID, role_id); err != nil { - embed := discord.NewEmbedBuilder(). - SetTitle(translate.Message(event.Locale(), "rp_v2_add_role_failed_embed_title")). - SetDescription(translate.Message(event.Locale(), "rp_v2_add_role_failed_embed_description")) - embed.Embed = botlib.SetEmbedProperties(embed.Embed) - if err := event.CreateMessage(discord.MessageCreate{ - Embeds: []discord.Embed{ - embed.Build(), - }, - Flags: discord.MessageFlagEphemeral, - }); err != nil { - return botlib.ReturnErr(event, err, botlib.WithEphemeral(true)) - } - return err - } - embed := discord.NewEmbedBuilder(). - SetTitle(translate.Message(event.Locale(), "rp_v2_add_role_added_embed_title")). - SetDescription(translate.Message(event.Locale(), "rp_v2_add_role_added_embed_description", translate.WithTemplate(map[string]any{"Role": discord.RoleMention(role_id)}))) - embed.Embed = botlib.SetEmbedProperties(embed.Embed) - if err := event.CreateMessage(discord.MessageCreate{ - Embeds: []discord.Embed{ - embed.Build(), - }, - Flags: discord.MessageFlagEphemeral, - }); err != nil { - return botlib.ReturnErr(event, err, botlib.WithEphemeral(true)) - } - } else { - if err := event.Client().Rest().RemoveMemberRole(*event.GuildID(), event.User().ID, role_id); err != nil { - embed := discord.NewEmbedBuilder(). - SetTitle(translate.Message(event.Locale(), "rp_v2_remove_role_failed_embed_title")). - SetDescription(translate.Message(event.Locale(), "rp_v2_remove_role_failed_embed_description")) - embed.Embed = botlib.SetEmbedProperties(embed.Embed) - if err := event.CreateMessage(discord.MessageCreate{ - Embeds: []discord.Embed{ - embed.Build(), - }, - Flags: discord.MessageFlagEphemeral, - }); err != nil { - return botlib.ReturnErr(event, err, botlib.WithEphemeral(true)) - } - return err - } - embed := discord.NewEmbedBuilder(). - SetTitle(translate.Message(event.Locale(), "rp_v2_add_role_removed_embed_title")). - SetDescription(translate.Message(event.Locale(), "rp_v2_add_role_removed_embed_description", translate.WithTemplate(map[string]any{"Role": discord.RoleMention(role_id)}))) - embed.Embed = botlib.SetEmbedProperties(embed.Embed) - if err := event.CreateMessage(discord.MessageCreate{ - Embeds: []discord.Embed{ - embed.Build(), - }, - Flags: discord.MessageFlagEphemeral, - }); err != nil { - return botlib.ReturnErr(event, err, botlib.WithEphemeral(true)) - } - } - return nil - } -} - -func rolePanelV2CallSelectMenuComponentHandler(b *botlib.Bot[*client.Client]) handler.ComponentHandler { - return func(event *events.ComponentInteractionCreate) error { - b.Self.GuildDataLock(*event.GuildID()).Lock() - defer b.Self.GuildDataLock(*event.GuildID()).Unlock() - gd, err := b.Self.DB.GuildData().Get(*event.GuildID()) - if err != nil { - return botlib.ReturnErr(event, err, botlib.WithEphemeral(true)) - } - key := fmt.Sprintf("%s/%s", event.Message.ChannelID, event.Message.ID) - panel_id, ok := gd.RolePanelV2Placed[key] - if !ok { - return botlib.ReturnErrMessage(event, "error_not_found", botlib.WithEphemeral(true)) - } - panel, err := b.Self.DB.RolePanelV2().Get(panel_id) - if err != nil { - return botlib.ReturnErr(event, err, botlib.WithEphemeral(true)) - } - - embed := discord.NewEmbedBuilder() - embed.SetTitle(translate.Message(event.Locale(), "rp_v2_call_select_menu_embed_title")) - embed.SetDescription(translate.Message(event.Locale(), "rp_v2_call_select_menu_embed_description")) - embed.Embed = botlib.SetEmbedProperties(embed.Embed) - message := discord.NewMessageCreateBuilder() - message.AddEmbeds(embed.Build()) - options := make([]discord.StringSelectMenuOption, len(panel.Roles)) - for i, rpvr := range panel.Roles { - options[i] = discord.StringSelectMenuOption{ - Label: rpvr.RoleName, - Value: rpvr.RoleID.String(), - Emoji: rpvr.Emoji, - Default: slices.Contains(event.Member().RoleIDs, rpvr.RoleID), - } - } - message.AddContainerComponents( - discord.NewActionRow( - discord.StringSelectMenuComponent{ - CustomID: fmt.Sprintf("handler:rp-v2:use_select_menu:%s", panel.ID.String()), - Placeholder: translate.Message(event.Locale(), "rp_v2_select_menu_placeholder"), - MinValues: json.Ptr(0), - MaxValues: len(panel.Roles), - Options: options, - }, - ), - ) - message.SetFlags(discord.MessageFlagEphemeral) - - if err := event.CreateMessage(message.Build()); err != nil { - return botlib.ReturnErr(event, err, botlib.WithEphemeral(true)) - } - return nil - } -} - -func rolePanelV2ConvertComponentHandler(b *botlib.Bot[*client.Client]) handler.ComponentHandler { - return func(event *events.ComponentInteractionCreate) error { - b.Self.GuildDataLock(*event.GuildID()).Lock() - defer b.Self.GuildDataLock(*event.GuildID()).Unlock() - args := strings.Split(event.Data.CustomID(), ":") - channel_id, err := snowflake.Parse(args[3]) - if err != nil { - return botlib.ReturnErrMessage(event, "error_invalid_id", botlib.WithEphemeral(true)) - } - message_id, err := snowflake.Parse(args[4]) - if err != nil { - return botlib.ReturnErrMessage(event, "error_invalid_id", botlib.WithEphemeral(true)) - } - message, err := event.Client().Rest().GetMessage(channel_id, message_id) - if err != nil { - return botlib.ReturnErr(event, err) - } - - if err := event.DeferCreateMessage(true); err != nil { - return botlib.ReturnErr(event, err, botlib.WithEphemeral(true)) - } - - lines := strings.Split(message.Embeds[0].Description, "\n") - b.Logger.Debugf("lines %d", len(lines)) - roles := []db.RolePanelV2Role{} - role_count := 0 - for _, v := range lines { - if !role_regexp.MatchString(v) { - b.Logger.Debug("failed role regexp") - continue - } - var emojis []string - if !emoji.MatchString(v) { - emojis = append(emojis, botlib.Number2Emoji(role_count+1)) - } else { - emojis = emoji.FindAllString(v) - } - component_emoji := botlib.ParseComponentEmoji(emojis[0]) - if _, ok := event.Client().Caches().Emoji(*event.GuildID(), component_emoji.ID); !ok && component_emoji.ID != 0 { - component_emoji = botlib.ParseComponentEmoji(botlib.Number2Emoji(role_count + 1)) - } - role_id, err := snowflake.Parse(role_id_regexp.FindString(role_regexp.FindString(v))) - if err != nil { - b.Logger.Debug("failed parse role id") - continue - } - role, ok := event.Client().Caches().Role(*event.GuildID(), role_id) - if !ok { - role_ptr, err := event.Client().Rest().GetRole(*event.GuildID(), role_id) - if err != nil { - b.Logger.Debug("failed get role id") - continue - } - role = *role_ptr - } - role_count++ - roles = append(roles, db.RolePanelV2Role{ - RoleID: role.ID, - RoleName: role.Name, - Emoji: &component_emoji, - }) - } - if len(roles) < 1 { - return botlib.ReturnErrMessage(event, "error_convert_failed_no_role", botlib.WithEphemeral(true), botlib.WithUpdate(true, event.Client())) - } - panel := db.NewRolePanelV2(message.Embeds[0].Title, "") - for _, r := range roles { - panel.AddRole(r.RoleID, r.RoleName, r.Emoji) - } - if err := b.Self.DB.RolePanelV2().Set(panel.ID, panel); err != nil { - return botlib.ReturnErr(event, err, botlib.WithEphemeral(true), botlib.WithUpdate(true, event.Client())) - } - gd, err := b.Self.DB.GuildData().Get(*event.GuildID()) - if err != nil { - return botlib.ReturnErr(event, err, botlib.WithEphemeral(true), botlib.WithUpdate(true, event.Client())) - } - gd.RolePanelV2[panel.ID] = panel.Name - gd.RolePanelV2Name[panel.Name]++ - if err := panelPlace(b, panel, &db.RolePanelV2Place{ - Config: db.RolePanelV2Config{ - PanelType: db.RolePanelV2TypeReaction, - }, - }, &gd, event.Locale(), channel_id); err != nil { - return botlib.ReturnErr(event, err, botlib.WithEphemeral(true), botlib.WithUpdate(true, event.Client())) - } - if err := event.Client().Rest().DeleteInteractionResponse(event.ApplicationID(), event.Token()); err != nil { - return botlib.ReturnErr(event, err, botlib.WithEphemeral(true), botlib.WithUpdate(true, event.Client())) - } - return nil - } -} - -func RolePanelV2Modal(b *botlib.Bot[*client.Client]) handler.Modal { - return handler.Modal{ - Name: "rp-v2", - Handler: map[string]handler.ModalHandler{ - "create-modal": rolePanelV2CreateModalHandler(b), - "edit_name": rolePanelV2EditPanelInfoModalHandler(b), - "edit_description": rolePanelV2EditPanelInfoModalHandler(b), - "edit_role_name": rolePanelV2EditRoleNameModalHandler(b), - }, - } -} - -func rolePanelV2CreateModalHandler(b *botlib.Bot[*client.Client]) handler.ModalHandler { - return func(event *events.ModalSubmitInteractionCreate) error { - b.Self.GuildDataLock(*event.GuildID()).Lock() - defer b.Self.GuildDataLock(*event.GuildID()).Unlock() - name := event.ModalSubmitInteraction.Data.Text("name") - description := event.ModalSubmitInteraction.Data.Text("description") - rp := db.NewRolePanelV2(name, description) - gd, err := b.Self.DB.GuildData().Get(*event.GuildID()) - if err != nil { - return botlib.ReturnErr(event, err, botlib.WithEphemeral(true)) - } - gd.RolePanelV2[rp.ID] = rp.Name - gd.RolePanelV2Name[rp.Name]++ - if err := b.Self.DB.RolePanelV2().Set(rp.ID, rp); err != nil { - return botlib.ReturnErr(event, err, botlib.WithEphemeral(true)) - } - - edit := db.NewRolePanelV2Edit(rp.ID, *event.GuildID(), event.Channel().ID(), interactions.New(event.Token(), event.CreatedAt())) - if err := b.Self.DB.RolePanelV2Edit().Set(edit.ID, edit); err != nil { - return botlib.ReturnErr(event, err, botlib.WithEphemeral(true)) - } - - gd.RolePanelV2Editing[rp.ID] = edit.ID - - if err := b.Self.DB.GuildData().Set(gd.ID, gd); err != nil { - return botlib.ReturnErr(event, err, botlib.WithEphemeral(true)) - } - - message := discord.NewMessageCreateBuilder() - message = db.RolePanelV2EditMenuEmbed(rp, event.Locale(), edit, message) - message.SetFlags(discord.MessageFlagEphemeral) - - if err := event.CreateMessage(message.Build()); err != nil { - return botlib.ReturnErr(event, err, botlib.WithEphemeral(true)) - } - return nil - } -} - -func rolePanelV2EditPanelInfoModalHandler(b *botlib.Bot[*client.Client]) handler.ModalHandler { - return func(event *events.ModalSubmitInteractionCreate) error { - b.Self.GuildDataLock(*event.GuildID()).Lock() - defer b.Self.GuildDataLock(*event.GuildID()).Unlock() - args := strings.Split(event.Data.CustomID, ":") - edit_id, err := uuid.Parse(args[3]) - if err != nil { - return botlib.ReturnErr(event, err, botlib.WithEphemeral(true)) - } - edit, err := b.Self.DB.RolePanelV2Edit().Get(edit_id) - if err != nil { - return botlib.ReturnErr(event, err, botlib.WithEphemeral(true)) - } - panel, err := b.Self.DB.RolePanelV2().Get(edit.RolePanelID) - if err != nil { - return botlib.ReturnErr(event, err, botlib.WithEphemeral(true)) - } - value := event.ModalSubmitInteraction.Data.Text("value") - switch args[2] { - case "edit_name": - gd, err := b.Self.DB.GuildData().Get(edit.GuildID) - if err != nil { - return botlib.ReturnErr(event, err, botlib.WithEphemeral(true)) - } - - gd.RolePanelV2Name[panel.Name]-- - gd.RolePanelV2Name[value]++ - gd.RolePanelV2[panel.ID] = value - - if err := b.Self.DB.GuildData().Set(gd.ID, gd); err != nil { - return botlib.ReturnErr(event, err, botlib.WithEphemeral(true)) - } - - panel.Name = value - case "edit_description": - panel.Description = value - } - if err := b.Self.DB.RolePanelV2().Set(panel.ID, panel); err != nil { - return nil - } - token, err := edit.InteractionToken.Get() - if err != nil { - return botlib.ReturnErrMessage(event, "error_timeout", botlib.WithEphemeral(true)) - } - message := discord.NewMessageUpdateBuilder() - message = db.RolePanelV2EditMenuEmbed(panel, event.Locale(), edit, message) - if _, err := event.Client().Rest().UpdateInteractionResponse(event.ApplicationID(), token, message.Build()); err != nil { - return botlib.ReturnErr(event, err, botlib.WithEphemeral(true)) - } - - go rolePanelV2Update(b, *event.GuildID(), panel, event.Locale()) - - if err := event.DeferUpdateMessage(); err != nil { - return botlib.ReturnErr(event, err, botlib.WithEphemeral(true)) - } - return nil - } -} - -func rolePanelV2EditRoleNameModalHandler(b *botlib.Bot[*client.Client]) handler.ModalHandler { - return func(event *events.ModalSubmitInteractionCreate) error { - b.Self.GuildDataLock(*event.GuildID()).Lock() - defer b.Self.GuildDataLock(*event.GuildID()).Unlock() - args := strings.Split(event.Data.CustomID, ":") - edit_id, err := uuid.Parse(args[3]) - if err != nil { - return botlib.ReturnErrMessage(event, "error_invalid_id", botlib.WithEphemeral(true)) - } - edit, err := b.Self.DB.RolePanelV2Edit().Get(edit_id) - if err != nil { - return botlib.ReturnErr(event, err, botlib.WithEphemeral(true)) - } - panel, err := b.Self.DB.RolePanelV2().Get(edit.RolePanelID) - if err != nil { - return botlib.ReturnErr(event, err, botlib.WithEphemeral(true)) - } - - if edit.SelectedID == nil { - return botlib.ReturnErrMessage(event, "error_unavailable", botlib.WithEphemeral(true)) - } - role_index := slices.IndexFunc(panel.Roles, func(rpvr db.RolePanelV2Role) bool { - return rpvr.RoleID == *edit.SelectedID - }) - if role_index == -1 { - return botlib.ReturnErrMessage(event, "error_unavailable", botlib.WithEphemeral(true)) - } - - role_name := event.ModalSubmitInteraction.Data.Text("name") - panel.Roles[role_index].RoleName = role_name - - if err := b.Self.DB.RolePanelV2().Set(panel.ID, panel); err != nil { - return botlib.ReturnErr(event, err, botlib.WithEphemeral(true)) - } - - token, err := edit.InteractionToken.Get() - if err != nil { - return botlib.ReturnErrMessage(event, "error_timeout", botlib.WithEphemeral(true)) - } - message := discord.NewMessageUpdateBuilder() - message = db.RolePanelV2EditMenuEmbed(panel, event.Locale(), edit, message) - if _, err := event.Client().Rest().UpdateInteractionResponse(event.ApplicationID(), token, message.Build()); err != nil { - return botlib.ReturnErr(event, err, botlib.WithEphemeral(true)) - } - - go rolePanelV2Update(b, *event.GuildID(), panel, event.Locale()) - - if err := event.DeferUpdateMessage(); err != nil { - return botlib.ReturnErr(event, err, botlib.WithEphemeral(true)) - } - return nil - } -} - -func RolePanelV2Message(b *botlib.Bot[*client.Client]) handler.Message { - return handler.Message{ - Handler: rolePanelV2MessageCreate(b), - } -} - -func rolePanelV2MessageCreate(b *botlib.Bot[*client.Client]) handler.MessageHandler { - return func(event *events.GuildMessageCreate) error { - if event.Message.Type != discord.MessageTypeDefault { - return nil - } - b.Self.GuildDataLock(event.GuildID).Lock() - defer b.Self.GuildDataLock(event.GuildID).Unlock() - - gd, err := b.Self.DB.GuildData().Get(event.GuildID) - if err != nil { - return err - } - for u, v := range gd.RolePanelV2EditingEmoji { - if v[0] != event.ChannelID || v[1] != event.Message.Author.ID { - continue - } - - if !emoji.MatchString(event.Message.Content) { - continue - } - raw_emoji := emoji.FindAllString(event.Message.Content) - if len(raw_emoji) < 1 { - continue - } - emoji := botlib.ParseComponentEmoji(raw_emoji[0]) - - edit_id, ok := gd.RolePanelV2Editing[u] - if !ok { - return nil - } - edit, err := b.Self.DB.RolePanelV2Edit().Get(edit_id) - if err != nil { - return nil - } - panel, err := b.Self.DB.RolePanelV2().Get(edit.RolePanelID) - if err != nil { - return nil - } - - if edit.SelectedID == nil { - return nil - } - role_index := slices.IndexFunc(panel.Roles, func(rpvr db.RolePanelV2Role) bool { - return rpvr.RoleID == *edit.SelectedID - }) - if role_index == -1 { - return nil - } - - panel.Roles[role_index].Emoji = &emoji - edit.EmojiMode = false - delete(gd.RolePanelV2EditingEmoji, panel.ID) - - if err := b.Self.DB.RolePanelV2().Set(panel.ID, panel); err != nil { - return err - } - if err := b.Self.DB.GuildData().Set(gd.ID, gd); err != nil { - return err - } - if err := b.Self.DB.RolePanelV2Edit().Set(edit.ID, edit); err != nil { - return err - } - - token, err := edit.InteractionToken.Get() - if err != nil { - return nil - } - message := discord.NewMessageUpdateBuilder() - message = db.RolePanelV2EditMenuEmbed(panel, edit.EmojiLocale, edit, message) - if _, err := event.Client().Rest().UpdateInteractionResponse(event.Client().ApplicationID(), token, message.Build()); err != nil { - return err - } - - go rolePanelV2Update(b, event.GuildID, panel, edit.EmojiLocale) - - if err := event.Client().Rest().AddReaction(event.ChannelID, event.MessageID, "✅"); err != nil { - return err - } - - return nil - } - return nil - } -} - -func RolePanelV2MessageDelete(b *botlib.Bot[*client.Client]) handler.MessageDelete { - return handler.MessageDelete{ - Handler: func(event *events.GuildMessageDelete) error { - b.Self.GuildDataLock(event.GuildID).Lock() - defer b.Self.GuildDataLock(event.GuildID).Unlock() - - gd, err := b.Self.DB.GuildData().Get(event.GuildID) - if err != nil { - return err - } - key := fmt.Sprintf("%s/%s", event.ChannelID, event.MessageID) - if _, ok := gd.RolePanelV2Placed[key]; ok { - delete(gd.RolePanelV2PlacedConfig, key) - delete(gd.RolePanelV2Placed, key) - if err := b.Self.DB.GuildData().Set(gd.ID, gd); err != nil { - b.Logger.Errorf("error on delete role panel message handling: %s", err.Error()) - return err - } - } - return nil - }, - } -} - -func RolePanelV2MessageReaction(b *botlib.Bot[*client.Client]) handler.Generics[events.GuildMessageReactionAdd] { - return handler.Generics[events.GuildMessageReactionAdd]{ - Handler: func(event *events.GuildMessageReactionAdd) error { - if event.Member.User.Bot || event.Member.User.System { - return nil - } - b.Logger.Debug("reaction added") - b.Self.GuildDataLock(event.GuildID).Lock() - defer b.Self.GuildDataLock(event.GuildID).Unlock() - - gd, err := b.Self.DB.GuildData().Get(event.GuildID) - if err != nil { - return err - } - key := fmt.Sprintf("%s/%s", event.ChannelID, event.MessageID) - if panel_id, ok := gd.RolePanelV2Placed[key]; ok { - panel, err := b.Self.DB.RolePanelV2().Get(panel_id) - if err != nil { - b.Logger.Errorf("error on handling add reaction role panel: %s", err.Error()) - return err - } - user, err := b.Self.DB.UserData().Get(event.UserID) - if err != nil { - return err - } - _ = event.Client().Rest().RemoveUserReaction(event.ChannelID, event.MessageID, event.Emoji.Reaction(), event.UserID) - for _, rpvr := range panel.Roles { - if event.Emoji.Reaction() != botlib.ReactionComponentEmoji(*rpvr.Emoji) { - continue - } - if slices.Index(event.Member.RoleIDs, rpvr.RoleID) == -1 { - if err := event.Client().Rest().AddMemberRole(event.GuildID, event.UserID, rpvr.RoleID); err != nil { - embed := discord.NewEmbedBuilder(). - SetTitle(translate.Message(user.Locale, "rp_v2_add_role_failed_embed_title")). - SetDescription(translate.Message(user.Locale, "rp_v2_add_role_failed_embed_description")) - embed.Embed = botlib.SetEmbedProperties(embed.Embed) - message, err := event.Client().Rest().CreateMessage(event.ChannelID, discord.MessageCreate{ - Content: discord.UserMention(event.UserID), - Embeds: []discord.Embed{ - embed.Build(), - }, - }) - if err == nil { - go RolePanelV2DeferDeleteMessage(b, event.ChannelID, message.ID) - } - return err - } - embed := discord.NewEmbedBuilder(). - SetTitle(translate.Message(user.Locale, "rp_v2_add_role_added_embed_title")). - SetDescription(translate.Message(user.Locale, "rp_v2_add_role_added_embed_description", translate.WithTemplate(map[string]any{"Role": discord.RoleMention(rpvr.RoleID)}))) - embed.Embed = botlib.SetEmbedProperties(embed.Embed) - message, err := event.Client().Rest().CreateMessage(event.ChannelID, discord.MessageCreate{ - Content: discord.UserMention(event.UserID), - Embeds: []discord.Embed{ - embed.Build(), - }, - }) - if err == nil { - go RolePanelV2DeferDeleteMessage(b, event.ChannelID, message.ID) - } - } else { - if err := event.Client().Rest().RemoveMemberRole(event.GuildID, event.UserID, rpvr.RoleID); err != nil { - embed := discord.NewEmbedBuilder(). - SetTitle(translate.Message(user.Locale, "rp_v2_remove_role_failed_embed_title")). - SetDescription(translate.Message(user.Locale, "rp_v2_remove_role_failed_embed_description")) - embed.Embed = botlib.SetEmbedProperties(embed.Embed) - message, err := event.Client().Rest().CreateMessage(event.ChannelID, discord.MessageCreate{ - Content: discord.UserMention(event.UserID), - Embeds: []discord.Embed{ - embed.Build(), - }, - }) - if err == nil { - go RolePanelV2DeferDeleteMessage(b, event.ChannelID, message.ID) - } - return err - } - embed := discord.NewEmbedBuilder(). - SetTitle(translate.Message(user.Locale, "rp_v2_add_role_removed_embed_title")). - SetDescription(translate.Message(user.Locale, "rp_v2_add_role_removed_embed_description", translate.WithTemplate(map[string]any{"Role": discord.RoleMention(rpvr.RoleID)}))) - embed.Embed = botlib.SetEmbedProperties(embed.Embed) - message, err := event.Client().Rest().CreateMessage(event.ChannelID, discord.MessageCreate{ - Content: discord.UserMention(event.UserID), - Embeds: []discord.Embed{ - embed.Build(), - }, - }) - if err == nil { - go RolePanelV2DeferDeleteMessage(b, event.ChannelID, message.ID) - } - } - } - } - return nil - }, - } -} - -func RolePanelV2DeferDeleteMessage(b *botlib.Bot[*client.Client], channel_id, message_id snowflake.ID) { - time.Sleep(time.Second * 5) - if err := b.Client.Rest().DeleteMessage(channel_id, message_id); err != nil { - b.Logger.Errorf("error on role panel defer delete message: %s", err.Error()) - return - } -} - -func rolePanelV2Update(b *botlib.Bot[*client.Client], guild_id snowflake.ID, panel *db.RolePanelV2, locale discord.Locale) { - b.Logger.Debug("update called") - b.Self.GuildDataLock(guild_id).Lock() - defer b.Self.GuildDataLock(guild_id).Unlock() - gd, err := b.Self.DB.GuildData().Get(guild_id) - if err != nil { - b.Logger.Errorf("error on update role panel message: %s", err.Error()) - return - } - - for k, u := range gd.RolePanelV2Placed { - if u != panel.ID { - continue - } - keys := strings.Split(k, "/") - channel_id := snowflake.MustParse(keys[0]) - message_id := snowflake.MustParse(keys[1]) - - panel_config := gd.RolePanelV2PlacedConfig[k] - - message_update := discord.NewMessageUpdateBuilder() - switch panel_config.PanelType { - case db.RolePanelV2TypeReaction: - message_update = db.RolePanelV2MessageReaction(panel, locale, message_update) - case db.RolePanelV2TypeSelectMenu: - message_update = db.RolePanelV2MessageSelectMenu(panel, locale, message_update, panel_config) - case db.RolePanelV2TypeButton: - message_update = db.RolePanelV2MessageButton(panel, locale, message_update, panel_config) - } - if _, err := b.Client.Rest().UpdateMessage(channel_id, message_id, message_update.Build()); err != nil { - b.Logger.Errorf("error on update role panel message: %s", err.Error()) - return - } - - if panel_config.PanelType == db.RolePanelV2TypeReaction { - if err := b.Client.Rest().RemoveAllReactions(channel_id, message_id); err != nil { - b.Logger.Errorf("error on update role panel message: %s", err.Error()) - return - } - for _, role := range panel.Roles { - if err = b.Client.Rest().AddReaction(channel_id, message_id, botlib.ReactionComponentEmoji(*role.Emoji)); err != nil { - b.Logger.Errorf("error on update role panel message: %s", err.Error()) - return - } - } - } - } -} - -func rolePanelV2MessageDelete(b *botlib.Bot[*client.Client], guild_id snowflake.ID, panel *db.RolePanelV2, locale discord.Locale) { - b.Self.GuildDataLock(guild_id).Lock() - defer b.Self.GuildDataLock(guild_id).Unlock() - gd, err := b.Self.DB.GuildData().Get(guild_id) - if err != nil { - b.Logger.Errorf("error on update role panel message: %s", err.Error()) - return - } - - for k, u := range gd.RolePanelV2Placed { - if u != panel.ID { - continue - } - keys := strings.Split(k, "/") - channel_id := snowflake.MustParse(keys[0]) - message_id := snowflake.MustParse(keys[1]) - - delete(gd.RolePanelV2Placed, k) - delete(gd.RolePanelV2PlacedConfig, k) - - if err := b.Client.Rest().DeleteMessage(channel_id, message_id); err != nil { - b.Logger.Errorf("error on delete role panel message: %s", err.Error()) - return - } - } -} - -func panelPlace(b *botlib.Bot[*client.Client], panel *db.RolePanelV2, place *db.RolePanelV2Place, gd *db.GuildData, locale discord.Locale, channel_id snowflake.ID) error { - message_create := discord.NewMessageCreateBuilder() - switch place.Config.PanelType { - case db.RolePanelV2TypeReaction: - message_create = db.RolePanelV2MessageReaction(panel, locale, message_create) - case db.RolePanelV2TypeSelectMenu: - message_create = db.RolePanelV2MessageSelectMenu(panel, locale, message_create, place.Config) - case db.RolePanelV2TypeButton: - message_create = db.RolePanelV2MessageButton(panel, locale, message_create, place.Config) - } - message, err := b.Client.Rest().CreateMessage(channel_id, message_create.Build()) - if err != nil { - return err - } - - key := fmt.Sprintf("%d/%d", channel_id, message.ID) - gd.RolePanelV2Placed[key] = panel.ID - gd.RolePanelV2PlacedConfig[key] = place.Config - if err := b.Self.DB.GuildData().Set(gd.ID, *gd); err != nil { - return err - } - - if place.Config.PanelType == db.RolePanelV2TypeReaction { - for _, role := range panel.Roles { - if err = b.Client.Rest().AddReaction(channel_id, message.ID, botlib.ReactionComponentEmoji(*role.Emoji)); err != nil { - return err - } - } - } - return nil -} diff --git a/bot/commands/role/import.go b/bot/commands/role/import.go new file mode 100644 index 00000000..fbebec8f --- /dev/null +++ b/bot/commands/role/import.go @@ -0,0 +1,153 @@ +package role + +import ( + "regexp" + "strings" + "time" + + "github.com/disgoorg/disgo/discord" + "github.com/disgoorg/disgo/events" + "github.com/disgoorg/snowflake/v2" + "github.com/sabafly/gobot/bot/components" + "github.com/sabafly/gobot/bot/components/generic" + "github.com/sabafly/gobot/ent/schema" + "github.com/sabafly/gobot/internal/builtin" + "github.com/sabafly/gobot/internal/discordutil" + "github.com/sabafly/gobot/internal/emoji" + "github.com/sabafly/gobot/internal/errors" + "github.com/sabafly/gobot/internal/translate" +) + +func ImportCommand(c *components.Components) components.Command { + return (&generic.Command{ + Namespace: "import-rolepanel", + CommandCreate: []discord.ApplicationCommandCreate{ + discord.MessageCommandCreate{ + Name: "import-rolepanel", + NameLocalizations: translate.MessageMap("components.role.panel.import.name", false), + DMPermission: builtin.Ptr(false), + Contexts: []discord.InteractionContextType{ + discord.InteractionContextTypeGuild, + }, + }, + }, + CommandHandlers: map[string]generic.PermissionCommandHandler{ + "m/import-rolepanel": generic.PCommandHandler{ + Permission: []generic.Permission{ + generic.PermissionString("role.panel.import"), + }, + DiscordPerm: discord.PermissionManageRoles, + CommandHandler: func(c *components.Components, event *events.ApplicationCommandInteractionCreate) errors.Error { + if !check(event) { + return errors.NewError(errors.ErrorMessage("errors.unsupported", event)) + } + message := event.MessageCommandInteractionData().TargetMessage() + lines := strings.Split(message.Embeds[0].Description, "\n") + var roles []schema.Role + roleCount := 0 + for _, v := range lines { + if !roleRegexp.MatchString(v) { + continue + } + var emojis []string + if !emoji.MatchString(v) { + emojis = append(emojis, discordutil.Number2Emoji(roleCount+1)) + } else { + emojis = emoji.FindAllString(v) + } + componentEmoji := discordutil.ParseComponentEmoji(emojis[0]) + if _, ok := event.Client().Caches().Emoji(*event.GuildID(), componentEmoji.ID); !ok && componentEmoji.ID != 0 { + componentEmoji = discordutil.ParseComponentEmoji(discordutil.Number2Emoji(roleCount + 1)) + } + roleID, err := snowflake.Parse(roleIDRegexp.FindString(roleRegexp.FindString(v))) + if err != nil { + continue + } + role, ok := event.Client().Caches().Role(*event.GuildID(), roleID) + if !ok { + rolePtr, err := event.Client().Rest().GetRole(*event.GuildID(), roleID) + if err != nil { + continue + } + role = *rolePtr + } + roleCount++ + roles = append(roles, schema.Role{ + ID: role.ID, + Name: role.Name, + Emoji: &componentEmoji, + }) + } + if len(roles) < 1 { + return errors.NewError(errors.ErrorMessage("errors.unsupported", event)) + } + + g, err := c.GuildCreateID(event, *event.GuildID()) + if err != nil { + return errors.NewError(err) + } + + panel := c.DB().RolePanel.Create(). + SetName(builtin.Or(message.Embeds[0].Title != "", message.Embeds[0].Title, translate.Message(event.Locale(), "components.role.panel.default_name"))). + SetDescription(""). + SetRoles(roles). + SetGuild(g). + SaveX(event) + + place := c.DB().RolePanelPlaced.Create(). + SetGuild(g). + SetChannelID(event.Channel().ID()). + SetRolePanel(panel). + SetName(panel.Name). + SetDescription(panel.Description). + SetRoles(panel.Roles). + SetUpdatedAt(time.Now()). + SaveX(event) + + if err := event.CreateMessage( + rpPlaceBaseMenu(place, event.Locale()). + SetFlags(discord.MessageFlagEphemeral). + BuildCreate(), + ); err != nil { + return errors.NewError(err) + } + + return nil + }, + }, + }, + }).SetComponent(c) +} + +var roleRegexp = regexp.MustCompile("<@&([0-9]{18,20})>") +var roleIDRegexp = regexp.MustCompile("[0-9]{18,20}") + +func check(event *events.ApplicationCommandInteractionCreate) bool { + message := event.MessageCommandInteractionData().TargetMessage() + var wid snowflake.ID + if message.WebhookID != nil { + wh, err := event.Client().Rest().GetWebhook(*message.WebhookID) + if err != nil { + return false + } else if wh.Type() == discord.WebhookTypeIncoming && wh.(discord.IncomingWebhook).User.ID == 716496407212589087 { + wid = message.Author.ID + } + } + switch message.Author.ID { + case 895912135039803402, 1138119538190340146, 1137367652482957313, 971523089550671953 /*圹職パネルv3*/, 682774762837377045 /*圹職パネルv2*/, 917780792032251904 /*圹職ボット*/, 669817785932578826 /*陜菜*/, 716496407212589087, wid /*RT*/, 718760319207473152 /*SevenBot*/, 832614051514417202 /*Glow-bot*/ : + if len(message.Embeds) < 1 { + return false + } + lines := strings.Split(message.Embeds[0].Description, "\r") + validLines := 0 + for _, v := range lines { + if !roleRegexp.MatchString(v) { + continue + } + validLines++ + } + return validLines > 0 + default: + return false + } +} diff --git a/bot/commands/role/panel.go b/bot/commands/role/panel.go new file mode 100644 index 00000000..a05faa13 --- /dev/null +++ b/bot/commands/role/panel.go @@ -0,0 +1,45 @@ +package role + +import ( + "context" + + "github.com/disgoorg/disgo/bot" + "github.com/disgoorg/disgo/discord" + "github.com/sabafly/gobot/ent" + "github.com/sabafly/gobot/ent/rolepanelplaced" + "github.com/sabafly/gobot/internal/discordutil" +) + +func rolePanelPlace(ctx context.Context, place *ent.RolePanelPlaced, locale discord.Locale, client bot.Client, react bool) error { + builder := rpPlacedMessage(place, locale) + if place.MessageID != nil { + if _, err := client.Rest().UpdateMessage(place.ChannelID, *place.MessageID, builder.BuildUpdate()); err != nil { + return err + } + if place.Type == rolepanelplaced.TypeReaction && react { + if err := client.Rest().RemoveAllReactions(place.ChannelID, *place.MessageID); err != nil { + return err + } + } + } else { + m, err := client.Rest().CreateMessage(place.ChannelID, builder.BuildCreate()) + if err != nil { + return err + } + *place = *place.Update().SetMessageID(m.ID).SaveX(ctx) + } + + if place.Type == rolepanelplaced.TypeReaction && react { + for i, r := range place.Roles { + if r.Emoji == nil { + r.Emoji = &discord.ComponentEmoji{ + Name: discordutil.Index2Emoji(i), + } + } + if err := client.Rest().AddReaction(place.ChannelID, *place.MessageID, discordutil.FormatComponentEmoji(*r.Emoji)); err != nil { + return err + } + } + } + return nil +} diff --git a/bot/commands/role/panel_autocomplete.go b/bot/commands/role/panel_autocomplete.go new file mode 100644 index 00000000..bad8cf9e --- /dev/null +++ b/bot/commands/role/panel_autocomplete.go @@ -0,0 +1,33 @@ +package role + +import ( + "fmt" + "slices" + + "github.com/disgoorg/disgo/discord" + "github.com/disgoorg/disgo/events" + "github.com/sabafly/gobot/bot/components" + "github.com/sabafly/gobot/ent" + "github.com/sabafly/gobot/ent/rolepanel" + "github.com/sabafly/gobot/internal/builtin" + "github.com/sabafly/gobot/internal/errors" +) + +func panelAutocomplete(c *components.Components, event *events.AutocompleteInteractionCreate) errors.Error { + g, err := c.GuildCreateID(event, *event.GuildID()) + if err != nil { + return errors.NewError(err) + } + panels := g.QueryRolePanels().Where(rolepanel.NameContains(event.Data.String("panel"))).AllX(event) + choices := make([]discord.AutocompleteChoice, len(panels)) + for i, p := range panels { + choices[i] = discord.AutocompleteChoiceString{ + Name: builtin.Or(slices.ContainsFunc(panels, func(rp *ent.RolePanel) bool { return rp.ID != p.ID && rp.Name == p.Name }), fmt.Sprintf("%s (%s)", p.Name, p.ID), p.Name), + Value: p.ID.String(), + } + } + if err := event.AutocompleteResult(choices); err != nil { + return errors.NewError(err) + } + return nil +} diff --git a/bot/commands/role/panel_message.go b/bot/commands/role/panel_message.go new file mode 100644 index 00000000..72278325 --- /dev/null +++ b/bot/commands/role/panel_message.go @@ -0,0 +1,512 @@ +package role + +import ( + "fmt" + "slices" + + "github.com/disgoorg/disgo/discord" + "github.com/sabafly/gobot/ent" + "github.com/sabafly/gobot/ent/rolepanelplaced" + "github.com/sabafly/gobot/ent/schema" + "github.com/sabafly/gobot/internal/builtin" + "github.com/sabafly/gobot/internal/discordutil" + "github.com/sabafly/gobot/internal/embeds" + "github.com/sabafly/gobot/internal/emoji" + "github.com/sabafly/gobot/internal/translate" +) + +func initialize(edit *ent.RolePanelEdit, panel *ent.RolePanel) { + if edit.Roles == nil { + edit.Roles = panel.Roles + } + if edit.Name == nil { + edit.Name = &panel.Name + } + if edit.Description == nil { + edit.Description = &panel.Description + } +} + +func rpEditBaseMessage(panel *ent.RolePanel, edit *ent.RolePanelEdit, locale discord.Locale) discord.MessageBuilder { + builder := discord.NewMessageBuilder() + var roleField string + for i, r := range edit.Roles { + if r.Emoji == nil { + r.Emoji = &discord.ComponentEmoji{ + Name: discordutil.Index2Emoji(i), + } + } + roleField += fmt.Sprintf("%s: %s: %s\n", discordutil.FormatComponentEmoji(*r.Emoji), r.Name, discord.RoleMention(r.ID)) + } + initialize(edit, panel) + builder.SetEmbeds( + embeds.SetEmbedsProperties( + []discord.Embed{ + discord.NewEmbedBuilder(). + SetTitle(translate.Message(locale, "components.role.panel.edit.menu.base.title")). + SetFields( + discord.EmbedField{ + Name: translate.Message(locale, "components.role.panel.edit.menu.base.field.name"), + Value: builtin.NonNil(edit.Name), + Inline: builtin.Ptr(true), + }, + discord.EmbedField{ + Name: translate.Message(locale, "components.role.panel.edit.menu.base.field.description"), + Value: builtin.Or(builtin.NonNil(edit.Description) != "", builtin.NonNil(edit.Description), fmt.Sprintf("`%s`", translate.Message(locale, "components.role.panel.edit.menu.base.field.value.empty"))), + Inline: builtin.Ptr(true), + }, + discord.EmbedField{ + Name: translate.Message(locale, "components.role.panel.edit.menu.base.field.roles"), + Value: builtin.Or(roleField != "", roleField, fmt.Sprintf("`%s`", translate.Message(locale, "components.role.panel.edit.menu.base.field.value.empty"))), + }, + ). + SetFooterTextf("id: %s", edit.ID). + Build(), + }, + )..., + ) + + disabled := len(edit.Roles) < 1 || edit.SelectedRole == nil || !slices.ContainsFunc(edit.Roles, func(r schema.Role) bool { return r.ID == *edit.SelectedRole }) + builder.SetContainerComponents( + discord.NewActionRow( + discord.ButtonComponent{ + Style: discord.ButtonStylePrimary, + Label: translate.Message(locale, "components.role.panel.edit.menu.base.components.change_name"), + CustomID: fmt.Sprintf("role:panel_edit_component:change_name:%s", edit.ID), + }, + discord.ButtonComponent{ + Style: discord.ButtonStylePrimary, + Label: translate.Message(locale, "components.role.panel.edit.menu.base.components.change_description"), + CustomID: fmt.Sprintf("role:panel_edit_component:change_description:%s", edit.ID), + }, + discord.ButtonComponent{ + Style: discord.ButtonStyleSecondary, + Label: translate.Message(locale, "components.role.panel.edit.menu.base.components.modify_roles"), + CustomID: fmt.Sprintf("role:panel_edit_component:modify_roles:%s", edit.ID), + }, + ), + discord.NewActionRow( + discord.ButtonComponent{ + Style: discord.ButtonStyleSuccess, + Label: translate.Message(locale, "components.role.panel.edit.menu.base.components.save_change"), + CustomID: fmt.Sprintf("role:panel_edit_component:save_change:%s", edit.ID), + Disabled: !edit.Modified, + }, + discord.ButtonComponent{ + Style: discord.ButtonStyleDanger, + Label: translate.Message(locale, "components.role.panel.edit.menu.base.components.apply_change"), + CustomID: fmt.Sprintf("role:panel_edit_component:apply_change:%s", edit.ID), + Disabled: !panel.AppliedAt.Before(panel.UpdatedAt) || len(panel.Roles) < 1, + }, + ), + discord.NewActionRow( + func() discord.StringSelectMenuComponent { + menu := discord.StringSelectMenuComponent{ + CustomID: fmt.Sprintf("role:panel_edit_component:select_role:%s", edit.ID), + Placeholder: translate.Message(locale, "components.role.panel.edit.menu.base.components.select_role"), + MinValues: builtin.Ptr(0), + MaxValues: 1, + Disabled: len(edit.Roles) < 1, + Options: func() []discord.StringSelectMenuOption { + options := make([]discord.StringSelectMenuOption, len(edit.Roles)) + for i, r := range edit.Roles { + if r.Emoji == nil { + r.Emoji = &discord.ComponentEmoji{ + Name: discordutil.Index2Emoji(i), + } + } + options[i] = discord.StringSelectMenuOption{ + Label: r.Name, + Value: r.ID.String(), + Emoji: r.Emoji, + Default: edit.SelectedRole != nil && *edit.SelectedRole == r.ID, + } + } + if len(edit.Roles) < 1 { + options = append(options, discord.NewStringSelectMenuOption("nil", "nil")) + } + return options + }(), + } + return menu + }(), + ), + discord.NewActionRow( + discord.ButtonComponent{ + Style: discord.ButtonStylePrimary, + Label: "↑", + CustomID: fmt.Sprintf("role:panel_edit_component:move_up:%s", edit.ID), + Disabled: disabled || slices.IndexFunc(edit.Roles, func(r schema.Role) bool { return r.ID == *edit.SelectedRole }) == 0, + }, + discord.ButtonComponent{ + Style: discord.ButtonStyleDanger, + Label: translate.Message(locale, "components.role.panel.edit.menu.base.components.delete"), + CustomID: fmt.Sprintf("role:panel_edit_component:delete:%s", edit.ID), + Disabled: disabled || len(edit.Roles) < 2, + }, + discord.ButtonComponent{ + Style: discord.ButtonStylePrimary, + Label: "↓", + CustomID: fmt.Sprintf("role:panel_edit_component:move_down:%s", edit.ID), + Disabled: disabled || slices.IndexFunc(edit.Roles, func(r schema.Role) bool { return r.ID == *edit.SelectedRole }) == len(edit.Roles)-1, + }, + ), + discord.NewActionRow( + discord.ButtonComponent{ + Style: discord.ButtonStyleSuccess, + Label: translate.Message(locale, "components.role.panel.edit.menu.base.components.set_emoji"), + CustomID: fmt.Sprintf("role:panel_edit_component:set_emoji:%s", edit.ID), + Disabled: disabled, + }, + discord.ButtonComponent{ + Style: discord.ButtonStyleSuccess, + Label: translate.Message(locale, "components.role.panel.edit.menu.base.components.set_display_name"), + CustomID: fmt.Sprintf("role:panel_edit_component:set_display_name:%s", edit.ID), + Disabled: disabled, + }, + ), + ) + + return builder +} + +func rpEditModifyRolesMessage(edit *ent.RolePanelEdit, locale discord.Locale) discord.MessageBuilder { + builder := discord.NewMessageBuilder() + var roleField string + for i, r := range edit.Roles { + if r.Emoji == nil { + r.Emoji = &discord.ComponentEmoji{ + Name: discordutil.Index2Emoji(i), + } + } + roleField += fmt.Sprintf("%s: %s: %s\n", discordutil.FormatComponentEmoji(*r.Emoji), r.Name, discord.RoleMention(r.ID)) + } + builder.SetEmbeds( + embeds.SetEmbedsProperties( + []discord.Embed{ + discord.NewEmbedBuilder(). + SetTitle(translate.Message(locale, "components.role.panel.edit.menu.modify_roles.title")). + SetFields( + discord.EmbedField{ + Name: translate.Message(locale, "components.role.panel.edit.menu.modify_roles.field.roles"), + Value: roleField, + }, + ). + Build(), + }, + )..., + ) + + builder.SetContainerComponents( + discord.NewActionRow( + discord.ButtonComponent{ + Style: discord.ButtonStyleSecondary, + Label: translate.Message(locale, "components.role.panel.edit.menu.base.components.back_base_menu"), + CustomID: fmt.Sprintf("role:panel_edit_component:base_menu:%s", edit.ID), + }, + ), + discord.NewActionRow( + discord.RoleSelectMenuComponent{ + CustomID: fmt.Sprintf("role:panel_edit_component:add_role:%s", edit.ID), + MinValues: builtin.Ptr(1), + MaxValues: 20, + DefaultValues: func() []discord.SelectMenuDefaultValue { + values := make([]discord.SelectMenuDefaultValue, len(edit.Roles)) + for i := range edit.Roles { + values[i] = discord.NewSelectMenuDefaultRole(edit.Roles[i].ID) + } + return values + }(), + }, + ), + ) + return builder +} + +func rpEditSetEmojiMessage(edit *ent.RolePanelEdit, locale discord.Locale) discord.MessageBuilder { + builder := discord.NewMessageBuilder() + builder.SetEmbeds( + embeds.SetEmbedProperties( + discord.NewEmbedBuilder(). + SetTitle(translate.Message(locale, "components.role.panel.edit.menu.set_emoji.title")). + SetDescription(translate.Message(locale, "components.role.panel.edit.menu.set_emoji.description")). + Build(), + ), + ) + + builder.SetContainerComponents( + discord.NewActionRow( + discord.ButtonComponent{ + Style: discord.ButtonStyleSecondary, + Label: translate.Message(locale, "components.role.panel.edit.menu.set_emoji.components.cancel"), + CustomID: fmt.Sprintf("role:panel_edit_component:cancel_emoji:%s", edit.ID), + }, + discord.ButtonComponent{ + Style: discord.ButtonStyleDanger, + Label: translate.Message(locale, "components.role.panel.edit.menu.set_emoji.components.reset"), + CustomID: fmt.Sprintf("role:panel_edit_component:reset_emoji:%s", edit.ID), + }, + ), + ) + return builder +} + +func rpPlaceBaseMenu(place *ent.RolePanelPlaced, locale discord.Locale) discord.MessageBuilder { + builder := discord.NewMessageBuilder() + var roleField string + for i, r := range place.Roles { + if r.Emoji == nil { + r.Emoji = &discord.ComponentEmoji{ + Name: discordutil.Index2Emoji(i), + } + } + roleField += fmt.Sprintf("%s| %s\n", discordutil.FormatComponentEmoji(*r.Emoji), builtin.Or(place.UseDisplayName, r.Name, discord.RoleMention(r.ID))) + } + builder.SetEmbeds( + embeds.SetEmbedsProperties( + []discord.Embed{ + discord.NewEmbedBuilder(). + SetAuthorName(translate.Message(locale, "components.role.panel.place.menu.author.text")). + Build(), + discord.NewEmbedBuilder(). + SetTitle(place.Name). + SetDescription(place.Description). + SetFields( + discord.EmbedField{ + Name: translate.Message(locale, "components.role.panel.embed.field.role"), + Value: roleField, + }, + ). + Build(), + }, + )..., + ) + + builder.AddContainerComponents( + discord.NewActionRow( + discord.StringSelectMenuComponent{ + CustomID: fmt.Sprintf("role:panel_place_component:type:%s", place.ID), + MinValues: builtin.Ptr(1), + MaxValues: 1, + Placeholder: translate.Message(locale, "components.role.panel.place.menu.select_type.placeholder"), + Options: []discord.StringSelectMenuOption{ + { + Label: translate.Message(locale, "components.role.panel.type.reaction"), + Value: rolepanelplaced.TypeReaction.String(), + Description: translate.Message(locale, "components.role.panel.type.reaction.description"), + Emoji: emoji.Reaction, + Default: place.Type == rolepanelplaced.TypeReaction, + }, + { + Label: translate.Message(locale, "components.role.panel.type.select_menu"), + Value: rolepanelplaced.TypeSelectMenu.String(), + Description: translate.Message(locale, "components.role.panel.type.select_menu.description"), + Emoji: emoji.SelectMenu, + Default: place.Type == rolepanelplaced.TypeSelectMenu, + }, + { + Label: translate.Message(locale, "components.role.panel.type.button"), + Value: rolepanelplaced.TypeButton.String(), + Description: translate.Message(locale, "components.role.panel.type.button.description"), + Emoji: emoji.Button, + Default: place.Type == rolepanelplaced.TypeButton, + }, + }, + }, + ), + ) + + switch place.Type { + case rolepanelplaced.TypeButton: + builder.AddContainerComponents( + discord.NewActionRow( + discord.StringSelectMenuComponent{ + CustomID: fmt.Sprintf("role:panel_place_component:button_type:%s", place.ID), + MinValues: builtin.Ptr(1), + MaxValues: 1, + Options: []discord.StringSelectMenuOption{ + { + Label: translate.Message(locale, "components.role.panel.button.color.green"), + Value: "green", + Emoji: emoji.GreenButton, + Default: place.ButtonType == discord.ButtonStyleSuccess, + }, + { + Label: translate.Message(locale, "components.role.panel.button.color.blue"), + Value: "blue", + Emoji: emoji.BlueButton, + Default: place.ButtonType == discord.ButtonStylePrimary, + }, + { + Label: translate.Message(locale, "components.role.panel.button.color.red"), + Value: "red", + Emoji: emoji.RedButton, + Default: place.ButtonType == discord.ButtonStyleDanger, + }, + { + Label: translate.Message(locale, "components.role.panel.button.color.gray"), + Value: "gray", + Emoji: emoji.GrayButton, + Default: place.ButtonType == discord.ButtonStyleSecondary, + }, + }, + }, + ), + discord.NewActionRow( + discord.ButtonComponent{ + Style: discord.ButtonStyleSecondary, + Label: translate.Message(locale, "components.role.panel.place.menu.button.show_name"), + Emoji: builtin.Or(place.ShowName, emoji.On, emoji.Off), + CustomID: fmt.Sprintf("role:panel_place_component:show_name:%s", place.ID), + }, + ), + ) + case rolepanelplaced.TypeSelectMenu: + builder.AddContainerComponents( + discord.NewActionRow( + discord.ButtonComponent{ + Style: discord.ButtonStyleSecondary, + Label: translate.Message(locale, "components.role.panel.place.menu.select_menu.folding_select_menu"), + Emoji: builtin.Or(place.FoldingSelectMenu, emoji.On, emoji.Off), + CustomID: fmt.Sprintf("role:panel_place_component:folding_select_menu:%s", place.ID), + }, + ), + ) + case rolepanelplaced.TypeReaction: + builder.AddContainerComponents( + discord.NewActionRow( + discord.ButtonComponent{ + Style: discord.ButtonStyleSecondary, + Label: translate.Message(locale, "components.role.panel.place.menu.reaction.hide_notice"), + Emoji: builtin.Or(place.HideNotice, emoji.On, emoji.Off), + CustomID: fmt.Sprintf("role:panel_place_component:hide_notice:%s", place.ID), + }, + ), + ) + } + + builder.AddContainerComponents( + discord.NewActionRow( + discord.ButtonComponent{ + Style: discord.ButtonStyleSecondary, + Label: translate.Message(locale, "components.role.panel.place.menu.generic.use_display_name"), + Emoji: builtin.Or(place.UseDisplayName, emoji.On, emoji.Off), + CustomID: fmt.Sprintf("role:panel_place_component:use_display_name:%s", place.ID), + Disabled: place.Type == "", + }, + ), + discord.NewActionRow( + discord.ButtonComponent{ + Style: discord.ButtonStyleSuccess, + Label: translate.Message(locale, "components.role.panel.place.menu.generic.create"), + CustomID: fmt.Sprintf("role:panel_place_component:create:%s", place.ID), + Disabled: place.Type == "", + }, + ), + ) + + return builder +} + +func rpPlacedMessage(place *ent.RolePanelPlaced, locale discord.Locale) discord.MessageBuilder { + builder := discord.NewMessageBuilder() + var roleField string + for i, r := range place.Roles { + if r.Emoji == nil { + r.Emoji = &discord.ComponentEmoji{ + Name: discordutil.Index2Emoji(i), + } + } + roleField += fmt.Sprintf("%s| %s\n", discordutil.FormatComponentEmoji(*r.Emoji), builtin.Or(place.UseDisplayName, r.Name, discord.RoleMention(r.ID))) + } + builder.SetEmbeds( + embeds.SetEmbedsProperties( + []discord.Embed{ + discord.NewEmbedBuilder(). + SetTitle(place.Name). + SetDescription(place.Description). + SetFields( + discord.EmbedField{ + Name: translate.Message(locale, "components.role.panel.embed.field.role"), + Value: roleField, + }, + ). + Build(), + }, + )..., + ) + switch place.Type { + case rolepanelplaced.TypeButton: + buttons := make([]discord.InteractiveComponent, len(place.Roles)) + for i, role := range place.Roles { + var label string + if place.ShowName { + label = role.Name + } + if role.Emoji == nil { + role.Emoji = &discord.ComponentEmoji{ + Name: discordutil.Index2Emoji(i), + } + } + buttons[i] = discord.ButtonComponent{ + Style: place.ButtonType, + Emoji: role.Emoji, + Label: label, + CustomID: fmt.Sprintf("role:panel_use:button:%s:%s", place.ID, role.ID), + } + } + components := make([]discord.ContainerComponent, (len(place.Roles)-1)/5+1) + for i := range components { + count := 5 + if len(buttons) < 5 { + count = len(buttons) + } + components[i] = discord.NewActionRow(buttons[:count]...) + buttons = buttons[count:] + } + builder.AddContainerComponents( + components..., + ) + case rolepanelplaced.TypeSelectMenu: + if place.FoldingSelectMenu { + builder.AddContainerComponents( + discord.NewActionRow( + discord.ButtonComponent{ + Style: discord.ButtonStyleSuccess, + Label: translate.Message(locale, "components.role.panel.components.use_button"), + CustomID: fmt.Sprintf("role:panel_use:select_menu_fold:%s", place.ID), + }, + ), + ) + } else { + builder.AddContainerComponents(rpPlacedSelectMenu(place, locale)) + } + } + return builder +} + +func rpPlacedSelectMenu(place *ent.RolePanelPlaced, locale discord.Locale) discord.ActionRowComponent { + options := make([]discord.StringSelectMenuOption, len(place.Roles)) + for i, role := range place.Roles { + if role.Emoji == nil { + role.Emoji = &discord.ComponentEmoji{ + Name: discordutil.Index2Emoji(i), + } + } + options[i] = discord.StringSelectMenuOption{ + Label: role.Name, + Value: role.ID.String(), + Emoji: role.Emoji, + } + } + actionRow := discord.NewActionRow( + discord.StringSelectMenuComponent{ + CustomID: fmt.Sprintf("role:panel_use:select_menu:%s", place.ID.String()), + Placeholder: translate.Message(locale, "components.role.panel.components.select_menu.placeholder"), + MinValues: builtin.Ptr(0), + MaxValues: len(place.Roles), + Options: options, + }, + ) + return actionRow +} diff --git a/bot/commands/role/role.go b/bot/commands/role/role.go new file mode 100644 index 00000000..939005b3 --- /dev/null +++ b/bot/commands/role/role.go @@ -0,0 +1,1205 @@ +package role + +import ( + "context" + "fmt" + "log/slog" + "slices" + "strings" + "time" + + "github.com/disgoorg/disgo/bot" + "github.com/disgoorg/disgo/discord" + "github.com/disgoorg/disgo/events" + "github.com/disgoorg/disgo/rest" + "github.com/disgoorg/snowflake/v2" + "github.com/google/uuid" + "github.com/sabafly/gobot/bot/components" + "github.com/sabafly/gobot/bot/components/generic" + "github.com/sabafly/gobot/ent" + "github.com/sabafly/gobot/ent/guild" + "github.com/sabafly/gobot/ent/rolepanel" + "github.com/sabafly/gobot/ent/rolepaneledit" + "github.com/sabafly/gobot/ent/rolepanelplaced" + "github.com/sabafly/gobot/ent/schema" + "github.com/sabafly/gobot/internal/builtin" + "github.com/sabafly/gobot/internal/discordutil" + "github.com/sabafly/gobot/internal/embeds" + "github.com/sabafly/gobot/internal/emoji" + "github.com/sabafly/gobot/internal/errors" + "github.com/sabafly/gobot/internal/ratelimit" + "github.com/sabafly/gobot/internal/translate" +) + +func Command(c *components.Components) components.Command { + return (&generic.Command{ + Namespace: "role", + CommandCreate: []discord.ApplicationCommandCreate{ + discord.SlashCommandCreate{ + Name: "role", + Description: "role", + DMPermission: builtin.Ptr(false), + Contexts: []discord.InteractionContextType{ + discord.InteractionContextTypeGuild, + }, + Options: []discord.ApplicationCommandOption{ + discord.ApplicationCommandOptionSubCommandGroup{ + Name: "panel", + Description: "panel", + Options: []discord.ApplicationCommandOptionSubCommand{ + { + Name: "create", + Description: "create role panel", + DescriptionLocalizations: translate.MessageMap("components.role.panel.create.command.description", false), + }, + { + Name: "place", + Description: "place role panel", + DescriptionLocalizations: translate.MessageMap("components.role.panel.place.command.description", false), + Options: []discord.ApplicationCommandOption{ + discord.ApplicationCommandOptionString{ + Name: "panel", + Description: "panel name or id", + NameLocalizations: translate.MessageMap("components.role.panel.place.command.options.panel.name", false), + DescriptionLocalizations: translate.MessageMap("components.role.panel.place.command.options.panel.description", false), + Required: true, + Autocomplete: true, + }, + }, + }, + { + Name: "edit", + Description: "edit role panel", + DescriptionLocalizations: translate.MessageMap("components.role.panel.edit.command.description", false), + Options: []discord.ApplicationCommandOption{ + discord.ApplicationCommandOptionString{ + Name: "panel", + Description: "panel name or id", + NameLocalizations: translate.MessageMap("components.role.panel.edit.command.options.panel.name", false), + DescriptionLocalizations: translate.MessageMap("components.role.panel.edit.command.options.panel.description", false), + Required: true, + Autocomplete: true, + }, + }, + }, + { + Name: "delete", + Description: "delete role panel", + DescriptionLocalizations: translate.MessageMap("components.role.panel.delete.command.description", false), + Options: []discord.ApplicationCommandOption{ + discord.ApplicationCommandOptionString{ + Name: "panel", + Description: "panel name or id", + NameLocalizations: translate.MessageMap("components.role.panel.delete.command.options.panel.name", false), + DescriptionLocalizations: translate.MessageMap("components.role.panel.delete.command.options.panel.description", false), + Required: true, + Autocomplete: true, + }, + }, + }, + }, + }, + }, + }, + }, + CommandHandlers: map[string]generic.PermissionCommandHandler{ + "/role/panel/create": generic.PCommandHandler{ + Permission: []generic.Permission{ + generic.PermissionString("role.panel.create"), + }, + DiscordPerm: discord.PermissionManageRoles, + CommandHandler: func(c *components.Components, event *events.ApplicationCommandInteractionCreate) errors.Error { + if err := event.Modal( + discord.NewModalCreateBuilder(). + SetTitle(translate.Message(event.Locale(), "components.role.panel.create.modal.title")). + SetCustomID("role:panel_create_modal"). + SetContainerComponents( + discord.NewActionRow( + discord.TextInputComponent{ + CustomID: "name", + Style: discord.TextInputStyleShort, + Label: translate.Message(event.Locale(), "components.role.panel.create.modal.input.1.label"), + MinLength: builtin.Ptr(1), + MaxLength: 32, + Required: true, + Value: translate.Message(event.Locale(), "components.role.panel.default_name"), + }, + ), + discord.NewActionRow( + discord.TextInputComponent{ + CustomID: "description", + Style: discord.TextInputStyleParagraph, + Label: translate.Message(event.Locale(), "components.role.panel.create.modal.input.2.label"), + MaxLength: 140, + }, + ), + ). + Build(), + ); err != nil { + return errors.NewError(err) + } + + return nil + }, + }, + "/role/panel/edit": generic.PCommandHandler{ + Permission: []generic.Permission{ + generic.PermissionString("role.panel.edit"), + }, + DiscordPerm: discord.PermissionManageRoles, + CommandHandler: func(c *components.Components, event *events.ApplicationCommandInteractionCreate) errors.Error { + g, err := c.GuildCreateID(event, *event.GuildID()) + if err != nil { + return errors.NewError(err) + } + + panelID, err := uuid.Parse(event.SlashCommandInteractionData().String("panel")) + if err != nil { + return errors.NewError(err) + } + + rolePanel := g.QueryRolePanels().WithEdit().Where(rolepanel.ID(panelID)).FirstX(event) + + if rolePanel.QueryEdit().ExistX(event) { + c.DB().RolePanelEdit.DeleteOneID(rolePanel.QueryEdit().FirstIDX(event)).ExecX(event) + } + + shouldUpdate := false + var removeRoles []snowflake.ID + var roles []discord.Role = nil + for _, r := range rolePanel.Roles { + if roles == nil { + roles, err = event.Client().Rest().GetRoles(*event.GuildID()) + if err != nil { + return errors.NewError(err) + } + } + if slices.ContainsFunc(roles, func(role discord.Role) bool { return role.ID == r.ID }) { + continue + } + shouldUpdate = true + removeRoles = append(removeRoles, r.ID) + } + if shouldUpdate { + for _, id := range removeRoles { + rolePanel.Roles = slices.DeleteFunc(rolePanel.Roles, func(r schema.Role) bool { return r.ID == id }) + } + rolePanel = + rolePanel.Update(). + SetUpdatedAt(time.Now()). + SetRoles(rolePanel.Roles). + SaveX(event) + } + + edit := c.DB().RolePanelEdit.Create(). + SetGuild(g). + SetParent(rolePanel). + SetChannelID(event.Channel().ID()). + SaveX(event) + + if err := event.CreateMessage( + rpEditBaseMessage(rolePanel, edit, event.Locale()). + SetFlags(discord.MessageFlagEphemeral). + BuildCreate(), + ); err != nil { + return errors.NewError(err) + } + + return nil + }, + }, + "/role/panel/place": generic.PCommandHandler{ + Permission: []generic.Permission{ + generic.PermissionString("role.panel.place"), + }, + DiscordPerm: discord.PermissionManageRoles, + CommandHandler: func(c *components.Components, event *events.ApplicationCommandInteractionCreate) errors.Error { + g, err := c.GuildCreateID(event, *event.GuildID()) + if err != nil { + return errors.NewError(err) + } + + c.DB().RolePanelPlaced.Delete().Where(rolepanelplaced.And(rolepanelplaced.MessageIDIsNil(), rolepanelplaced.HasGuildWith(guild.ID(g.ID)))).ExecX(event) + + panelID, err := uuid.Parse(event.SlashCommandInteractionData().String("panel")) + if err != nil { + return errors.NewError(err) + } + + panel := g.QueryRolePanels().Where(rolepanel.ID(panelID)).FirstX(event) + + place := c.DB().RolePanelPlaced.Create(). + SetGuild(g). + SetChannelID(event.Channel().ID()). + SetRolePanel(panel). + SetName(panel.Name). + SetDescription(panel.Description). + SetRoles(panel.Roles). + SetUpdatedAt(time.Now()). + SaveX(event) + + if err := event.CreateMessage( + rpPlaceBaseMenu(place, event.Locale()). + SetFlags(discord.MessageFlagEphemeral). + BuildCreate(), + ); err != nil { + return errors.NewError(err) + } + return nil + }, + }, + "/role/panel/delete": generic.PCommandHandler{ + Permission: []generic.Permission{ + generic.PermissionString("role.panel.delete"), + }, + DiscordPerm: discord.PermissionManageRoles, + CommandHandler: func(c *components.Components, event *events.ApplicationCommandInteractionCreate) errors.Error { + g, err := c.GuildCreateID(event, *event.GuildID()) + if err != nil { + return errors.NewError(err) + } + panelID, err := uuid.Parse(event.SlashCommandInteractionData().String("panel")) + if err != nil { + return errors.NewError(err) + } + + panel := g.QueryRolePanels().Where(rolepanel.ID(panelID)).FirstX(event) + + places := panel.QueryPlacements().AllX(event) + for _, place := range places { + if place.MessageID == nil { + continue + } + _ = event.Client().Rest().DeleteMessage(place.ChannelID, *place.MessageID) + } + + c.DB().RolePanelPlaced.Delete(). + Where(rolepanelplaced.HasRolePanelWith(rolepanel.ID(panel.ID))). + ExecX(event) + c.DB().RolePanelEdit.Delete(). + Where(rolepaneledit.HasParentWith(rolepanel.ID(panel.ID))). + ExecX(event) + + c.DB().RolePanel.DeleteOne(panel).ExecX(event) + + if err := event.CreateMessage( + discord.NewMessageBuilder(). + SetEmbeds( + embeds.SetEmbedProperties( + discord.NewEmbedBuilder(). + SetTitle(translate.Message(event.Locale(), "components.role.panel.delete.message.embed.title")). + SetDescription(translate.Message(event.Locale(), "components.role.panel.delete.message.embed.description", translate.WithTemplate(map[string]any{"RolePanel": panel.Name}))). + Build(), + ), + ). + BuildCreate(), + ); err != nil { + return errors.NewError(err) + } + return nil + }, + }, + }, + AutocompleteHandlers: map[string]generic.PermissionAutocompleteHandler{ + "/role/panel/place:panel": generic.PAutocompleteHandler{ + Permission: []generic.Permission{ + generic.PermissionString("role.panel.place"), + }, + DiscordPerm: discord.PermissionManageRoles, + AutocompleteHandler: panelAutocomplete, + }, + "/role/panel/edit:panel": generic.PAutocompleteHandler{ + Permission: []generic.Permission{ + generic.PermissionString("role.panel.edit"), + }, + DiscordPerm: discord.PermissionManageRoles, + AutocompleteHandler: panelAutocomplete, + }, + "/role/panel/delete:panel": generic.PAutocompleteHandler{ + Permission: []generic.Permission{ + generic.PermissionString("role.panel.delete"), + }, + DiscordPerm: discord.PermissionManageRoles, + AutocompleteHandler: panelAutocomplete, + }, + }, + ModalHandlers: map[string]generic.ModalHandler{ + "role:panel_create_modal": func(c *components.Components, event *events.ModalSubmitInteractionCreate) errors.Error { + g, err := c.GuildCreateID(event, *event.GuildID()) + if err != nil { + return errors.NewError(err) + } + + rolePanel := c.DB().RolePanel.Create(). + SetName(event.Data.Text("name")). + SetDescription(event.Data.Text("description")). + SetGuild(g). + SaveX(event) + + edit := c.DB().RolePanelEdit.Create(). + SetGuild(g). + SetParent(rolePanel). + SetChannelID(event.Channel().ID()). + SaveX(event) + + initialize(edit, rolePanel) + + if err := event.CreateMessage( + rpEditBaseMessage(rolePanel, edit, event.Locale()). + SetFlags(discord.MessageFlagEphemeral). + BuildCreate(), + ); err != nil { + return errors.NewError(err) + } + + return nil + }, + "role:panel_edit_modal": func(c *components.Components, event *events.ModalSubmitInteractionCreate) errors.Error { + args := strings.Split(event.Data.CustomID, ":") + action := args[2] + editID, err := uuid.Parse(args[3]) + if err != nil { + return errors.NewError(err) + } + g, err := c.GuildCreateID(event, *event.GuildID()) + if err != nil { + return errors.NewError(err) + } + if !g.QueryRolePanelEdits().Where(rolepaneledit.ID(editID)).ExistX(event) { + return errors.NewError(errors.ErrorMessage("errors.timeout", event)) + } + + edit := g.QueryRolePanelEdits().Where(rolepaneledit.ID(editID)).FirstX(event) + panel := edit.QueryParent().OnlyX(event) + + initialize(edit, panel) + + switch action { + case "change_name": + edit = edit.Update(). + SetModified(true). + SetName(event.Data.Text("name")). + SaveX(event) + if err := event.UpdateMessage( + rpEditBaseMessage(panel, edit, event.Locale()). + SetFlags(discord.MessageFlagEphemeral). + BuildUpdate(), + ); err != nil { + return errors.NewError(err) + } + case "change_description": + edit = edit.Update(). + SetModified(true). + SetDescription(event.Data.Text("description")). + SaveX(event) + if err := event.UpdateMessage( + rpEditBaseMessage(panel, edit, event.Locale()). + SetFlags(discord.MessageFlagEphemeral). + BuildUpdate(), + ); err != nil { + return errors.NewError(err) + } + case "set_display_name": + if edit.SelectedRole != nil { + edit.Roles[slices.IndexFunc(edit.Roles, func(r schema.Role) bool { return r.ID == *edit.SelectedRole })].Name = event.Data.Text("display_name") + edit = edit.Update().SetRoles(panel.Roles).SaveX(event) + } + + if err := event.UpdateMessage( + rpEditBaseMessage(panel, edit, event.Locale()). + SetFlags(discord.MessageFlagEphemeral). + BuildUpdate(), + ); err != nil { + return errors.NewError(err) + } + } + + return nil + }, + }, + ComponentHandlers: map[string]generic.PermissionComponentHandler{ + "role:panel_edit_component": generic.PComponentHandler{ + Permission: []generic.Permission{ + generic.PermissionString("role.panel.edit"), + }, + DiscordPerm: discord.PermissionManageRoles, + ComponentHandler: func(c *components.Components, event *events.ComponentInteractionCreate) errors.Error { + args := strings.Split(event.Data.CustomID(), ":") + action := args[2] + editID, err := uuid.Parse(args[3]) + if err != nil { + return errors.NewError(err) + } + g, err := c.GuildCreateID(event, *event.GuildID()) + if err != nil { + return errors.NewError(err) + } + if !g.QueryRolePanelEdits().Where(rolepaneledit.ID(editID)).ExistX(event) { + return errors.NewError(errors.ErrorMessage("errors.timeout", event)) + } + edit := g.QueryRolePanelEdits().Where(rolepaneledit.ID(editID)).FirstX(event) + panel := edit.QueryParent().OnlyX(event) + + initialize(edit, panel) + + switch action { + case "change_name", "change_description": + if err := event.Modal( + discord.NewModalCreateBuilder(). + SetTitle(translate.Message(event.Locale(), fmt.Sprintf("components.role.panel.edit.action.%s.title", action))). + SetCustomID(fmt.Sprintf("role:panel_edit_modal:%s:%s", action, edit.ID)). + SetContainerComponents( + builtin.Or(action == "change_name", + discord.NewActionRow( + discord.TextInputComponent{ + CustomID: "name", + Style: discord.TextInputStyleShort, + Label: translate.Message(event.Locale(), "components.role.panel.create.modal.input.1.label"), + MinLength: builtin.Ptr(1), + MaxLength: 32, + Required: true, + Value: *edit.Name, + }, + ), + discord.NewActionRow( + discord.TextInputComponent{ + CustomID: "description", + Style: discord.TextInputStyleParagraph, + Label: translate.Message(event.Locale(), "components.role.panel.create.modal.input.2.label"), + MaxLength: 140, + Value: *edit.Description, + }, + ), + ), + ). + Build(), + ); err != nil { + return errors.NewError(err) + } + case "modify_roles": + if err := event.UpdateMessage( + rpEditModifyRolesMessage(edit, event.Locale()). + SetFlags(discord.MessageFlagEphemeral). + BuildUpdate(), + ); err != nil { + return errors.NewError(err) + } + case "base_menu": + if err := event.UpdateMessage( + rpEditBaseMessage(panel, edit, event.Locale()). + SetFlags(discord.MessageFlagEphemeral). + BuildUpdate(), + ); err != nil { + return errors.NewError(err) + } + case "add_role": + selectedRoles := event.RoleSelectMenuInteractionData().Resolved.Roles + self, valid := event.Client().Caches().SelfMember(*event.GuildID()) + if !valid { + return errors.NewError(errors.ErrorMessage("errors.invalid.self", event)) + } + var roles []discord.Role + roleMap := map[snowflake.ID]discord.Role{} + for _, id := range self.RoleIDs { + role, ok := event.Client().Caches().Role(*event.GuildID(), id) + if !ok { + continue + } + roleMap[id] = role + roles = append(roles, role) + } + highestRole := discordutil.GetHighestRole(roles) + if highestRole == nil { + return errors.NewError(errors.ErrorMessage("errors.invalid.self", event)) + } + var deletedRole []snowflake.ID + + for i, r := range selectedRoles { + if slices.ContainsFunc(edit.Roles, func(r1 schema.Role) bool { return r1.ID == r.ID }) { + continue + } + if r.Managed || r.Compare(*highestRole) != -1 { + delete(selectedRoles, i) + deletedRole = append(deletedRole, i) + continue + } + edit.Roles = append(edit.Roles, schema.Role{ + ID: r.ID, + Name: r.Name, + }) + } + + if len(deletedRole) > 0 { + var deletedRoleString string + for _, id := range deletedRole { + deletedRoleString += fmt.Sprintf("- %s\r", discord.RoleMention(id)) + } + if err := event.CreateMessage( + discord.NewMessageBuilder(). + SetEmbeds( + embeds.SetEmbedProperties( + discord.NewEmbedBuilder(). + SetTitle(translate.Message(event.Locale(), "components.role.panel.edit.add_role.deleted_role.embed.title")). + SetDescriptionf("%s\n"+deletedRoleString, translate.Message(event.Locale(), "components.role.panel.edit.add_role.deleted_role.embed.description")). + Build(), + ), + ). + SetFlags(discord.MessageFlagEphemeral). + BuildCreate(), + ); err != nil { + return errors.NewError(err) + } + return nil + } + edit.Roles = slices.DeleteFunc(edit.Roles, func(r schema.Role) bool { _, ok := selectedRoles[r.ID]; return !ok }) + + edit = edit.Update(). + SetModified(true). + SetRoles(edit.Roles). + SaveX(event) + + if err := event.UpdateMessage( + rpEditBaseMessage(panel, edit, event.Locale()). + SetFlags(discord.MessageFlagEphemeral). + BuildUpdate(), + ); err != nil { + return errors.NewError(err) + } + case "select_role": + var id *snowflake.ID + if values := event.StringSelectMenuInteractionData().Values; len(values) > 0 { + id = builtin.Ptr(snowflake.MustParse(values[0])) + } + if id == nil { + edit = edit.Update(). + ClearSelectedRole(). + SaveX(event) + } else { + edit = edit.Update(). + SetNillableSelectedRole(id). + SaveX(event) + } + + if err := event.UpdateMessage( + rpEditBaseMessage(panel, edit, event.Locale()). + SetFlags(discord.MessageFlagEphemeral). + BuildUpdate(), + ); err != nil { + return errors.NewError(err) + } + case "delete": + if edit.SelectedRole != nil { + edit.Roles = slices.DeleteFunc(edit.Roles, func(r schema.Role) bool { return r.ID == *edit.SelectedRole }) + edit = edit.Update(). + SetModified(true). + SetRoles(edit.Roles). + SaveX(event) + } + + if err := event.UpdateMessage( + rpEditBaseMessage(panel, edit, event.Locale()). + SetFlags(discord.MessageFlagEphemeral). + BuildUpdate(), + ); err != nil { + return errors.NewError(err) + } + case "move_up", "move_down": + if edit.SelectedRole != nil { + index := slices.IndexFunc(edit.Roles, func(r schema.Role) bool { return r.ID == *edit.SelectedRole }) + mv := builtin.Or(action == "move_up", -1, 1) + edit.Roles[index+mv], edit.Roles[index] = edit.Roles[index], edit.Roles[index+mv] + + edit = edit.Update(). + SetModified(true). + SetRoles(edit.Roles). + SaveX(event) + } + + if err := event.UpdateMessage( + rpEditBaseMessage(panel, edit, event.Locale()). + SetFlags(discord.MessageFlagEphemeral). + BuildUpdate(), + ); err != nil { + return errors.NewError(err) + } + case "set_display_name": + if edit.SelectedRole != nil { + if err := event.Modal( + discord.NewModalCreateBuilder(). + SetTitle(translate.Message(event.Locale(), "components.role.panel.edit.set_display.name.modal.title")). + SetCustomID(fmt.Sprintf("role:panel_edit_modal:set_display_name:%s", edit.ID)). + SetContainerComponents( + discord.NewActionRow( + discord.TextInputComponent{ + CustomID: "display_name", + Style: discord.TextInputStyleShort, + Label: translate.Message(event.Locale(), "components.role.panel.edit.set_display.name.modal.input.display_name.label"), + MinLength: builtin.Ptr(1), + MaxLength: 100, + Required: true, + Value: edit.Roles[slices.IndexFunc(edit.Roles, func(r schema.Role) bool { return r.ID == *edit.SelectedRole })].Name, + }, + ), + ). + Build(), + ); err != nil { + return errors.NewError(err) + } + } + case "set_emoji": + if edit.SelectedRole != nil { + edit = edit.Update(). + SetEmojiAuthor(event.User().ID). + SetToken(event.Token()). + SaveX(event) + } + + if err := event.UpdateMessage( + rpEditSetEmojiMessage(edit, event.Locale()). + SetFlags(discord.MessageFlagEphemeral). + BuildUpdate(), + ); err != nil { + return errors.NewError(err) + } + case "cancel_emoji", "reset_emoji": + edit = edit.Update(). + ClearEmojiAuthor(). + ClearToken(). + SaveX(event) + + if action == "reset_emoji" { + edit.Roles[slices.IndexFunc(edit.Roles, func(r schema.Role) bool { return r.ID == *edit.SelectedRole })].Emoji = nil + edit = edit.Update(). + SetModified(true). + SetRoles(panel.Roles). + SaveX(event) + } + + if err := event.UpdateMessage( + rpEditBaseMessage(panel, edit, event.Locale()). + SetFlags(discord.MessageFlagEphemeral). + BuildUpdate(), + ); err != nil { + return errors.NewError(err) + } + case "save_change": + + edit = edit.Update(). + SetModified(false). + SaveX(event) + + update := panel.Update(). + SetUpdatedAt(time.Now()). + SetNillableName(edit.Name). + SetNillableDescription(edit.Description) + if edit.Roles != nil { + update.SetRoles(edit.Roles) + } + panel = update.SaveX(event) + + if err := event.UpdateMessage( + rpEditBaseMessage(panel, edit, event.Locale()). + SetFlags(discord.MessageFlagEphemeral). + BuildUpdate(), + ); err != nil { + return errors.NewError(err) + } + case "apply_change": + var ok bool + g.RolePanelEditTimes, ok = ratelimit.CheckLimit(g.RolePanelEditTimes, []ratelimit.Rule{ + { + Limit: 3, + Unit: time.Minute * 10, + }, + { + Limit: 5, + Unit: time.Minute * 30, + }, + }) + g.Update(). + SetRolePanelEditTimes(g.RolePanelEditTimes). + SaveX(event) + if !ok || len(panel.Roles) < 1 { + return errors.NewError(errors.ErrorMessage("errors.ratelimited", event)) + } + + panel = panel.Update(). + SetAppliedAt(time.Now()). + SaveX(event) + + go updateRolePanel(event, panel, event.Locale(), event.Client(), true) + if err := event.UpdateMessage( + rpEditBaseMessage(panel, edit, event.Locale()). + SetFlags(discord.MessageFlagEphemeral). + BuildUpdate(), + ); err != nil { + return errors.NewError(err) + } + default: + slog.Warn("䞍明なcustom_id", "id", event.Data.CustomID()) + } + + return nil + }, + }, + "role:panel_place_component": generic.PComponentHandler{ + Permission: []generic.Permission{ + generic.PermissionString("role.panel.place"), + }, + DiscordPerm: discord.PermissionManageRoles, + ComponentHandler: func(c *components.Components, event *events.ComponentInteractionCreate) errors.Error { + args := strings.Split(event.Data.CustomID(), ":") + action := args[2] + placeID, err := uuid.Parse(args[3]) + if err != nil { + return errors.NewError(err) + } + g, err := c.GuildCreateID(event, *event.GuildID()) + if err != nil { + return errors.NewError(err) + } + if !g.QueryRolePanelPlacements().Where(rolepanelplaced.ID(placeID)).ExistX(event) { + return errors.NewError(errors.ErrorMessage("errors.timeout", event)) + } + place := g.QueryRolePanelPlacements().Where(rolepanelplaced.ID(placeID)).FirstX(event) + panel := place.QueryRolePanel().OnlyX(event) + + switch action { + case "type": + place = place.Update(). + SetType(rolepanelplaced.Type(event.StringSelectMenuInteractionData().Values[0])). + SaveX(event) + case "button_type": + var t discord.ButtonStyle = discord.ButtonStylePrimary + switch event.StringSelectMenuInteractionData().Values[0] { + case "green": + t = discord.ButtonStyleSuccess + case "blue": + t = discord.ButtonStylePrimary + case "red": + t = discord.ButtonStyleDanger + case "gray": + t = discord.ButtonStyleSecondary + } + place = place.Update(). + SetButtonType(t). + SaveX(event) + case "show_name": + place = place.Update(). + SetShowName(!place.ShowName). + SaveX(event) + case "folding_select_menu": + place = place.Update(). + SetFoldingSelectMenu(!place.FoldingSelectMenu). + SaveX(event) + case "hide_notice": + place = place.Update(). + SetHideNotice(!place.HideNotice). + SaveX(event) + case "use_display_name": + place = place.Update(). + SetUseDisplayName(!place.UseDisplayName). + SaveX(event) + case "create": + if len(panel.Roles) < 1 { + return errors.NewError(errors.ErrorMessage("errors.not_exist", event)) + } + if err := rolePanelPlace(event, place, event.Locale(), event.Client(), true); err != nil { + return errors.NewError(err) + } + + updateMessage := discord.NewMessageBuilder(). + SetEmbeds( + embeds.SetEmbedProperties( + discord.NewEmbedBuilder(). + SetTitle(translate.Message(event.Locale(), "components.role.panel.create.message")). + SetDescription(translate.Message(event.Locale(), "components.role.panel.create.description")). + Build(), + ), + ). + BuildUpdate() + updateMessage.Components = &[]discord.ContainerComponent{} + if err := event.UpdateMessage( + updateMessage, + ); err != nil { + return errors.NewError(err) + } + return nil + } + if err := event.UpdateMessage( + rpPlaceBaseMenu(place, event.Locale()). + SetFlags(discord.MessageFlagEphemeral). + BuildUpdate(), + ); err != nil { + return errors.NewError(err) + } + return nil + }, + }, + "role:panel_use": generic.ComponentHandler(func(c *components.Components, event *events.ComponentInteractionCreate) errors.Error { + args := strings.Split(event.Data.CustomID(), ":") + action := args[2] + placeID, err := uuid.Parse(args[3]) + if err != nil { + return errors.NewError(err) + } + g, err := c.GuildCreateID(event, *event.GuildID()) + if err != nil { + return errors.NewError(err) + } + if !g.QueryRolePanelPlacements().Where(rolepanelplaced.ID(placeID)).ExistX(event) { + if err := event.Client().Rest().DeleteMessage(event.Channel().ID(), event.Message.ID); err != nil { + return errors.NewError(err) + } + return errors.NewError(errors.ErrorMessage("errors.deleted", event)) + } + place := g.QueryRolePanelPlacements().Where(rolepanelplaced.ID(placeID)).FirstX(event) + + switch action { + case "button": + roleID := snowflake.MustParse(args[4]) + if !slices.ContainsFunc(place.Roles, func(r schema.Role) bool { return r.ID == roleID }) { + if err := event.UpdateMessage( + rpPlacedMessage(place, event.Locale()). + BuildUpdate(), + ); err != nil { + return errors.NewError(err) + } + return nil + } + + _, ok := event.Client().Caches().Role(*event.GuildID(), roleID) + if !ok { + if err := event.DeferUpdateMessage(); err != nil { + return errors.NewError(err) + } + return nil + } + + contain := slices.Contains(event.Member().RoleIDs, roleID) + if contain { + if err := event.Client().Rest().RemoveMemberRole(g.ID, event.User().ID, roleID, rest.WithReason(fmt.Sprintf("Role Panel \"%s\" (%s)", place.Name, place.ID))); err != nil { + return errors.NewError(errors.ErrorMessage("errors.fail.role.panel", event)) + } + } else { + if err := event.Client().Rest().AddMemberRole(g.ID, event.User().ID, roleID, rest.WithReason(fmt.Sprintf("Role Panel \"%s\" (%s)", place.Name, place.ID))); err != nil { + return errors.NewError(errors.ErrorMessage("errors.fail.role.panel", event)) + } + } + if err := event.CreateMessage( + discord.NewMessageBuilder(). + SetEmbeds( + embeds.SetEmbedProperties( + discord.NewEmbedBuilder(). + SetTitle(translate.Message(event.Locale(), "components.role.panel.use."+builtin.Or(!contain, "added", "removed"))). + SetDescription(translate.Message(event.Locale(), "components.role.panel.use."+builtin.Or(!contain, "added", "removed")+".description", translate.WithTemplate(map[string]any{"Role": discord.RoleMention(roleID)}))). + Build(), + ), + ). + SetFlags(discord.MessageFlagEphemeral). + BuildCreate(), + ); err != nil { + return errors.NewError(err) + } + case "select_menu_fold": + options := make([]discord.StringSelectMenuOption, len(place.Roles)) + for i, role := range place.Roles { + if role.Emoji == nil { + role.Emoji = &discord.ComponentEmoji{ + Name: discordutil.Index2Emoji(i), + } + } + options[i] = discord.StringSelectMenuOption{ + Label: role.Name, + Value: role.ID.String(), + Emoji: role.Emoji, + Default: slices.Contains(event.Member().RoleIDs, role.ID), + } + } + actionRow := discord.NewActionRow( + discord.StringSelectMenuComponent{ + CustomID: fmt.Sprintf("role:panel_use:select_menu:%s", place.ID.String()), + Placeholder: translate.Message(event.Locale(), "components.role.panel.components.select_menu.placeholder"), + MinValues: builtin.Ptr(0), + MaxValues: len(place.Roles), + Options: options, + }, + ) + if err := event.CreateMessage( + discord.NewMessageBuilder(). + SetContainerComponents(actionRow). + SetFlags(discord.MessageFlagEphemeral). + BuildCreate(), + ); err != nil { + return errors.NewError(err) + } + case "select_menu": + var selectedRoles []snowflake.ID + for _, v := range event.StringSelectMenuInteractionData().Values { + selectedRoles = append(selectedRoles, snowflake.MustParse(v)) + } + + var addRoles []snowflake.ID + var removedRoles []snowflake.ID + var unchangedRole []snowflake.ID + for _, role := range place.Roles { + if slices.Contains(selectedRoles, role.ID) { + // 遞ばれたずき + if slices.Index(event.Member().RoleIDs, role.ID) != -1 { + // 持っおたなら + unchangedRole = append(unchangedRole, role.ID) + continue + } else { + // 持っおないなら + _, ok := event.Client().Caches().Role(*event.GuildID(), role.ID) + if !ok { + continue + } + addRoles = append(addRoles, role.ID) + + if err := event.Client().Rest().AddMemberRole(*event.GuildID(), event.User().ID, role.ID); err != nil { + return errors.NewError(errors.ErrorMessage("errors.fail.role.panel", event)) + } + } + } else { + // 遞ばれおないずき + if slices.Index(event.Member().RoleIDs, role.ID) != -1 { + // 持っおたなら + removedRoles = append(removedRoles, role.ID) + + if err := event.Client().Rest().RemoveMemberRole(*event.GuildID(), event.User().ID, role.ID); err != nil { + return errors.NewError(errors.ErrorMessage("errors.fail.role.panel", event)) + } + } else { + // 持っおないなら + continue + } + } + } + + embed := discord.NewEmbedBuilder(). + SetTitle(translate.Message(event.Locale(), "components.role.panel.use.changed")) + if len(addRoles) > 0 { + var addRolesString string + for _, id := range addRoles { + addRolesString += fmt.Sprintf("%s\n", discord.RoleMention(id)) + } + embed.AddFields( + discord.EmbedField{ + Name: translate.Message(event.Locale(), "components.role.panel.use.changed.add"), + Value: addRolesString, + }, + ) + } + if len(unchangedRole) > 0 { + var unchangedRoleString string + for _, id := range unchangedRole { + unchangedRoleString += fmt.Sprintf("%s\n", discord.RoleMention(id)) + } + embed.AddFields( + discord.EmbedField{ + Name: translate.Message(event.Locale(), "components.role.panel.use.changed.unchanged"), + Value: unchangedRoleString, + }, + ) + } + if len(removedRoles) > 0 { + var removedRolesString string + for _, id := range removedRoles { + removedRolesString += fmt.Sprintf("%s\n", discord.RoleMention(id)) + } + embed.AddFields( + discord.EmbedField{ + Name: translate.Message(event.Locale(), "components.role.panel.use.changed.remove"), + Value: removedRolesString, + }, + ) + } + if err := event.RespondMessage( + discord.NewMessageBuilder(). + SetEmbeds(embeds.SetEmbedProperties(embed.Build())). + SetFlags(discord.MessageFlagEphemeral), + ); err != nil { + return errors.NewError(err) + } + } + return nil + }), + }, + EventHandler: func(c *components.Components, event bot.Event) errors.Error { + switch event := event.(type) { + case *events.GuildMessageCreate: + if event.Message.Author.Bot || event.Message.Author.System { + return nil + } + g, err := c.GuildCreateID(event, event.GuildID) + if err != nil { + return errors.NewError(err) + } + u, err := c.UserCreate(event, event.Message.Author) + if err != nil { + return errors.NewError(err) + } + + edits := g.QueryRolePanelEdits().Where(rolepaneledit.ChannelID(event.ChannelID)).AllX(event) + for _, edit := range edits { + if edit.EmojiAuthor == nil || *edit.EmojiAuthor != event.Message.Author.ID || edit.Token == nil { + continue + } + token := *edit.Token + emojis := emoji.FindAllString(event.Message.Content) + if len(emojis) < 1 { + continue + } + componentEmoji := discordutil.ParseComponentEmoji(emojis[0]) + panel := edit.QueryParent().OnlyX(event) + + initialize(edit, panel) + + edit.Roles[slices.IndexFunc(edit.Roles, func(r schema.Role) bool { return r.ID == *edit.SelectedRole })].Emoji = &componentEmoji + edit = edit.Update(). + ClearEmojiAuthor(). + ClearToken(). + SetRoles(edit.Roles). + SaveX(event) + + if err := event.Client().Rest().AddReaction(event.ChannelID, event.MessageID, "✅"); err != nil { + return errors.NewError(err) + } + + if _, err := event.Client().Rest().UpdateInteractionResponse(event.Client().ApplicationID(), token, + rpEditBaseMessage(panel, edit, u.Locale). + SetFlags(discord.MessageFlagEphemeral). + BuildUpdate(), + ); err != nil { + return errors.NewError(err) + } + } + case *events.GuildMessageDelete: + g, err := c.GuildCreateID(event, event.GuildID) + if err != nil { + return errors.NewError(err) + } + + c.DB().RolePanelPlaced.Delete(). + Where( + rolepanelplaced.And( + rolepanelplaced.HasGuildWith(guild.ID(g.ID)), + rolepanelplaced.ChannelID(event.ChannelID), + rolepanelplaced.MessageID(event.MessageID), + ), + ). + ExecX(event) + case *events.GuildMessageReactionAdd: + if event.Member.User.Bot || event.Member.User.System { + return nil + } + g, err := c.GuildCreateID(event, event.GuildID) + if err != nil { + return errors.NewError(err) + } + u, err := c.UserCreate(event, event.Member.User) + if err != nil { + return errors.NewError(err) + } + + if !g.QueryRolePanelPlacements().Where(rolepanelplaced.ChannelID(event.ChannelID), rolepanelplaced.MessageID(event.MessageID)).ExistX(event) { + return nil + } + place := g.QueryRolePanelPlacements().Where(rolepanelplaced.ChannelID(event.ChannelID), rolepanelplaced.MessageID(event.MessageID)).FirstX(event) + panel := place.QueryRolePanel().OnlyX(event) + + if err := event.Client().Rest().RemoveUserReaction(event.ChannelID, event.MessageID, event.Emoji.Reaction(), event.UserID); err != nil { + return errors.NewError(err) + } + + for i, role := range panel.Roles { + if role.Emoji == nil { + role.Emoji = &discord.ComponentEmoji{ + Name: discordutil.Index2Emoji(i), + } + } + if event.Emoji.Reaction() != discordutil.ReactionComponentEmoji(*role.Emoji) { + continue + } + _, ok := event.Client().Caches().Role(event.GuildID, role.ID) + if !ok { + return nil + } + contains := slices.Contains(event.Member.RoleIDs, role.ID) + if contains { + err = event.Client().Rest().RemoveMemberRole(event.GuildID, event.UserID, role.ID) + } else { + err = event.Client().Rest().AddMemberRole(event.GuildID, event.UserID, role.ID) + } + if err != nil { + m, err := event.Client().Rest().CreateMessage(event.ChannelID, + discord.NewMessageBuilder(). + SetEmbeds( + embeds.SetEmbedProperties( + discord.NewEmbedBuilder(). + SetTitlef("❗ %s", translate.Message(u.Locale, "errors.fail.role.panel")). + SetDescription(translate.Message(u.Locale, "errors.fail.role.panel.description")). + SetColor(0xff2121). + Build(), + ), + ). + SetFlags(discord.MessageFlagEphemeral).BuildCreate(), + ) + if err != nil { + return errors.NewError(err) + } + if err := discordutil.DeleteMessageAfter(event.Client(), event.ChannelID, m.ID, time.Second*10); err != nil { + return errors.NewError(err) + } + return nil + } + if place.HideNotice { + return nil + } + m, err := event.Client().Rest().CreateMessage(event.ChannelID, + discord.NewMessageBuilder(). + SetContent(discord.UserMention(event.UserID)). + SetEmbeds( + embeds.SetEmbedProperties( + discord.NewEmbedBuilder(). + SetTitle(translate.Message(u.Locale, "components.role.panel.use."+builtin.Or(!contains, "added", "removed"))). + SetDescription(translate.Message(u.Locale, "components.role.panel.use."+builtin.Or(!contains, "added", "removed")+".description", translate.WithTemplate(map[string]any{"Role": discord.RoleMention(role.ID)}))). + Build(), + ), + ). + SetFlags(discord.MessageFlagEphemeral).BuildCreate(), + ) + if err != nil { + return errors.NewError(err) + } + if err := discordutil.DeleteMessageAfter(event.Client(), event.ChannelID, m.ID, time.Second*10); err != nil { + return errors.NewError(err) + } + } + } + return nil + }, + }).SetComponent(c) +} + +func UpdateRolePanel(ctx context.Context, place *ent.RolePanelPlaced, locale discord.Locale, client bot.Client) { + if err := rolePanelPlace(ctx, place, locale, client, true); err != nil { + slog.Error("アップデヌトに倱敗", "err", err) + } +} + +func updateRolePanel(ctx context.Context, panel *ent.RolePanel, locale discord.Locale, client bot.Client, react bool) { + places := panel.QueryPlacements().AllX(ctx) + for _, place := range places { + place = place.Update(). + SetName(panel.Name). + SetDescription(panel.Description). + SetRoles(panel.Roles). + SetUpdatedAt(time.Now()). + SaveX(ctx) + if err := rolePanelPlace(ctx, place, locale, client, react); err != nil { + slog.Error("アップデヌトに倱敗", "err", err) + } + } +} diff --git a/bot/commands/role_panel.go b/bot/commands/role_panel.go deleted file mode 100644 index a4ef9672..00000000 --- a/bot/commands/role_panel.go +++ /dev/null @@ -1,77 +0,0 @@ -package commands - -import ( - "github.com/sabafly/disgo/discord" - "github.com/sabafly/disgo/events" - "github.com/sabafly/gobot/bot/client" - botlib "github.com/sabafly/sabafly-lib/v2/bot" - "github.com/sabafly/sabafly-lib/v2/handler" - "github.com/sabafly/sabafly-lib/v2/translate" -) - -func RolePanel(b *botlib.Bot[*client.Client]) handler.Command { - return handler.Command{ - Create: discord.SlashCommandCreate{ - Name: "role-panel", - Description: "summon role panels", - DMPermission: &b.Config.DMPermission, - }, - CommandHandlers: map[string]handler.CommandHandler{ - "": rolePanelHandler(b), - }, - } -} - -// TODO: V2に察応 -func rolePanelHandler(b *botlib.Bot[*client.Client]) func(event *events.ApplicationCommandInteractionCreate) error { - return func(event *events.ApplicationCommandInteractionCreate) error { - mute := b.Self.GuildDataLock(*event.GuildID()) - if !mute.TryLock() { - return botlib.ReturnErrMessage(event, "error_busy") - } - defer mute.Unlock() - gData, err := b.Self.DB.GuildData().Get(*event.GuildID()) - if err != nil { - return botlib.ReturnErrMessage(event, "error_has_no_data") - } - options := []discord.StringSelectMenuOption{} - for u, gdrp := range gData.RolePanel { - if !gdrp.OnList { - continue - } - rp, err := b.Self.DB.RolePanel().Get(u) - if err != nil { - return botlib.ReturnErr(event, err) - } - options = append(options, discord.StringSelectMenuOption{ - Label: rp.Name, - Description: rp.Description, - Value: rp.UUID().String(), - }) - } - if len(options) == 0 { - return botlib.ReturnErrMessage(event, "error_has_no_panel") - } - embeds := []discord.Embed{ - { - Title: translate.Message(event.Locale(), "role_panel"), - }, - } - embeds = botlib.SetEmbedsProperties(embeds) - err = event.CreateMessage(discord.MessageCreate{ - Embeds: embeds, - Components: []discord.ContainerComponent{ - discord.ActionRowComponent{ - discord.StringSelectMenuComponent{ - CustomID: "handler:rolepanel:call", - Options: options, - }, - }, - }, - }) - if err != nil { - return err - } - return nil - } -} diff --git a/bot/commands/setting/setting.go b/bot/commands/setting/setting.go new file mode 100644 index 00000000..4a96b2ae --- /dev/null +++ b/bot/commands/setting/setting.go @@ -0,0 +1,567 @@ +package setting + +import ( + "context" + "log/slog" + "sync" + "time" + + "github.com/disgoorg/disgo/bot" + "github.com/disgoorg/disgo/discord" + "github.com/disgoorg/disgo/events" + "github.com/disgoorg/snowflake/v2" + "github.com/sabafly/gobot/bot/components" + "github.com/sabafly/gobot/bot/components/generic" + "github.com/sabafly/gobot/ent" + "github.com/sabafly/gobot/internal/builtin" + "github.com/sabafly/gobot/internal/embeds" + "github.com/sabafly/gobot/internal/errors" + "github.com/sabafly/gobot/internal/translate" +) + +func Command(c *components.Components) components.Command { + return (&generic.Command{ + Namespace: "setting", + CommandCreate: []discord.ApplicationCommandCreate{ + discord.SlashCommandCreate{ + Name: "setting", + Description: "setting", + DMPermission: builtin.Ptr(false), + Contexts: []discord.InteractionContextType{ + discord.InteractionContextTypeGuild, + }, + Options: []discord.ApplicationCommandOption{ + discord.ApplicationCommandOptionSubCommandGroup{ + Name: "bump", + Description: "bump", + Options: []discord.ApplicationCommandOptionSubCommand{ + { + Name: "toggle", + Description: "toggle", + DescriptionLocalizations: translate.MessageMap("components.setting.bump.toggle", false), + }, + { + Name: "message", + Description: "set message", + DescriptionLocalizations: translate.MessageMap("components.setting.bump.message", false), + }, + { + Name: "mention", + Description: "set mention target", + DescriptionLocalizations: translate.MessageMap("components.setting.bump.mention", false), + Options: []discord.ApplicationCommandOption{ + discord.ApplicationCommandOptionRole{ + Name: "target", + Description: "target role", + DescriptionLocalizations: translate.MessageMap("components.setting.mention.target", false), + }, + }, + }, + }, + }, + discord.ApplicationCommandOptionSubCommandGroup{ + Name: "up", + Description: "up", + Options: []discord.ApplicationCommandOptionSubCommand{ + { + Name: "toggle", + Description: "toggle", + DescriptionLocalizations: translate.MessageMap("components.setting.up.toggle", false), + }, + { + Name: "message", + Description: "set message", + DescriptionLocalizations: translate.MessageMap("components.setting.up.message", false), + }, + { + Name: "mention", + Description: "set mention target", + DescriptionLocalizations: translate.MessageMap("components.setting.up.mention", false), + Options: []discord.ApplicationCommandOption{ + discord.ApplicationCommandOptionRole{ + Name: "target", + Description: "target role", + DescriptionLocalizations: translate.MessageMap("components.setting.mention.target", false), + }, + }, + }, + }, + }, + // discord.ApplicationCommandOptionSubCommandGroup{ + // Name: "welcome", + // Description: "welcome", + // Options: []discord.ApplicationCommandOptionSubCommand{ + // { + // Name: "set-message", + // Description: "set message", + // DescriptionLocalizations: translate.MessageMap("components.setting.welcome.set-message", false), + // }, + // { + // Name: "set-channel", + // Description: "set channel", + // DescriptionLocalizations: translate.MessageMap("components.setting.welcome.set-channel", false), + // Options: []discord.ApplicationCommandOption{ + // discord.ApplicationCommandOptionChannel{ + // Name: "channel", + // Description: "channel", + // DescriptionLocalizations: translate.MessageMap("components.setting.welcome.channel", false), + // }, + // }, + // }, + // }, + // }, + }, + }, + }, + CommandHandlers: map[string]generic.PermissionCommandHandler{ + "/setting/bump/toggle": generic.PCommandHandler{ + Permission: []generic.Permission{ + generic.PermissionString("setting.bump.toggle"), + }, + DiscordPerm: discord.PermissionManageGuild, + CommandHandler: func(c *components.Components, event *events.ApplicationCommandInteractionCreate) errors.Error { + g, err := c.GuildCreateID(event, *event.GuildID()) + if err != nil { + return errors.NewError(err) + } + g = g.Update(). + SetBumpEnabled(!g.BumpEnabled). + SaveX(event) + if err := event.CreateMessage( + discord.NewMessageBuilder(). + SetContent(translate.Message(event.Locale(), "components.setting.bump.toggle."+builtin.Or(g.BumpEnabled, "enabled", "disabled"))). + BuildCreate(), + ); err != nil { + return errors.NewError(err) + } + return nil + }, + }, + "/setting/up/toggle": generic.PCommandHandler{ + Permission: []generic.Permission{ + generic.PermissionString("setting.up.toggle"), + }, + DiscordPerm: discord.PermissionManageGuild, + CommandHandler: func(c *components.Components, event *events.ApplicationCommandInteractionCreate) errors.Error { + g, err := c.GuildCreateID(event, *event.GuildID()) + if err != nil { + return errors.NewError(err) + } + g = g.Update(). + SetUpEnabled(!g.UpEnabled). + SaveX(event) + if err := event.CreateMessage( + discord.NewMessageBuilder(). + SetContent(translate.Message(event.Locale(), "components.setting.up.toggle."+builtin.Or(g.UpEnabled, "enabled", "disabled"))). + BuildCreate(), + ); err != nil { + return errors.NewError(err) + } + return nil + }, + }, + "/setting/bump/mention": generic.PCommandHandler{ + Permission: []generic.Permission{ + generic.PermissionString("setting.bump.mention"), + }, + DiscordPerm: discord.PermissionManageGuild, + CommandHandler: func(c *components.Components, event *events.ApplicationCommandInteractionCreate) errors.Error { + g, err := c.GuildCreateID(event, *event.GuildID()) + if err != nil { + return errors.NewError(err) + } + update := g.Update() + if r, ok := event.SlashCommandInteractionData().OptRole("target"); ok { + update.SetBumpMention(r.ID) + } else { + update.ClearBumpMention() + } + g = update.SaveX(event) + if err := event.CreateMessage( + discord.NewMessageBuilder(). + SetContent(translate.Message(event.Locale(), "components.setting.bump.mention.used", + translate.WithTemplate(map[string]any{ + "Role": builtin.Or(g.BumpMention != nil, + discord.RoleMention(builtin.NonNil(g.BumpMention)), + "`"+translate.Message(event.Locale(), "components.setting.mention.none")+"`", + ), + }), + )). + BuildCreate(), + ); err != nil { + return errors.NewError(err) + } + return nil + }, + }, + "/setting/up/mention": generic.PCommandHandler{ + Permission: []generic.Permission{ + generic.PermissionString("setting.up.mention"), + }, + DiscordPerm: discord.PermissionManageGuild, + CommandHandler: func(c *components.Components, event *events.ApplicationCommandInteractionCreate) errors.Error { + g, err := c.GuildCreateID(event, *event.GuildID()) + if err != nil { + return errors.NewError(err) + } + update := g.Update() + if r, ok := event.SlashCommandInteractionData().OptRole("target"); ok { + update.SetUpMention(r.ID) + } else { + update.ClearUpMention() + } + g = update.SaveX(event) + if err := event.CreateMessage( + discord.NewMessageBuilder(). + SetContent(translate.Message(event.Locale(), "components.setting.up.mention.used", + translate.WithTemplate(map[string]any{ + "Role": builtin.Or(g.UpMention != nil, + discord.RoleMention(builtin.NonNil(g.UpMention)), + "`"+translate.Message(event.Locale(), "components.setting.mention.none")+"`", + ), + }), + )). + BuildCreate(), + ); err != nil { + return errors.NewError(err) + } + return nil + }, + }, + "/setting/bump/message": generic.PCommandHandler{ + Permission: []generic.Permission{ + generic.PermissionString("setting.bump.message"), + }, + DiscordPerm: discord.PermissionManageGuild, + CommandHandler: func(c *components.Components, event *events.ApplicationCommandInteractionCreate) errors.Error { + g, err := c.GuildCreateID(event, *event.GuildID()) + if err != nil { + return errors.NewError(err) + } + if err := event.Modal( + discord.NewModalCreateBuilder(). + SetTitle(translate.Message(event.Locale(), "components.setting.bump.message.modal.title")). + SetCustomID("setting:bump_message"). + SetContainerComponents( + discord.NewActionRow( + discord.TextInputComponent{ + CustomID: "message_title", + Style: discord.TextInputStyleShort, + Label: translate.Message(event.Locale(), "components.setting.message.modal.message_title"), + MinLength: builtin.Ptr(1), + MaxLength: 30, + Required: true, + Value: g.BumpMessageTitle, + }, + ), + discord.NewActionRow( + discord.TextInputComponent{ + CustomID: "message", + Style: discord.TextInputStyleParagraph, + Label: translate.Message(event.Locale(), "components.setting.message.modal.message"), + MinLength: builtin.Ptr(1), + MaxLength: 300, + Required: true, + Value: g.BumpMessage, + }, + ), + discord.NewActionRow( + discord.TextInputComponent{ + CustomID: "remind.message_title", + Style: discord.TextInputStyleShort, + Label: translate.Message(event.Locale(), "components.setting.message.modal.remind.message_title"), + MinLength: builtin.Ptr(1), + MaxLength: 30, + Required: true, + Value: g.BumpRemindMessageTitle, + }, + ), + discord.NewActionRow( + discord.TextInputComponent{ + CustomID: "remind.message", + Style: discord.TextInputStyleParagraph, + Label: translate.Message(event.Locale(), "components.setting.message.modal.remind.message"), + MinLength: builtin.Ptr(1), + MaxLength: 300, + Required: true, + Value: g.BumpRemindMessage, + }, + ), + ). + Build(), + ); err != nil { + return errors.NewError(err) + } + return nil + }, + }, + "/setting/up/message": generic.PCommandHandler{ + Permission: []generic.Permission{ + generic.PermissionString("setting.up.message"), + }, + DiscordPerm: discord.PermissionManageGuild, + CommandHandler: func(c *components.Components, event *events.ApplicationCommandInteractionCreate) errors.Error { + g, err := c.GuildCreateID(event, *event.GuildID()) + if err != nil { + return errors.NewError(err) + } + if err := event.Modal( + discord.NewModalCreateBuilder(). + SetTitle(translate.Message(event.Locale(), "components.setting.up.message.modal.title")). + SetCustomID("setting:up_message"). + SetContainerComponents( + discord.NewActionRow( + discord.TextInputComponent{ + CustomID: "message_title", + Style: discord.TextInputStyleShort, + Label: translate.Message(event.Locale(), "components.setting.message.modal.message_title"), + MinLength: builtin.Ptr(1), + MaxLength: 30, + Required: true, + Value: g.UpMessageTitle, + }, + ), + discord.NewActionRow( + discord.TextInputComponent{ + CustomID: "message", + Style: discord.TextInputStyleParagraph, + Label: translate.Message(event.Locale(), "components.setting.message.modal.message"), + MinLength: builtin.Ptr(1), + MaxLength: 300, + Required: true, + Value: g.UpMessage, + }, + ), + discord.NewActionRow( + discord.TextInputComponent{ + CustomID: "remind.message_title", + Style: discord.TextInputStyleShort, + Label: translate.Message(event.Locale(), "components.setting.message.modal.remind.message_title"), + MinLength: builtin.Ptr(1), + MaxLength: 30, + Required: true, + Value: g.UpRemindMessageTitle, + }, + ), + discord.NewActionRow( + discord.TextInputComponent{ + CustomID: "remind.message", + Style: discord.TextInputStyleParagraph, + Label: translate.Message(event.Locale(), "components.setting.message.modal.remind.message"), + MinLength: builtin.Ptr(1), + MaxLength: 300, + Required: true, + Value: g.UpRemindMessage, + }, + ), + ). + Build(), + ); err != nil { + return errors.NewError(err) + } + return nil + }, + }, + "/setting/welcome/set-channel": generic.PCommandHandler{ + Permission: []generic.Permission{ + generic.PermissionString("setting.welcome.set-channel"), + }, + DiscordPerm: discord.PermissionManageGuild, + CommandHandler: func(c *components.Components, event *events.ApplicationCommandInteractionCreate) errors.Error { + + return nil + }, + }, + }, + ModalHandlers: map[string]generic.ModalHandler{ + "setting:bump_message": func(c *components.Components, event *events.ModalSubmitInteractionCreate) errors.Error { + g, err := c.GuildCreateID(event, *event.GuildID()) + if err != nil { + return errors.NewError(err) + } + g.Update(). + SetBumpMessageTitle(event.ModalSubmitInteraction.Data.Text("message_title")). + SetBumpMessage(event.ModalSubmitInteraction.Data.Text("message")). + SetBumpRemindMessageTitle(event.ModalSubmitInteraction.Data.Text("remind.message_title")). + SetBumpRemindMessage(event.ModalSubmitInteraction.Data.Text("remind.message")). + ExecX(event) + if err := event.DeferUpdateMessage(); err != nil { + return errors.NewError(err) + } + return nil + }, + "setting:up_message": func(c *components.Components, event *events.ModalSubmitInteractionCreate) errors.Error { + g, err := c.GuildCreateID(event, *event.GuildID()) + if err != nil { + return errors.NewError(err) + } + g.Update(). + SetUpMessageTitle(event.ModalSubmitInteraction.Data.Text("message_title")). + SetUpMessage(event.ModalSubmitInteraction.Data.Text("message")). + SetUpRemindMessageTitle(event.ModalSubmitInteraction.Data.Text("remind.message_title")). + SetUpRemindMessage(event.ModalSubmitInteraction.Data.Text("remind.message")). + ExecX(event) + if err := event.DeferUpdateMessage(); err != nil { + return errors.NewError(err) + } + return nil + }, + }, + + EventHandler: func(c *components.Components, event bot.Event) errors.Error { + if e, ok := event.(*events.GuildMessageUpdate); ok { + event = &events.GuildMessageCreate{GenericGuildMessage: e.GenericGuildMessage} + } + switch event := event.(type) { + case *events.GuildMessageCreate: + if event.Message.Interaction == nil || event.Message.ApplicationID == nil { + return nil + } + if event.Message.Author.ID != c.Config().BumpUserID && event.Message.Author.ID != c.Config().UpUserID { + return nil + } + g, err := c.GuildCreateID(event, event.GuildID) + if err != nil { + return errors.NewError(err) + } + if g.BumpEnabled { + if err := bumpHandler(c, g, event); err != nil { + return errors.NewError(err) + } + } + if g.UpEnabled { + if err := upHandler(c, g, event); err != nil { + return errors.NewError(err) + } + } + return nil + } + return nil + }, + + Schedulers: []components.Scheduler{ + { + Duration: time.Minute, + Worker: func(c *components.Components, client bot.Client) error { + bumpLock.Lock() + defer bumpLock.Unlock() + for k, n := range bumpNotice { + g, err := c.GuildCreateID(context.Background(), n.guildID) + if err != nil { + continue + } + if !g.BumpEnabled { + continue + } + + if time.Now().After(n.t.Add(-time.Minute * 2)) { + go func() { + time.Sleep(time.Until(n.t)) + createNotice(g.BumpRemindMessageTitle, g.BumpRemindMessage, n, client, builtin.Or(g.BumpMention != nil, discord.RoleMention(builtin.NonNil(g.BumpMention)), "")) + }() + delete(bumpNotice, k) + } + } + upLock.Lock() + defer upLock.Unlock() + for k, n := range upNotice { + g, err := c.GuildCreateID(context.Background(), n.guildID) + if err != nil { + continue + } + if !g.UpEnabled { + continue + } + + if time.Now().After(n.t.Add(-time.Minute * 2)) { + go func() { + time.Sleep(time.Until(n.t)) + createNotice(g.UpRemindMessageTitle, g.UpRemindMessage, n, client, builtin.Or(g.UpMention != nil, discord.RoleMention(builtin.NonNil(g.UpMention)), "")) + }() + delete(upNotice, k) + } + } + + return nil + }, + }, + }, + }).SetComponent(c) +} + +type notice struct { + channelID snowflake.ID + guildID snowflake.ID + t time.Time +} + +var bumpNotice = map[snowflake.ID]notice{} +var bumpLock sync.Mutex + +func bumpHandler(c *components.Components, g *ent.Guild, event *events.GuildMessageCreate) error { + bumpLock.Lock() + defer bumpLock.Unlock() + if event.Message.Interaction == nil || event.Message.Interaction.Name != "bump" { + return nil + } + if len(event.Message.Embeds) < 1 || event.Message.Embeds[0].Image == nil || event.Message.Embeds[0].Image.URL != c.Config().BumpImage { + return nil + } + if !g.BumpEnabled { + return nil + } + n := + notice{ + channelID: event.ChannelID, + guildID: event.GuildID, + t: event.Message.CreatedAt.Add(time.Hour * 2), + } + bumpNotice[event.GuildID] = n + createNotice(g.BumpMessageTitle, g.BumpMessage, n, event.Client(), "") + return nil +} + +var upNotice = map[snowflake.ID]notice{} +var upLock sync.Mutex + +func upHandler(c *components.Components, g *ent.Guild, event *events.GuildMessageCreate) error { + upLock.Lock() + defer upLock.Unlock() + if event.Message.Interaction == nil || event.Message.Interaction.Name != "dissoku up" { + return nil + } + if len(event.Message.Embeds) < 1 || event.Message.Embeds[0].Color != c.Config().UpColor { + return nil + } + if !g.UpEnabled { + return nil + } + n := + notice{ + channelID: event.ChannelID, + guildID: event.GuildID, + t: event.Message.CreatedAt.Add(time.Hour * 1), + } + upNotice[event.GuildID] = n + createNotice(g.UpMessageTitle, g.UpMessage, n, event.Client(), "") + return nil +} + +func createNotice(title, message string, n notice, client bot.Client, content string) { + if _, err := client.Rest().CreateMessage(n.channelID, + discord.NewMessageBuilder(). + SetContent(content). + SetEmbeds( + embeds.SetEmbedProperties( + discord.NewEmbedBuilder(). + SetTitle(title). + SetDescription(message). + Build(), + ), + ). + BuildCreate(), + ); err != nil { + slog.Error("通知䜜成に倱敗", slog.Any("err", err)) + return + } +} diff --git a/bot/commands/user.go b/bot/commands/user.go deleted file mode 100644 index ad7b4415..00000000 --- a/bot/commands/user.go +++ /dev/null @@ -1,140 +0,0 @@ -package commands - -import ( - "time" - - "github.com/disgoorg/json" - "github.com/sabafly/disgo/discord" - "github.com/sabafly/disgo/events" - "github.com/sabafly/gobot/bot/client" - botlib "github.com/sabafly/sabafly-lib/v2/bot" - "github.com/sabafly/sabafly-lib/v2/handler" - "github.com/sabafly/sabafly-lib/v2/translate" -) - -func User(b *botlib.Bot[*client.Client]) handler.Command { - return handler.Command{ - Create: discord.SlashCommandCreate{ - Name: "user", - Description: "user", - DMPermission: &b.Config.DMPermission, - Options: []discord.ApplicationCommandOption{ - discord.ApplicationCommandOptionSubCommand{ - Name: "set-birthday", - Description: "set your own birthday", - DescriptionLocalizations: translate.MessageMap("user_set_birthday_command_description", false), - Options: []discord.ApplicationCommandOption{ - discord.ApplicationCommandOptionInt{ - Name: "month", - Description: "month", - DescriptionLocalizations: translate.MessageMap("user_set_birthday_command_month_description", false), - Required: true, - Choices: []discord.ApplicationCommandOptionChoiceInt{ - { - Name: "January", - NameLocalizations: translate.MessageMap("january", false), - Value: 1, - }, - { - Name: "February", - NameLocalizations: translate.MessageMap("february", false), - Value: 2, - }, - { - Name: "March", - NameLocalizations: translate.MessageMap("march", false), - Value: 3, - }, - { - Name: "April", - NameLocalizations: translate.MessageMap("april", false), - Value: 4, - }, - { - Name: "May", - NameLocalizations: translate.MessageMap("may", false), - Value: 5, - }, - { - Name: "June", - NameLocalizations: translate.MessageMap("june", false), - Value: 6, - }, - { - Name: "July", - NameLocalizations: translate.MessageMap("july", false), - Value: 7, - }, - { - Name: "August", - NameLocalizations: translate.MessageMap("august", false), - Value: 8, - }, - { - Name: "September", - NameLocalizations: translate.MessageMap("september", false), - Value: 9, - }, - { - Name: "October", - NameLocalizations: translate.MessageMap("october", false), - Value: 10, - }, - { - Name: "November", - NameLocalizations: translate.MessageMap("november", false), - Value: 11, - }, - { - Name: "December", - NameLocalizations: translate.MessageMap("december", false), - Value: 12, - }, - }, - }, - discord.ApplicationCommandOptionInt{ - Name: "date", - Description: "date of number", - DescriptionLocalizations: translate.MessageMap("user_set_birthday_command_date_description", false), - Required: true, - MinValue: json.Ptr(1), - MaxValue: json.Ptr(31), - }, - }, - }, - }, - }, - CommandHandlers: map[string]handler.CommandHandler{ - "set-birthday": userSetBirthDayCommandHandler(b), - }, - } -} - -func userSetBirthDayCommandHandler(b *botlib.Bot[*client.Client]) handler.CommandHandler { - return func(event *events.ApplicationCommandInteractionCreate) error { - b.Self.UserDataLock(event.User().ID).Lock() - defer b.Self.UserDataLock(event.User().ID).Unlock() - ud, err := b.Self.DB.UserData().Get(event.User().ID) - if err != nil { - return botlib.ReturnErr(event, err) - } - month := event.SlashCommandInteractionData().Int("month") - day := event.SlashCommandInteractionData().Int("date") - date := time.Date(time.Now().Year(), time.Month(month), day, 0, 0, 0, 0, ud.Location.Location) - ud.BirthDay = [2]int{int(date.Month()), date.Day()} - if err := b.Self.DB.UserData().Set(ud.ID, ud); err != nil { - return botlib.ReturnErr(event, err) - } - embed := discord.NewEmbedBuilder() - embed.SetTitle(translate.Message(event.Locale(), "user_changed")) - embed.SetDescription(translate.Message(event.Locale(), "user_set_birthday", translate.WithTemplate(map[string]any{"Date": date.Format("01/02")}))) - embed.Embed = botlib.SetEmbedProperties(embed.Embed) - message := discord.NewMessageCreateBuilder() - message.AddEmbeds(embed.Build()) - message.SetFlags(discord.MessageFlagEphemeral) - if err := event.CreateMessage(message.Build()); err != nil { - return err - } - return nil - } -} diff --git a/bot/commands/user_info.go b/bot/commands/user_info.go deleted file mode 100644 index b067a460..00000000 --- a/bot/commands/user_info.go +++ /dev/null @@ -1,142 +0,0 @@ -package commands - -import ( - "fmt" - "time" - - "github.com/dustin/go-humanize" - "github.com/sabafly/disgo/discord" - "github.com/sabafly/disgo/events" - "github.com/sabafly/gobot/bot/client" - "github.com/sabafly/gobot/bot/db" - botlib "github.com/sabafly/sabafly-lib/v2/bot" - "github.com/sabafly/sabafly-lib/v2/handler" - "github.com/sabafly/sabafly-lib/v2/translate" -) - -func UserInfo(b *botlib.Bot[*client.Client]) handler.Command { - return handler.Command{ - Create: discord.UserCommandCreate{ - Name: "info", - NameLocalizations: translate.MessageMap("user_info_command", false), - DMPermission: &b.Config.DMPermission, - }, - CommandHandlers: map[string]handler.CommandHandler{ - "": userInfoUserCommandHandler(b), - }, - } -} - -func userInfoUserCommandHandler(b *botlib.Bot[*client.Client]) handler.CommandHandler { - return func(event *events.ApplicationCommandInteractionCreate) error { - b.Self.GuildDataLock(*event.GuildID()).Lock() - defer b.Self.GuildDataLock(*event.GuildID()).Unlock() - b.Self.UserDataLock(event.UserCommandInteractionData().TargetID()).Lock() - defer b.Self.UserDataLock(event.UserCommandInteractionData().TargetID()).Unlock() - member := event.UserCommandInteractionData().TargetMember() - embed := discord.NewEmbedBuilder() - embed.SetTitle(member.User.Tag()) - embed.SetDescription(user_flags2emoji(member.User.PublicFlags)) - embed.SetThumbnail(member.EffectiveAvatarURL()) - var nick string - if member.Nick != nil { - nick = *member.Nick - } - embed.AddField("Nick", nick, false) - var global_name string - if member.User.GlobalName != nil { - global_name = *member.User.GlobalName - } - embed.AddField("GlobalName", global_name, false) - embed.AddField("Created At", discord.FormattedTimestampMention(member.CreatedAt().Unix(), discord.TimestampStyleLongDateTime), false) - embed.AddField("Joined At", discord.FormattedTimestampMention(member.JoinedAt.Unix(), discord.TimestampStyleLongDateTime), false) - var roles string - for i, id := range member.RoleIDs { - roles += fmt.Sprintf("%d. %s\r", i+1, discord.RoleMention(id)) - } - embed.AddField("Roles", roles, false) - var status string - presence, ok := event.Client().Caches().Presence(*event.GuildID(), member.User.ID) - if ok { - status = fmt.Sprintf( - "Desktop: %s\rMobile: %s\rWeb: %s", - botlib.StatusString(presence.ClientStatus.Desktop), - botlib.StatusString(presence.ClientStatus.Mobile), - botlib.StatusString(presence.ClientStatus.Web), - ) - } - embed.AddField("Status "+botlib.StatusString(presence.Status), status, true) - - gd, err := b.Self.DB.GuildData().Get(*event.GuildID()) - if err != nil { - return botlib.ReturnErr(event, err, botlib.WithEphemeral(true)) - } - ud, err := b.Self.DB.UserData().Get(member.User.ID) - if err != nil { - return botlib.ReturnErr(event, err, botlib.WithEphemeral(true)) - } - - embed2 := discord.NewEmbedBuilder() - embed2.SetTitle("User Info") - if _, ok := gd.UserLevels[member.User.ID]; !ok { - gd.UserLevels[member.User.ID] = db.NewGuildDataUserLevel() - } - embed2.AddField("Level", fmt.Sprintf("%s lv (%s xp)", gd.UserLevels[member.User.ID].Level().String(), humanize.SI(float64(gd.UserLevels[member.User.ID].Point.Int64()), "")), false) - embed2.AddField("Message Count", fmt.Sprintf("%d", gd.UserLevels[member.User.ID].MessageCount), false) - var birthday string - if ud.BirthDay != [2]int{} { - btime := time.Date(time.Now().Year(), time.Month(ud.BirthDay[0]), ud.BirthDay[1], 0, 0, 0, 0, time.Local) - if btime.Before(time.Now()) { - btime = time.Date(time.Now().Year()+1, time.Month(ud.BirthDay[0]), ud.BirthDay[1], 0, 0, 0, 0, time.Local) - } - birthday = fmt.Sprintf("%s (%s)", discord.FormattedTimestampMention(btime.Unix(), discord.TimestampStyleShortDate), discord.FormattedTimestampMention(btime.Unix(), discord.TimestampStyleRelative)) - } - embed2.AddField("Birthday", birthday, false) - - message := discord.NewMessageCreateBuilder() - message.SetEmbeds(embed.Build(), embed2.Build()) - message.Embeds = botlib.SetEmbedsProperties(message.Embeds) - if err := event.CreateMessage(message.Build()); err != nil { - return err - } - return nil - } -} - -func user_flags2emoji(flags discord.UserFlags) string { - var str string - if flags.Has(discord.UserFlagTeamUser) { - str += "<:TEAM_PSEUDO_USER:1133432677438062642>" - } - if flags.Has(discord.UserFlagActiveDeveloper) { - str += "<:ACTIVE_DEVELOPER:1133431399895027854>" - } - if flags.Has(discord.UserFlagHouseBalance) { - str += "<:HYPTESQUAD_ONLINE_HOUSE_1:1133432354099183717>" - } - if flags.Has(discord.UserFlagHouseBravery) { - str += "<:HYPESQUAD_ONLINE_HOUSE_2:1133432075719020686>" - } - if flags.Has(discord.UserFlagHouseBrilliance) { - str += "<:HYPESQUAD_ONLINE_HOUSE_3:1133432218551861258>" - } - if flags.Has(discord.UserFlagBugHunterLevel1) { - str += "<:BUG_HUNTER_LEVEL_1:1133431932307390525>" - } - if flags.Has(discord.UserFlagBugHunterLevel2) { - str += "<:BUG_HUNTER_LEVEL_2:1133432825668968518>" - } - if flags.Has(discord.UserFlagEarlySupporter) { - str += "<:PREMIUM_EARLY_SUPPORTER:1133432535184052315>" - } - if flags.Has(discord.UserFlagEarlyVerifiedBotDeveloper) { - str += "<:VERIFIED_DEVELOPER:1133433147451777035>" - } - if flags.Has(discord.UserFlagHypeSquadEvents) { - str += "<:HYPESQUAD:1133431760936513627>" - } - if flags.Has(discord.UserFlagDiscordCertifiedModerator) { - str += "<:CERTIFIED_MODERATOR:1133433285255639092>" - } - return str -} diff --git a/bot/commands/user_info/info.go b/bot/commands/user_info/info.go new file mode 100644 index 00000000..6a3897f2 --- /dev/null +++ b/bot/commands/user_info/info.go @@ -0,0 +1,76 @@ +package userinfo + +import ( + "fmt" + "github.com/disgoorg/disgo/discord" + "github.com/disgoorg/disgo/events" + "github.com/sabafly/gobot/bot/components" + "github.com/sabafly/gobot/bot/components/generic" + "github.com/sabafly/gobot/internal/builtin" + "github.com/sabafly/gobot/internal/embeds" + "github.com/sabafly/gobot/internal/errors" + "github.com/sabafly/gobot/internal/translate" + "slices" +) + +func Command(c *components.Components) components.Command { + return (&generic.Command{ + Namespace: "userinfo", + Private: true, + CommandCreate: []discord.ApplicationCommandCreate{ + discord.UserCommandCreate{ + Name: "userinfo", + NameLocalizations: translate.MessageMap("components.user.info.name", false), + DMPermission: builtin.Ptr(false), + Contexts: []discord.InteractionContextType{ + discord.InteractionContextTypeGuild, + }, + }, + }, + CommandHandlers: map[string]generic.PermissionCommandHandler{ + "u/userinfo": generic.CommandHandler(func(_ *components.Components, event *events.ApplicationCommandInteractionCreate) errors.Error { + var roleString string + { // ロヌルを取埗する + roles, err := event.Client().Rest().GetRoles(*event.GuildID()) + if err != nil { + return errors.NewError(err) + } + slices.SortStableFunc(roles, func(a, b discord.Role) int { + return a.Compare(b) + }) + memberRoleIDs := append(slices.Clone(event.Member().RoleIDs), *event.GuildID()) + var memberRoles []discord.Role + for _, role := range roles { + index := slices.Index(memberRoleIDs, role.ID) + if index == -1 { + continue + } + memberRoles = append(memberRoles, role) + } + for i, r := range memberRoles { + roleString += fmt.Sprintf("%d %s\n", i+1, discord.RoleMention(r.ID)) + } + } + if err := event.CreateMessage( + discord.NewMessageBuilder(). + SetEmbeds( + embeds.SetEmbedProperties( + discord.NewEmbedBuilder(). + SetFields( + discord.EmbedField{ + Name: translate.Message(event.Locale(), "userinfo.roles"), + Value: roleString, + }, + ). + Build(), + ), + ). + BuildCreate(), + ); err != nil { + return errors.NewError(err) + } + return nil + }), + }, + }).SetComponent(c) +} diff --git a/bot/commands/util.go b/bot/commands/util.go deleted file mode 100644 index dabf37e8..00000000 --- a/bot/commands/util.go +++ /dev/null @@ -1,308 +0,0 @@ -package commands - -import ( - "strings" - - "github.com/google/uuid" - "github.com/sabafly/disgo/discord" - "github.com/sabafly/disgo/events" - "github.com/sabafly/gobot/bot/client" - "github.com/sabafly/gobot/bot/db" - botlib "github.com/sabafly/sabafly-lib/v2/bot" - "github.com/sabafly/sabafly-lib/v2/handler" - "github.com/sabafly/sabafly-lib/v2/translate" -) - -func Util(b *botlib.Bot[*client.Client]) handler.Command { - return handler.Command{ - Create: discord.SlashCommandCreate{ - Name: "util", - Description: "utilities", - DMPermission: &b.Config.DMPermission, - Options: []discord.ApplicationCommandOption{ - discord.ApplicationCommandOptionSubCommand{ - Name: "calc", - Description: "in discord calculator", - DescriptionLocalizations: translate.MessageMap("util_calc_command_description", false), - Options: []discord.ApplicationCommandOption{ - discord.ApplicationCommandOptionBool{ - Name: "ephemeral", - Description: "create calculator as ephemeral message", - DescriptionLocalizations: translate.MessageMap("util_calc_command_ephemeral_option_description", false), - Required: false, - }, - }, - }, - }, - }, - CommandHandlers: map[string]handler.CommandHandler{ - "calc": utilCommandCalcHandler(b), - }, - } -} - -func utilCommandCalcHandler(b *botlib.Bot[*client.Client]) func(event *events.ApplicationCommandInteractionCreate) error { - return func(event *events.ApplicationCommandInteractionCreate) error { - calc := db.NewCalc() - err := b.Self.DB.Calc().Set(calc.ID(), calc) - if err != nil { - return botlib.ReturnErr(event, err) - } - err = b.Self.DB.Interactions().Set(calc.ID(), event.Token()) - if err != nil { - return botlib.ReturnErr(event, err) - } - - mes, err := calc.Message(botlib.SetEmbedsProperties) - if err != nil { - return botlib.ReturnErr(event, err) - } - if event.SlashCommandInteractionData().Bool("ephemeral") { - mes.Flags = mes.Flags.Add(discord.MessageFlagEphemeral) - } - err = event.CreateMessage(mes) - if err != nil { - return botlib.ReturnErr(event, err) - } - return nil - } -} - -func UtilCalcComponent(b *botlib.Bot[*client.Client]) handler.Component { - return handler.Component{ - Name: "utilcalc", - Handler: map[string]handler.ComponentHandler{ - "num": utilCalcComponentNumHandler(b), - "act": utilCalcComponentActHandler(b), - "do": utilCalcComponentDoHandler(b), - "c": utilCalcComponentCHandler(b), - "ce": utilCalcComponentCEHandler(b), - "back": utilCalcComponentBackHandler(b), - }, - } -} - -func utilCalcComponentBackHandler(b *botlib.Bot[*client.Client]) func(event *events.ComponentInteractionCreate) error { - return func(event *events.ComponentInteractionCreate) error { - args := strings.Split(event.Data.CustomID(), ":") - calcID := uuid.MustParse(args[3]) - calc, err := b.Self.DB.Calc().Get(calcID) - if err != nil { - return botlib.ReturnErrMessage(event, "error_timeout", botlib.WithEphemeral(true)) - } - token, err := b.Self.DB.Interactions().Get(calcID) - if err != nil { - return botlib.ReturnErrMessage(event, "error_timeout", botlib.WithEphemeral(true)) - } - calc.Back() - mes, err := calc.Message(botlib.SetEmbedsProperties) - if err != nil { - return botlib.ReturnErr(event, err) - } - err = b.Self.DB.Calc().Set(calc.ID(), calc) - if err != nil { - return botlib.ReturnErrMessage(event, "error_timeout", botlib.WithEphemeral(true)) - } - _, err = event.Client().Rest().UpdateInteractionResponse(event.ApplicationID(), token, discord.MessageUpdate{ - Content: &mes.Content, - Components: &mes.Components, - }) - if err != nil { - return botlib.ReturnErr(event, err) - } - return event.DeferUpdateMessage() - } -} - -func utilCalcComponentCEHandler(b *botlib.Bot[*client.Client]) func(event *events.ComponentInteractionCreate) error { - return func(event *events.ComponentInteractionCreate) error { - args := strings.Split(event.Data.CustomID(), ":") - calcID := uuid.MustParse(args[3]) - calc, err := b.Self.DB.Calc().Get(calcID) - if err != nil { - return botlib.ReturnErrMessage(event, "error_timeout", botlib.WithEphemeral(true)) - } - token, err := b.Self.DB.Interactions().Get(calcID) - if err != nil { - return botlib.ReturnErrMessage(event, "error_timeout", botlib.WithEphemeral(true)) - } - calc.CE() - mes, err := calc.Message(botlib.SetEmbedsProperties) - if err != nil { - return botlib.ReturnErr(event, err) - } - err = b.Self.DB.Calc().Set(calc.ID(), calc) - if err != nil { - return botlib.ReturnErrMessage(event, "error_timeout", botlib.WithEphemeral(true)) - } - _, err = event.Client().Rest().UpdateInteractionResponse(event.ApplicationID(), token, discord.MessageUpdate{ - Content: &mes.Content, - Components: &mes.Components, - }) - if err != nil { - return botlib.ReturnErr(event, err) - } - return event.DeferUpdateMessage() - } -} - -func utilCalcComponentCHandler(b *botlib.Bot[*client.Client]) func(event *events.ComponentInteractionCreate) error { - return func(event *events.ComponentInteractionCreate) error { - args := strings.Split(event.Data.CustomID(), ":") - calcID := uuid.MustParse(args[3]) - calc, err := b.Self.DB.Calc().Get(calcID) - if err != nil { - return botlib.ReturnErrMessage(event, "error_timeout", botlib.WithEphemeral(true)) - } - token, err := b.Self.DB.Interactions().Get(calcID) - if err != nil { - return botlib.ReturnErrMessage(event, "error_timeout", botlib.WithEphemeral(true)) - } - calc.Reset() - mes, err := calc.Message(botlib.SetEmbedsProperties) - if err != nil { - return botlib.ReturnErr(event, err) - } - err = b.Self.DB.Calc().Set(calc.ID(), calc) - if err != nil { - return botlib.ReturnErrMessage(event, "error_timeout", botlib.WithEphemeral(true)) - } - _, err = event.Client().Rest().UpdateInteractionResponse(event.ApplicationID(), token, discord.MessageUpdate{ - Content: &mes.Content, - Components: &mes.Components, - }) - if err != nil { - return botlib.ReturnErr(event, err) - } - return event.DeferUpdateMessage() - } -} - -func utilCalcComponentDoHandler(b *botlib.Bot[*client.Client]) func(event *events.ComponentInteractionCreate) error { - return func(event *events.ComponentInteractionCreate) error { - args := strings.Split(event.Data.CustomID(), ":") - calcID := uuid.MustParse(args[3]) - calc, err := b.Self.DB.Calc().Get(calcID) - if err != nil { - return botlib.ReturnErrMessage(event, "error_timeout", botlib.WithEphemeral(true)) - } - token, err := b.Self.DB.Interactions().Get(calcID) - if err != nil { - return botlib.ReturnErrMessage(event, "error_timeout", botlib.WithEphemeral(true)) - } - - calc.Do() - - mes, err := calc.Message(botlib.SetEmbedsProperties) - if err != nil { - return botlib.ReturnErr(event, err) - } - err = b.Self.DB.Calc().Set(calc.ID(), calc) - if err != nil { - return botlib.ReturnErrMessage(event, "error_timeout", botlib.WithEphemeral(true)) - } - _, err = event.Client().Rest().UpdateInteractionResponse(event.ApplicationID(), token, discord.MessageUpdate{ - Content: &mes.Content, - Components: &mes.Components, - }) - if err != nil { - return botlib.ReturnErr(event, err) - } - return event.DeferUpdateMessage() - } -} - -func utilCalcComponentActHandler(b *botlib.Bot[*client.Client]) func(event *events.ComponentInteractionCreate) error { - return func(event *events.ComponentInteractionCreate) error { - args := strings.Split(event.Data.CustomID(), ":") - calcID := uuid.MustParse(args[4]) - calc, err := b.Self.DB.Calc().Get(calcID) - if err != nil { - return botlib.ReturnErrMessage(event, "error_timeout", botlib.WithEphemeral(true)) - } - token, err := b.Self.DB.Interactions().Get(calcID) - if err != nil { - return botlib.ReturnErrMessage(event, "error_timeout", botlib.WithEphemeral(true)) - } - switch args[3] { - case "plus": - calc.Plus() - case "minus": - calc.Minus() - case "multiple": - calc.Multiple() - case "divide": - calc.Divide() - } - mes, err := calc.Message(botlib.SetEmbedsProperties) - if err != nil { - return botlib.ReturnErr(event, err) - } - err = b.Self.DB.Calc().Set(calc.ID(), calc) - if err != nil { - return botlib.ReturnErrMessage(event, "error_timeout", botlib.WithEphemeral(true)) - } - _, err = event.Client().Rest().UpdateInteractionResponse(event.ApplicationID(), token, discord.MessageUpdate{ - Content: &mes.Content, - Components: &mes.Components, - }) - if err != nil { - return botlib.ReturnErr(event, err) - } - return event.DeferUpdateMessage() - } -} - -func utilCalcComponentNumHandler(b *botlib.Bot[*client.Client]) func(event *events.ComponentInteractionCreate) error { - return func(event *events.ComponentInteractionCreate) error { - args := strings.Split(event.Data.CustomID(), ":") - calcID := uuid.MustParse(args[4]) - calc, err := b.Self.DB.Calc().Get(calcID) - if err != nil { - return botlib.ReturnErrMessage(event, "error_timeout", botlib.WithEphemeral(true)) - } - token, err := b.Self.DB.Interactions().Get(calcID) - if err != nil { - return botlib.ReturnErrMessage(event, "error_timeout", botlib.WithEphemeral(true)) - } - switch args[3] { - case "±": - calc.InputDo() // TODO: 電卓に合わせる - if strings.HasPrefix(calc.Input, "-") { - calc.Input = strings.TrimPrefix(calc.Input, "-") - } else { - calc.Input = "-" + calc.Input - } - case ".": - calc.InputDo() - if strings.Count(calc.Input, ".") == 0 { - calc.Input += "." - } - default: - calc.InputDo() - if calc.Input == "0" { - calc.Input = "" - } - if calc.Input == "-0" { - calc.Input = "-" - } - calc.Input += args[3] - } - mes, err := calc.Message(botlib.SetEmbedsProperties) - if err != nil { - return botlib.ReturnErr(event, err) - } - err = b.Self.DB.Calc().Set(calc.ID(), calc) - if err != nil { - return botlib.ReturnErrMessage(event, "error_timeout", botlib.WithEphemeral(true)) - } - _, err = event.Client().Rest().UpdateInteractionResponse(event.ApplicationID(), token, discord.MessageUpdate{ - Content: &mes.Content, - Components: &mes.Components, - }) - if err != nil { - return botlib.ReturnErr(event, err) - } - return event.DeferUpdateMessage() - } -} diff --git a/bot/components/commands.go b/bot/components/commands.go new file mode 100644 index 00000000..9d7d0379 --- /dev/null +++ b/bot/components/commands.go @@ -0,0 +1,160 @@ +package components + +import ( + "log/slog" + "strings" + + "github.com/disgoorg/disgo/bot" + "github.com/disgoorg/disgo/discord" + "github.com/disgoorg/disgo/events" + "github.com/disgoorg/disgo/rest" +) + +var ( + DefaultCommands []Command +) + +func (c *Components) AddCommands(cmds ...Command) { + for _, cmd := range cmds { + c.commandsRegistry[cmd.Name()] = cmd + } +} + +func (c *Components) AddCommand(cmd Command) { + c.commandsRegistry[cmd.Name()] = cmd +} + +func (c *Components) Initialize(client bot.Client) error { + for _, cmd := range DefaultCommands { + c.AddCommand(cmd) + } + + var commands, privateCommands []discord.ApplicationCommandCreate + for name, cmd := range c.commandsRegistry { + if len(cmd.Scheduler()) > 0 { + slog.Info("コマンドスケゞュヌラ―を登録したす", "name", name, "count", len(cmd.Create())) + for _, s := range cmd.Scheduler() { + go execSchedule(c, client, s) + } + } + if len(cmd.Create()) > 0 { + slog.Info("コマンドを登録したす", "name", name, "count", len(cmd.Create()), "is_private", cmd.IsPrivate()) + if cmd.IsPrivate() { + privateCommands = append(privateCommands, cmd.Create()...) + } else { + commands = append(commands, cmd.Create()...) + } + } + } + + if _, err := client.Rest().SetGlobalCommands(client.ApplicationID(), commands); err != nil { + slog.Error("コマンドの登録に倱敗", slog.Any("err", err), slog.String("body", string(err.(rest.Error).RsBody))) + return err + } + + for _, id := range c.Config().Debug.DebugGuilds { + if _, err := client.Rest().SetGuildCommands(client.ApplicationID(), id, privateCommands); err != nil { + slog.Error("プラむベヌトコマンドの登録に倱敗", "err", err, "guild", id) + return err + } + } + + client.EventManager().AddEventListeners( + bot.NewListenerFunc(c.OnEvent()), + &events.ListenerAdapter{ + OnGuildJoin: c.OnGuildJoin(), + OnGuildLeave: c.OnGuildLeave(), + }, + ) + return nil +} + +func (c *Components) OnEvent() func(bot bot.Event) { + return func(event bot.Event) { + switch e := event.(type) { + case *events.ApplicationCommandInteractionCreate: + cmd, ok := c.commandsRegistry[e.Data.CommandName()] + if !ok { + slog.Warn("䞍明なコマンド", "command_name", e.Data.CommandName()) + return + } + h := cmd.CommandHandler() + if h == nil { + slog.Warn("コマンド凊理がnil", "custom_id", e.Data.CommandName()) + return + } + if err := h(e); err != nil { + slog.Error("コマンド凊理䞭に゚ラヌが発生したした", "err", err) + } + case *events.ComponentInteractionCreate: + namespace := strings.Split(e.Data.CustomID(), ":") + cmd, ok := c.commandsRegistry[namespace[0]] + if !ok { + slog.Warn("䞍明なコンポヌネント", "custom_id", e.Data.CustomID()) + return + } + h := cmd.ComponentHandler() + if h == nil { + slog.Warn("コンポヌネント凊理がnil", "custom_id", e.Data.CustomID()) + return + } + if err := h(e); err != nil { + slog.Error("コンポヌネント凊理䞭に゚ラヌが発生したした", "err", err) + return + } + case *events.ModalSubmitInteractionCreate: + namespace := strings.Split(e.Data.CustomID, ":") + cmd, ok := c.commandsRegistry[namespace[0]] + if !ok { + slog.Warn("䞍明なモヌダル提出むンタラクション", "custom_id", e.Data.CustomID) + return + } + h := cmd.ModalHandler() + if h == nil { + slog.Warn("モヌダル提出むンタラクション凊理がnil", "custom_id", e.Data.CustomID) + return + } + if err := h(e); err != nil { + slog.Error("モヌダル提出むンタラクション凊理䞭に゚ラヌが発生したした", "err", err) + return + } + case *events.AutocompleteInteractionCreate: + namespace := strings.Split(e.Data.CommandName, ":") + cmd, ok := c.commandsRegistry[namespace[0]] + if !ok { + slog.Warn("䞍明なオヌトコンプリヌト", "custom_id", e.Data.CommandName) + return + } + h := cmd.AutocompleteHandler() + if h == nil { + slog.Warn("オヌトコンプリヌト凊理がnil", "custom_id", e.Data.CommandName) + return + } + if err := h(e); err != nil { + slog.Error("オヌトコンプリヌト凊理䞭に゚ラヌが発生したした", "err", err) + return + } + default: + for name, cmd := range c.commandsRegistry { + if h := cmd.OnEvent(); h != nil { + if err := h(event); err != nil { + slog.Error("むベント凊理䞭に゚ラヌが発生したした", "err", err, "cmd_name", name) + } + } + } + } + } +} + +type Command interface { + Name() string + + Create() []discord.ApplicationCommandCreate + IsPrivate() bool + CommandHandler() func(event *events.ApplicationCommandInteractionCreate) error + ComponentHandler() func(event *events.ComponentInteractionCreate) error + ModalHandler() func(event *events.ModalSubmitInteractionCreate) error + AutocompleteHandler() func(event *events.AutocompleteInteractionCreate) error + OnEvent() func(event bot.Event) error + Scheduler() []Scheduler +} diff --git a/bot/components/components.go b/bot/components/components.go new file mode 100644 index 00000000..3cbfb89a --- /dev/null +++ b/bot/components/components.go @@ -0,0 +1,28 @@ +package components + +import ( + "github.com/sabafly/gobot/ent" + "github.com/sabafly/gobot/internal/smap" +) + +func New(db *ent.Client, conf Config) *Components { + return &Components{ + db: db, + commandsRegistry: make(map[string]Command), + config: conf, + } +} + +type Components struct { + db *ent.Client + + config Config + + commandsRegistry map[string]Command + + l smap.SyncedMap[string, *Mu] + + Version string +} + +func (c *Components) DB() *ent.Client { return c.db } diff --git a/bot/components/config.go b/bot/components/config.go new file mode 100644 index 00000000..78587313 --- /dev/null +++ b/bot/components/config.go @@ -0,0 +1,53 @@ +package components + +import ( + "os" + + "github.com/disgoorg/snowflake/v2" + "gopkg.in/yaml.v2" +) + +type Config struct { + TranslateDir string `yaml:"translate_dir"` + Debug ConfigDebug `yaml:"debug"` + Message ConfigMessage `yaml:"message"` + + MySQL string `yaml:"mysql"` + Redis []string `yaml:"redis"` + + BumpUserID snowflake.ID `yaml:"bump_user"` + BumpImage string `yaml:"bump_image"` + UpUserID snowflake.ID `yaml:"up_user"` + UpColor int `yaml:"up_color"` +} + +type ConfigDebug struct { + DebugUsers []snowflake.ID `yaml:"users"` + DebugGuilds []snowflake.ID `yaml:"guilds"` +} + +type ConfigMessage struct { + PinIconImage string `yaml:"pin_icon_image"` +} + +func (c *Components) Config() Config { return c.config } + +func Load(path string) (config *Config, err error) { + config = &Config{} + f, err := os.Open(path) + if err != nil { + return nil, err + } + defer func(f *os.File) { + e := f.Close() + if e != nil { + err = e + } + }(f) + + if err := yaml.NewDecoder(f).Decode(config); err != nil { + return nil, err + } + + return config, nil +} diff --git a/bot/components/generic/command.go b/bot/components/generic/command.go new file mode 100644 index 00000000..0b40d8be --- /dev/null +++ b/bot/components/generic/command.go @@ -0,0 +1,312 @@ +package generic + +import ( + "fmt" + "log/slog" + "runtime/debug" + "strings" + + "github.com/disgoorg/disgo/bot" + "github.com/disgoorg/disgo/discord" + "github.com/disgoorg/disgo/events" + "github.com/disgoorg/disgo/rest" + "github.com/sabafly/gobot/bot/components" + "github.com/sabafly/gobot/internal/errors" + "github.com/sabafly/gobot/internal/translate" +) + +func createErrorMessage( + err errors.Error, + event interface { + CreateMessage(messageCreate discord.MessageCreate, opts ...rest.RequestOpt) error + Locale() discord.Locale + }, +) { + key := "errors.generic.message" + if em, ok := err.(errors.ErrorWithMessage); ok { + key = em.Key() + } + _ = event.CreateMessage( + discord.NewMessageBuilder(). + SetEmbeds( + discord.NewEmbedBuilder(). + SetTitlef("🔥 %s", translate.Message(event.Locale(), key)). + SetDescriptionf("```%s``````%s``````%s```", err.Error(), err.Stack(), err.File()). + SetFooterText(err.ID().String()). + SetColor(0xff2121). + Build(), + ). + SetFlags(discord.MessageFlagEphemeral). + BuildCreate(), + ) +} + +func rec(event interface { + RespondMessage(messageBuilder discord.MessageBuilder, opts ...rest.RequestOpt) error + Locale() discord.Locale +}) { + if v := recover(); v != nil { + _ = errors.ErrorMessage("errors.panic.message", event, errors.WithDescription(fmt.Sprintf("```\nargs=%v stack=%s```", v, string(debug.Stack())))) + slog.Error("panic", "args", v, "stack", string(debug.Stack())) + panic(v) + } +} + +// Command + +type CommandHandler EventHandler[*events.ApplicationCommandInteractionCreate] + +func (c CommandHandler) Handler() EventHandler[*events.ApplicationCommandInteractionCreate] { + return EventHandler[*events.ApplicationCommandInteractionCreate](c) +} +func (c CommandHandler) Permissions() []Permission { return nil } +func (c CommandHandler) DiscordPermission() discord.Permissions { return 0 } + +var _ PermissionCommandHandler = (*CommandHandler)(nil) + +type PCommandHandler struct { + CommandHandler EventHandler[*events.ApplicationCommandInteractionCreate] + Permission []Permission + DiscordPerm discord.Permissions +} + +func (c PCommandHandler) Handler() EventHandler[*events.ApplicationCommandInteractionCreate] { + return c.CommandHandler +} +func (c PCommandHandler) Permissions() []Permission { return c.Permission } +func (c PCommandHandler) DiscordPermission() discord.Permissions { return c.DiscordPerm } + +var _ PermissionCommandHandler = (*PCommandHandler)(nil) + +// AutoComplete + +type AutocompleteHandler EventHandler[*events.AutocompleteInteractionCreate] + +func (c AutocompleteHandler) Handler() EventHandler[*events.AutocompleteInteractionCreate] { + return EventHandler[*events.AutocompleteInteractionCreate](c) +} +func (c AutocompleteHandler) Permissions() []Permission { return nil } +func (c AutocompleteHandler) DiscordPermission() discord.Permissions { return 0 } + +var _ PermissionAutocompleteHandler = (*AutocompleteHandler)(nil) + +type PAutocompleteHandler struct { + AutocompleteHandler EventHandler[*events.AutocompleteInteractionCreate] + Permission []Permission + DiscordPerm discord.Permissions +} + +func (c PAutocompleteHandler) Handler() EventHandler[*events.AutocompleteInteractionCreate] { + return c.AutocompleteHandler +} +func (c PAutocompleteHandler) Permissions() []Permission { return c.Permission } +func (c PAutocompleteHandler) DiscordPermission() discord.Permissions { return c.DiscordPerm } + +var _ PermissionAutocompleteHandler = (*PAutocompleteHandler)(nil) + +// Component + +type ComponentHandler EventHandler[*events.ComponentInteractionCreate] + +func (c ComponentHandler) Handler() EventHandler[*events.ComponentInteractionCreate] { + return EventHandler[*events.ComponentInteractionCreate](c) +} +func (c ComponentHandler) Permissions() []Permission { return nil } +func (c ComponentHandler) DiscordPermission() discord.Permissions { return 0 } + +var _ PermissionComponentHandler = (*ComponentHandler)(nil) + +type PComponentHandler struct { + ComponentHandler EventHandler[*events.ComponentInteractionCreate] + Permission []Permission + DiscordPerm discord.Permissions +} + +func (c PComponentHandler) Handler() EventHandler[*events.ComponentInteractionCreate] { + return c.ComponentHandler +} +func (c PComponentHandler) Permissions() []Permission { return c.Permission } +func (c PComponentHandler) DiscordPermission() discord.Permissions { return c.DiscordPerm } + +var _ PermissionComponentHandler = (*PComponentHandler)(nil) + +// Modal + +type ModalHandler func(c *components.Components, event *events.ModalSubmitInteractionCreate) errors.Error + +// Permissions + +type PermissionCommandHandler PermissionHandler[*events.ApplicationCommandInteractionCreate] +type PermissionAutocompleteHandler PermissionHandler[*events.AutocompleteInteractionCreate] +type PermissionComponentHandler PermissionHandler[*events.ComponentInteractionCreate] + +// Generic Types + +type EventHandler[E bot.Event] func(c *components.Components, event E) errors.Error + +type PermissionHandler[E bot.Event] interface { + Handler() EventHandler[E] + Permissions() []Permission + DiscordPermission() discord.Permissions +} + +type Permission interface { + PermString() string + Default() bool +} + +type PermissionString string + +func (p PermissionString) PermString() string { return string(p) } +func (p PermissionString) Default() bool { return false } + +type PermissionDefaultString string + +func (p PermissionDefaultString) PermString() string { return string(p) } +func (p PermissionDefaultString) Default() bool { return true } + +var _ components.Command = (*Command)(nil) + +type Command struct { + Namespace string + Private bool + CommandCreate []discord.ApplicationCommandCreate + // /command/subcommand_group/subcommand + CommandHandlers map[string]PermissionCommandHandler + ComponentHandlers map[string]PermissionComponentHandler + ModalHandlers map[string]ModalHandler + AutocompleteHandlers map[string]PermissionAutocompleteHandler + EventHandler EventHandler[bot.Event] + Schedulers []components.Scheduler + component *components.Components +} + +func (gc *Command) Scheduler() []components.Scheduler { return gc.Schedulers } + +func (gc *Command) SetComponent(c *components.Components) *Command { + gc.component = c + return gc +} + +func (gc *Command) Name() string { return gc.Namespace } +func (gc *Command) Create() []discord.ApplicationCommandCreate { return gc.CommandCreate } +func (gc *Command) IsPrivate() bool { return gc.Private } +func (gc *Command) CommandHandler() func(event *events.ApplicationCommandInteractionCreate) error { + return func(event *events.ApplicationCommandInteractionCreate) error { + defer rec(event) + var path string + switch event.Data.Type() { + case discord.ApplicationCommandTypeSlash: + path = event.SlashCommandInteractionData().CommandPath() + case discord.ApplicationCommandTypeMessage: + path = "m/" + event.MessageCommandInteractionData().CommandName() + case discord.ApplicationCommandTypeUser: + path = "u/" + event.UserCommandInteractionData().CommandName() + } + cmd, ok := gc.CommandHandlers[path] + if !ok { + return fmt.Errorf("unknown handler: command_path=%s", path) + } + if c := permissionCheck(event, gc.component, cmd.Permissions(), cmd.DiscordPermission()); !c { + if err := noPermissionMessage(event, cmd.Permissions()); err != nil { + createErrorMessage(errors.NewError(err), event) + return err + } + return nil + } + h := cmd.Handler() + if h == nil { + return fmt.Errorf("nil handler: command_path=%s", path) + } + if err := h(gc.component, event); err != nil { + createErrorMessage(err, event) + return err + } + return nil + } +} + +func (gc *Command) ComponentHandler() func(event *events.ComponentInteractionCreate) error { + return func(event *events.ComponentInteractionCreate) error { + defer rec(event) + customID := strings.Split(event.Data.CustomID(), ":") + cmd, ok := gc.ComponentHandlers[strings.Join(customID[:2], ":")] + if !ok { + return fmt.Errorf("unknown handler: custom_id=%s", event.Data.CustomID()) + } + if c := permissionCheck(event, gc.component, cmd.Permissions(), cmd.DiscordPermission()); !c { + if err := noPermissionMessage(event, cmd.Permissions()); err != nil { + createErrorMessage(errors.NewError(err), event) + return err + } + return nil + } + h := cmd.Handler() + if h == nil { + return fmt.Errorf("nil handler: custom_id=%s", event.Data.CustomID()) + } + if err := h(gc.component, event); err != nil { + createErrorMessage(err, event) + return err + } + return nil + } +} + +func (gc *Command) ModalHandler() func(event *events.ModalSubmitInteractionCreate) error { + return func(event *events.ModalSubmitInteractionCreate) error { + defer rec(event) + customID := strings.Split(event.Data.CustomID, ":") + cmd, ok := gc.ModalHandlers[strings.Join(customID[:2], ":")] + if !ok { + return fmt.Errorf("unknown handler: custom_id=%s", event.Data.CustomID) + } + if err := cmd(gc.component, event); err != nil { + createErrorMessage(err, event) + return err + } + return nil + } +} + +func (gc *Command) AutocompleteHandler() func(event *events.AutocompleteInteractionCreate) error { + return func(event *events.AutocompleteInteractionCreate) error { + var focused string + for _, ao := range event.Data.Options { + if ao.Focused { + focused = ao.Name + } + } + path := event.Data.CommandPath() + ":" + focused + cmd, ok := gc.AutocompleteHandlers[path] + if !ok { + return fmt.Errorf("unknown handler: command_path=%s", path) + } + if c := permissionCheck(event, gc.component, cmd.Permissions(), cmd.DiscordPermission()); !c { + if err := event.AutocompleteResult(make([]discord.AutocompleteChoice, 0)); err != nil { + return err + } + return nil + } + h := cmd.Handler() + if h == nil { + return fmt.Errorf("nil handler: command_path=%s", path) + } + if err := h(gc.component, event); err != nil { + return err + } + return nil + } +} + +func (gc *Command) OnEvent() func(event bot.Event) error { + return func(event bot.Event) error { + if gc.EventHandler == nil { + return nil + } + if err := gc.EventHandler(gc.component, event); err != nil { + return err + } + return nil + } +} diff --git a/bot/components/generic/permission.go b/bot/components/generic/permission.go new file mode 100644 index 00000000..188abf3a --- /dev/null +++ b/bot/components/generic/permission.go @@ -0,0 +1,157 @@ +package generic + +import ( + "context" + "fmt" + "log/slog" + "slices" + + "github.com/disgoorg/disgo/bot" + "github.com/disgoorg/disgo/discord" + "github.com/disgoorg/disgo/rest" + "github.com/disgoorg/snowflake/v2" + "github.com/sabafly/gobot/bot/components" + "github.com/sabafly/gobot/ent" + "github.com/sabafly/gobot/ent/guild" + "github.com/sabafly/gobot/ent/member" + "github.com/sabafly/gobot/ent/user" + "github.com/sabafly/gobot/internal/translate" +) + +func noPermissionMessage(event interface { + CreateMessage(messageCreate discord.MessageCreate, opts ...rest.RequestOpt) error + Locale() discord.Locale +}, perms []Permission) error { + var permStr string + for _, p := range perms { + permStr += fmt.Sprintf("`%s` ", p.PermString()) + } + return event.CreateMessage( + discord.NewMessageBuilder(). + SetEmbeds( + discord.NewEmbedBuilder(). + SetTitlef("⚠ %s", translate.Message(event.Locale(), "errors.invalid.permission")). + SetDescription(translate.Message(event.Locale(), "errors.invalid.permission.description", + translate.WithTemplate(map[string]any{"Permission": permStr}), + )). + SetColor(0xEEE731). + Build(), + ). + SetFlags(discord.MessageFlagEphemeral). + BuildCreate(), + ) +} + +func PermissionCheck(ctx context.Context, c *components.Components, g *ent.Guild, client bot.Client, m discord.ResolvedMember, guildID snowflake.ID, perms []Permission) bool { + + if len(perms) == 0 { + return true + } + + if m := c.DB().Guild.Query(). + Where(guild.ID(guildID)). + FirstX(ctx). + QueryMembers(). + Where(member.HasUserWith(user.ID(m.User.ID))). + FirstX(ctx); m != nil { + for _, p := range perms { + var r bool + if p.Default() { + if m.Permission.Disabled(p.PermString()) { + return false + } else { + r = true + } + } else { + if m.Permission.Enabled(p.PermString()) { + r = true + } else if m.Permission.Disabled(p.PermString()) { + return false + } + } + if r { + return r + } + } + } + + m.RoleIDs = append(m.RoleIDs, guildID) + + return RolePermissionCheck(g, guildID, client, m.RoleIDs, perms) +} + +func RolePermissionCheck(g *ent.Guild, guildID snowflake.ID, client bot.Client, roleIds []snowflake.ID, perms []Permission) bool { + if len(perms) == 0 { + return true + } + + var roles []discord.Role + client.Caches().RolesForEach(guildID, func(role discord.Role) { + roles = append(roles, role) + }) + slices.SortStableFunc(roles, func(a, b discord.Role) int { + return a.Compare(b) + }) + var memberRoles []discord.Role + for _, role := range roles { + if !slices.Contains(roleIds, role.ID) { + continue + } + memberRoles = append(memberRoles, role) + } + + ok := false + for _, p := range perms { + for _, r := range memberRoles { + l := g.Permissions[r.ID] + if l.Enabled(p.PermString()) { + ok = true + } else if l.Disabled(p.PermString()) { + ok = false + } + } + } + + return ok +} + +func permissionCheck(event interface { + context.Context + Member() *discord.ResolvedMember + GuildID() *snowflake.ID + User() discord.User + Client() bot.Client +}, c *components.Components, perms []Permission, dPerm discord.Permissions) bool { + + if len(perms) == 0 { + return true + } + + if slices.Contains(c.Config().Debug.DebugUsers, event.User().ID) { + return true + } + + if dPerm != 0 && event.Member().Permissions.Has(dPerm) { + if m := c.DB().Guild.Query(). + Where(guild.ID(*event.GuildID())). + FirstX(event). + QueryMembers(). + Where(member.HasUserWith(user.ID(event.User().ID))). + FirstX(event); m != nil { + for _, p := range perms { + if m.Permission.Disabled(p.PermString()) { + return false + } + } + } + return true + } + + g, err := c.GuildCreateID(event, *event.GuildID()) + if err != nil { + slog.Warn("failed to GuildCreateID", "id", event.GuildID()) + return false + } + + return PermissionCheck(event, c, g, event.Client(), *event.Member(), *event.GuildID(), perms) +} diff --git a/bot/components/guild.go b/bot/components/guild.go new file mode 100644 index 00000000..a4216ec5 --- /dev/null +++ b/bot/components/guild.go @@ -0,0 +1,95 @@ +package components + +import ( + "context" + "github.com/sabafly/gobot/ent/member" + "github.com/sabafly/gobot/ent/messagepin" + "github.com/sabafly/gobot/ent/messageremind" + "github.com/sabafly/gobot/ent/rolepanel" + "github.com/sabafly/gobot/ent/rolepaneledit" + "github.com/sabafly/gobot/ent/rolepanelplaced" + "github.com/sabafly/gobot/ent/wordsuffix" + "log/slog" + + "github.com/disgoorg/disgo/bot" + "github.com/disgoorg/disgo/discord" + "github.com/disgoorg/disgo/events" + "github.com/disgoorg/snowflake/v2" + "github.com/sabafly/gobot/ent" + "github.com/sabafly/gobot/ent/guild" + "github.com/sabafly/gobot/ent/user" +) + +func (c *Components) OnGuildJoin() func(event *events.GuildJoin) { + return func(event *events.GuildJoin) { + slog.Info("ギルド参加", "id", event.Guild.ID, "member_count", event.Guild.MemberCount, "name", event.Guild.Name) + member, err := event.Client().Rest().GetMember(event.GuildID, event.Guild.OwnerID) + if err != nil { + slog.Error("ギルド参加 オヌナヌの取埗に倱敗", "err", err) + return + } + u, err := c.UserCreate(event, member.User) + if err != nil { + slog.Error("ギルド参加 オヌナヌの初期化に倱敗", "err", err) + return + } + + if _, err := c.GuildCreate(event, u.ID, event.GenericGuild); err != nil { + slog.Error("ギルドの䜜成に倱敗", "err", err) + return + } + + u = c.db.User.Query().Where(user.ID(u.ID)).OnlyX(event) + slog.Debug("ギルドオヌナヌ情報", "id", u.ID, "name", u.Name, "own_guilds", u.QueryOwnGuilds().AllX(event), "guilds", u.QueryGuilds().AllX(event)) + } +} + +func (c *Components) OnGuildLeave() func(event *events.GuildLeave) { + return func(event *events.GuildLeave) { + slog.Info("ギルド脱退", "id", event.Guild.ID, "name", event.Guild.Name) + c.db.Member.Delete().Where(member.HasGuildWith(guild.ID(event.Guild.ID))).ExecX(event) + c.db.MessagePin.Delete().Where(messagepin.HasGuildWith(guild.ID(event.Guild.ID))).ExecX(event) + c.db.MessageRemind.Delete().Where(messageremind.HasGuildWith(guild.ID(event.Guild.ID))).ExecX(event) + c.db.RolePanelPlaced.Delete().Where(rolepanelplaced.HasGuildWith(guild.ID(event.Guild.ID))).ExecX(event) + c.db.RolePanelEdit.Delete().Where(rolepaneledit.HasGuildWith(guild.ID(event.Guild.ID))).ExecX(event) + c.db.RolePanel.Delete().Where(rolepanel.HasGuildWith(guild.ID(event.Guild.ID))).ExecX(event) + c.db.WordSuffix.Delete().Where(wordsuffix.HasGuildWith(guild.ID(event.Guild.ID))).ExecX(event) + c.db.Guild.DeleteOneID(event.Guild.ID).ExecX(event) + } +} + +func (c *Components) GuildCreate(ctx context.Context, ownerID snowflake.ID, g *events.GenericGuild) (*ent.Guild, error) { + ok := c.db.Guild. + Query(). + Where(guild.ID(g.Guild.ID)).ExistX(ctx) + if ok { + return c.db.Guild. + Query(). + Where(guild.ID(g.GuildID)). + Only(ctx) + } + slog.Debug("新芏ギルド䜜成", "gid", g.GuildID, "name", g.Guild.Name) + return c.db.Guild.Create(). + SetID(g.GuildID). + SetName(g.Guild.Name). + SetOwnerID(ownerID). + Save(ctx) +} + +func (c *Components) GuildCreateID(ctx context.Context, gid snowflake.ID) (*ent.Guild, error) { + return c.db.Guild. + Query(). + Where(guild.ID(gid)). + Only(ctx) +} + +func (c *Components) GuildRequest(client bot.Client, gid snowflake.ID) (*discord.Guild, error) { + if g, ok := client.Caches().Guild(gid); ok { + return &g, nil + } + g, err := client.Rest().GetGuild(gid, true) + if err != nil { + return nil, err + } + return &g.Guild, nil +} diff --git a/bot/components/member.go b/bot/components/member.go new file mode 100644 index 00000000..a6ce97ce --- /dev/null +++ b/bot/components/member.go @@ -0,0 +1,31 @@ +package components + +import ( + "context" + + "github.com/disgoorg/disgo/discord" + "github.com/disgoorg/snowflake/v2" + "github.com/sabafly/gobot/ent" + "github.com/sabafly/gobot/ent/guild" + "github.com/sabafly/gobot/ent/member" + "github.com/sabafly/gobot/ent/user" +) + +func (c *Components) MemberCreate(ctx context.Context, u discord.User, gid snowflake.ID) (*ent.Member, error) { + eu, err := c.UserCreate(ctx, u) + if err != nil { + return nil, err + } + ok := c.db.Member. + Query(). + Where(member.HasUserWith(user.ID(u.ID)), member.HasGuildWith(guild.ID(gid))).ExistX(ctx) + if ok { + return c.db.Member. + Query(). + Where(member.HasUserWith(user.ID(u.ID)), member.HasGuildWith(guild.ID(gid))).Only(ctx) + } + return c.db.Member.Create(). + SetUser(eu). + SetGuildID(gid). + Save(ctx) +} diff --git a/bot/components/scheduler.go b/bot/components/scheduler.go new file mode 100644 index 00000000..ea34d293 --- /dev/null +++ b/bot/components/scheduler.go @@ -0,0 +1,38 @@ +package components + +import ( + "log/slog" + "time" + + "github.com/disgoorg/disgo/bot" +) + +type SchedulerFunc func(c *Components, client bot.Client) error + +type Scheduler struct { + Duration time.Duration + Worker SchedulerFunc +} + +func recoverSchedule() { + if v := recover(); v != nil { + slog.Error("recovered from panic", slog.Any("value", v)) + } +} + +func execSchedule(c *Components, client bot.Client, s Scheduler) { + now := time.Now() + time.Sleep(time.Until(time.Date(now.Year(), now.Month(), now.Day(), now.Hour(), now.Minute()+1, 0, 0, now.Location()))) + for { + doSchedule(c, client, s) + time.Sleep(s.Duration) + } +} + +func doSchedule(c *Components, client bot.Client, s Scheduler) { + defer recoverSchedule() + if err := s.Worker(c, client); err != nil { + slog.Error("コンポヌネント凊理䞭に゚ラヌが発生したした", "err", err) + return + } +} diff --git a/bot/components/sync.go b/bot/components/sync.go new file mode 100644 index 00000000..6d1a28eb --- /dev/null +++ b/bot/components/sync.go @@ -0,0 +1,22 @@ +package components + +import ( + "sync" + + "github.com/disgoorg/snowflake/v2" + "github.com/sabafly/gobot/internal/smap" +) + +type Mu struct { + m smap.SyncedMap[snowflake.ID, *sync.Mutex] +} + +func (m *Mu) Mutex(id snowflake.ID) *sync.Mutex { + mu, _ := m.m.LoadOrStore(id, &sync.Mutex{}) + return mu +} + +func (c *Components) GetLock(namespace string) *Mu { + m, _ := c.l.LoadOrStore(namespace, &Mu{}) + return m +} diff --git a/bot/components/user.go b/bot/components/user.go new file mode 100644 index 00000000..040d3442 --- /dev/null +++ b/bot/components/user.go @@ -0,0 +1,29 @@ +package components + +import ( + "context" + "log/slog" + + "github.com/disgoorg/disgo/discord" + "github.com/sabafly/gobot/ent" + "github.com/sabafly/gobot/ent/user" + "github.com/sabafly/gobot/internal/errors" +) + +func (c *Components) UserCreate(ctx context.Context, u discord.User) (*ent.User, error) { + if u.Bot || u.System { + return nil, errors.New("bot cannot use to create user") + } + if ok := c.db.User. + Query(). + Where(user.ID(u.ID)).ExistX(ctx); ok { + return c.db.User. + Query(). + Where(user.ID(u.ID)).Only(ctx) + } + slog.Debug("新芏ナヌザヌ䜜成", "uid", u.ID, "uname", u.Username) + return c.db.User.Create(). + SetID(u.ID). + SetName(u.EffectiveName()). + Save(ctx) +} diff --git a/bot/console.go b/bot/console.go new file mode 100644 index 00000000..7e49431b --- /dev/null +++ b/bot/console.go @@ -0,0 +1 @@ +package bot diff --git a/bot/db/calc.go b/bot/db/calc.go deleted file mode 100644 index f459a77e..00000000 --- a/bot/db/calc.go +++ /dev/null @@ -1,459 +0,0 @@ -package db - -import ( - "context" - "encoding/json" - "fmt" - "strconv" - "strings" - "time" - - "github.com/go-redis/redis/v8" - "github.com/google/uuid" - "github.com/sabafly/disgo/discord" -) - -type CalcDB interface { - Get(id uuid.UUID) (Calc, error) - Set(id uuid.UUID, data Calc) error - Del(id uuid.UUID) error -} - -var _ CalcDB = (*CalcDBImpl)(nil) - -type CalcDBImpl struct { - db *redis.Client -} - -func (c *CalcDBImpl) Get(id uuid.UUID) (Calc, error) { - res := c.db.Get(context.TODO(), "calc"+id.String()) - if err := res.Err(); err != nil { - return Calc{}, err - } - buf := []byte(res.Val()) - val := Calc{} - err := json.Unmarshal(buf, &val) - if err != nil { - return Calc{}, err - } - return val, nil -} - -func (c *CalcDBImpl) Set(id uuid.UUID, data Calc) error { - buf, err := json.Marshal(data) - if err != nil { - return err - } - res := c.db.Set(context.TODO(), "calc"+id.String(), buf, time.Minute*14) - if err := res.Err(); err != nil { - return err - } - return nil -} - -func (c *CalcDBImpl) Del(id uuid.UUID) error { - res := c.db.Del(context.TODO(), id.String()) - if err := res.Err(); err != nil { - return err - } - return nil -} - -func NewCalc() Calc { - return Calc{ - Input: "0", - LastInput: "0", - id: uuid.New(), - Mode: CalcModeInput, - } -} - -type Calc struct { - id uuid.UUID - Input string - inputFloat float64 - LastInput string - lastInputFloat float64 - currentIndicator CalcIndicator - Mode CalcMode - answer float64 -} - -type CalcMode int - -const ( - CalcModeInput CalcMode = 1 // 最初の入力 倀が䞀぀のみ - CalcModeInputSecond CalcMode = 2 // 二぀目の入力 倀が二぀ - CalcModeAnswer CalcMode = 3 // 蚈算埌の状態 - CalcModeTemp CalcMode = 4 // 挔算子入力埌の状態 -) - -type CalcIndicator rune - -const ( - CalcIndicatorNone CalcIndicator = '_' - CalcIndicatorPlus CalcIndicator = '+' - CalcIndicatorMinus CalcIndicator = '-' - CalcIndicatorMultiple CalcIndicator = '×' - CalcIndicatorDivide CalcIndicator = '÷' - CalcIndicatorPercent CalcIndicator = '%' -) - -func (c Calc) MarshalJSON() ([]byte, error) { - alias := struct { - ID uuid.UUID `json:"id"` - Input string `json:"input"` - LastInput string `json:"last_input"` - CurrentIndicator CalcIndicator `json:"current_indicator"` - Mode CalcMode `json:"mode"` - Answer float64 `json:"answer"` - }{ - ID: c.id, - Input: c.Input, - LastInput: c.LastInput, - CurrentIndicator: c.currentIndicator, - Mode: c.Mode, - Answer: c.answer, - } - return json.Marshal(alias) -} - -func (c *Calc) UnmarshalJSON(b []byte) error { - alias := struct { - ID uuid.UUID `json:"id"` - Input string `json:"input"` - LastInput string `json:"last_input"` - CurrentIndicator CalcIndicator `json:"current_indicator"` - Mode CalcMode `json:"mode"` - Answer float64 `json:"answer"` - }{} - err := json.Unmarshal(b, &alias) - if err != nil { - return err - } - *c = Calc{ - id: alias.ID, - Input: alias.Input, - LastInput: alias.LastInput, - currentIndicator: alias.CurrentIndicator, - Mode: alias.Mode, - answer: alias.Answer, - } - return nil -} - -func (c Calc) ID() uuid.UUID { - return c.id -} - -func (c Calc) Indicator() CalcIndicator { - return c.currentIndicator -} - -func (c *Calc) InputDo() { - switch c.Mode { - case CalcModeTemp: - c.Mode = CalcModeInputSecond - c.Input = "" - case CalcModeAnswer: - c.Reset() - } -} - -func (c *Calc) Back() { - switch c.Mode { - case CalcModeAnswer: - c.lastInputFloat = 0 - c.inputFloat = c.answer - c.answer = 0 - c.toString() - c.Mode = CalcModeInput - default: - if strings.Count(c.Input, "e") != 0 { - return - } - if len(c.Input) <= 1 || (strings.HasPrefix(c.Input, "-") && len(c.Input) <= 2) { - c.Input = "0" - } else { - c.Input = c.Input[:len(c.Input)-1] - } - } -} - -func (c *Calc) CE() { - switch c.Mode { - case CalcModeTemp: - c.InputDo() - c.Input += "0" - case CalcModeAnswer: - c.Reset() - default: - c.inputFloat = 0 - c.toString() - } -} - -func (c *Calc) Reset() { - *c = Calc{ - id: c.id, - Input: "0", - LastInput: "0", - Mode: CalcModeInput, - } -} - -func (c *Calc) beforeIndicator() { - switch c.Mode { - case CalcModeInputSecond: - if err := c.do(); err != nil { - panic(err) - } - c.lastInputFloat = c.answer - c.toString() - c.Mode = CalcModeTemp - case CalcModeAnswer: - c.lastInputFloat = c.answer - c.toString() - c.Mode = CalcModeTemp - } -} - -func (c *Calc) Plus() { - c.beforeIndicator() - c.currentIndicator = CalcIndicatorPlus - if c.Mode != CalcModeTemp { - c.LastInput = c.Input - } - c.Mode = CalcModeTemp -} - -func (c *Calc) Minus() { - c.beforeIndicator() - c.currentIndicator = CalcIndicatorMinus - if c.Mode != CalcModeTemp { - c.LastInput = c.Input - } - c.Mode = CalcModeTemp -} - -func (c *Calc) Multiple() { - c.beforeIndicator() - c.currentIndicator = CalcIndicatorMultiple - if c.Mode != CalcModeTemp { - c.LastInput = c.Input - } - c.Mode = CalcModeTemp -} - -func (c *Calc) Divide() { - c.beforeIndicator() - c.currentIndicator = CalcIndicatorDivide - if c.Mode != CalcModeTemp { - c.LastInput = c.Input - } - c.Mode = CalcModeTemp -} - -func (c *Calc) Do() { - if c.Mode == CalcModeAnswer { - if err := c.toFloat(); err != nil { - panic(err) - } - c.lastInputFloat = c.answer - c.toString() - c.Mode = CalcModeInputSecond - if err := c.do(); err != nil { - panic(err) - } - c.Mode = CalcModeAnswer - } else { - if err := c.do(); err != nil { - panic(err) - } - c.Mode = CalcModeAnswer - } -} - -func (c *Calc) toFloat() error { - var err error - if c.LastInput == "" || c.LastInput == "-" { - c.LastInput = "0" - } - c.lastInputFloat, err = strconv.ParseFloat(c.LastInput, 64) - if err != nil { - return err - } - if c.Input == "" || c.Input == "-" { - c.Input = "0" - } - c.inputFloat, err = strconv.ParseFloat(c.Input, 64) - if err != nil { - return err - } - return nil -} - -func (c *Calc) toString() { - c.LastInput = fmt.Sprintf("%v", c.lastInputFloat) - c.Input = fmt.Sprintf("%v", c.inputFloat) -} - -func (c *Calc) do() error { - err := c.toFloat() - if err != nil { - return err - } - switch c.currentIndicator { - case CalcIndicatorPlus: - c.answer = c.lastInputFloat + c.inputFloat - case CalcIndicatorMinus: - c.answer = c.lastInputFloat - c.inputFloat - case CalcIndicatorMultiple: - c.answer = c.lastInputFloat * c.inputFloat - case CalcIndicatorDivide: - c.answer = c.lastInputFloat / c.inputFloat - } - c.toString() - return nil -} - -func (c *Calc) Message(formatter func([]discord.Embed) []discord.Embed) (discord.MessageCreate, error) { - mes := discord.MessageCreate{} - err := c.toFloat() - if err != nil { - return mes, err - } - var content string - switch c.Mode { - case CalcModeInput: - content = fmt.Sprintf("```\r\r%32v```", c.Input) - case CalcModeInputSecond: - content = fmt.Sprintf("```\r%v %s\r%32v```", c.lastInputFloat, string(c.currentIndicator), c.Input) - case CalcModeAnswer: - if c.currentIndicator == 0 { - content = fmt.Sprintf("```\r%v =\r%32v```", c.inputFloat, c.inputFloat) - } else { - content = fmt.Sprintf("```\r%v %s %v =\r%32v```", c.lastInputFloat, string(c.currentIndicator), c.inputFloat, c.answer) - } - case CalcModeTemp: - content = fmt.Sprintf("```\r%v %s\r%32v```", c.lastInputFloat, string(c.currentIndicator), c.lastInputFloat) - } - mes.Content = content - mes.Components = c.Component() - return mes, nil -} - -func (c Calc) Component() []discord.ContainerComponent { - return []discord.ContainerComponent{ - discord.ActionRowComponent{ - discord.ButtonComponent{ - Style: discord.ButtonStyle(discord.ButtonStyleDanger), - CustomID: fmt.Sprintf("handler:utilcalc:ce:%s", c.id.String()), - Label: "CE", - }, - discord.ButtonComponent{ - Style: discord.ButtonStyle(discord.ButtonStyleDanger), - CustomID: fmt.Sprintf("handler:utilcalc:c:%s", c.id.String()), - Label: "C", - }, - discord.ButtonComponent{ - Style: discord.ButtonStyle(discord.ButtonStylePrimary), - CustomID: fmt.Sprintf("handler:utilcalc:back:%s", c.id.String()), - Label: "←", - }, - discord.ButtonComponent{ - Style: discord.ButtonStyle(discord.ButtonStylePrimary), - CustomID: fmt.Sprintf("handler:utilcalc:act:divide:%s", c.id.String()), - Label: "÷", - }, - }, - discord.ActionRowComponent{ - discord.ButtonComponent{ - Style: discord.ButtonStyle(discord.ButtonStyleSecondary), - CustomID: fmt.Sprintf("handler:utilcalc:num:%d:%s", 7, c.id.String()), - Label: "7", - }, - discord.ButtonComponent{ - Style: discord.ButtonStyle(discord.ButtonStyleSecondary), - CustomID: fmt.Sprintf("handler:utilcalc:num:%d:%s", 8, c.id.String()), - Label: "8", - }, - discord.ButtonComponent{ - Style: discord.ButtonStyle(discord.ButtonStyleSecondary), - CustomID: fmt.Sprintf("handler:utilcalc:num:%d:%s", 9, c.id.String()), - Label: "9", - }, - discord.ButtonComponent{ - Style: discord.ButtonStyle(discord.ButtonStylePrimary), - CustomID: fmt.Sprintf("handler:utilcalc:act:multiple:%s", c.id.String()), - Label: "×", - }, - }, - discord.ActionRowComponent{ - discord.ButtonComponent{ - Style: discord.ButtonStyle(discord.ButtonStyleSecondary), - CustomID: fmt.Sprintf("handler:utilcalc:num:%d:%s", 4, c.id.String()), - Label: "4", - }, - discord.ButtonComponent{ - Style: discord.ButtonStyle(discord.ButtonStyleSecondary), - CustomID: fmt.Sprintf("handler:utilcalc:num:%d:%s", 5, c.id.String()), - Label: "5", - }, - discord.ButtonComponent{ - Style: discord.ButtonStyle(discord.ButtonStyleSecondary), - CustomID: fmt.Sprintf("handler:utilcalc:num:%d:%s", 6, c.id.String()), - Label: "6", - }, - discord.ButtonComponent{ - Style: discord.ButtonStyle(discord.ButtonStylePrimary), - CustomID: fmt.Sprintf("handler:utilcalc:act:minus:%s", c.id.String()), - Label: "-", - }, - }, - discord.ActionRowComponent{ - discord.ButtonComponent{ - Style: discord.ButtonStyle(discord.ButtonStyleSecondary), - CustomID: fmt.Sprintf("handler:utilcalc:num:%d:%s", 1, c.id.String()), - Label: "1", - }, - discord.ButtonComponent{ - Style: discord.ButtonStyle(discord.ButtonStyleSecondary), - CustomID: fmt.Sprintf("handler:utilcalc:num:%d:%s", 2, c.id.String()), - Label: "2", - }, - discord.ButtonComponent{ - Style: discord.ButtonStyle(discord.ButtonStyleSecondary), - CustomID: fmt.Sprintf("handler:utilcalc:num:%d:%s", 3, c.id.String()), - Label: "3", - }, - discord.ButtonComponent{ - Style: discord.ButtonStyle(discord.ButtonStylePrimary), - CustomID: fmt.Sprintf("handler:utilcalc:act:plus:%s", c.id.String()), - Label: "+", - }, - }, - discord.ActionRowComponent{ - discord.ButtonComponent{ - Style: discord.ButtonStyle(discord.ButtonStyleSecondary), - CustomID: fmt.Sprintf("handler:utilcalc:num:%s:%s", "±", c.id.String()), - Label: "±", - }, - discord.ButtonComponent{ - Style: discord.ButtonStyle(discord.ButtonStyleSecondary), - CustomID: fmt.Sprintf("handler:utilcalc:num:%d:%s", 0, c.id.String()), - Label: "0", - }, - discord.ButtonComponent{ - Style: discord.ButtonStyle(discord.ButtonStyleSecondary), - CustomID: fmt.Sprintf("handler:utilcalc:num:%s:%s", ".", c.id.String()), - Label: ".", - }, - discord.ButtonComponent{ - Style: discord.ButtonStyle(discord.ButtonStyleSuccess), - CustomID: fmt.Sprintf("handler:utilcalc:do:%s", c.id.String()), - Label: "=", - }, - }, - } -} diff --git a/bot/db/db.go b/bot/db/db.go deleted file mode 100644 index 305f9130..00000000 --- a/bot/db/db.go +++ /dev/null @@ -1,158 +0,0 @@ -package db - -import ( - "context" - "fmt" - "time" - - "github.com/go-redis/redis/v8" -) - -type DBConfig struct { - Host string `json:"host"` - Port string `json:"port"` - DB int `json:"db"` -} - -type DB interface { - Close() error - PollCreate() PollCreateDB - Poll() PollDB - RolePanelCreate() RolePanelCreateDB - RolePanel() RolePanelDB - GuildData() GuildDataDB - Calc() CalcDB - MessagePin() MessagePinDB - EmbedDialog() EmbedDialogDB - UserData() UserDataDB - MinecraftServer() MinecraftServerDB - MinecraftStatusPanel() MinecraftStatusPanelDB - NoticeSchedule() NoticeScheduleDB - RolePanelV2() RolePanelV2DB - RolePanelV2Edit() RolePanelV2EditDB - RolePanelV2Place() RolePanelV2PlaceDB - Interactions() InteractionsDB -} - -func SetupDatabase(cfg DBConfig) (DB, error) { - db := redis.NewClient(&redis.Options{ - Network: "tcp", - Addr: fmt.Sprintf("%s:%s", cfg.Host, cfg.Port), - DB: cfg.DB, - }) - ctx, cancel := context.WithTimeout(context.Background(), time.Second) - defer cancel() - res := db.Ping(ctx) - if err := res.Err(); err != nil { - return nil, err - } - return &dbImpl{ - db: db, - pollCreate: &pollCreateDBImpl{db: db}, - poll: &pollDBImpl{db: db}, - rolePanelCreate: &rolePanelCreateDBImpl{db: db}, - rolePanel: &rolePanelDBImpl{db: db}, - guildData: &guildDataDBImpl{db: db}, - calc: &CalcDBImpl{db: db}, - messagePin: &messagePinDBImpl{db: db}, - embedDialog: &embedDialogDBImpl{db: db}, - userData: &userDataDBImpl{db: db}, - minecraftServer: &minecraftServerDBImpl{db: db}, - minecraftStatusPanel: &minecraftStatusPanelDBImpl{db: db}, - noticeSchedule: ¬iceScheduleDBImpl{db: db}, - rolePanelV2: &rolePanelV2DBImpl{db: db}, - rolePanelV2Edit: &rolePanelV2EditDBImpl{db: db}, - rolePanelV2Place: &rolePanelV2PlaceDBImpl{db: db}, - interactions: &interactionsImpl{db: db}, - }, nil -} - -var _ DB = (*dbImpl)(nil) - -type dbImpl struct { - db *redis.Client - pollCreate *pollCreateDBImpl - poll *pollDBImpl - rolePanelCreate *rolePanelCreateDBImpl - rolePanel *rolePanelDBImpl - guildData *guildDataDBImpl - calc *CalcDBImpl - messagePin *messagePinDBImpl - embedDialog *embedDialogDBImpl - userData *userDataDBImpl - minecraftServer *minecraftServerDBImpl - minecraftStatusPanel *minecraftStatusPanelDBImpl - noticeSchedule *noticeScheduleDBImpl - rolePanelV2 *rolePanelV2DBImpl - rolePanelV2Edit *rolePanelV2EditDBImpl - rolePanelV2Place *rolePanelV2PlaceDBImpl - interactions *interactionsImpl -} - -func (d *dbImpl) PollCreate() PollCreateDB { - return d.pollCreate -} - -func (d *dbImpl) Poll() PollDB { - return d.poll -} - -func (d *dbImpl) RolePanelCreate() RolePanelCreateDB { - return d.rolePanelCreate -} - -func (d *dbImpl) RolePanel() RolePanelDB { - return d.rolePanel -} - -func (d *dbImpl) GuildData() GuildDataDB { - return d.guildData -} - -func (d *dbImpl) Calc() CalcDB { - return d.calc -} - -func (d *dbImpl) MessagePin() MessagePinDB { - return d.messagePin -} - -func (d *dbImpl) EmbedDialog() EmbedDialogDB { - return d.embedDialog -} - -func (d *dbImpl) UserData() UserDataDB { - return d.userData -} - -func (d *dbImpl) MinecraftServer() MinecraftServerDB { - return d.minecraftServer -} - -func (d *dbImpl) MinecraftStatusPanel() MinecraftStatusPanelDB { - return d.minecraftStatusPanel -} - -func (d *dbImpl) NoticeSchedule() NoticeScheduleDB { - return d.noticeSchedule -} - -func (d *dbImpl) RolePanelV2() RolePanelV2DB { - return d.rolePanelV2 -} - -func (d *dbImpl) RolePanelV2Edit() RolePanelV2EditDB { - return d.rolePanelV2Edit -} - -func (d *dbImpl) RolePanelV2Place() RolePanelV2PlaceDB { - return d.rolePanelV2Place -} - -func (d *dbImpl) Interactions() InteractionsDB { - return d.interactions -} - -func (d *dbImpl) Close() error { - return d.db.Close() -} diff --git a/bot/db/embed_dialog.go b/bot/db/embed_dialog.go deleted file mode 100644 index 759615e3..00000000 --- a/bot/db/embed_dialog.go +++ /dev/null @@ -1,155 +0,0 @@ -package db - -import ( - "context" - "encoding/json" - "fmt" - "time" - - "github.com/go-redis/redis/v8" - "github.com/google/uuid" - "github.com/sabafly/disgo/discord" - botlib "github.com/sabafly/sabafly-lib/v2/bot" - "github.com/sabafly/sabafly-lib/v2/handler/interactions" - "github.com/sabafly/sabafly-lib/v2/translate" -) - -type EmbedDialogDB interface { - Set(id uuid.UUID, data EmbedDialog) error - Get(id uuid.UUID) (*EmbedDialog, error) - Del(id uuid.UUID) error -} - -type embedDialogDBImpl struct { - db *redis.Client -} - -func (e *embedDialogDBImpl) Set(id uuid.UUID, data EmbedDialog) error { - buf, err := json.Marshal(data) - if err != nil { - return err - } - res := e.db.Set(context.TODO(), "embed-dialog"+id.String(), buf, time.Minute*5) - if err := res.Err(); err != nil { - return err - } - return nil -} - -func (e *embedDialogDBImpl) Get(id uuid.UUID) (*EmbedDialog, error) { - res := e.db.Get(context.TODO(), "embed-dialog"+id.String()) - if err := res.Err(); err != nil { - return nil, err - } - var data EmbedDialog - if err := json.Unmarshal([]byte(res.Val()), &data); err != nil { - return nil, err - } - return &data, nil -} - -func (e *embedDialogDBImpl) Del(id uuid.UUID) error { - res := e.db.Del(context.TODO(), id.String()) - if err := res.Err(); err != nil { - return err - } - return nil -} - -func NewEmbedDialog(handler_name string, interaction_token interactions.Token, locale discord.Locale) *EmbedDialog { - return &EmbedDialog{ - ID: uuid.New(), - HandlerName: handler_name, - Locale: locale, - InteractionToken: interaction_token, - EmbedBuilder: discord.NewEmbedBuilder(), - } -} - -type EmbedDialog struct { - ID uuid.UUID `json:"id"` - HandlerName string `json:"handler_name"` - Locale discord.Locale `json:"locale"` - InteractionToken interactions.Token `json:"interaction_token"` - *discord.EmbedBuilder `json:"embed"` -} - -func (e EmbedDialog) BaseMenu() (mes discord.MessageUpdate) { - if mes.Embeds == nil { - mes.Embeds = &[]discord.Embed{} - } - *mes.Embeds = append(*mes.Embeds, e.Build()) - *mes.Embeds = append(*mes.Embeds, - discord.Embed{ - Author: &discord.EmbedAuthor{ - Name: translate.Message(e.Locale, "embed_dialog_base_menu_title"), - }, - }, - ) - *mes.Embeds = botlib.SetEmbedsProperties(*mes.Embeds) - if mes.Components == nil { - mes.Components = &[]discord.ContainerComponent{} - } - *mes.Components = append(*mes.Components, - discord.ActionRowComponent{ - discord.ButtonComponent{ - Style: discord.ButtonStyleSecondary, - Label: translate.Message(e.Locale, "embed_dialog_button_to_title_description_menu"), - CustomID: fmt.Sprintf("handler:ed:to-title-desc:%s", e.ID.String()), - }, - }, - discord.ActionRowComponent{ - discord.ButtonComponent{ - Style: discord.ButtonStyleSuccess, - Label: "✓", //TODO 絵文字にする - CustomID: fmt.Sprintf("handler:%s:%s", e.HandlerName, e.ID.String()), - }, - }, - ) - return -} - -func (e EmbedDialog) TitleDescriptionMenu() (mes discord.MessageUpdate) { - if mes.Embeds == nil { - mes.Embeds = &[]discord.Embed{} - } - *mes.Embeds = append(*mes.Embeds, discord.Embed{ - Title: translate.Message(e.Locale, "embed_dialog_title_description_menu_title"), - Fields: []discord.EmbedField{ - { - Name: translate.Message(e.Locale, "embed_dialog_title_description_menu_fields_0_title"), - Value: e.Embed.Title, - }, - { - Name: translate.Message(e.Locale, "embed_dialog_title_description_menu_fields_1_title"), - Value: e.Embed.Description, - }, - }, - }) - *mes.Embeds = botlib.SetEmbedsProperties(*mes.Embeds) - if mes.Components == nil { - mes.Components = &[]discord.ContainerComponent{} - } - *mes.Components = append(*mes.Components, - discord.ActionRowComponent{ - discord.ButtonComponent{ - Style: discord.ButtonStylePrimary, - Label: translate.Message(e.Locale, "embed_dialog_title_description_menu_button_set_title_label"), - CustomID: fmt.Sprintf("handler:ed:set-title:%s", e.ID.String()), - }, - discord.ButtonComponent{ - Style: discord.ButtonStylePrimary, - Label: translate.Message(e.Locale, "embed_dialog_title_description_menu_button_set_description_label"), - CustomID: fmt.Sprintf("handler:ed:set-desc:%s", e.ID.String()), - }, - }, - discord.ActionRowComponent{ - discord.ButtonComponent{ - Style: discord.ButtonStyleSecondary, - Label: "Back", //TODO: 絵文字にする - CustomID: fmt.Sprintf("handler:ed:base-menu:%s", e.ID.String()), - }, - }, - ) - return -} diff --git a/bot/db/guild_data.go b/bot/db/guild_data.go deleted file mode 100644 index 9088fec3..00000000 --- a/bot/db/guild_data.go +++ /dev/null @@ -1,288 +0,0 @@ -package db - -import ( - "context" - "time" - - "github.com/disgoorg/json" - "github.com/disgoorg/snowflake/v2" - "github.com/go-redis/redis/v8" - "github.com/google/uuid" - "github.com/sabafly/sabafly-lib/v2/permissions" -) - -type GuildDataDB interface { - Get(id snowflake.ID) (GuildData, error) - Set(id snowflake.ID, data GuildData) error - Del(id snowflake.ID) error -} - -var _ GuildDataDB = (*guildDataDBImpl)(nil) - -type guildDataDBImpl struct { - db *redis.Client -} - -func (g *guildDataDBImpl) Get(id snowflake.ID) (GuildData, error) { - res := g.db.HGet(context.TODO(), "guild-data", id.String()) - if err := res.Err(); err != nil { - if err != redis.Nil { - return GuildData{}, err - } else { - return NewGuildData(id), nil - } - } - buf := []byte(res.Val()) - val := GuildData{} - if err := json.Unmarshal(buf, &val); err != nil { - return GuildData{}, err - } - return val, nil -} - -func (g *guildDataDBImpl) Set(id snowflake.ID, data GuildData) error { - buf, err := json.Marshal(data) - if err != nil { - return err - } - res := g.db.HSet(context.TODO(), "guild-data", id.String(), buf) - if err := res.Err(); err != nil { - return err - } - return nil -} - -func (g *guildDataDBImpl) Del(id snowflake.ID) error { - res := g.db.HDel(context.TODO(), "guild-data", id.String()) - if err := res.Err(); err != nil { - return err - } - return nil -} - -func NewGuildData(id snowflake.ID) GuildData { - g := GuildData{ - ID: id, - RolePanel: make(map[uuid.UUID]GuildDataRolePanel), - RolePanelLimit: 10, - } - b, _ := json.Marshal(g) - _ = g.validate(b) - return g -} - -const GuildDataVersion = 11 - -type GuildData struct { - ID snowflake.ID `json:"id"` - RolePanel map[uuid.UUID]GuildDataRolePanel `json:"role_panel"` - RolePanelLimit int `json:"role_panel_limit"` - UserPermissions map[snowflake.ID]permissions.Permission `json:"user_permissions"` - RolePermissions map[snowflake.ID]permissions.Permission `json:"role_permissions"` - UserLevels map[snowflake.ID]GuildDataUserLevel `json:"user_levels"` - Config GuildDataConfig `json:"config"` - BumpStatus BumpStatus `json:"bump_status"` - - MCStatusPanel map[uuid.UUID]string `json:"mc_status_panel"` - MCStatusPanelName map[string]int `json:"mc_status_panel_name"` - MCStatusPanelMax int `json:"mc_status_panel_max"` - - MessageSuffix map[snowflake.ID]MessageSuffix `json:"message_suffix"` - - UserLevelExcludeChannels map[snowflake.ID]string `json:"user_level_exclude_channels"` - - RolePanelV2 map[uuid.UUID]string `json:"role_panel_v2"` - RolePanelV2Name map[string]int `json:"role_panel_v2_name"` - RolePanelV2Placed map[string]uuid.UUID `json:"role_panel_v2_placed"` - RolePanelV2PlacedConfig map[string]RolePanelV2Config `json:"role_panel_v2_placed_config"` - RolePanelV2Limit int `json:"role_panel_v2_limit"` - - RolePanelV2Editing map[uuid.UUID]uuid.UUID `json:"role_panel_v2_editing"` - - RolePanelV2EditingEmoji map[uuid.UUID][2]snowflake.ID `json:"role_panel_v2_emoji"` - - DataVersion *int `json:"data_version,omitempty"` -} - -func NewMessageSuffix(target snowflake.ID, suffix string, rule MessageSuffixRuleType) MessageSuffix { - return MessageSuffix{ - Target: target, - Suffix: suffix, - RuleType: rule, - } -} - -type MessageSuffix struct { - Target snowflake.ID `json:"target"` - Suffix string `json:"suffix"` - RuleType MessageSuffixRuleType `json:"rule_type"` -} - -type MessageSuffixRuleType int - -const ( - MessageSuffixRuleTypeWarning = iota - MessageSuffixRuleTypeDelete - MessageSuffixRuleTypeWebhook -) - -type BumpStatus struct { - BumpEnabled bool `json:"bump_enabled"` - BumpChannel *snowflake.ID `json:"bump_channel"` - BumpRole *snowflake.ID `json:"bump_role"` - BumpMessage [2]string `json:"bump_message"` - BumpRemind [2]string `json:"bump_remind"` - LastBump time.Time `json:"last_bump"` - LastBumpChannel *snowflake.ID `json:"last_bump_channel"` - UpEnabled bool `json:"up_enabled"` - UpChannel *snowflake.ID `json:"up_channel"` - UpRole *snowflake.ID `json:"up_role"` - UpMessage [2]string `json:"up_message"` - UpRemind [2]string `json:"up_remind"` - LastUp time.Time `json:"last_up"` - LastUpChannel *snowflake.ID `json:"last_up_channel"` - - BumpCountMap map[snowflake.ID]uint64 `json:"bump_count_map"` - UpCountMap map[snowflake.ID]uint64 `json:"up_count_map"` -} - -type GuildDataConfig struct { - LevelUpMessage string `json:"level_up_message"` - LevelUpMessageChannel *snowflake.ID `json:"level_up_message_channel"` -} - -func NewGuildDataUserLevel() GuildDataUserLevel { - return GuildDataUserLevel{ - UserDataLevel: NewUserDataLevel(), - } -} - -type GuildDataUserLevel struct { - UserDataLevel - MessageCount int64 `json:"message_count"` - LastMessageTime time.Time `json:"last_message_time"` -} - -func (g *GuildData) UnmarshalJSON(b []byte) error { - type guildData GuildData - var v struct { - guildData - } - if err := json.Unmarshal(b, &v); err != nil { - return err - } - *g = GuildData(v.guildData) - if !g.isValid() { - if err := g.validate(b); err != nil { - return err - } - } - return nil -} - -func (g GuildData) isValid() bool { - if g.DataVersion == nil { - return false - } - return *g.DataVersion > GuildDataVersion -} - -func (g *GuildData) validate(b []byte) error { - if g.DataVersion == nil { - g.DataVersion = json.Ptr(0) - } - switch *g.DataVersion { - case 0: - g.UserPermissions = make(map[snowflake.ID]permissions.Permission) - g.RolePermissions = make(map[snowflake.ID]permissions.Permission) - g.UserLevels = make(map[snowflake.ID]GuildDataUserLevel) - *g.DataVersion = 1 - fallthrough - case 1: - g.Config = GuildDataConfig{ - LevelUpMessage: "{mention} がレベルアップしたした。 {level} lv", - } - *g.DataVersion = 2 - fallthrough - case 2: - g.MCStatusPanel = make(map[uuid.UUID]string) - g.MCStatusPanelName = make(map[string]int) - g.MCStatusPanelMax = 10 - *g.DataVersion = 3 - fallthrough - case 3: - g.BumpStatus.UpEnabled = true - if g.BumpStatus.UpMessage == [2]string{} { - g.BumpStatus.UpMessage = [2]string{ - "UPを怜知したよ", - "時間埌に通知するね", - } - } - if g.BumpStatus.UpRemind == [2]string{} { - g.BumpStatus.UpRemind = [2]string{ - "UPできるよ!", - "`/dissoku up` でUPしよう!", - } - } - g.BumpStatus.BumpEnabled = true - if g.BumpStatus.BumpMessage == [2]string{} { - g.BumpStatus.BumpMessage = [2]string{ - "Bumpを怜知したよ", - "時間埌に通知するね", - } - } - if g.BumpStatus.BumpRemind == [2]string{} { - g.BumpStatus.BumpRemind = [2]string{ - "Bumpできるよ!", - "`/bump` でBumpしよう!", - } - } - g.BumpStatus.BumpCountMap = make(map[snowflake.ID]uint64) - g.BumpStatus.UpCountMap = make(map[snowflake.ID]uint64) - g.UserLevelExcludeChannels = make(map[snowflake.ID]string) - *g.DataVersion = 4 - fallthrough - case 4: - g.MessageSuffix = make(map[snowflake.ID]MessageSuffix) - *g.DataVersion = 5 - fallthrough - case 5: - g.RolePanelV2 = make(map[uuid.UUID]string) - g.RolePanelV2Name = make(map[string]int) - g.RolePanelV2Placed = make(map[string]uuid.UUID) - g.RolePanelV2Limit = 5 - *g.DataVersion = 6 - fallthrough - case 6: - g.RolePanelV2Editing = make(map[uuid.UUID]uuid.UUID) - g.RolePanelV2Limit = 15 - *g.DataVersion = 7 - fallthrough - case 7: - g.RolePanelV2Editing = make(map[uuid.UUID]uuid.UUID) - *g.DataVersion = 8 - fallthrough - case 8: - g.RolePanelV2EditingEmoji = make(map[uuid.UUID][2]snowflake.ID) - *g.DataVersion = 9 - fallthrough - case 9: - // g.RolePanelV2PlacedType = make(map[string]RolePanelV2Type) - *g.DataVersion = 10 - fallthrough - case 10: - g.RolePanelV2PlacedConfig = make(map[string]RolePanelV2Config) - *g.DataVersion = 11 - fallthrough - case GuildDataVersion: - return nil - default: - d := NewGuildData(g.ID) - *g = d - return nil - } -} - -type GuildDataRolePanel struct { - OnList bool `json:"on_list"` -} diff --git a/bot/db/interactions.go b/bot/db/interactions.go deleted file mode 100644 index 8e7c29cb..00000000 --- a/bot/db/interactions.go +++ /dev/null @@ -1,49 +0,0 @@ -package db - -import ( - "context" - "time" - - "github.com/go-redis/redis/v8" - "github.com/google/uuid" -) - -type InteractionsDB interface { - Get(id uuid.UUID) (string, error) - Set(id uuid.UUID, token string) error - Del(id uuid.UUID) error -} - -var _ InteractionsDB = (*interactionsImpl)(nil) - -type interactionsImpl struct { - db *redis.Client -} - -func (i *interactionsImpl) Get(id uuid.UUID) (string, error) { - res := i.db.Get(context.TODO(), "interactions"+id.String()) - if err := res.Err(); err != nil { - return "", err - } - rt, err := res.Result() - if err != nil { - return "", err - } - return rt, nil -} - -func (i *interactionsImpl) Set(id uuid.UUID, token string) error { - res := i.db.Set(context.TODO(), "interactions"+id.String(), token, time.Minute*14) - if err := res.Err(); err != nil { - return err - } - return nil -} - -func (i *interactionsImpl) Del(id uuid.UUID) error { - res := i.db.Del(context.TODO(), "interactions"+id.String()) - if err := res.Err(); err != nil { - return err - } - return nil -} diff --git a/bot/db/message_pin.go b/bot/db/message_pin.go deleted file mode 100644 index fff6fb2b..00000000 --- a/bot/db/message_pin.go +++ /dev/null @@ -1,115 +0,0 @@ -package db - -import ( - "context" - "encoding/json" - "time" - - "github.com/disgoorg/snowflake/v2" - "github.com/go-redis/redis/v8" - "github.com/sabafly/disgo/bot" - "github.com/sabafly/disgo/discord" - botlib "github.com/sabafly/sabafly-lib/v2/bot" -) - -type MessagePinDB interface { - Get(id snowflake.ID) (*GuildMessagePins, error) - GetAll() (map[snowflake.ID]*GuildMessagePins, error) - Set(id snowflake.ID, data *GuildMessagePins) error - Del(id snowflake.ID) error -} - -var _ MessagePinDB = (*messagePinDBImpl)(nil) - -type messagePinDBImpl struct { - db *redis.Client -} - -func (m *messagePinDBImpl) Get(id snowflake.ID) (*GuildMessagePins, error) { - res := m.db.HGet(context.TODO(), "message-pin", id.String()) - if err := res.Err(); err != nil { - return nil, err - } - val := &GuildMessagePins{} - if err := json.Unmarshal([]byte(res.Val()), val); err != nil { - return nil, err - } - return val, nil -} - -func (m *messagePinDBImpl) GetAll() (map[snowflake.ID]*GuildMessagePins, error) { - res := m.db.HGetAll(context.TODO(), "message-pin") - if err := res.Err(); err != nil { - return nil, err - } - val := make(map[snowflake.ID]*GuildMessagePins) - for k, v := range res.Val() { - id, err := snowflake.Parse(k) - if err != nil { - return nil, err - } - data := &GuildMessagePins{} - if err := json.Unmarshal([]byte(v), data); err != nil { - return nil, err - } - val[id] = data - } - return val, nil -} - -func (m *messagePinDBImpl) Set(id snowflake.ID, data *GuildMessagePins) error { - buf, err := json.Marshal(data) - if err != nil { - return err - } - res := m.db.HSet(context.TODO(), "message-pin", id.String(), buf) - if err := res.Err(); err != nil { - return err - } - return nil -} - -func (m *messagePinDBImpl) Del(id snowflake.ID) error { - res := m.db.HDel(context.TODO(), "message-pin", id.String()) - if err := res.Err(); err != nil { - return err - } - return nil -} - -type GuildMessagePins struct { - Enabled bool `json:"enabled"` - Pins map[snowflake.ID]MessagePin `json:"pins"` -} - -type MessagePin struct { - WebhookMessageCreate discord.WebhookMessageCreate `json:"webhook_message_create"` - ChannelID snowflake.ID `json:"channel_id"` - LastMessageID *snowflake.ID `json:"last_message_id"` - - limit []time.Time -} - -func (m *MessagePin) CheckLimit() bool { - m.limit = append(m.limit[0:min(9, len(m.limit))], time.Now()) - return (len(m.limit) < 3 || time.Since(m.limit[2]) >= time.Second*15) && (len(m.limit) < 10 || time.Since(m.limit[0]) >= time.Minute) -} - -func (self *MessagePin) Update(client bot.Client) error { - if self.LastMessageID != nil { - go func() { _ = client.Rest().DeleteMessage(self.ChannelID, *self.LastMessageID) }() - } - m, err := botlib.SendWebhook(client, self.ChannelID, self.WebhookMessageCreate) - if err != nil { - return err - } - self.LastMessageID = &m.ID - return nil -} - -func NewMessagePin() *GuildMessagePins { - return &GuildMessagePins{ - Enabled: true, - Pins: make(map[snowflake.ID]MessagePin), - } -} diff --git a/bot/db/minecraft.go b/bot/db/minecraft.go deleted file mode 100644 index 08680b3c..00000000 --- a/bot/db/minecraft.go +++ /dev/null @@ -1,233 +0,0 @@ -package db - -import ( - "context" - "crypto/sha256" - "encoding/hex" - "encoding/json" - "fmt" - "io" - "time" - - "github.com/Tnze/go-mc/chat" - "github.com/disgoorg/snowflake/v2" - "github.com/go-redis/redis/v8" - "github.com/xrjr/mcutils/pkg/bedrock" - "github.com/xrjr/mcutils/pkg/ping" -) - -type MinecraftServerDB interface { - Set(hash string, server MinecraftServer) error - Get(hash string) (MinecraftServer, error) - GetAll() ([]MinecraftServer, error) - Del(hash string) error -} - -type minecraftServerDBImpl struct { - db *redis.Client -} - -func (m minecraftServerDBImpl) Set(hash string, server MinecraftServer) error { - buf, err := json.Marshal(server) - if err != nil { - return err - } - res := m.db.HSet(context.TODO(), "mc-server", hash, buf) - if err := res.Err(); err != nil { - return err - } - return nil -} - -func (m minecraftServerDBImpl) Get(hash string) (MinecraftServer, error) { - res := m.db.HGet(context.TODO(), "mc-server", hash) - if err := res.Err(); err != nil { - return MinecraftServer{}, err - } - var val MinecraftServer - if err := json.Unmarshal([]byte(res.Val()), &val); err != nil { - return MinecraftServer{}, err - } - return val, nil -} - -func (m minecraftServerDBImpl) GetAll() ([]MinecraftServer, error) { - res := m.db.HGetAll(context.TODO(), "mc-server") - if err := res.Err(); err != nil { - return nil, err - } - var val []MinecraftServer - for _, v := range res.Val() { - var v2 MinecraftServer - if err := json.Unmarshal([]byte(v), &v2); err != nil { - continue - } - val = append(val, v2) - } - return val, nil -} - -func (m minecraftServerDBImpl) Del(hash string) error { - res := m.db.HDel(context.TODO(), "mc-server", hash) - if err := res.Err(); err != nil { - return err - } - return nil -} - -type MinecraftServerType string - -const ( - MinecraftServerTypeJava = "java" - MinecraftServerTypeBedrock = "bedrock" -) - -func Address2Hash(address string, port int) (string, error) { - hash := sha256.New() - if _, err := io.WriteString(hash, fmt.Sprintf("%s:%d", address, port)); err != nil { - return "", err - } - buf := hash.Sum(nil) - str := hex.EncodeToString(buf) - return str, nil -} - -func NewMinecraftServer(hash, address string, port uint16, s_type MinecraftServerType) MinecraftServer { - return MinecraftServer{ - Hash: hash, - Address: address, - Port: port, - Type: s_type, - } -} - -type MinecraftServer struct { - Hash string `json:"hash"` - Type MinecraftServerType `json:"type"` - Address string `json:"address"` - Port uint16 `json:"port"` - WatchingGuilds []snowflake.ID `json:"watching_guilds"` - LastResponseTime time.Time `json:"last_response_time"` - LastResponse *MinecraftPingResponse `json:"last_response"` -} - -func (m MinecraftServer) String() string { - if (m.Port == 25565 && m.Type == MinecraftServerTypeJava) || (m.Port == 19132 && m.Type == MinecraftServerTypeBedrock) { - return m.Address - } - return fmt.Sprintf("%s:%d", m.Address, m.Port) -} - -func (ms *MinecraftServer) Fetch() (r *MinecraftPingResponse, err error) { - ctx, cancel := context.WithTimeout(context.Background(), time.Second*2) - defer cancel() - defer func() { - if r != nil { - ms.LastResponse = r - ms.LastResponseTime = time.Now() - } - }() - go func() { - switch ms.Type { - case MinecraftServerTypeJava: - c := ping.NewClient(ms.Address, int(ms.Port)) - if err = c.Connect(); err != nil { - r = &MinecraftPingResponse{ - Infos: ping.Infos{Description: err.Error()}, - Type: ms.Type, - Succeed: false, - } - err = nil - return - } - defer func() { _ = c.Disconnect() }() - var h ping.Handshake - t := time.Now() - h, err = c.Handshake() - if err != nil { - r = &MinecraftPingResponse{ - Infos: ping.Infos{Description: err.Error()}, - Type: ms.Type, - Succeed: false, - } - err = nil - return - } - latency := time.Since(t).Milliseconds() - r = &MinecraftPingResponse{ - Infos: h.Properties.Infos(), - Latency: latency, - Type: ms.Type, - Succeed: true, - } - nbt_mes := chat.Message{} - b, _ := json.Marshal(h.Properties["description"]) - _ = nbt_mes.UnmarshalJSON(b) - r.Description = nbt_mes.String() - case MinecraftServerTypeBedrock: - c := bedrock.NewClient(ms.String(), int(ms.Port)) - if err = c.Connect(); err != nil { - r = &MinecraftPingResponse{ - Infos: ping.Infos{Description: err.Error()}, - Type: ms.Type, - Succeed: false, - } - err = nil - return - } - var res bedrock.UnconnectedPong - var latency int - res, latency, err = c.UnconnectedPing() - if err != nil { - r = &MinecraftPingResponse{ - Infos: ping.Infos{Description: err.Error()}, - Type: ms.Type, - Succeed: false, - } - err = nil - return - } - r = &MinecraftPingResponse{ - Infos: ping.Infos{ - Description: res.MOTD, - Favicon: "", - }, - Latency: int64(latency), - Type: ms.Type, - Succeed: true, - } - r.Version.Name = res.MinecraftVersion - r.Version.Protocol = res.ProtocolVersion - r.Players.Max = res.MaxPlayers - r.Players.Online = res.OnlinePlayers - } - cancel() - }() - for { - time.Sleep(10 * time.Millisecond) - select { - case <-ctx.Done(): - if ctx.Err() == context.DeadlineExceeded { - r = &MinecraftPingResponse{ - Infos: ping.Infos{Description: "TIMEOUT"}, - Type: ms.Type, - Succeed: false, - } - return r, nil - } - return - default: - } - } -} - -type MinecraftPingResponse struct { - ping.Infos - Latency int64 - Type MinecraftServerType `json:"type"` - Succeed bool `json:"succeed"` -} - -func (r MinecraftPingResponse) AnsiDescription() string { - return chat.Text(r.Description).String() -} diff --git a/bot/db/minecraft_status_panel.go b/bot/db/minecraft_status_panel.go deleted file mode 100644 index 035e1031..00000000 --- a/bot/db/minecraft_status_panel.go +++ /dev/null @@ -1,140 +0,0 @@ -package db - -import ( - "context" - "fmt" - - "github.com/Tnze/go-mc/chat" - "github.com/disgoorg/json" - "github.com/disgoorg/snowflake/v2" - "github.com/go-redis/redis/v8" - "github.com/google/uuid" - "github.com/sabafly/disgo/discord" - botlib "github.com/sabafly/sabafly-lib/v2/bot" -) - -type MinecraftStatusPanelDB interface { - Set(id uuid.UUID, panel MinecraftStatusPanel) error - Get(id uuid.UUID) (MinecraftStatusPanel, error) - Del(id uuid.UUID) error -} - -type minecraftStatusPanelDBImpl struct { - db *redis.Client -} - -func (m minecraftStatusPanelDBImpl) Set(id uuid.UUID, panel MinecraftStatusPanel) error { - buf, err := json.Marshal(panel) - if err != nil { - return err - } - res := m.db.HSet(context.TODO(), "mc-status-panel", id.String(), buf) - if err := res.Err(); err != nil { - return err - } - return nil -} - -func (m minecraftStatusPanelDBImpl) Get(id uuid.UUID) (MinecraftStatusPanel, error) { - res := m.db.HGet(context.TODO(), "mc-status-panel", id.String()) - if err := res.Err(); err != nil { - return MinecraftStatusPanel{}, err - } - var v MinecraftStatusPanel - if err := json.Unmarshal([]byte(res.Val()), &v); err != nil { - return MinecraftStatusPanel{}, err - } - return v, nil -} - -func (m minecraftStatusPanelDBImpl) Del(id uuid.UUID) error { - res := m.db.HDel(context.TODO(), "mc-status-panel", id.String()) - if err := res.Err(); err != nil { - return err - } - return nil -} - -func NewMinecraftStatusPanel(name string, guildID, channelID, messageID snowflake.ID, hash string, showAddress bool) MinecraftStatusPanel { - return MinecraftStatusPanel{ - Name: name, - ID: uuid.New(), - GuildID: guildID, - ChannelID: channelID, - MessageID: messageID, - Hash: hash, - IsShowAddress: showAddress, - } -} - -type MinecraftStatusPanel struct { - ID uuid.UUID `json:"id"` - Name string `json:"name"` - Hash string `json:"hash"` - IsShowAddress bool `json:"is_show_address"` - GuildID snowflake.ID `json:"guild_id"` - ChannelID snowflake.ID `json:"channel_id"` - MessageID snowflake.ID `json:"message_id"` -} - -func (m MinecraftStatusPanel) Embed(address string, response *MinecraftPingResponse) discord.Embed { - embed := discord.NewEmbedBuilder() - embed.SetTitle(m.Name) - if !response.Succeed { - response.Latency = -1 - embed.SetColor(0xff2313) - } - embed.SetDescriptionf("```ansi\r%s ```", response.Description) - embed.SetThumbnail("attachment://favicon.png") - embed.AddFields( - discord.EmbedField{ - Name: "Players", - Value: fmt.Sprintf("(%d / %d)", response.Players.Online, response.Players.Max), - Inline: json.Ptr(true), - }, - discord.EmbedField{ - Name: "Latency", - Value: fmt.Sprintf("```%d ms```", response.Latency), - Inline: json.Ptr(true), - }, - discord.EmbedField{ - Name: "Version", - Value: fmt.Sprintf("```%s ```", chat.Text(response.Version.Name).String()), - Inline: json.Ptr(true), - }, - discord.EmbedField{ - Name: "Edition", - Value: fmt.Sprintf("```%s ```", response.Type), - Inline: json.Ptr(true), - }, - ) - if len(response.Players.Sample) > 0 { - for _, ips := range response.Players.Sample { - embed.Fields[0].Value += "\r" + chat.Text(ips.Name).String() - } - } - embed.Fields[0].Value = fmt.Sprintf("```ansi\r%s ```", embed.Fields[0].Value) - if m.IsShowAddress { - embed.AddFields( - discord.EmbedField{ - Name: "Address", - Value: fmt.Sprintf("```%s ```", address), - Inline: json.Ptr(true), - }, - ) - } - embed.Embed = botlib.SetEmbedProperties(embed.Embed) - return embed.Build() -} - -func (m MinecraftStatusPanel) Components() []discord.ContainerComponent { - return []discord.ContainerComponent{ - discord.NewActionRow( - discord.ButtonComponent{ - Style: discord.ButtonStyleSuccess, - Label: "Refresh", - CustomID: fmt.Sprintf("handler:minecraft:status-refresh:%s", m.ID.String()), - }, - ), - } -} diff --git a/bot/db/notice_schedule.go b/bot/db/notice_schedule.go deleted file mode 100644 index 1954b233..00000000 --- a/bot/db/notice_schedule.go +++ /dev/null @@ -1,199 +0,0 @@ -package db - -import ( - "context" - "encoding/json" - "fmt" - "time" - - "github.com/disgoorg/snowflake/v2" - "github.com/go-redis/redis/v8" - "github.com/google/uuid" -) - -type NoticeScheduleDB interface { - Set(id uuid.UUID, data NoticeSchedule) error - Get(id uuid.UUID) (NoticeSchedule, error) - GetAll() ([]NoticeSchedule, error) - GetByType(t NoticeScheduleType) ([]NoticeSchedule, error) - Del(id uuid.UUID) error -} - -type noticeScheduleDBImpl struct { - db *redis.Client -} - -func (n *noticeScheduleDBImpl) Set(id uuid.UUID, data NoticeSchedule) error { - buf, err := json.Marshal(data) - if err != nil { - return err - } - res := n.db.HSet(context.TODO(), "notice-schedule", id.String(), buf) - if err := res.Err(); err != nil { - return err - } - return nil -} - -func (n *noticeScheduleDBImpl) Get(id uuid.UUID) (NoticeSchedule, error) { - res := n.db.HGet(context.TODO(), "notice-schedule", id.String()) - if err := res.Err(); err != nil { - return nil, err - } - var v noticeScheduleUnmarshal - if err := json.Unmarshal([]byte(res.Val()), &v); err != nil { - return nil, err - } - return v.NoticeSchedule, nil -} - -func (n *noticeScheduleDBImpl) GetAll() ([]NoticeSchedule, error) { - res := n.db.HGetAll(context.TODO(), "notice-schedule") - if err := res.Err(); err != nil { - return nil, err - } - var r []NoticeSchedule - for _, data := range res.Val() { - var v noticeScheduleUnmarshal - if err := json.Unmarshal([]byte(data), &v); err != nil { - return nil, err - } - r = append(r, v.NoticeSchedule) - } - return r, nil -} - -func (n *noticeScheduleDBImpl) GetByType(t NoticeScheduleType) ([]NoticeSchedule, error) { - res := n.db.HGetAll(context.TODO(), "notice-schedule") - if err := res.Err(); err != nil { - return nil, err - } - var r []NoticeSchedule - for _, data := range res.Val() { - var v noticeScheduleUnmarshal - if err := json.Unmarshal([]byte(data), &v); err != nil { - return nil, err - } - if v.Type() != t { - continue - } - r = append(r, v) - } - return r, nil -} - -func (n *noticeScheduleDBImpl) Del(id uuid.UUID) error { - res := n.db.HDel(context.TODO(), "notice-schedule", id.String()) - if err := res.Err(); err != nil { - return err - } - return nil -} - -type noticeScheduleUnmarshal struct { - NoticeSchedule -} - -func (n *noticeScheduleUnmarshal) UnmarshalJSON(data []byte) error { - var nType struct { - Type NoticeScheduleType `json:"type"` - } - - if err := json.Unmarshal(data, &nType); err != nil { - return err - } - - var ( - noticeSchedule NoticeSchedule - err error - ) - - switch nType.Type { - case NoticeScheduleTypeBump: - var v NoticeScheduleBump - err = json.Unmarshal(data, &v) - noticeSchedule = v - default: - err = fmt.Errorf("unknown notice schedule with type %d received", nType.Type) - } - - if err != nil { - return err - } - - n.NoticeSchedule = noticeSchedule - return nil -} - -type NoticeSchedule interface { - Type() NoticeScheduleType - ID() uuid.UUID -} - -type NoticeScheduleType int - -const ( - NoticeScheduleTypeBump = iota + 1 -) - -func (t NoticeScheduleType) String() string { - switch t { - case NoticeScheduleTypeBump: - return "bump" - } - return "unknown" -} - -func NewNoticeScheduleBump(is_up bool, guildID, channelID snowflake.ID, schedule_time time.Time) NoticeSchedule { - return NoticeScheduleBump{ - id: uuid.New(), - IsUp: is_up, - GuildID: guildID, - ChannelID: channelID, - ScheduledTime: schedule_time, - } -} - -type NoticeScheduleBump struct { - id uuid.UUID - IsUp bool `json:"is_up"` - GuildID snowflake.ID `json:"guild_id"` - ChannelID snowflake.ID `json:"channel_id"` - ScheduledTime time.Time `json:"scheduled_time"` -} - -func (n NoticeScheduleBump) Type() NoticeScheduleType { - return NoticeScheduleTypeBump -} - -func (n NoticeScheduleBump) ID() uuid.UUID { - return n.id -} - -func (n *NoticeScheduleBump) UnmarshalJSON(data []byte) error { - type noticeScheduleBump NoticeScheduleBump - var v struct { - ID uuid.UUID - noticeScheduleBump - } - if err := json.Unmarshal(data, &v); err != nil { - return err - } - *n = NoticeScheduleBump(v.noticeScheduleBump) - n.id = v.ID - return nil -} - -func (n NoticeScheduleBump) MarshalJSON() ([]byte, error) { - type noticeScheduleBump NoticeScheduleBump - return json.Marshal(struct { - Type NoticeScheduleType `json:"type"` - ID uuid.UUID `json:"id"` - noticeScheduleBump - }{ - Type: n.Type(), - ID: n.id, - noticeScheduleBump: noticeScheduleBump(n), - }, - ) -} diff --git a/bot/db/poll.go b/bot/db/poll.go deleted file mode 100644 index 7ff74c4d..00000000 --- a/bot/db/poll.go +++ /dev/null @@ -1,302 +0,0 @@ -package db - -import ( - "context" - "encoding/json" - "fmt" - "sort" - "time" - - "github.com/disgoorg/snowflake/v2" - "github.com/go-redis/redis/v8" - "github.com/google/uuid" - "github.com/sabafly/disgo/discord" - botlib "github.com/sabafly/sabafly-lib/v2/bot" - "github.com/sabafly/sabafly-lib/v2/translate" -) - -type PollDB interface { - GetAll() ([]Poll, error) - Get(id uuid.UUID) (Poll, error) - Set(id uuid.UUID, poll Poll) error - Del(id uuid.UUID) error -} - -var _ PollDB = (*pollDBImpl)(nil) - -type pollDBImpl struct { - db *redis.Client -} - -func (p *pollDBImpl) GetAll() ([]Poll, error) { - res := p.db.HGetAll(context.TODO(), "poll") - if err := res.Err(); err != nil { - return []Poll{}, err - } - rmap := res.Val() - rt := []Poll{} - for _, v := range rmap { - data := Poll{} - err := json.Unmarshal([]byte(v), &data) - if err != nil { - return []Poll{}, err - } - rt = append(rt, data) - } - return rt, nil -} - -func (p *pollDBImpl) Get(id uuid.UUID) (Poll, error) { - res := p.db.HGet(context.TODO(), "poll", id.String()) - if err := res.Err(); err != nil { - return Poll{}, err - } - buf, err := res.Result() - if err != nil { - return Poll{}, err - } - data := Poll{} - err = json.Unmarshal([]byte(buf), &data) - if err != nil { - return Poll{}, err - } - return data, nil -} - -func (p *pollDBImpl) Set(id uuid.UUID, poll Poll) error { - buf, err := json.Marshal(poll) - if err != nil { - return err - } - res := p.db.HSet(context.TODO(), "poll", id.String(), buf) - if err := res.Err(); err != nil { - return err - } - return nil -} - -func (p *pollDBImpl) Del(id uuid.UUID) error { - res := p.db.HDel(context.TODO(), "poll", id.String()) - if err := res.Err(); err != nil { - return err - } - return nil -} - -type Poll struct { - Username string `json:"username"` - UserAvatar string `json:"user_avatar"` - Users map[snowflake.ID]bool `json:"users"` - ID uuid.UUID `json:"id"` - MessageID snowflake.ID `json:"message_id"` - GuildId snowflake.ID `json:"guild_id"` - ChannelID snowflake.ID - Title string `json:"title"` - Description string `json:"description"` - EndAt int64 `json:"end_at"` - MaxChoice int `json:"max"` - MinChoice int `json:"min"` - Choices map[uuid.UUID]PollChoice `json:"choices"` - - Locale discord.Locale `json:"locale"` - Settings PollSettings `json:"settings"` - Finished bool `json:"finished"` -} - -type PollChoice struct { - Users map[snowflake.ID]bool `json:"users"` - ID uuid.UUID `json:"id"` - Position int `json:"position"` - Name string `json:"name"` - Description string `json:"description"` - Emoji *discord.ComponentEmoji `json:"emoji"` -} - -func (p *Poll) MessageEmbed() []discord.Embed { - choicesEmbed := discord.Embed{ - Title: translate.Message(p.Locale, "poll_choices_title"), - } - inline := true - choices := []PollChoice{} - for _, pc := range p.Choices { - choices = append(choices, pc) - } - sort.Slice(choices, func(i, j int) bool { - return choices[i].Position < choices[j].Position - }) - for _, pc := range choices { - choicesEmbed.Fields = append(choicesEmbed.Fields, discord.EmbedField{ - Name: fmt.Sprintf("%s | %s", botlib.FormatComponentEmoji(*pc.Emoji), pc.Name), - Value: pc.Description, - Inline: &inline, - }) - } - fields := []discord.EmbedField{ - { - Name: translate.Message(p.Locale, "poll_embed_field_end_at"), - Value: discord.FormattedTimestampMention(p.EndAt, discord.TimestampStyleLongDateTime), - }, - { - Name: translate.Message(p.Locale, "poll_embed_field_number_of_votes"), - Value: fmt.Sprintf("%3s: %2d\r%3s: %2d", - translate.Message(p.Locale, "max"), p.MaxChoice, - translate.Message(p.Locale, "min"), p.MinChoice, - ), - }, - } - fieldEx := []discord.EmbedField{} - if p.Settings.ShowTotalCount { - var count int - for _, pc := range p.Choices { - count += len(pc.Users) - } - fieldEx = append(fieldEx, discord.EmbedField{ - Name: translate.Message(p.Locale, "poll_embed_field_ex_total_votes"), - Value: fmt.Sprintf("%d", len(p.Users)), - }) - } - fields = append(fields, fieldEx...) - - return []discord.Embed{ - { - Title: p.Title, - Description: p.Description, - Author: &discord.EmbedAuthor{ - Name: p.Username, - IconURL: p.UserAvatar, - }, - Fields: fields, - }, - choicesEmbed, - } -} - -func (p *Poll) MessageComponent() []discord.ContainerComponent { - if time.Now().After(time.Unix(p.EndAt, 0)) { - return []discord.ContainerComponent{ - discord.ActionRowComponent{ - discord.ButtonComponent{ - Style: discord.ButtonStyle(discord.ButtonStylePrimary), - CustomID: fmt.Sprintf("handler:poll:seeresult:%s", p.ID), - Label: translate.Message(p.Locale, "poll_component_button_see_result_label"), - }, - }, - } - } else { - return []discord.ContainerComponent{ - discord.ActionRowComponent{ - discord.ButtonComponent{ - Style: discord.ButtonStyle(discord.ButtonStyleSuccess), - CustomID: fmt.Sprintf("handler:poll:vote:%s", p.ID), - Label: translate.Message(p.Locale, "poll_component_button_vote_label"), - }, - discord.ButtonComponent{ - Style: discord.ButtonStyle(discord.ButtonStylePrimary), - CustomID: fmt.Sprintf("handler:poll:seeinfo:%s", p.ID), - Label: translate.Message(p.Locale, "poll_component_button_see_info_label"), - }, - }, - } - } -} - -func (p *Poll) VoteComponent(tokenID uuid.UUID) []discord.ContainerComponent { - var options []discord.StringSelectMenuOption - choices := []PollChoice{} - for _, pc := range p.Choices { - choices = append(choices, pc) - } - sort.Slice(choices, func(i, j int) bool { - return choices[i].Position < choices[j].Position - }) - for i, pc := range choices { - o := discord.StringSelectMenuOption{ - Label: pc.Name, - Description: pc.Description, - Value: pc.ID.String(), - Emoji: pc.Emoji, - } - if o.Emoji == nil { - o.Emoji = &discord.ComponentEmoji{ - Name: botlib.Number2Emoji(i + 1), - } - } - options = append(options, o) - } - return []discord.ContainerComponent{ - discord.ActionRowComponent{ - discord.StringSelectMenuComponent{ - CustomID: fmt.Sprintf("handler:poll:votedo:%s:%s", p.ID, tokenID), - Options: options, - MaxValues: p.MaxChoice, - MinValues: &p.MinChoice, - }, - }, - } -} - -func (p *Poll) SeeInfoComponent(tokenID uuid.UUID) []discord.ContainerComponent { - var options []discord.StringSelectMenuOption - choices := []PollChoice{} - for _, pc := range p.Choices { - choices = append(choices, pc) - } - sort.Slice(choices, func(i, j int) bool { - return choices[i].Position < choices[j].Position - }) - for i, pc := range choices { - o := discord.StringSelectMenuOption{ - Label: pc.Name, - Description: pc.Description, - Value: pc.ID.String(), - Emoji: pc.Emoji, - } - if o.Emoji == nil { - o.Emoji = &discord.ComponentEmoji{ - Name: botlib.Number2Emoji(i + 1), - } - } - options = append(options, o) - } - return []discord.ContainerComponent{ - discord.ActionRowComponent{ - discord.StringSelectMenuComponent{ - CustomID: fmt.Sprintf("handler:poll:seeinfodo:%s:%s", p.ID, tokenID), - Options: options, - }, - }, - } -} - -func (p *Poll) SeeResultComponent(tokenID uuid.UUID) []discord.ContainerComponent { - var options []discord.StringSelectMenuOption - choices := []PollChoice{} - for _, pc := range p.Choices { - choices = append(choices, pc) - } - sort.Slice(choices, func(i, j int) bool { - return choices[i].Position < choices[j].Position - }) - for i, pc := range choices { - o := discord.StringSelectMenuOption{ - Label: pc.Name, - Description: pc.Description, - Value: pc.ID.String(), - Emoji: pc.Emoji, - } - if o.Emoji == nil { - o.Emoji = &discord.ComponentEmoji{ - Name: botlib.Number2Emoji(i + 1), - } - } - options = append(options, o) - } - return []discord.ContainerComponent{ - discord.ActionRowComponent{ - discord.StringSelectMenuComponent{ - CustomID: fmt.Sprintf("handler:poll:seeresultdo:%s:%s", p.ID, tokenID), - Options: options, - }, - }, - } -} diff --git a/bot/db/poll_create.go b/bot/db/poll_create.go deleted file mode 100644 index 8e14527e..00000000 --- a/bot/db/poll_create.go +++ /dev/null @@ -1,545 +0,0 @@ -package db - -import ( - "context" - "encoding/json" - "fmt" - "sort" - "strings" - "time" - - "github.com/disgoorg/snowflake/v2" - "github.com/go-redis/redis/v8" - "github.com/google/uuid" - "github.com/sabafly/disgo/discord" - botlib "github.com/sabafly/sabafly-lib/v2/bot" - "github.com/sabafly/sabafly-lib/v2/translate" -) - -type PollCreateDB interface { - Get(id uuid.UUID) (PollCreate, error) - Set(id uuid.UUID, data PollCreate) error - Del(id uuid.UUID) error -} - -var _ PollCreateDB = (*pollCreateDBImpl)(nil) - -type pollCreateDBImpl struct { - db *redis.Client -} - -func (p *pollCreateDBImpl) Get(id uuid.UUID) (PollCreate, error) { - res := p.db.Get(context.TODO(), "polls"+id.String()) - if err := res.Err(); err != nil { - return PollCreate{}, err - } - buf, err := res.Result() - if err != nil { - return PollCreate{}, err - } - data := PollCreate{} - err = json.Unmarshal([]byte(buf), &data) - if err != nil { - return PollCreate{}, err - } - return data, nil -} - -func (p *pollCreateDBImpl) Set(id uuid.UUID, poll PollCreate) error { - buf, err := json.Marshal(poll) - if err != nil { - return err - } - res := p.db.Set(context.TODO(), "polls"+id.String(), buf, time.Minute*14) - if err := res.Err(); err != nil { - return err - } - return nil -} - -func (p *pollCreateDBImpl) Del(id uuid.UUID) error { - res := p.db.Del(context.TODO(), "polls"+id.String()) - if err := res.Err(); err != nil { - return err - } - return nil -} - -type PollCreate struct { - ID uuid.UUID `json:"id"` - Title string `json:"title"` - Description string `json:"description"` - EndAt int64 `json:"time_limit"` - MaxChoice int `json:"max"` - MinChoice int `json:"min"` - Choices map[uuid.UUID]PollCreateChoice `json:"choices"` - - Locale discord.Locale `json:"locale"` - Settings PollSettings `json:"settings"` -} - -type PollCreateChoice struct { - ID uuid.UUID `json:"id"` - Position int `json:"position"` - Name string `json:"name"` - Description string `json:"description"` - Emoji *discord.ComponentEmoji `json:"emoji"` -} - -type PollSettings struct { - ShowUser PollSettingShowType `json:"show_user"` - ShowCount PollSettingShowType `json:"show_count"` - ShowTotalCount PollSettingsBool `json:"show_total_count"` - ShowUserInResult PollSettingsBool `json:"show_user_in_result"` - CanChangeTarget PollSettingsBool `json:"can_change_target"` -} - -type PollSettingsType int - -const ( - PollSettingsTypeShowUser PollSettingsType = iota + 1 - PollSettingsTypeShowCount - PollSettingsTypeShowTotalCount - PollSettingsTypeShowUserInResult - PollSettingsTypeCanChangeTarget -) - -type PollSettingShowType int - -const ( - PollSettingShowTypeAlways = iota - PollSettingShowTypeNever - PollSettingShowTypeAfterVote -) - -func (p PollSettingShowType) String(locale discord.Locale) string { - var str string - switch p { - case PollSettingShowTypeAlways: - str = translate.Message(locale, "command_text_poll_settings_show_type_always") - case PollSettingShowTypeNever: - str = translate.Message(locale, "command_text_poll_settings_show_type_never") - case PollSettingShowTypeAfterVote: - str = translate.Message(locale, "command_text_poll_settings_show_type_after_vote") - default: - str = "Unknown" - } - return str -} - -type PollSettingsBool bool - -func (p PollSettingsBool) EmojiString() string { - if p { - return "⭕" - } else { - return "❌" - } -} - -func (p *PollCreate) CreatePoll(user discord.User) Poll { - choices := make(map[uuid.UUID]PollChoice) - for k, pcc := range p.Choices { - choices[k] = PollChoice{ - Name: pcc.Name, - Description: pcc.Description, - ID: pcc.ID, - Position: pcc.Position, - Emoji: pcc.Emoji, - Users: make(map[snowflake.ID]bool), - } - } - poll := Poll{ - Username: user.Username, - UserAvatar: *user.AvatarURL(), - Users: make(map[snowflake.ID]bool), - ID: uuid.New(), - Title: p.Title, - Description: p.Description, - EndAt: p.EndAt, - MaxChoice: p.MaxChoice, - MinChoice: p.MinChoice, - Choices: choices, - - Locale: p.Locale, - Settings: p.Settings, - } - return poll -} - -func (v *PollCreate) ConfigEmbed() []discord.Embed { - embeds := []discord.Embed{} - inline := true - embeds = append(embeds, discord.Embed{ - Title: translate.Message(v.Locale, "command_text_poll_create_embed_message_title"), - Fields: []discord.EmbedField{ - { - Name: translate.Message(v.Locale, "command_text_poll_create_embed_field_title"), - Value: fmt.Sprintf("```\r%s```", v.Title), - Inline: &inline, - }, - { - Name: translate.Message(v.Locale, "command_text_poll_create_embed_field_description"), - Value: fmt.Sprintf("```\r%s```", v.Description), - Inline: &inline, - }, - { - Name: translate.Message(v.Locale, "command_text_poll_create_embed_field_time_limit"), - Value: fmt.Sprintf("%s (%s)", discord.FormattedTimestampMention(v.EndAt, discord.TimestampStyleLongDateTime), discord.FormattedTimestampMention(v.EndAt, discord.TimestampStyleRelative)), - Inline: &inline, - }, - { - Name: translate.Message(v.Locale, "command_text_poll_create_embed_field_choices"), - Value: fmt.Sprintf("%3s: %2d\r%3s: %2d", - translate.Message(v.Locale, "max"), v.MaxChoice, - translate.Message(v.Locale, "min"), v.MinChoice, - ), - Inline: &inline, - }, - }, - }) - return embeds -} - -func (v *PollCreate) Components() []discord.ContainerComponent { - var options []discord.StringSelectMenuOption - var disabled bool - switch { - case len(v.Choices) == 0: - disabled = true - options = []discord.StringSelectMenuOption{ - { - Label: "if you can see this, it would be a bug!", - Value: "dummy", - }, - } - case len(v.Choices) > 0: - disabled = false - choices := []PollCreateChoice{} - for _, pc := range v.Choices { - choices = append(choices, pc) - } - sort.Slice(choices, func(i, j int) bool { - return choices[i].Position < choices[j].Position - }) - for i, pc := range choices { - o := discord.StringSelectMenuOption{ - Label: pc.Name, - Description: pc.Description, - Value: pc.ID.String(), - Emoji: pc.Emoji, - } - if o.Emoji == nil { - o.Emoji = &discord.ComponentEmoji{ - Name: botlib.Number2Emoji(i + 1), - } - } - options = append(options, o) - } - } - choicesSelectMenu := discord.StringSelectMenuComponent{ - CustomID: fmt.Sprintf("handler:poll:editchoice:%s", v.ID.String()), - Disabled: disabled, - Placeholder: translate.Message(v.Locale, "command_text_poll_create_embed_component_edit_choice_placeholder"), - MaxValues: 1, - Options: options, - } - var addDisabled bool - if len(v.Choices) >= 25 { - addDisabled = true - } - return []discord.ContainerComponent{ - discord.ActionRowComponent{ - choicesSelectMenu, - }, - discord.ActionRowComponent{ - discord.ButtonComponent{ - Style: discord.ButtonStyle(discord.ButtonStyleSecondary), - CustomID: fmt.Sprintf("handler:poll:addchoice:%s", v.ID), - Disabled: addDisabled, - Emoji: &discord.ComponentEmoji{ - ID: snowflake.ID(1081653685320433724), - Name: "plus", - }, - }, - discord.ButtonComponent{ - Style: discord.ButtonStyle(discord.ButtonStylePrimary), - CustomID: fmt.Sprintf("handler:poll:changepollinfo:%s", v.ID.String()), - Emoji: &discord.ComponentEmoji{ - ID: snowflake.ID(1082025248330891388), - Name: "modify", - }, - }, - discord.ButtonComponent{ - Style: discord.ButtonStyle(discord.ButtonStylePrimary), - CustomID: fmt.Sprintf("handler:poll:editsettings:%s", v.ID.String()), - Emoji: &discord.ComponentEmoji{ - ID: snowflake.ID(1083053845632000010), - Name: "setting", - }, - }, - discord.ButtonComponent{ - Style: discord.ButtonStyle(discord.ButtonStyleSuccess), - CustomID: fmt.Sprintf("handler:poll:create:%s", v.ID.String()), - Disabled: disabled, - Emoji: &discord.ComponentEmoji{ - Name: "🛠", - }, - }, - }, - } -} - -func (p *PollCreate) EditChoiceEmbed(choiceID uuid.UUID) []discord.Embed { - inline := true - return []discord.Embed{ - { - Title: translate.Message(p.Locale, "command_text_poll_create_embed_component_edit_choice_response_message_title"), - Fields: []discord.EmbedField{ - { - Name: translate.Message(p.Locale, "command_text_poll_create_modal_add_choice_component_name_label"), - Value: fmt.Sprintf("```\r%s```", p.Choices[choiceID].Name), - Inline: &inline, - }, - { - Name: translate.Message(p.Locale, "command_text_poll_create_modal_add_choice_component_description_label"), - Value: fmt.Sprintf("```\r%s```", p.Choices[choiceID].Description), - Inline: &inline, - }, - { - Name: translate.Message(p.Locale, "command_text_poll_create_embed_component_edit_choice_response_field_emoji_name"), - Value: botlib.FormatComponentEmoji(*p.Choices[choiceID].Emoji), - }, - }, - }, - } -} - -func (p *PollCreate) EditChoiceComponent(choiceID uuid.UUID) []discord.ContainerComponent { - return []discord.ContainerComponent{ - discord.ActionRowComponent{ - discord.ButtonComponent{ - Style: discord.ButtonStyle(discord.ButtonStyleSecondary), - CustomID: fmt.Sprintf("handler:poll:backmenu:%s", p.ID.String()), - Emoji: &discord.ComponentEmoji{ - ID: snowflake.ID(1081932944739938414), - Name: "left", - }, - }, - discord.ButtonComponent{ - Style: discord.ButtonStyle(discord.ButtonStylePrimary), - CustomID: fmt.Sprintf("handler:poll:changechoiceinfo:%s:%s", strings.ReplaceAll(p.ID.String(), "-", ""), strings.ReplaceAll(choiceID.String(), "-", "")), - Emoji: &discord.ComponentEmoji{ - ID: snowflake.ID(1082025248330891388), - Name: "modify", - }, - }, - discord.ButtonComponent{ - Style: discord.ButtonStyle(discord.ButtonStylePrimary), - CustomID: fmt.Sprintf("handler:poll:changechoiceemoji:%s:%s", strings.ReplaceAll(p.ID.String(), "-", ""), strings.ReplaceAll(choiceID.String(), "-", "")), - Emoji: &discord.ComponentEmoji{ - ID: snowflake.ID(1082267519374589992), - Name: "smile", - }, - }, - discord.ButtonComponent{ - Style: discord.ButtonStyle(discord.ButtonStyleDanger), - CustomID: fmt.Sprintf("handler:poll:deletechoice:%s:%s", strings.ReplaceAll(p.ID.String(), "-", ""), strings.ReplaceAll(choiceID.String(), "-", "")), - Emoji: &discord.ComponentEmoji{ - ID: snowflake.ID(1081940223547678757), - Name: "trash", - }, - }, - }, - } -} - -func (p *PollCreate) EditSettingsEmbed() []discord.Embed { - return []discord.Embed{ - { - Title: translate.Message(p.Locale, "command_text_poll_create_embed_component_edit_settings_response_message_title"), - Fields: []discord.EmbedField{ - { - Name: translate.Message(p.Locale, "command_text_poll_settings_type_show_user"), - Value: p.Settings.ShowUser.String(p.Locale), - }, - { - Name: translate.Message(p.Locale, "command_text_poll_settings_type_show_count"), - Value: p.Settings.ShowCount.String(p.Locale), - }, - { - Name: translate.Message(p.Locale, "command_text_poll_settings_type_show_total_count"), - Value: p.Settings.ShowTotalCount.EmojiString(), - }, - { - Name: translate.Message(p.Locale, "command_text_poll_settings_type_show_user_in_result"), - Value: p.Settings.ShowUserInResult.EmojiString(), - }, - { - Name: translate.Message(p.Locale, "command_text_poll_settings_type_can_change_target"), - Value: p.Settings.CanChangeTarget.EmojiString(), - }, - }, - }, - } -} - -func (p *PollCreate) EditSettingsComponent() []discord.ContainerComponent { - return []discord.ContainerComponent{ - discord.ActionRowComponent{ - discord.ButtonComponent{ - Style: discord.ButtonStyle(discord.ButtonStyleSecondary), - CustomID: fmt.Sprintf("handler:poll:backmenu:%s", p.ID), - Emoji: &discord.ComponentEmoji{ - ID: snowflake.ID(1081932944739938414), - Name: "left", - }, - }, - }, - discord.ActionRowComponent{ - discord.StringSelectMenuComponent{ - CustomID: fmt.Sprintf("handler:poll:changesettingsmenu:%s", p.ID), - Placeholder: translate.Message(p.Locale, "command_text_poll_create_embed_component_edit_settings_response_select_menu_placeholder"), - Options: []discord.StringSelectMenuOption{ - { - Label: translate.Message(p.Locale, "command_text_poll_settings_type_show_user"), - Value: "1", - Emoji: &discord.ComponentEmoji{ - Name: "1⃣", - }, - }, - { - Label: translate.Message(p.Locale, "command_text_poll_settings_type_show_count"), - Value: "2", - Emoji: &discord.ComponentEmoji{ - Name: "2⃣", - }, - }, - { - Label: translate.Message(p.Locale, "command_text_poll_settings_type_show_total_count"), - Value: "3", - Emoji: &discord.ComponentEmoji{ - Name: "3⃣", - }, - }, - { - Label: translate.Message(p.Locale, "command_text_poll_settings_type_show_user_in_result"), - Value: "4", - Emoji: &discord.ComponentEmoji{ - Name: "4⃣", - }, - }, - { - Label: translate.Message(p.Locale, "command_text_poll_settings_type_can_change_target"), - Value: "5", - Emoji: &discord.ComponentEmoji{ - Name: "5⃣", - }, - }, - }, - }, - }, - } -} - -func (p *PollCreate) ChangeSettingsMenuComponent(t PollSettingsType) []discord.ContainerComponent { - resAction := discord.ActionRowComponent{} - switch t { - case PollSettingsTypeShowUser: - resAction = discord.ActionRowComponent{ - discord.ButtonComponent{ - Style: discord.ButtonStyle(discord.ButtonStyleSuccess), - CustomID: fmt.Sprintf("handler:poll:changesettings:%s:showuser:0", p.ID), - Label: translate.Message(p.Locale, "command_text_poll_settings_show_type_always"), - }, - discord.ButtonComponent{ - Style: discord.ButtonStyle(discord.ButtonStyleDanger), - CustomID: fmt.Sprintf("handler:poll:changesettings:%s:showuser:1", p.ID), - Label: translate.Message(p.Locale, "command_text_poll_settings_show_type_never"), - }, - discord.ButtonComponent{ - Style: discord.ButtonStyle(discord.ButtonStylePrimary), - CustomID: fmt.Sprintf("handler:poll:changesettings:%s:showuser:2", p.ID), - Label: translate.Message(p.Locale, "command_text_poll_settings_show_type_after_vote"), - }, - } - case PollSettingsTypeShowCount: - resAction = discord.ActionRowComponent{ - discord.ButtonComponent{ - Style: discord.ButtonStyle(discord.ButtonStyleSuccess), - CustomID: fmt.Sprintf("handler:poll:changesettings:%s:showcount:0", p.ID), - Label: translate.Message(p.Locale, "command_text_poll_settings_show_type_always"), - }, - discord.ButtonComponent{ - Style: discord.ButtonStyle(discord.ButtonStyleDanger), - CustomID: fmt.Sprintf("handler:poll:changesettings:%s:showcount:1", p.ID), - Label: translate.Message(p.Locale, "command_text_poll_settings_show_type_never"), - }, - discord.ButtonComponent{ - Style: discord.ButtonStyle(discord.ButtonStylePrimary), - CustomID: fmt.Sprintf("handler:poll:changesettings:%s:showcount:2", p.ID), - Label: translate.Message(p.Locale, "command_text_poll_settings_show_type_after_vote"), - }, - } - case PollSettingsTypeShowTotalCount: - resAction = discord.ActionRowComponent{ - discord.ButtonComponent{ - Style: discord.ButtonStyle(discord.ButtonStyleSuccess), - CustomID: fmt.Sprintf("handler:poll:changesettings:%s:showtotalcount:true", p.ID), - Emoji: &discord.ComponentEmoji{ - ID: snowflake.ID(1082691057931788368), - Name: "o_", - }, - }, - discord.ButtonComponent{ - Style: discord.ButtonStyle(discord.ButtonStyleDanger), - CustomID: fmt.Sprintf("handler:poll:changesettings:%s:showtotalcount:false", p.ID), - Emoji: &discord.ComponentEmoji{ - ID: snowflake.ID(1082689149557014549), - Name: "x_", - }, - }, - } - case PollSettingsTypeShowUserInResult: - resAction = discord.ActionRowComponent{ - discord.ButtonComponent{ - Style: discord.ButtonStyle(discord.ButtonStyleSuccess), - CustomID: fmt.Sprintf("handler:poll:changesettings:%s:showuserinresult:true", p.ID), - Emoji: &discord.ComponentEmoji{ - ID: snowflake.ID(1082691057931788368), - Name: "o_", - }, - }, - discord.ButtonComponent{ - Style: discord.ButtonStyle(discord.ButtonStyleDanger), - CustomID: fmt.Sprintf("handler:poll:changesettings:%s:showuserinresult:false", p.ID), - Emoji: &discord.ComponentEmoji{ - ID: snowflake.ID(1082689149557014549), - Name: "x_", - }, - }, - } - case PollSettingsTypeCanChangeTarget: - resAction = discord.ActionRowComponent{ - discord.ButtonComponent{ - Style: discord.ButtonStyle(discord.ButtonStyleSuccess), - CustomID: fmt.Sprintf("handler:poll:changesettings:%s:canchangetarget:true", p.ID), - Emoji: &discord.ComponentEmoji{ - ID: snowflake.ID(1082691057931788368), - Name: "o_", - }, - }, - discord.ButtonComponent{ - Style: discord.ButtonStyle(discord.ButtonStyleDanger), - CustomID: fmt.Sprintf("handler:poll:changesettings:%s:canchangetarget:false", p.ID), - Emoji: &discord.ComponentEmoji{ - ID: snowflake.ID(1082689149557014549), - Name: "x_", - }, - }, - } - } - res := p.EditSettingsComponent() - res = append(res, resAction) - return res -} diff --git a/bot/db/role_panel.go b/bot/db/role_panel.go deleted file mode 100644 index 5f84c424..00000000 --- a/bot/db/role_panel.go +++ /dev/null @@ -1,198 +0,0 @@ -package db - -import ( - "context" - "encoding/json" - "fmt" - "sort" - - "github.com/disgoorg/snowflake/v2" - "github.com/go-redis/redis/v8" - "github.com/google/uuid" - "github.com/sabafly/disgo/discord" - botlib "github.com/sabafly/sabafly-lib/v2/bot" - "github.com/sabafly/sabafly-lib/v2/translate" -) - -type RolePanelDB interface { - Get(uuid.UUID) (RolePanel, error) - Set(RolePanel) error - Del(uuid.UUID) error -} - -var _ RolePanelDB = (*rolePanelDBImpl)(nil) - -type rolePanelDBImpl struct { - db *redis.Client -} - -func (r *rolePanelDBImpl) Get(id uuid.UUID) (RolePanel, error) { - res := r.db.HGet(context.TODO(), "rolepanel", id.String()) - if err := res.Err(); err != nil { - return RolePanel{}, err - } - data := RolePanel{} - if err := json.Unmarshal([]byte(res.Val()), &data); err != nil { - return RolePanel{}, err - } - return data, nil -} - -func (r *rolePanelDBImpl) Set(data RolePanel) error { - buf, err := json.Marshal(data) - if err != nil { - return err - } - res := r.db.HSet(context.TODO(), "rolepanel", data.id.String(), buf) - if err := res.Err(); err != nil { - return err - } - return nil -} - -func (r *rolePanelDBImpl) Del(id uuid.UUID) error { - res := r.db.HDel(context.TODO(), "rolepanel", id.String()) - if err := res.Err(); err != nil { - return err - } - return nil -} - -func NewRolePanel(panel RolePanelCreate) RolePanel { - return RolePanel{ - RolePanelCreate: &panel, - } -} - -type RolePanel struct { - *RolePanelCreate `json:"role_data"` - ChannelID snowflake.ID `json:"channel_id"` - MessageID snowflake.ID `json:"message_id"` - GuildID snowflake.ID `json:"guild_id"` -} - -func (r RolePanel) MarshalJSON() ([]byte, error) { - return json.Marshal(&struct { - RoleData RolePanelCreate `json:"role_data"` - ChannelID snowflake.ID `json:"channel_id"` - MessageID snowflake.ID `json:"message_id"` - GuildID snowflake.ID `json:"guild_id"` - }{ - RoleData: *r.RolePanelCreate, - ChannelID: r.ChannelID, - MessageID: r.MessageID, - GuildID: r.GuildID, - }) -} - -func (r *RolePanel) UnmarshalJSON(data []byte) error { - aux := &struct { - RoleData *RolePanelCreate `json:"role_data"` - ChannelID snowflake.ID `json:"channel_id"` - MessageID snowflake.ID `json:"message_id"` - GuildID snowflake.ID `json:"guild_id"` - }{} - if err := json.Unmarshal(data, &aux); err != nil { - return err - } - *r = RolePanel{ - RolePanelCreate: aux.RoleData, - ChannelID: aux.ChannelID, - MessageID: aux.MessageID, - GuildID: aux.GuildID, - } - return nil -} - -func (r *RolePanel) BuildMessage(format func([]discord.Embed) []discord.Embed) discord.MessageCreate { - fields := []discord.EmbedField{} - roles := []RolePanelCreateRole{} - for _, rpcr := range r.roles { - roles = append(roles, rpcr) - } - sort.Slice(roles, func(i, j int) bool { - return roles[i].Position() < roles[j].Position() - }) - for _, v := range roles { - fields = append(fields, discord.EmbedField{ - Name: fmt.Sprintf("%s:%s", botlib.FormatComponentEmoji(v.Emoji), v.Label), - Value: v.Description, - }) - } - embeds := []discord.Embed{ - { - Footer: &discord.EmbedFooter{ - Text: fmt.Sprintf("%s %s", botlib.BotName, translate.Message(r.locale, "role_panel")), - }, - Title: r.Name, - Description: r.Description, - Fields: fields, - }, - } - embeds = format(embeds) - components := []discord.ContainerComponent{ - discord.ActionRowComponent{ - discord.ButtonComponent{ - CustomID: fmt.Sprintf("handler:rolepanel:use:%s", r.UUID().String()), - Style: discord.ButtonStyle(discord.ButtonStyleSuccess), - Label: translate.Message(r.locale, "command_text_role_panel_create_build_message_component_button_use_label"), - }, - }, - } - return discord.MessageCreate{ - Embeds: embeds, - Components: components, - } -} - -func (r *RolePanel) UseMessage(format func([]discord.Embed) []discord.Embed, member discord.Member) discord.MessageCreate { - options := []discord.StringSelectMenuOption{} - roles := []RolePanelCreateRole{} - for _, rpcr := range r.roles { - roles = append(roles, rpcr) - } - sort.Slice(roles, func(i, j int) bool { - return roles[i].Position() < roles[j].Position() - }) - mRoles := map[snowflake.ID]bool{} - for _, i2 := range member.RoleIDs { - mRoles[i2] = true - } - for _, v := range roles { - emoji := v.Emoji - options = append(options, discord.StringSelectMenuOption{ - Label: v.Label, - Description: v.Description, - Value: v.RoleID.String(), - Emoji: &emoji, - Default: mRoles[v.RoleID], - }) - } - embeds := []discord.Embed{ - { - Title: translate.Message(r.locale, "command_text_role_panel_use_embed_title"), - Description: translate.Message(r.locale, "command_text_role_panel_use_embed_description"), - }, - } - embeds = format(embeds) - components := []discord.ContainerComponent{ - discord.ActionRowComponent{ - discord.StringSelectMenuComponent{ - CustomID: fmt.Sprintf("handler:rolepanel:getrole:%s", r.UUID().String()), - MaxValues: func() int { - if r.Max > len(options) { - return len(options) - } - return r.Max - }(), - MinValues: &r.Min, - Options: options, - }, - }, - } - return discord.MessageCreate{ - Flags: discord.MessageFlagEphemeral, - Embeds: embeds, - Components: components, - } -} diff --git a/bot/db/role_panel_create.go b/bot/db/role_panel_create.go deleted file mode 100644 index c42835bc..00000000 --- a/bot/db/role_panel_create.go +++ /dev/null @@ -1,488 +0,0 @@ -package db - -import ( - "context" - "encoding/json" - "fmt" - "sort" - "time" - - "github.com/disgoorg/snowflake/v2" - "github.com/go-redis/redis/v8" - "github.com/google/uuid" - "github.com/sabafly/disgo/discord" - botlib "github.com/sabafly/sabafly-lib/v2/bot" - "github.com/sabafly/sabafly-lib/v2/translate" -) - -type RolePanelCreateDB interface { - Get(uuid.UUID) (RolePanelCreate, error) - Set(RolePanelCreate) error - Del(uuid.UUID) error -} - -var _ RolePanelCreateDB = (*rolePanelCreateDBImpl)(nil) - -type rolePanelCreateDBImpl struct { - db *redis.Client -} - -func (r *rolePanelCreateDBImpl) Get(id uuid.UUID) (RolePanelCreate, error) { - res := r.db.Get(context.TODO(), "rolepanelcreate"+id.String()) - if err := res.Err(); err != nil { - return RolePanelCreate{}, err - } - data := RolePanelCreate{} - if err := json.Unmarshal([]byte(res.Val()), &data); err != nil { - return RolePanelCreate{}, err - } - return data, nil -} - -func (r *rolePanelCreateDBImpl) Set(data RolePanelCreate) error { - buf, err := json.Marshal(data) - if err != nil { - return err - } - res := r.db.Set(context.TODO(), "rolepanelcreate"+data.id.String(), buf, time.Minute*14) - if err := res.Err(); err != nil { - return err - } - return nil -} - -func (r *rolePanelCreateDBImpl) Del(id uuid.UUID) error { - res := r.db.Del(context.TODO(), "rolepanelcreate"+id.String()) - if err := res.Err(); err != nil { - return err - } - return nil -} - -func NewRolePanelCreate(name, description string, locale discord.Locale) RolePanelCreate { - return RolePanelCreate{ - id: uuid.New(), - Name: name, - Description: description, - roles: make(map[snowflake.ID]RolePanelCreateRole), - Max: 25, - Min: 0, - locale: locale, - } -} - -type RolePanelCreate struct { - id uuid.UUID - Name string - Description string - roles map[snowflake.ID]RolePanelCreateRole - Max int - Min int - locale discord.Locale -} - -func (r RolePanelCreate) MarshalJSON() ([]byte, error) { - v, err := json.Marshal(&struct { - ID uuid.UUID `json:"id"` - Name string `json:"name"` - Description string `json:"description"` - Roles map[snowflake.ID]RolePanelCreateRole `json:"roles"` - Max int `json:"max"` - Min int `json:"min"` - Locale discord.Locale `json:"locale"` - }{ - ID: r.id, - Name: r.Name, - Description: r.Description, - Roles: r.roles, - Max: r.Max, - Min: r.Min, - Locale: r.locale, - }) - return v, err -} - -func (r *RolePanelCreate) UnmarshalJSON(b []byte) error { - r2 := &struct { - ID uuid.UUID `json:"id"` - Name string `json:"name"` - Description string `json:"description"` - Roles map[snowflake.ID]RolePanelCreateRole `json:"roles"` - Max int `json:"max"` - Min int `json:"min"` - Locale discord.Locale `json:"locale"` - }{} - - err := json.Unmarshal(b, r2) - if err != nil { - return err - } - - r.id = r2.ID - r.Name = r2.Name - r.Description = r2.Description - r.roles = r2.Roles - r.Max = r2.Max - r.Min = r2.Min - r.locale = r2.Locale - - return err -} - -func (r *RolePanelCreate) selectMenuComponent(id string, min, max int) discord.StringSelectMenuComponent { - options := []discord.StringSelectMenuOption{} - roles := []RolePanelCreateRole{} - for _, rpcr := range r.roles { - roles = append(roles, rpcr) - } - sort.Slice(roles, func(i, j int) bool { - return roles[i].Position() < roles[j].Position() - }) - for i, rpcr := range roles { - emoji := rpcr.Emoji - options = append(options, discord.StringSelectMenuOption{ - Label: rpcr.Label, - Description: rpcr.Description, - Emoji: &emoji, - Value: rpcr.RoleID.String(), - }) - - rpcr.position = i + 1 - r.roles[rpcr.RoleID] = rpcr - } - disabled := false - if len(options) < 1 { - disabled = true - options = append(options, discord.StringSelectMenuOption{ - Label: "dummy", - Value: "dummy", - }) - } - return discord.StringSelectMenuComponent{ - CustomID: id, - MinValues: &min, - MaxValues: max, - Options: options, - Disabled: disabled, - } -} - -func (r RolePanelCreate) BaseMenuEmbed() []discord.Embed { - inline := true - return []discord.Embed{ - { - Title: translate.Message(r.locale, "command_text_role_panel_create_base_menu_embed_title"), - Fields: []discord.EmbedField{ - { - Name: translate.Message(r.locale, "command_text_role_panel_create_base_menu_embed_field_name_name"), - Value: fmt.Sprintf("```\r%s```", r.Name), - Inline: &inline, - }, - { - Name: translate.Message(r.locale, "command_text_role_panel_create_base_menu_embed_field_description_name"), - Value: fmt.Sprintf("```\r%s```", r.Description), - Inline: &inline, - }, - }, - }, - } -} - -func (r RolePanelCreate) BaseMenuComponent() []discord.ContainerComponent { - return []discord.ContainerComponent{ - discord.ActionRowComponent{ - r.selectMenuComponent(fmt.Sprintf("handler:rolepanel:editrole:%s", r.id.String()), 1, 1), - }, - discord.ActionRowComponent{ - discord.ButtonComponent{ - Style: discord.ButtonStyle(discord.ButtonStyleDanger), - CustomID: fmt.Sprintf("handler:rolepanel:addrole:%s", r.id), - Emoji: &discord.ComponentEmoji{ - ID: snowflake.ID(1081653685320433724), - Name: "plus", - }, - }, - discord.ButtonComponent{ - Style: discord.ButtonStyle(discord.ButtonStylePrimary), - CustomID: fmt.Sprintf("handler:rolepanel:editpanelinfo:%s", r.id.String()), - Emoji: &discord.ComponentEmoji{ - ID: snowflake.ID(1082025248330891388), - Name: "modify", - }, - }, - discord.ButtonComponent{ - Style: discord.ButtonStyle(discord.ButtonStylePrimary), - CustomID: fmt.Sprintf("handler:rolepanel:editpanelsettings:%s", r.id.String()), - Emoji: &discord.ComponentEmoji{ - ID: snowflake.ID(1083053845632000010), - Name: "setting", - }, - }, - discord.ButtonComponent{ - Style: discord.ButtonStyle(discord.ButtonStyleSuccess), - CustomID: fmt.Sprintf("handler:rolepanel:create:%s", r.id.String()), - Emoji: &discord.ComponentEmoji{ - Name: "🛠", - }, - Disabled: len(r.roles) < 1, - }, - }, - } -} - -func (r *RolePanelCreate) EditRoleMenuEmbed(id snowflake.ID) []discord.Embed { - inline := true - return []discord.Embed{ - { - Title: translate.Message(r.locale, "command_text_role_panel_create_edit_role_menu_embed_title"), - Fields: []discord.EmbedField{ - { - Name: translate.Message(r.locale, "command_text_role_panel_create_edit_role_menu_embed_fields_role"), - Value: discord.RoleMention(r.roles[id].RoleID), - Inline: &inline, - }, - { - Name: translate.Message(r.locale, "command_text_role_panel_create_edit_role_menu_embed_fields_display_name"), - Value: fmt.Sprintf("```\r%s```", r.roles[id].Label), - Inline: &inline, - }, - { - Name: translate.Message(r.locale, "command_text_role_panel_create_edit_role_menu_embed_fields_description"), - Value: fmt.Sprintf("```\r%s```", r.roles[id].Description), - Inline: &inline, - }, - { - Name: translate.Message(r.locale, "command_text_role_panel_create_edit_role_menu_embed_fields_emoji"), - Value: botlib.FormatComponentEmoji(r.roles[id].Emoji), - Inline: &inline, - }, - }, - }, - } -} - -func (r *RolePanelCreate) EditRoleMenuComponent(id snowflake.ID) discord.ContainerComponent { - return discord.ActionRowComponent{ - r.BackMainMenuButton(), - discord.ButtonComponent{ - Style: discord.ButtonStyle(discord.ButtonStylePrimary), - CustomID: fmt.Sprintf("handler:rolepanel:editroleinfo:%s:%d", r.id.String(), id), - Emoji: &discord.ComponentEmoji{ - ID: snowflake.ID(1082025248330891388), - Name: "modify", - }, - }, - discord.ButtonComponent{ - Style: discord.ButtonStyle(discord.ButtonStylePrimary), - CustomID: fmt.Sprintf("handler:rolepanel:editroleemoji:%s:%d", r.id.String(), id), - Emoji: &discord.ComponentEmoji{ - ID: snowflake.ID(1082267519374589992), - Name: "smile", - }, - }, - discord.ButtonComponent{ - Style: discord.ButtonStyle(discord.ButtonStyleDanger), - CustomID: fmt.Sprintf("handler:rolepanel:editdeleterole:%s:%d", r.id.String(), id), - Emoji: &discord.ComponentEmoji{ - ID: snowflake.ID(1081940223547678757), - Name: "trash", - }, - }, - } -} - -func (r *RolePanelCreate) AddRoleMenuEmbed() []discord.Embed { - return []discord.Embed{ - { - Title: translate.Message(r.locale, "command_text_role_panel_create_add_role_menu_embed_title"), - Description: translate.Message(r.locale, "command_text_role_panel_create_add_role_menu_embed_description"), - }, - } -} - -func (r *RolePanelCreate) AddRoleMenuComponent() []discord.ContainerComponent { - min := 1 - max := 25 - return []discord.ContainerComponent{ - discord.ActionRowComponent{ - discord.RoleSelectMenuComponent{ - CustomID: fmt.Sprintf("handler:rolepanel:addroleselectmenu:%s", r.id.String()), - MinValues: &min, - MaxValues: max, - }, - }, - discord.ActionRowComponent{ - r.BackMainMenuButton(), - }, - } -} - -func (r *RolePanelCreate) EditPanelSettingsEmbed() []discord.Embed { - return []discord.Embed{ - { - Title: translate.Message(r.locale, "command_text_role_panel_create_edit_panel_config_title"), - Fields: []discord.EmbedField{ - { - Name: translate.Message(r.locale, "command_text_role_panel_create_edit_panel_config_fields_max_name"), - Value: fmt.Sprintf("%d %s", r.Max, translate.Message(r.locale, "role", translate.WithPluralCount(r.Max), translate.WithFallback("role"))), - }, - { - Name: translate.Message(r.locale, "command_text_role_panel_create_edit_panel_config_fields_min_name"), - Value: fmt.Sprintf("%d %s", r.Min, translate.Message(r.locale, "role", translate.WithPluralCount(r.Min), translate.WithFallback("role"))), - }, - }, - }, - } -} - -func (r *RolePanelCreate) EditPanelSettingsComponent() []discord.ContainerComponent { - return []discord.ContainerComponent{ - discord.ActionRowComponent{ - discord.StringSelectMenuComponent{ - CustomID: fmt.Sprintf("handler:rolepanel:changesettings:%s", r.id.String()), - Options: []discord.StringSelectMenuOption{ - { - Label: translate.Message(r.locale, "command_text_role_panel_create_edit_panel_config_fields_max_name"), - Value: "max", - Emoji: &discord.ComponentEmoji{ - Name: "1⃣", - }, - }, - { - Label: translate.Message(r.locale, "command_text_role_panel_create_edit_panel_config_fields_min_name"), - Value: "min", - Emoji: &discord.ComponentEmoji{ - Name: "2⃣", - }, - }, - }, - }, - }, - discord.ActionRowComponent{ - r.BackMainMenuButton(), - }, - } -} - -func (r *RolePanelCreate) UUID() uuid.UUID { - return r.id -} - -func (r *RolePanelCreate) DeleteRole(id snowflake.ID) { - delete(r.roles, id) -} - -func (r RolePanelCreate) GetRole(id snowflake.ID) (RolePanelCreateRole, bool) { - role, ok := r.roles[id] - return role, ok -} - -func (r RolePanelCreate) GetRoles() map[snowflake.ID]RolePanelCreateRole { - return r.roles -} - -func (r *RolePanelCreate) SetRole(label, description string, roleID snowflake.ID, emoji *discord.ComponentEmoji) { - if v, ok := r.roles[roleID]; ok { - if emoji == nil { - emoji = &discord.ComponentEmoji{ - Name: botlib.Number2Emoji(v.position), - } - } - v.Label = label - v.Description = description - v.RoleID = roleID - v.Emoji = *emoji - r.roles[roleID] = v - } else { - if len(r.roles) >= 25 { - panic("cannot add roles more than 25") - } - if emoji == nil { - emoji = &discord.ComponentEmoji{ - Name: botlib.Number2Emoji(len(r.roles) + 1), - } - } - r.roles[roleID] = RolePanelCreateRole{ - position: len(r.roles) + 1, - Label: label, - Description: description, - RoleID: roleID, - Emoji: *emoji, - } - } -} - -func (r *RolePanelCreate) Validate() { - if r.Max <= 0 { - r.Max = 1 - } - if r.Max > 25 { - r.Max = 25 - } - if r.Min < 0 { - r.Min = 0 - } - if r.Min > r.Max { - r.Min = r.Max - } -} - -func (r RolePanelCreate) BackMainMenuButton() discord.ButtonComponent { - return discord.ButtonComponent{ - Style: discord.ButtonStyle(discord.ButtonStyleSecondary), - CustomID: fmt.Sprintf("handler:rolepanel:backmainmenu:%s", r.id.String()), - Emoji: &discord.ComponentEmoji{ - ID: snowflake.ID(1081932944739938414), - Name: "left", - }, - } -} - -type RolePanelCreateRole struct { - position int - Label string - Description string - RoleID snowflake.ID - Emoji discord.ComponentEmoji -} - -func (r RolePanelCreateRole) MarshalJSON() ([]byte, error) { - v, err := json.Marshal(&struct { - Position int `json:"position"` - Label string `json:"label"` - Description string `json:"description"` - RoleID snowflake.ID `json:"role_id"` - Emoji discord.ComponentEmoji `json:"emoji"` - }{ - Position: r.position, - Label: r.Label, - Description: r.Description, - RoleID: r.RoleID, - Emoji: r.Emoji, - }) - return v, err -} - -func (r *RolePanelCreateRole) UnmarshalJSON(b []byte) error { - r2 := &struct { - Position int `json:"position"` - Label string `json:"label"` - Description string `json:"description"` - RoleID snowflake.ID `json:"role_id"` - Emoji discord.ComponentEmoji `json:"emoji"` - }{} - err := json.Unmarshal(b, r2) - if err != nil { - return err - } - r.position = r2.Position - r.Label = r2.Label - r.Description = r2.Description - r.RoleID = r2.RoleID - r.Emoji = r2.Emoji - return nil -} - -func (r RolePanelCreateRole) Position() int { - return r.position -} diff --git a/bot/db/role_panel_v2.go b/bot/db/role_panel_v2.go deleted file mode 100644 index 637bbdef..00000000 --- a/bot/db/role_panel_v2.go +++ /dev/null @@ -1,470 +0,0 @@ -package db - -import ( - "context" - "fmt" - "slices" - - "github.com/disgoorg/json" - "github.com/disgoorg/snowflake/v2" - "github.com/go-redis/redis/v8" - "github.com/google/uuid" - "github.com/sabafly/disgo/discord" - botlib "github.com/sabafly/sabafly-lib/v2/bot" - "github.com/sabafly/sabafly-lib/v2/translate" -) - -type RolePanelV2DB interface { - Get(id uuid.UUID) (*RolePanelV2, error) - Set(id uuid.UUID, data *RolePanelV2) error - Del(id uuid.UUID) error -} - -type rolePanelV2DBImpl struct { - db *redis.Client -} - -func (r *rolePanelV2DBImpl) Get(id uuid.UUID) (*RolePanelV2, error) { - res := r.db.HGet(context.TODO(), "role-panel-v2", id.String()) - if err := res.Err(); err != nil { - return nil, err - } - data := &RolePanelV2{} - if err := json.Unmarshal([]byte(res.Val()), data); err != nil { - return nil, err - } - return data, nil -} - -func (r *rolePanelV2DBImpl) Set(id uuid.UUID, data *RolePanelV2) error { - buf, err := json.Marshal(data) - if err != nil { - return err - } - res := r.db.HSet(context.TODO(), "role-panel-v2", id.String(), buf) - if err := res.Err(); err != nil { - return err - } - return nil -} - -func (r *rolePanelV2DBImpl) Del(id uuid.UUID) error { - res := r.db.HDel(context.TODO(), "role-panel-v2", id.String()) - if err := res.Err(); err != nil { - return err - } - return nil -} - -func NewRolePanelV2(name, description string) *RolePanelV2 { - return &RolePanelV2{ - ID: uuid.New(), - Name: name, - Description: description, - Roles: []RolePanelV2Role{}, - } -} - -type RolePanelV2 struct { - ID uuid.UUID `json:"uuid"` - Name string `json:"name"` - Description string `json:"description"` - Roles []RolePanelV2Role `json:"roles"` -} - -func (r *RolePanelV2) AddRole(id snowflake.ID, name string, emoji *discord.ComponentEmoji) bool { - if slices.IndexFunc(r.Roles, func(rpvr RolePanelV2Role) bool { - return rpvr.RoleID == id - }) != -1 { - return false - } - if emoji == nil { - emoji = &discord.ComponentEmoji{ - Name: botlib.Number2Emoji(len(r.Roles) + 1), - } - } - r.Roles = append(r.Roles, RolePanelV2Role{ - RoleID: id, - RoleName: name, - Emoji: emoji, - }) - return true -} - -type rolePanelV2MessageBuilder[T any] interface { - AddEmbeds(...discord.Embed) T - AddContainerComponents(...discord.ContainerComponent) T -} - -func NewRolePanelV2Config() RolePanelV2Config { - return RolePanelV2Config{ - PanelType: RolePanelV2TypeNone, - ButtonStyle: discord.ButtonStyleSuccess, - ButtonShowName: false, - SimpleSelectMenu: true, - } -} - -type RolePanelV2Config struct { - PanelType RolePanelV2Type `json:"panel_type"` - ButtonStyle discord.ButtonStyle `json:"button_style"` - ButtonShowName bool `json:"show_name"` - SimpleSelectMenu bool `json:"simple_select_menu"` -} - -func RolePanelV2MessageReaction[T rolePanelV2MessageBuilder[T]](r *RolePanelV2, locale discord.Locale, message T) T { - message.AddEmbeds(r.rolePanelV2Embed(locale)) - return message -} - -func RolePanelV2MessageSelectMenu[T rolePanelV2MessageBuilder[T]](r *RolePanelV2, locale discord.Locale, message T, config RolePanelV2Config) T { - message.AddEmbeds(r.rolePanelV2Embed(locale)) - if config.SimpleSelectMenu { - options := make([]discord.StringSelectMenuOption, len(r.Roles)) - for i, rpvr := range r.Roles { - options[i] = discord.StringSelectMenuOption{ - Label: rpvr.RoleName, - Value: rpvr.RoleID.String(), - Emoji: rpvr.Emoji, - } - } - message.AddContainerComponents( - discord.NewActionRow( - discord.StringSelectMenuComponent{ - CustomID: fmt.Sprintf("handler:rp-v2:use_select_menu:%s", r.ID.String()), - Placeholder: translate.Message(locale, "rp_v2_select_menu_placeholder"), - MinValues: json.Ptr(0), - MaxValues: len(r.Roles), - Options: options, - }, - ), - ) - } else { - message.AddContainerComponents( - discord.NewActionRow( - discord.ButtonComponent{ - Style: discord.ButtonStyleSuccess, - Label: translate.Message(locale, "rp_v2_use_button_label"), - CustomID: fmt.Sprintf("handler:rp-v2:call_select_menu:%s", r.ID.String()), - }, - ), - ) - } - return message -} - -func RolePanelV2MessageButton[T rolePanelV2MessageBuilder[T]](r *RolePanelV2, locale discord.Locale, message T, config RolePanelV2Config) T { - message.AddEmbeds(r.rolePanelV2Embed(locale)) - buttons := make([]discord.InteractiveComponent, len(r.Roles)) - components := []discord.ContainerComponent{} - for i, rpvr := range r.Roles { - var label string - if config.ButtonShowName { - label = rpvr.RoleName - } - buttons[i] = discord.ButtonComponent{ - Style: config.ButtonStyle, - Emoji: rpvr.Emoji, - Label: label, - CustomID: fmt.Sprintf("handler:rp-v2:use_button:%s:%s", r.ID, rpvr.RoleID), - } - } - a := make([]int, len(r.Roles)/5+1) - for range a { - count := 5 - if len(buttons) < 5 { - count = len(buttons) - } - components = append(components, discord.NewActionRow(buttons[:count]...)) - } - message.AddContainerComponents( - components..., - ) - return message -} - -func (r *RolePanelV2) rolePanelV2Embed(locale discord.Locale) discord.Embed { - embed := discord.NewEmbedBuilder() - embed.SetTitle(r.Name) - embed.SetDescription(r.Description) - var role_string string - for _, role := range r.Roles { - role_string += fmt.Sprintf("%s| %s\r", botlib.FormatComponentEmoji(*role.Emoji), discord.RoleMention(role.RoleID)) - } - embed.AddFields( - discord.EmbedField{ - Name: translate.Message(locale, "rp_v2_roles"), - Value: role_string, - }, - ) - embed.Embed = botlib.SetEmbedProperties(embed.Embed) - return embed.Build() -} - -func RolePanelV2PlaceMenuEmbed[T rolePanelV2MessageBuilder[T]](r *RolePanelV2, locale discord.Locale, place *RolePanelV2Place, message T) T { - embed := discord.NewEmbedBuilder() - embed.SetTitle(translate.Message(locale, "rp_v2_place_embed_title")) - embed.SetDescription(translate.Message(locale, "rp_v2_place_embed_description")) - embed.Embed = botlib.SetEmbedProperties(embed.Embed) - - message.AddEmbeds(embed.Build()) - - panel_type_select_menu := discord.StringSelectMenuComponent{ - CustomID: fmt.Sprintf("handler:rp-v2:place_type:%s", place.ID), - MinValues: json.Ptr(1), - MaxValues: 1, - Placeholder: translate.Message(locale, "rp_v2_place_type_select_menu_placeholder"), - Options: []discord.StringSelectMenuOption{ - { - Label: translate.Message(locale, "rp_v2_place_type_reaction"), - Value: RolePanelV2TypeReaction, - Description: translate.Message(locale, "rp_v2_place_type_reaction_description"), - Emoji: &discord.ComponentEmoji{ - ID: 1141985795641716736, - Name: "reaction", - }, - Default: place.Config.PanelType == RolePanelV2TypeReaction, - }, - { - Label: translate.Message(locale, "rp_v2_place_type_select_menu"), - Value: RolePanelV2TypeSelectMenu, - Description: translate.Message(locale, "rp_v2_place_type_select_menu_description"), - Emoji: &discord.ComponentEmoji{ - ID: 1141991243832901704, - Name: "select_menu", - }, - Default: place.Config.PanelType == RolePanelV2TypeSelectMenu, - }, - { - Label: translate.Message(locale, "rp_v2_place_type_button"), - Value: RolePanelV2TypeButton, - Description: translate.Message(locale, "rp_v2_place_type_button_description"), - Emoji: &discord.ComponentEmoji{ - ID: 1141991285281001553, - Name: "button", - }, - Default: place.Config.PanelType == RolePanelV2TypeButton, - }, - }, - } - - message.AddContainerComponents( - discord.NewActionRow(panel_type_select_menu), - ) - - switch place.Config.PanelType { - case RolePanelV2TypeButton: - var emoji *discord.ComponentEmoji - if place.Config.ButtonShowName { - emoji = &discord.ComponentEmoji{ - ID: 1142095470227890279, - Name: "on", - } - } else { - emoji = &discord.ComponentEmoji{ - ID: 1142110196462788779, - Name: "off", - } - } - message.AddContainerComponents( - discord.NewActionRow( - discord.StringSelectMenuComponent{ - CustomID: fmt.Sprintf("handler:rp-v2:place_button_color:%s", place.ID), - Placeholder: translate.Message(locale, "rp_v2_place_button_color_select_menu_placeholder"), - MinValues: json.Ptr(1), - MaxValues: 1, - Options: []discord.StringSelectMenuOption{ - { - Label: translate.Message(locale, "rp_v2_place_button_color_green"), - Value: "green", - Emoji: &discord.ComponentEmoji{ - ID: 1142333937180483687, - Name: "green_button", - }, - Default: place.Config.ButtonStyle == discord.ButtonStyleSuccess, - }, - { - Label: translate.Message(locale, "rp_v2_place_button_color_blue"), - Value: "blue", - Emoji: &discord.ComponentEmoji{ - ID: 1142333868490367037, - Name: "blue_button", - }, - Default: place.Config.ButtonStyle == discord.ButtonStylePrimary, - }, - { - Label: translate.Message(locale, "rp_v2_place_button_color_red"), - Value: "red", - Emoji: &discord.ComponentEmoji{ - ID: 1142334020403871745, - Name: "red_button", - }, - Default: place.Config.ButtonStyle == discord.ButtonStyleDanger, - }, - { - Label: translate.Message(locale, "rp_v2_place_button_color_gray"), - Value: "gray", - Emoji: &discord.ComponentEmoji{ - ID: 1142333913906298960, - Name: "gray_button", - }, - Default: place.Config.ButtonStyle == discord.ButtonStyleSecondary, - }, - }, - }, - ), - discord.NewActionRow( - discord.ButtonComponent{ - Style: discord.ButtonStyleSecondary, - Label: translate.Message(locale, "rp_v2_place_button_show_name_label"), - CustomID: fmt.Sprintf("handler:rp-v2:place_button_show_name:%s", place.ID), - Emoji: emoji, - }, - ), - ) - case RolePanelV2TypeSelectMenu: - var emoji *discord.ComponentEmoji - if !place.Config.SimpleSelectMenu { - emoji = &discord.ComponentEmoji{ - ID: 1142095470227890279, - Name: "on", - } - } else { - emoji = &discord.ComponentEmoji{ - ID: 1142110196462788779, - Name: "off", - } - } - message.AddContainerComponents( - discord.NewActionRow( - discord.ButtonComponent{ - Style: discord.ButtonStyleSecondary, - Label: translate.Message(locale, "rp_v2_place_simple_select_menu_label"), - CustomID: fmt.Sprintf("handler:rp-v2:place_simple_select_menu:%s", place.ID), - Emoji: emoji, - }, - ), - ) - } - - message.AddContainerComponents( - discord.NewActionRow(discord.ButtonComponent{ - Style: discord.ButtonStyleSuccess, - CustomID: fmt.Sprintf("handler:rp-v2:place:%s", place.ID.String()), - Label: translate.Message(locale, "rp_v2_place_button_label"), - Disabled: place.Config.PanelType == RolePanelV2TypeNone, - }), - ) - - return message -} - -func RolePanelV2EditMenuEmbed[T rolePanelV2MessageBuilder[T]](r *RolePanelV2, locale discord.Locale, edit *RolePanelV2Edit, message T) T { - // 埋め蟌みを組み立おる - var role_string string - for _, rpvr := range r.Roles { - role_string += fmt.Sprintf("%s| %s\r", botlib.FormatComponentEmoji(*rpvr.Emoji), discord.RoleMention(rpvr.RoleID)) - } - embed := discord.NewEmbedBuilder() - embed.AddFields( - discord.EmbedField{ - Name: translate.Message(locale, "rp_v2_edit_embed_field_title_0"), - Value: r.Name, - }, - discord.EmbedField{ - Name: translate.Message(locale, "rp_v2_edit_embed_field_title_1"), - Value: r.Description, - }, - discord.EmbedField{ - Name: translate.Message(locale, "rp_v2_edit_embed_field_title_2"), - Value: role_string, - }, - ) - - disabled := false - - role_select_menu_option := make([]discord.StringSelectMenuOption, len(r.Roles)) - for i, rpvr := range r.Roles { - role_select_menu_option[i] = discord.StringSelectMenuOption{ - Label: rpvr.RoleName, - Value: rpvr.RoleID.String(), - Emoji: rpvr.Emoji, - Default: edit.IsSelected(rpvr.RoleID), - } - } - - if len(r.Roles) == 0 { - disabled = true - role_select_menu_option = append(role_select_menu_option, discord.StringSelectMenuOption{ - Label: "disabled", - Value: "disabled", - }) - } - - // コンポヌネントを組み立おる(ク゜だるい) - role_select_menu := discord.StringSelectMenuComponent{ - CustomID: fmt.Sprintf("handler:rp-v2:edit-rsm:%s", edit.ID.String()), - Placeholder: translate.Message(locale, "rp_v2_edit_role_select_menu_placeholder"), - MinValues: json.Ptr(0), - MaxValues: 1, - Disabled: disabled, - Options: role_select_menu_option, - } - - panel_edit_buttons := []discord.InteractiveComponent{ - discord.ButtonComponent{ - Style: discord.ButtonStylePrimary, - Label: translate.Message(locale, "rp_v2_edit_embed_edit_name_button"), - CustomID: fmt.Sprintf("handler:rp-v2:edit_name:%s", edit.ID.String()), - }, - discord.ButtonComponent{ - Style: discord.ButtonStylePrimary, - Label: translate.Message(locale, "rp_v2_edit_embed_edit_description_button"), - CustomID: fmt.Sprintf("handler:rp-v2:edit_description:%s", edit.ID.String()), - }, - discord.ButtonComponent{ - Style: discord.ButtonStyleSecondary, - Label: translate.Message(locale, "rp_v2_edit_embed_edit_roles_button"), - CustomID: fmt.Sprintf("handler:rp-v2:edit_roles:%s", edit.ID.String()), - }, - } - - role_edit_buttons := []discord.InteractiveComponent{ - discord.ButtonComponent{ - Style: discord.ButtonStyleSuccess, - Label: translate.Message(locale, "rp_v2_edit_embed_edit_role_emoji_button"), - CustomID: fmt.Sprintf("handler:rp-v2:edit_role_emoji:%s", edit.ID.String()), - Disabled: !edit.HasSelectedRole(), - }, - discord.ButtonComponent{ - Style: discord.ButtonStyleSuccess, - Label: translate.Message(locale, "rp_v2_edit_embed_edit_role_name_button"), - CustomID: fmt.Sprintf("handler:rp-v2:edit_role_name:%s", edit.ID.String()), - Disabled: !edit.HasSelectedRole(), - }, - discord.ButtonComponent{ - Style: discord.ButtonStyleDanger, - Label: translate.Message(locale, "rp_v2_edit_embed_edit_role_delete_button"), - CustomID: fmt.Sprintf("handler:rp-v2:edit_role_delete:%s", edit.ID.String()), - Disabled: !edit.HasSelectedRole() || len(r.Roles) <= 1, - }, - } - - embed.Embed = botlib.SetEmbedProperties(embed.Embed) - message.AddEmbeds(embed.Build()) - message.AddContainerComponents( - discord.ActionRowComponent(panel_edit_buttons), - discord.NewActionRow( - role_select_menu, - ), - discord.ActionRowComponent(role_edit_buttons), - ) - - return message -} - -type RolePanelV2Role struct { - RoleID snowflake.ID `json:"role_id"` - RoleName string `json:"role_name"` - Emoji *discord.ComponentEmoji `json:"emoji"` -} diff --git a/bot/db/role_panel_v2_edit.go b/bot/db/role_panel_v2_edit.go deleted file mode 100644 index ee1cbe5d..00000000 --- a/bot/db/role_panel_v2_edit.go +++ /dev/null @@ -1,90 +0,0 @@ -package db - -import ( - "context" - "encoding/json" - "time" - - "github.com/disgoorg/snowflake/v2" - "github.com/go-redis/redis/v8" - "github.com/google/uuid" - "github.com/sabafly/disgo/discord" - "github.com/sabafly/sabafly-lib/v2/handler/interactions" -) - -type RolePanelV2EditDB interface { - Get(id uuid.UUID) (data *RolePanelV2Edit, err error) - Set(id uuid.UUID, data *RolePanelV2Edit) (err error) - Del(id uuid.UUID) (err error) -} - -type rolePanelV2EditDBImpl struct { - db *redis.Client -} - -func (self rolePanelV2EditDBImpl) Get(id uuid.UUID) (*RolePanelV2Edit, error) { - res := self.db.Get(context.TODO(), "role-panel-v2-edit"+id.String()) - if err := res.Err(); err != nil { - return nil, err - } - data := &RolePanelV2Edit{} - if err := json.Unmarshal([]byte(res.Val()), data); err != nil { - return nil, err - } - return data, nil -} - -func (self rolePanelV2EditDBImpl) Set(id uuid.UUID, data *RolePanelV2Edit) error { - buf, err := json.Marshal(data) - if err != nil { - return err - } - res := self.db.Set(context.TODO(), "role-panel-v2-edit"+id.String(), buf, (time.Minute*15)-(time.Since(data.CreatedAt))) - if err := res.Err(); err != nil { - return err - } - return nil -} - -func (self rolePanelV2EditDBImpl) Del(id uuid.UUID) error { - res := self.db.Del(context.TODO(), "role-panel-v2-edit"+id.String()) - if err := res.Err(); err != nil { - return err - } - return nil -} - -func NewRolePanelV2Edit(rolePanelID uuid.UUID, guildID, channelID snowflake.ID, token interactions.Token) *RolePanelV2Edit { - return &RolePanelV2Edit{ - ID: uuid.New(), - CreatedAt: time.Now(), - GuildID: guildID, - ChannelID: channelID, - InteractionToken: token, - RolePanelID: rolePanelID, - } -} - -type RolePanelV2Edit struct { - ID uuid.UUID `json:"id"` - CreatedAt time.Time `json:"created_at"` - - RolePanelID uuid.UUID `json:"role_panel_id"` - - GuildID snowflake.ID `json:"guild_id"` - ChannelID snowflake.ID `json:"channel_id"` - MessageID snowflake.ID `json:"message_id"` - InteractionToken interactions.Token `json:"interaction_token"` - EmojiMode bool `json:"emoji_mode"` - EmojiLocale discord.Locale `json:"emoji_locale"` - - SelectedID *snowflake.ID -} - -func (r RolePanelV2Edit) IsSelected(id snowflake.ID) bool { - return r.SelectedID != nil && *r.SelectedID == id -} - -func (r RolePanelV2Edit) HasSelectedRole() bool { - return r.SelectedID != nil -} diff --git a/bot/db/role_panel_v2_place.go b/bot/db/role_panel_v2_place.go deleted file mode 100644 index 6fc800bf..00000000 --- a/bot/db/role_panel_v2_place.go +++ /dev/null @@ -1,83 +0,0 @@ -package db - -import ( - "context" - "encoding/json" - "time" - - "github.com/disgoorg/snowflake/v2" - "github.com/go-redis/redis/v8" - "github.com/google/uuid" - "github.com/sabafly/sabafly-lib/v2/handler/interactions" -) - -type RolePanelV2PlaceDB interface { - Get(id uuid.UUID) (data *RolePanelV2Place, err error) - Set(id uuid.UUID, data *RolePanelV2Place) (err error) - Del(id uuid.UUID) (err error) -} - -type rolePanelV2PlaceDBImpl struct { - db *redis.Client -} - -func (self rolePanelV2PlaceDBImpl) Get(id uuid.UUID) (*RolePanelV2Place, error) { - res := self.db.Get(context.TODO(), "role-panel-v2-place"+id.String()) - if err := res.Err(); err != nil { - return nil, err - } - data := &RolePanelV2Place{} - if err := json.Unmarshal([]byte(res.Val()), data); err != nil { - return nil, err - } - return data, nil -} - -func (self rolePanelV2PlaceDBImpl) Set(id uuid.UUID, data *RolePanelV2Place) error { - buf, err := json.Marshal(data) - if err != nil { - return err - } - res := self.db.Set(context.TODO(), "role-panel-v2-place"+id.String(), buf, ((time.Minute * 15) - (time.Since(data.CreatedAt)))) - if err := res.Err(); err != nil { - return err - } - return nil -} - -func (self rolePanelV2PlaceDBImpl) Del(id uuid.UUID) error { - res := self.db.Del(context.TODO(), id.String()) - if err := res.Err(); err != nil { - return err - } - return nil -} - -func NewRolePanelV2Place(guild_id snowflake.ID, panel_id uuid.UUID, interaction_token interactions.Token) *RolePanelV2Place { - return &RolePanelV2Place{ - ID: uuid.New(), - CreatedAt: time.Now(), - GuildID: guild_id, - PanelID: panel_id, - Config: NewRolePanelV2Config(), - InteractionToken: interaction_token, - } -} - -type RolePanelV2Place struct { - ID uuid.UUID `json:"id"` - CreatedAt time.Time `json:"created_at"` - GuildID snowflake.ID `json:"guild_id"` - PanelID uuid.UUID `json:"panel_id"` - Config RolePanelV2Config `json:"config"` - InteractionToken interactions.Token `json:"interaction_token"` -} - -type RolePanelV2Type string - -const ( - RolePanelV2TypeNone = "" - RolePanelV2TypeReaction = "reaction" - RolePanelV2TypeSelectMenu = "select_menu" - RolePanelV2TypeButton = "button" -) diff --git a/bot/db/userdata.go b/bot/db/userdata.go deleted file mode 100644 index d9fd28a6..00000000 --- a/bot/db/userdata.go +++ /dev/null @@ -1,217 +0,0 @@ -package db - -import ( - "context" - "encoding/json" - "math/big" - "math/rand" - "time" - - "github.com/disgoorg/snowflake/v2" - "github.com/go-redis/redis/v8" - "github.com/sabafly/disgo/discord" -) - -type UserDataDB interface { - Get(id snowflake.ID) (*UserData, error) - Set(id snowflake.ID, data *UserData) error - Del(id snowflake.ID) error -} - -type userDataDBImpl struct { - db *redis.Client -} - -func (self *userDataDBImpl) Get(id snowflake.ID) (*UserData, error) { - res := self.db.HGet(context.TODO(), "user-data", id.String()) - if err := res.Err(); err != nil { - if err != redis.Nil { - return nil, err - } else { - return NewUserData(id) - } - } - var u *UserData = &UserData{} - if err := json.Unmarshal([]byte(res.Val()), u); err != nil { - return nil, err - } - return u, nil -} - -func (self *userDataDBImpl) Set(id snowflake.ID, data *UserData) error { - buf, err := json.Marshal(data) - if err != nil { - return err - } - res := self.db.HSet(context.TODO(), "user-data", id.String(), buf) - if err := res.Err(); err != nil { - return err - } - return nil -} - -func (self *userDataDBImpl) Del(id snowflake.ID) error { - res := self.db.HDel(context.TODO(), "user-data", id.String()) - if err := res.Err(); err != nil { - return err - } - return nil -} - -func NewUserData(id snowflake.ID) (*UserData, error) { - return &UserData{ - ID: id, - CreatedAt: time.Now(), - DataVersion: 0, - GlobalLevel: UserDataLevel{ - Point: big.NewInt(0), - }, - GlobalMessageLevel: UserDataLevel{ - Point: big.NewInt(0), - }, - GlobalVoiceLevel: UserDataLevel{ - Point: big.NewInt(0), - }, - }, nil -} - -const UserDataVersion = 1 - -type UserData struct { - ID snowflake.ID `json:"id"` - - CreatedAt time.Time `json:"created_at"` - BirthDay [2]int `json:"birth_day"` - Location UserLocation `json:"location"` - Locale discord.Locale `json:"locale"` - - LastMessageTime time.Time `json:"last_message_time"` - MessageCount int64 `json:"message_count"` - GlobalLevel UserDataLevel `json:"global_level"` - GlobalMessageLevel UserDataLevel `json:"global_message_level"` - GlobalVoiceLevel UserDataLevel `json:"global_voice_level"` - - DataVersion int `json:"data_version"` -} - -func (u *UserData) UnmarshalJSON(b []byte) error { - type userData UserData - var v struct { - userData - } - if err := json.Unmarshal(b, &v); err != nil { - return err - } - *u = UserData(v.userData) - if !u.isValid() { - if err := u.validate(b); err != nil { - return err - } - } - return nil -} - -func (u *UserData) isValid() bool { - return u.DataVersion < UserDataVersion -} - -func (u *UserData) validate(b []byte) error { - switch u.DataVersion { - case 0: - u.Locale = discord.LocaleJapanese - u.DataVersion = 1 - fallthrough - case UserDataVersion: - return nil - default: - v, err := NewUserData(u.ID) - if err != nil { - return err - } - *u = *v - return nil - } -} - -func NewUserLocation(str string) (UserLocation, error) { - tl, err := time.LoadLocation(str) - if err != nil { - return UserLocation{time.UTC}, err - } - return UserLocation{tl}, nil -} - -type UserLocation struct { - *time.Location -} - -func (u UserLocation) MarshalJSON() ([]byte, error) { - return json.Marshal(u.Location.String()) -} - -func (u *UserLocation) UnmarshalJSON(b []byte) error { - var data string - err := json.Unmarshal(b, &data) - if err != nil { - return err - } - lc, err := time.LoadLocation(data) - if err != nil { - return err - } - u.Location = lc - return nil -} - -func NewUserDataLevel() UserDataLevel { - return UserDataLevel{ - Point: big.NewInt(0), - } -} - -type UserDataLevel struct { - Point *big.Int `json:"point"` -} - -var i = big.NewInt(10) -var a = big.NewInt(2) - -func (UserDataLevel) sum_required_level_point(n *big.Int) *big.Int { - n.Add(n, big.NewInt(3)) - return new(big.Int).Add(new(big.Int).Mul(i, new(big.Int).Div(new(big.Int).Sub(new(big.Int).Exp(a, n, nil), big.NewInt(1)), new(big.Int).Sub(a, big.NewInt(1)))), big.NewInt(0)) -} - -func (UserDataLevel) required_level_point(n *big.Int) *big.Int { - n.Add(n, big.NewInt(3)) - return new(big.Int).Add(new(big.Int).Mul(i, new(big.Int).Exp(a, n, nil)), big.NewInt(0)) -} - -func (u UserDataLevel) ReqPoint() *big.Int { - return u.required_level_point(u.Level()) -} - -func (u UserDataLevel) SumReqPoint() *big.Int { - return u.sum_required_level_point(u.Level()) -} - -func (u UserDataLevel) Level() *big.Int { - if u.Point == nil { - u.Point = big.NewInt(0) - } - for k := 0; k < 999; k++ { - lv := u.sum_required_level_point(big.NewInt(int64(k))) - if lv.Cmp(u.Point) == 1 { - return big.NewInt(int64(k)) - } - } - return big.NewInt(0) -} - -func (u *UserDataLevel) Add(i *big.Int) { - u.Point.Add(u.Point, i) -} - -func (u *UserDataLevel) AddRandom() { - r := rand.Intn(10) - u.Add(new(big.Int).Add(big.NewInt(int64(r)), big.NewInt(15))) -} diff --git a/bot/gobot.go b/bot/gobot.go deleted file mode 100644 index 48666052..00000000 --- a/bot/gobot.go +++ /dev/null @@ -1,289 +0,0 @@ -/* - Copyright (C) 2022-2023 sabafly - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see . -*/ -package gobot - -import ( - "context" - "fmt" - "os" - "os/signal" - "runtime" - "syscall" - "time" - - "github.com/disgoorg/dislog" - "github.com/disgoorg/snowflake/v2" - "github.com/mattn/go-colorable" - "github.com/sabafly/disgo/bot" - "github.com/sabafly/disgo/events" - "github.com/sabafly/gobot/bot/client" - "github.com/sabafly/gobot/bot/commands" - "github.com/sabafly/gobot/bot/db" - "github.com/sabafly/gobot/bot/handlers" - "github.com/sabafly/gobot/bot/worker" - "github.com/sirupsen/logrus" - - botlib "github.com/sabafly/sabafly-lib/v2/bot" - "github.com/sabafly/sabafly-lib/v2/handler" - "github.com/sabafly/sabafly-lib/v2/logging" - "github.com/sabafly/sabafly-lib/v2/translate" -) - -var ( - version = "v0.12.2" -) - -func init() { - botlib.BotName = "gobot" - botlib.Color = 0x00AED9 -} - -func Run(file_path, lang_path, gobot_path string) error { - if _, err := translate.LoadTranslations(lang_path); err != nil { - return err - } - cfg, err := botlib.LoadConfig(file_path) - if err != nil { - return err - } - - logger := logrus.New() - logger.ReportCaller = cfg.DevMode - logger.SetFormatter(&logrus.TextFormatter{ - ForceColors: true, - FullTimestamp: true, - CallerPrettyfier: func(f *runtime.Frame) (function string, file string) { - return "", fmt.Sprintf("%s:%d", f.File, f.Line) - }, - }) - logger.SetOutput(colorable.NewColorableStdout()) - lvl, err := logrus.ParseLevel(cfg.LogLevel) - if err != nil { - return err - } - logger.SetLevel(lvl) - if err := os.MkdirAll("./logs", 0755); err != nil { - return err - } - l, err := logging.New(logging.Config{ - LogPath: "./logs", - LogLevels: logrus.AllLevels, - }) - if err != nil { - return err - } - defer l.Close() - logger.AddHook(l) - dlog, err := dislog.New( - dislog.WithLogLevels(dislog.TraceLevelAndAbove...), - dislog.WithWebhookIDToken(cfg.Dislog.WebhookID, cfg.Dislog.WebhookToken), - ) - if err != nil { - logger.Fatal("error initializing dislog: ", err) - } - defer dlog.Close(context.TODO()) - logger.AddHook(dlog) - logger.Infof("Starting bot version: %s", version) - logger.Infof("Syncing commands? %t", cfg.ShouldSyncCommands) - - b := botlib.New[*client.Client](logger, version, *cfg) - - gobot_cfg, err := client.LoadConfig(gobot_path) - if err != nil { - return err - } - d, err := db.SetupDatabase(gobot_cfg.DBConfig) - if err != nil { - return err - } - defer d.Close() - cl, err := client.New(gobot_cfg, d) - if err != nil { - return err - } - defer cl.Close() - - b.Self = cl - - b.Handler.AddExclude(b.Config.Dislog.WebhookChannel) - - b.Logger.Infof("dev guilds %v", b.Config.DevGuildIDs) - b.Handler.DevGuildID = b.Config.DevGuildIDs - b.Handler.IsDebug = b.Config.DevMode - b.Handler.IsLogEvent = true - - b.Handler.AddCommands( - commands.Ping(b), - commands.Poll(b), - commands.Role(b), - commands.Util(b), - commands.Admin(b), - commands.About(b), - commands.Message(b), - commands.Level(b), - commands.Permission(b), - commands.Config(b), - commands.Minecraft(b), - commands.User(b), - - commands.UserInfo(b), - - commands.MessageOther(b), - ) - - b.Handler.AddComponents( - commands.PollComponent(b), - commands.UtilCalcComponent(b), - commands.MessageComponent(b), - commands.MinecraftComponent(b), - commands.RolePanelV2Component(b), - - handlers.EmbedDialogComponent(b), - ) - - b.Handler.AddModals( - commands.PollModal(b), - commands.MessageModal(b), - commands.LevelModal(b), - commands.ConfigModal(b), - commands.RolePanelV2Modal(b), - - handlers.EmbedDialogModal(b), - ) - - b.Handler.AddMessages( - commands.MessagePinMessageCreateHandler(b), - commands.MessageSuffixMessageCreateHandler(b), - commands.RolePanelV2Message(b), - - handlers.LogMessage(b), - handlers.UserDataMessage(b), - handlers.BumpUpMessage(b), - handlers.MentionMessage(b), - ) - - b.Handler.AddMessageUpdates( - handlers.BumpUpdateMessage(b), - ) - - b.Handler.AddMessageDelete( - commands.RolePanelV2MessageDelete(b), - ) - - b.Handler.MessageReactionAdd.Adds( - commands.RolePanelV2MessageReaction(b), - ) - - b.Handler.AddReady(func(r *events.Ready) { - b.Logger.Info("Ready!") - polls, err := b.Self.DB.Poll().GetAll() - if err == nil { - for _, p := range polls { - go commands.End(b, p) - } - } - mp, err := b.Self.DB.MessagePin().GetAll() - if err == nil { - b.Self.MessagePin = mp - } - }) - - b.Handler.MemberJoin.Adds(handler.Generics[events.GuildMemberJoin]{ - Handler: func(event *events.GuildMemberJoin) error { - onGuildMemberJoin(event, b) - return nil - }, - }) - - b.Handler.MemberLeave.Adds(handler.Generics[events.GuildMemberLeave]{ - Handler: func(event *events.GuildMemberLeave) error { - onGuildMemberLeave(event, b) - return nil - }, - }) - - b.Handler.AddEvent( - handlers.LogEvent(b), - ) - - b.SetupBot(bot.NewListenerFunc(b.Handler.OnEvent)) - b.Client.EventManager().AddEventListeners(&events.ListenerAdapter{ - OnGuildJoin: onGuildJoin(b), - OnGuildLeave: onGuildLeave(b), - OnGuildReady: func(event *events.GuildReady) { - b.Logger.Infof("guild ready: %s", event.GuildID) - }, - OnGuildsReady: func(event *events.GuildsReady) { - b.Logger.Infof("guilds on shard %d ready", event.ShardID()) - }, - }) - - if cfg.ShouldSyncCommands { - var guilds []snowflake.ID - if cfg.DevOnly { - guilds = b.Config.DevGuildIDs - } - b.Handler.SyncCommands(b.Client, guilds...) - } - - w := worker.New() - w.Add( - func(b *botlib.Bot[*client.Client]) error { - ns, err := b.Self.DB.NoticeSchedule().GetAll() - if err != nil { - return err - } - for _, s := range ns { - switch s.Type() { - case db.NoticeScheduleTypeBump: - s, ok := s.(db.NoticeScheduleBump) - if !ok { - b.Logger.Warn("failed to convert") - break - } - if !time.Now().After(s.ScheduledTime.Add(-time.Minute * 15)) { - continue - } - if err := handlers.ScheduleBump(b, s); err != nil { - b.Logger.Errorf("error on worker notice schedule: %s", err) - continue - } - if err := b.Self.DB.NoticeSchedule().Del(s.ID()); err != nil { - b.Logger.Errorf("error on worker notice schedule delete: %s", err) - continue - } - } - } - return nil - }, - 5, - ) - w.Start(b) - - if err := b.Client.OpenShardManager(context.TODO()); err != nil { - b.Logger.Fatalf("failed to open shard manager: %s", err) - } - defer b.Client.ShardManager().Close(context.TODO()) - - b.Logger.Infof("shard count: %d", len(b.Client.ShardManager().Shards())) - b.Logger.Info("Bot is running. Press CTRL-C to exit.") - s := make(chan os.Signal, 1) - signal.Notify(s, syscall.SIGINT, syscall.SIGTERM, os.Interrupt) - <-s - b.Logger.Info("Shutting down...") - return nil -} diff --git a/bot/handlers/bump.go b/bot/handlers/bump.go deleted file mode 100644 index 77e1b152..00000000 --- a/bot/handlers/bump.go +++ /dev/null @@ -1,153 +0,0 @@ -package handlers - -import ( - "time" - - "github.com/disgoorg/snowflake/v2" - "github.com/sabafly/disgo/discord" - "github.com/sabafly/disgo/events" - "github.com/sabafly/gobot/bot/client" - "github.com/sabafly/gobot/bot/db" - botlib "github.com/sabafly/sabafly-lib/v2/bot" - "github.com/sabafly/sabafly-lib/v2/handler" -) - -func BumpUpMessage(b *botlib.Bot[*client.Client]) handler.Message { - return handler.Message{ - Handler: bumpUpMessageHandler(b), - } -} - -func bumpUpMessageHandler(b *botlib.Bot[*client.Client]) func(event *events.GuildMessageCreate) error { - return func(event *events.GuildMessageCreate) error { - if event.Message.Interaction == nil || event.Message.ApplicationID == nil { - return nil - } - if event.Message.Author.ID != 761562078095867916 && event.Message.Author.ID != 302050872383242240 { - return nil - } - b.Self.GuildDataLock(event.GuildID).Lock() - defer b.Self.GuildDataLock(event.GuildID).Unlock() - gd, err := b.Self.DB.GuildData().Get(event.GuildID) - if err != nil { - return err - } - switch event.Message.Interaction.Name { - case "bump": // disboard - if !gd.BumpStatus.BumpEnabled { - return nil - } - if event.Message.Embeds[0].Image.URL != "https://disboard.org/images/bot-command-image-bump.png" { - return nil - } - gd.BumpStatus.LastBump = event.Message.CreatedAt - gd.BumpStatus.LastBumpChannel = &event.ChannelID - channelID := event.Message.ChannelID - gd.BumpStatus.BumpCountMap[event.Message.Interaction.User.ID]++ - if gd.BumpStatus.BumpChannel != nil { - channelID = *gd.BumpStatus.BumpChannel - } - - ns := db.NewNoticeScheduleBump(false, event.GuildID, channelID, time.Now().Add(2*time.Hour)) - if err := b.Self.DB.NoticeSchedule().Set(ns.ID(), ns); err != nil { - return err - } - - message := discord.NewMessageCreateBuilder() - embed := discord.NewEmbedBuilder() - embed.SetTitle(gd.BumpStatus.BumpMessage[0]) - embed.SetDescription(gd.BumpStatus.BumpMessage[1]) - embed.Embed = botlib.SetEmbedProperties(embed.Embed) - message.AddEmbeds(embed.Build()) - if _, err := b.Client.Rest().CreateMessage(event.Message.ChannelID, message.Build()); err != nil { - b.Logger.Errorf("error on bump message: %s", err) - } - case "dissoku up": // dissoku - if !gd.BumpStatus.UpEnabled { - return nil - } - if len(event.Message.Embeds) < 1 || event.Message.Embeds[0].Color != 7506394 { - return nil - } - gd.BumpStatus.LastUp = event.Message.CreatedAt - gd.BumpStatus.LastUpChannel = &event.ChannelID - channelID := event.Message.ChannelID - gd.BumpStatus.UpCountMap[event.Message.Interaction.User.ID]++ - if gd.BumpStatus.UpChannel != nil { - channelID = *gd.BumpStatus.UpChannel - } - - ns := db.NewNoticeScheduleBump(true, event.GuildID, channelID, time.Now().Add(time.Hour)) - if err := b.Self.DB.NoticeSchedule().Set(ns.ID(), ns); err != nil { - return err - } - - message := discord.NewMessageCreateBuilder() - embed := discord.NewEmbedBuilder() - embed.SetTitle(gd.BumpStatus.UpMessage[0]) - embed.SetDescription(gd.BumpStatus.UpMessage[1]) - embed.Embed = botlib.SetEmbedProperties(embed.Embed) - message.AddEmbeds(embed.Build()) - if _, err := b.Client.Rest().CreateMessage(event.Message.ChannelID, message.Build()); err != nil { - b.Logger.Errorf("error on bump message: %s", err) - } - } - if err := b.Self.DB.GuildData().Set(gd.ID, gd); err != nil { - return err - } - return nil - } -} - -func BumpUpdateMessage(b *botlib.Bot[*client.Client]) handler.MessageUpdate { - return handler.MessageUpdate{ - Handler: bumpUpdateHandler(b), - } -} - -func bumpUpdateHandler(b *botlib.Bot[*client.Client]) handler.MessageUpdateHandler { - return func(event *events.GuildMessageUpdate) error { - return bumpUpMessageHandler(b)(&events.GuildMessageCreate{GenericGuildMessage: event.GenericGuildMessage}) - } -} - -func ScheduleBump(b *botlib.Bot[*client.Client], bp db.NoticeScheduleBump) error { - b.Self.GuildDataLock(bp.GuildID).Lock() - defer b.Self.GuildDataLock(bp.GuildID).Unlock() - gd, err := b.Self.DB.GuildData().Get(bp.GuildID) - if err != nil { - return err - } - if !bp.IsUp { - channelID := bp.ChannelID - if gd.BumpStatus.BumpChannel != nil { - channelID = *gd.BumpStatus.BumpChannel - } - go bumpScheduler(b, channelID, gd.BumpStatus.BumpRole, gd.BumpStatus.BumpRemind[0], gd.BumpStatus.BumpRemind[1], bp.ScheduledTime) - } else { - channelID := bp.ChannelID - if gd.BumpStatus.UpChannel != nil { - channelID = *gd.BumpStatus.UpChannel - } - go bumpScheduler(b, channelID, gd.BumpStatus.UpRole, gd.BumpStatus.UpRemind[0], gd.BumpStatus.UpRemind[1], bp.ScheduledTime) - } - return nil -} - -func bumpScheduler(b *botlib.Bot[*client.Client], channelID snowflake.ID, roleID *snowflake.ID, title, desc string, tm time.Time) { - time.Sleep(time.Until(tm)) - var mention string - if roleID != nil { - mention = discord.RoleMention(*roleID) - } - message := discord.NewMessageCreateBuilder() - message.SetContent(mention) - embed := discord.NewEmbedBuilder() - embed.SetTitle(title) - embed.SetDescription(desc) - embed.Embed = botlib.SetEmbedProperties(embed.Embed) - message.AddEmbeds(embed.Build()) - if _, err := b.Client.Rest().CreateMessage(channelID, message.Build()); err != nil { - b.Logger.Errorf("error on bump message: %s", err) - } -} diff --git a/bot/handlers/embed_dialog.go b/bot/handlers/embed_dialog.go deleted file mode 100644 index bf50622b..00000000 --- a/bot/handlers/embed_dialog.go +++ /dev/null @@ -1,203 +0,0 @@ -package handlers - -import ( - "strings" - - "github.com/google/uuid" - "github.com/sabafly/disgo/discord" - "github.com/sabafly/disgo/events" - "github.com/sabafly/gobot/bot/client" - botlib "github.com/sabafly/sabafly-lib/v2/bot" - "github.com/sabafly/sabafly-lib/v2/handler" - "github.com/sabafly/sabafly-lib/v2/translate" -) - -func EmbedDialogComponent(b *botlib.Bot[*client.Client]) handler.Component { - return handler.Component{ - Name: "ed", - Handler: map[string]handler.ComponentHandler{ - "base-menu": embedDialogComponentBaseMenuHandler(b), - "to-title-desc": embedDialogComponentTitleDescHandler(b), - "set-title": embedDialogComponentSetTitleHandler(b), - "set-desc": embedDialogComponentSetDescHandler(b), - }, - } -} - -func embedDialogComponentBaseMenuHandler(b *botlib.Bot[*client.Client]) handler.ComponentHandler { - return func(event *events.ComponentInteractionCreate) error { - args := strings.Split(event.Data.CustomID(), ":") - ed_id, err := uuid.Parse(args[3]) - if err != nil { - return botlib.ReturnErrMessage(event, "error_invalid_id") - } - ed, err := b.Self.DB.EmbedDialog().Get(ed_id) - if err != nil { - return botlib.ReturnErrMessage(event, "error_timeout") - } - token, err := ed.InteractionToken.Get() - if err != nil { - return botlib.ReturnErrMessage(event, "error_timeout") - } - if _, err := event.Client().Rest().UpdateInteractionResponse(event.ApplicationID(), token, ed.BaseMenu()); err != nil { - return botlib.ReturnErr(event, err, botlib.WithEphemeral(true)) - } - if err := event.DeferUpdateMessage(); err != nil { - return botlib.ReturnErr(event, err) - } - return nil - } -} - -func embedDialogComponentTitleDescHandler(b *botlib.Bot[*client.Client]) handler.ComponentHandler { - return func(event *events.ComponentInteractionCreate) error { - args := strings.Split(event.Data.CustomID(), ":") - ed_id, err := uuid.Parse(args[3]) - if err != nil { - return botlib.ReturnErrMessage(event, "error_invalid_id") - } - ed, err := b.Self.DB.EmbedDialog().Get(ed_id) - if err != nil { - return botlib.ReturnErrMessage(event, "error_timeout") - } - token, err := ed.InteractionToken.Get() - if err != nil { - return botlib.ReturnErrMessage(event, "error_timeout") - } - if _, err := event.Client().Rest().UpdateInteractionResponse(event.ApplicationID(), token, ed.TitleDescriptionMenu()); err != nil { - return botlib.ReturnErr(event, err, botlib.WithEphemeral(true)) - } - if err := event.DeferUpdateMessage(); err != nil { - return botlib.ReturnErr(event, err) - } - return nil - } -} - -func embedDialogComponentSetTitleHandler(b *botlib.Bot[*client.Client]) handler.ComponentHandler { - return func(event *events.ComponentInteractionCreate) error { - args := strings.Split(event.Data.CustomID(), ":") - ed_id, err := uuid.Parse(args[3]) - if err != nil { - return botlib.ReturnErrMessage(event, "error_invalid_id") - } - ed, err := b.Self.DB.EmbedDialog().Get(ed_id) - if err != nil { - return botlib.ReturnErrMessage(event, "error_timeout") - } - if err := event.CreateModal(discord.ModalCreate{ - CustomID: event.Data.CustomID(), - Title: translate.Message(event.Locale(), "embed_dialog_set_title_modal_title"), - Components: []discord.ContainerComponent{ - discord.NewActionRow( - discord.TextInputComponent{ - Style: discord.TextInputStyleShort, - CustomID: "title", - Label: translate.Message(event.Locale(), "embed_dialog_set_title_modal_0_text_input_label"), - Required: true, - MaxLength: 256, - Value: ed.Title, - }, - ), - }, - }); err != nil { - return botlib.ReturnErr(event, err, botlib.WithEphemeral(true)) - } - return nil - } -} - -func embedDialogComponentSetDescHandler(b *botlib.Bot[*client.Client]) handler.ComponentHandler { - return func(event *events.ComponentInteractionCreate) error { - args := strings.Split(event.Data.CustomID(), ":") - ed_id, err := uuid.Parse(args[3]) - if err != nil { - return botlib.ReturnErrMessage(event, "error_invalid_id") - } - ed, err := b.Self.DB.EmbedDialog().Get(ed_id) - if err != nil { - return botlib.ReturnErrMessage(event, "error_timeout") - } - if err := event.CreateModal(discord.ModalCreate{ - CustomID: event.Data.CustomID(), - Title: translate.Message(event.Locale(), "embed_dialog_set_desc_modal_title"), - Components: []discord.ContainerComponent{ - discord.NewActionRow( - discord.TextInputComponent{ - Style: discord.TextInputStyleParagraph, - CustomID: "desc", - Label: translate.Message(event.Locale(), "embed_dialog_set_desc_modal_0_text_input_label"), - Required: true, - MaxLength: 4000, - Value: ed.Description, - }, - ), - }, - }); err != nil { - return botlib.ReturnErr(event, err, botlib.WithEphemeral(true)) - } - return nil - } -} - -func EmbedDialogModal(b *botlib.Bot[*client.Client]) handler.Modal { - return handler.Modal{ - Name: "ed", - Handler: map[string]handler.ModalHandler{ - "set-title": embedDialogModalSetTitleHandler(b), - "set-desc": embedDialogModalSetDescHandler(b), - }, - } -} - -func embedDialogModalSetTitleHandler(b *botlib.Bot[*client.Client]) handler.ModalHandler { - return func(event *events.ModalSubmitInteractionCreate) error { - args := strings.Split(event.Data.CustomID, ":") - ed_id, err := uuid.Parse(args[3]) - if err != nil { - return botlib.ReturnErrMessage(event, "error_invalid_id") - } - ed, err := b.Self.DB.EmbedDialog().Get(ed_id) - if err != nil { - return botlib.ReturnErrMessage(event, "error_timeout") - } - ed.SetTitle(event.ModalSubmitInteraction.Data.Text("title")) - if err := b.Self.DB.EmbedDialog().Set(ed.ID, *ed); err != nil { - return botlib.ReturnErr(event, err, botlib.WithEphemeral(true)) - } - token, err := ed.InteractionToken.Get() - if err != nil { - return botlib.ReturnErrMessage(event, "error_timeout") - } - if _, err := event.Client().Rest().UpdateInteractionResponse(event.ApplicationID(), token, ed.TitleDescriptionMenu()); err != nil { - return botlib.ReturnErr(event, err, botlib.WithEphemeral(true)) - } - return event.DeferUpdateMessage() - } -} - -func embedDialogModalSetDescHandler(b *botlib.Bot[*client.Client]) handler.ModalHandler { - return func(event *events.ModalSubmitInteractionCreate) error { - args := strings.Split(event.Data.CustomID, ":") - ed_id, err := uuid.Parse(args[3]) - if err != nil { - return botlib.ReturnErrMessage(event, "error_invalid_id") - } - ed, err := b.Self.DB.EmbedDialog().Get(ed_id) - if err != nil { - return botlib.ReturnErrMessage(event, "error_timeout") - } - ed.SetDescription(event.ModalSubmitInteraction.Data.Text("desc")) - if err := b.Self.DB.EmbedDialog().Set(ed.ID, *ed); err != nil { - return botlib.ReturnErr(event, err, botlib.WithEphemeral(true)) - } - token, err := ed.InteractionToken.Get() - if err != nil { - return botlib.ReturnErrMessage(event, "error_timeout") - } - if _, err := event.Client().Rest().UpdateInteractionResponse(event.ApplicationID(), token, ed.TitleDescriptionMenu()); err != nil { - return botlib.ReturnErr(event, err, botlib.WithEphemeral(true)) - } - return event.DeferUpdateMessage() - } -} diff --git a/bot/handlers/logging.go b/bot/handlers/logging.go deleted file mode 100644 index 523323da..00000000 --- a/bot/handlers/logging.go +++ /dev/null @@ -1,131 +0,0 @@ -package handlers - -import ( - "bytes" - "encoding/json" - "fmt" - - "github.com/sabafly/disgo/bot" - "github.com/sabafly/disgo/discord" - "github.com/sabafly/disgo/events" - "github.com/sabafly/gobot/bot/client" - botlib "github.com/sabafly/sabafly-lib/v2/bot" - "github.com/sabafly/sabafly-lib/v2/handler" -) - -func LogMessage(b *botlib.Bot[*client.Client]) handler.Message { - return handler.Message{ - Handler: messageHandler(b), - } -} - -func messageHandler(b *botlib.Bot[*client.Client]) handler.MessageHandler { - return func(event *events.GuildMessageCreate) error { - err := b.Self.Logger.Message.Log( - "message", - fmt.Sprintf("%s at:%s/%s by:%s(%s) %s", - event.Message.ID, - event.GuildID, - event.ChannelID, - event.Message.Author.Tag(), - event.Message.Author.ID, - event.Message.Content, - ), - event.Message.CreatedAt, - ) - if err != nil { - b.Logger.Errorf("error on message log: %s", err.Error()) - } - - if l, ok := b.Self.Logger.DebugChannel[event.ChannelID]; ok { - raw, err := json.MarshalIndent(event.Message, "", " ") - if err != nil { - b.Logger.Errorf("error on marshal json object: %s", err.Error()) - return err - } - if l.LogChannel != nil { - if _, err := botlib.SendWebhook(event.Client(), *l.LogChannel, discord.WebhookMessageCreate{ - Content: event.Message.Content, - Username: event.Message.Author.Tag(), - AvatarURL: event.Message.Author.EffectiveAvatarURL(), - Embeds: event.Message.Embeds, - Components: event.Message.Components, - Files: []*discord.File{ - { - Name: "message-" + event.Message.ID.String() + ".json", - Reader: bytes.NewBuffer(raw), - }, - }, - }); err != nil { - b.Logger.Errorf("error on debug channel: %s", err.Error()) - } - } - if l.Logger != nil { - if err := l.Logger.Log( - "message", - fmt.Sprintf("%s at:%s/%s by:%s(%s) %s", - event.Message.ID, - event.GuildID, - event.ChannelID, - event.Message.Author.Tag(), - event.Message.Author.ID, - event.Message.Content, - ), - event.Message.CreatedAt, - ); err != nil { - b.Logger.Errorf("error on logger log: %s", err) - } - } - } - - return nil - } -} - -func LogEvent(b *botlib.Bot[*client.Client]) handler.Event { - return handler.Event{ - Handler: eventHandler(b), - } -} - -func eventHandler(b *botlib.Bot[*client.Client]) handler.RawHandler { - return func(event bot.Event) error { - switch e := event.(type) { - case *events.GuildAuditLogEntryCreate: - if l, ok := b.Self.Logger.DebugGuild[e.GuildID]; ok { - if l.LogChannel != nil { - raw, err := json.MarshalIndent(e, "", " ") - if err != nil { - b.Logger.Errorf("error on marshal json object: %s", err.Error()) - return err - } - if _, err := botlib.SendWebhook(event.Client(), *l.LogChannel, discord.WebhookMessageCreate{ - Files: []*discord.File{ - { - Name: "audit-log-" + e.GuildID.String() + ".json", - Reader: bytes.NewBuffer(raw), - }, - }, - }); err != nil { - b.Logger.Errorf("error on debug channel: %s", err.Error()) - } - } - if l.Logger != nil { - raw, err := json.Marshal(e) - if err != nil { - b.Logger.Errorf("error on marshal json object: %s", err.Error()) - return err - } - if err := l.Logger.Log( - "audit-log", - string(raw), - e.AuditLogEntry.ID.Time(), - ); err != nil { - b.Logger.Errorf("error on logger log: %s", err) - } - } - } - } - return nil - } -} diff --git a/bot/handlers/mention.go b/bot/handlers/mention.go deleted file mode 100644 index 4cd665cf..00000000 --- a/bot/handlers/mention.go +++ /dev/null @@ -1,49 +0,0 @@ -package handlers - -import ( - "slices" - - "github.com/sabafly/disgo/discord" - "github.com/sabafly/disgo/events" - "github.com/sabafly/gobot/bot/client" - botlib "github.com/sabafly/sabafly-lib/v2/bot" - "github.com/sabafly/sabafly-lib/v2/handler" - "github.com/sabafly/sabafly-lib/v2/translate" -) - -func MentionMessage(b *botlib.Bot[*client.Client]) handler.Message { - return handler.Message{ - Handler: mentionMessageHandler(b), - } -} - -func mentionMessageHandler(b *botlib.Bot[*client.Client]) handler.MessageHandler { - return func(event *events.GuildMessageCreate) error { - if event.Message.Author.Bot || event.Message.Author.System { - return nil - } - - if !slices.ContainsFunc(event.Message.Mentions, func(u discord.User) bool { - return u.ID == event.Client().ApplicationID() - }) { - return nil - } - - message := discord.NewMessageCreateBuilder() - message.SetMessageReferenceByID(event.MessageID) - message.SetAllowedMentions(&discord.AllowedMentions{ - RepliedUser: true, - }) - - user, err := b.Self.DB.UserData().Get(event.Message.Author.ID) - if err != nil { - return nil - } - message.SetContent(translate.Message(user.Locale, "message_mention_help")) - - if _, err := event.Client().Rest().CreateMessage(event.ChannelID, message.Build()); err != nil { - return err - } - return nil - } -} diff --git a/bot/handlers/userdata.go b/bot/handlers/userdata.go deleted file mode 100644 index aa9c6953..00000000 --- a/bot/handlers/userdata.go +++ /dev/null @@ -1,82 +0,0 @@ -package handlers - -import ( - "strings" - "time" - - "github.com/sabafly/disgo/discord" - "github.com/sabafly/disgo/events" - "github.com/sabafly/gobot/bot/client" - "github.com/sabafly/gobot/bot/db" - botlib "github.com/sabafly/sabafly-lib/v2/bot" - "github.com/sabafly/sabafly-lib/v2/handler" -) - -func UserDataMessage(b *botlib.Bot[*client.Client]) handler.Message { - return handler.Message{ - Handler: userDataMessageHandler(b), - } -} - -func userDataMessageHandler(b *botlib.Bot[*client.Client]) func(event *events.GuildMessageCreate) error { - return func(event *events.GuildMessageCreate) error { - if event.Message.Author.System || event.Message.Author.Bot { - return nil - } - if !b.Self.UserDataLock(event.Message.Author.ID).TryLock() { - return nil - } - defer b.Self.UserDataLock(event.Message.Author.ID).Unlock() - u, err := b.Self.DB.UserData().Get(event.Message.Author.ID) - if err != nil { - return err - } - if !u.LastMessageTime.Add(time.Minute * 3).After(time.Now()) { - u.GlobalLevel.AddRandom() - u.MessageCount++ - u.LastMessageTime = event.Message.CreatedAt - u.GlobalMessageLevel.AddRandom() - if err := b.Self.DB.UserData().Set(u.ID, u); err != nil { - return err - } - } - if b.Self.GuildDataLock(event.GuildID).TryLock() { - defer b.Self.GuildDataLock(event.GuildID).Unlock() - gd, err := b.Self.DB.GuildData().Get(event.GuildID) - if err != nil { - return err - } - _, ok := gd.UserLevelExcludeChannels[event.ChannelID] - if !gd.UserLevels[event.Message.Author.ID].LastMessageTime.Add(time.Minute*3).After(time.Now()) && !ok { - ul, ok := gd.UserLevels[event.Message.Author.ID] - if !ok { - ul = db.NewGuildDataUserLevel() - } - before := ul.Level() - ul.AddRandom() - after := ul.Level() - if before.Cmp(after) == -1 { - // メッセヌゞを送る凊理 - mes := strings.ReplaceAll(gd.Config.LevelUpMessage, "{mention}", discord.UserMention(event.Message.Author.ID)) - mes = strings.ReplaceAll(mes, "{username}", event.Message.Author.EffectiveName()) - mes = strings.ReplaceAll(mes, "{level}", after.Text(10)) - mes = strings.ReplaceAll(mes, "{level_before}", before.Text(10)) - channelID := event.ChannelID - if gd.Config.LevelUpMessageChannel != nil { - channelID = *gd.Config.LevelUpMessageChannel - } - if _, err := event.Client().Rest().CreateMessage(channelID, discord.MessageCreate{Content: mes}); err != nil { - return err - } - } - ul.MessageCount++ - ul.LastMessageTime = event.Message.CreatedAt - gd.UserLevels[event.Message.Author.ID] = ul - } - if err := b.Self.DB.GuildData().Set(gd.ID, gd); err != nil { - return err - } - } - return nil - } -} diff --git a/bot/status.go b/bot/status.go deleted file mode 100644 index 3d99ff49..00000000 --- a/bot/status.go +++ /dev/null @@ -1,64 +0,0 @@ -package gobot - -import ( - "context" - "fmt" - - "github.com/sabafly/disgo/discord" - "github.com/sabafly/disgo/events" - "github.com/sabafly/disgo/gateway" - "github.com/sabafly/gobot/bot/client" - botlib "github.com/sabafly/sabafly-lib/v2/bot" -) - -func onGuildJoin(b *botlib.Bot[*client.Client]) func(g *events.GuildJoin) { - return func(g *events.GuildJoin) { - b.Logger.Infof("[#%d]ギルド参加 %3dメンバヌ 䜜成 %s 名前 %s(%d)", g.ShardID(), g.Guild.MemberCount, g.Guild.CreatedAt().String(), g.Guild.Name, g.GuildID) - go refreshPresence(b) - } -} - -func onGuildLeave(b *botlib.Bot[*client.Client]) func(g *events.GuildLeave) { - return func(g *events.GuildLeave) { - b.Logger.Infof("[#%d]ギルド脱退 %3dメンバヌ 䜜成 %s 名前 %s(%d)", g.ShardID(), g.Guild.MemberCount, g.Guild.CreatedAt().String(), g.Guild.Name, g.GuildID) - b.Client.Caches().RemoveGuild(g.GuildID) - b.Client.Caches().RemoveMembersByGuildID(g.GuildID) - go refreshPresence(b) - } -} - -func onGuildMemberJoin(m *events.GuildMemberJoin, b *botlib.Bot[*client.Client]) { - if g, ok := m.Client().Caches().Guild(m.GuildID); ok { - b.Logger.Infof("[#%d]ギルドメンバヌ参加 %32s#%s(%d) ギルド %s(%d) %3d メンバヌ", m.ShardID(), m.Member.User.Username, m.Member.User.Discriminator, m.Member.User.ID, g.Name, g.ID, g.MemberCount) - } - go refreshPresence(b) -} - -func onGuildMemberLeave(m *events.GuildMemberLeave, b *botlib.Bot[*client.Client]) { - if g, ok := m.Client().Caches().Guild(m.GuildID); ok { - b.Logger.Infof("[#%d]ギルドメンバヌ脱退 %32s#%s(%d) ギルド %s(%d) %3d メンバヌ", m.ShardID(), m.Member.User.Username, m.Member.User.Discriminator, m.Member.User.ID, g.Name, g.ID, g.MemberCount) - } - b.Client.Caches().RemoveMember(m.GuildID, m.User.ID) - go refreshPresence(b) -} - -func refreshPresence(b *botlib.Bot[*client.Client]) { - var ( - guilds int = b.Client.Caches().GuildsLen() - users int = b.Client.Caches().MembersAllLen() - ) - shards := b.Client.ShardManager().Shards() - for k := range shards { - state := fmt.Sprintf("/help | %d Servers | %d Users | #%d", guilds, users, k) - if err := b.Client.SetPresenceForShard(context.TODO(), k, gateway.WithOnlineStatus(discord.OnlineStatusOnline), gateway.WithPlayingActivity(state)); err != nil { - b.Logger.Errorf("ステヌタス曎新に倱敗 %s", err) - } - } - if len(shards) == 0 { - state := fmt.Sprintf("/help | %d Servers | %d Users", guilds, users) - err := b.Client.SetPresence(context.TODO(), gateway.WithPlayingActivity(state)) - if err != nil { - b.Logger.Errorf("ステヌタス曎新に倱敗 %s", err) - } - } -} diff --git a/bot/worker/worker.go b/bot/worker/worker.go deleted file mode 100644 index c5d9864b..00000000 --- a/bot/worker/worker.go +++ /dev/null @@ -1,51 +0,0 @@ -package worker - -import ( - "time" - - "github.com/sabafly/gobot/bot/client" - botlib "github.com/sabafly/sabafly-lib/v2/bot" -) - -func New() *Worker { - return &Worker{} -} - -type WorkerFunc func(b *botlib.Bot[*client.Client]) error - -type WorkerHandler struct { - Handler WorkerFunc - Minutes int -} - -type Worker struct { - handler []WorkerHandler -} - -func (w *Worker) Add(wf WorkerFunc, minutes int) { - w.handler = append(w.handler, - WorkerHandler{ - Handler: wf, - Minutes: minutes, - }, - ) -} - -func (w *Worker) Start(b *botlib.Bot[*client.Client]) { - b.Logger.Info("Worker Started.") - for _, wh := range w.handler { - go scheduleHandler(wh.Handler, wh.Minutes, b) - } -} - -func scheduleHandler(w WorkerFunc, minutes int, b *botlib.Bot[*client.Client]) { - var now time.Time - for { - b.Logger.Debug("working...") - if err := w(b); err != nil { - b.Logger.Errorf("error on worker: %s", err.Error()) - } - now = time.Now() - time.Sleep(time.Until(time.Date(now.Year(), now.Month(), now.Day(), now.Hour(), (now.Minute()-now.Minute()%minutes)+minutes, 0, 0, time.Local))) - } -} diff --git a/crowdin.yml b/crowdin.yml index 9c0436f1..468fcc0a 100644 --- a/crowdin.yml +++ b/crowdin.yml @@ -1,3 +1,3 @@ files: - - source: /lib/translate/ja.yaml - translation: /lib/tanslate/lang/%two_letters_code%.yaml + - source: /lang/ja.yaml + translation: /lang/%two_letters_code%.yaml diff --git a/ent/client.go b/ent/client.go new file mode 100644 index 00000000..0e4eeb07 --- /dev/null +++ b/ent/client.go @@ -0,0 +1,1851 @@ +// Code generated by ent, DO NOT EDIT. + +package ent + +import ( + "context" + "errors" + "fmt" + "log" + "reflect" + + snowflake "github.com/disgoorg/snowflake/v2" + "github.com/google/uuid" + "github.com/sabafly/gobot/ent/migrate" + + "entgo.io/ent" + "entgo.io/ent/dialect" + "entgo.io/ent/dialect/sql" + "entgo.io/ent/dialect/sql/sqlgraph" + "github.com/sabafly/gobot/ent/guild" + "github.com/sabafly/gobot/ent/member" + "github.com/sabafly/gobot/ent/messagepin" + "github.com/sabafly/gobot/ent/messageremind" + "github.com/sabafly/gobot/ent/rolepanel" + "github.com/sabafly/gobot/ent/rolepaneledit" + "github.com/sabafly/gobot/ent/rolepanelplaced" + "github.com/sabafly/gobot/ent/user" + "github.com/sabafly/gobot/ent/wordsuffix" +) + +// Client is the client that holds all ent builders. +type Client struct { + config + // Schema is the client for creating, migrating and dropping schema. + Schema *migrate.Schema + // Guild is the client for interacting with the Guild builders. + Guild *GuildClient + // Member is the client for interacting with the Member builders. + Member *MemberClient + // MessagePin is the client for interacting with the MessagePin builders. + MessagePin *MessagePinClient + // MessageRemind is the client for interacting with the MessageRemind builders. + MessageRemind *MessageRemindClient + // RolePanel is the client for interacting with the RolePanel builders. + RolePanel *RolePanelClient + // RolePanelEdit is the client for interacting with the RolePanelEdit builders. + RolePanelEdit *RolePanelEditClient + // RolePanelPlaced is the client for interacting with the RolePanelPlaced builders. + RolePanelPlaced *RolePanelPlacedClient + // User is the client for interacting with the User builders. + User *UserClient + // WordSuffix is the client for interacting with the WordSuffix builders. + WordSuffix *WordSuffixClient +} + +// NewClient creates a new client configured with the given options. +func NewClient(opts ...Option) *Client { + client := &Client{config: newConfig(opts...)} + client.init() + return client +} + +func (c *Client) init() { + c.Schema = migrate.NewSchema(c.driver) + c.Guild = NewGuildClient(c.config) + c.Member = NewMemberClient(c.config) + c.MessagePin = NewMessagePinClient(c.config) + c.MessageRemind = NewMessageRemindClient(c.config) + c.RolePanel = NewRolePanelClient(c.config) + c.RolePanelEdit = NewRolePanelEditClient(c.config) + c.RolePanelPlaced = NewRolePanelPlacedClient(c.config) + c.User = NewUserClient(c.config) + c.WordSuffix = NewWordSuffixClient(c.config) +} + +type ( + // config is the configuration for the client and its builder. + config struct { + // driver used for executing database requests. + driver dialect.Driver + // debug enable a debug logging. + debug bool + // log used for logging on debug mode. + log func(...any) + // hooks to execute on mutations. + hooks *hooks + // interceptors to execute on queries. + inters *inters + } + // Option function to configure the client. + Option func(*config) +) + +// newConfig creates a new config for the client. +func newConfig(opts ...Option) config { + cfg := config{log: log.Println, hooks: &hooks{}, inters: &inters{}} + cfg.options(opts...) + return cfg +} + +// options applies the options on the config object. +func (c *config) options(opts ...Option) { + for _, opt := range opts { + opt(c) + } + if c.debug { + c.driver = dialect.Debug(c.driver, c.log) + } +} + +// Debug enables debug logging on the ent.Driver. +func Debug() Option { + return func(c *config) { + c.debug = true + } +} + +// Log sets the logging function for debug mode. +func Log(fn func(...any)) Option { + return func(c *config) { + c.log = fn + } +} + +// Driver configures the client driver. +func Driver(driver dialect.Driver) Option { + return func(c *config) { + c.driver = driver + } +} + +// Open opens a database/sql.DB specified by the driver name and +// the data source name, and returns a new client attached to it. +// Optional parameters can be added for configuring the client. +func Open(driverName, dataSourceName string, options ...Option) (*Client, error) { + switch driverName { + case dialect.MySQL, dialect.Postgres, dialect.SQLite: + drv, err := sql.Open(driverName, dataSourceName) + if err != nil { + return nil, err + } + return NewClient(append(options, Driver(drv))...), nil + default: + return nil, fmt.Errorf("unsupported driver: %q", driverName) + } +} + +// ErrTxStarted is returned when trying to start a new transaction from a transactional client. +var ErrTxStarted = errors.New("ent: cannot start a transaction within a transaction") + +// Tx returns a new transactional client. The provided context +// is used until the transaction is committed or rolled back. +func (c *Client) Tx(ctx context.Context) (*Tx, error) { + if _, ok := c.driver.(*txDriver); ok { + return nil, ErrTxStarted + } + tx, err := newTx(ctx, c.driver) + if err != nil { + return nil, fmt.Errorf("ent: starting a transaction: %w", err) + } + cfg := c.config + cfg.driver = tx + return &Tx{ + ctx: ctx, + config: cfg, + Guild: NewGuildClient(cfg), + Member: NewMemberClient(cfg), + MessagePin: NewMessagePinClient(cfg), + MessageRemind: NewMessageRemindClient(cfg), + RolePanel: NewRolePanelClient(cfg), + RolePanelEdit: NewRolePanelEditClient(cfg), + RolePanelPlaced: NewRolePanelPlacedClient(cfg), + User: NewUserClient(cfg), + WordSuffix: NewWordSuffixClient(cfg), + }, nil +} + +// BeginTx returns a transactional client with specified options. +func (c *Client) BeginTx(ctx context.Context, opts *sql.TxOptions) (*Tx, error) { + if _, ok := c.driver.(*txDriver); ok { + return nil, errors.New("ent: cannot start a transaction within a transaction") + } + tx, err := c.driver.(interface { + BeginTx(context.Context, *sql.TxOptions) (dialect.Tx, error) + }).BeginTx(ctx, opts) + if err != nil { + return nil, fmt.Errorf("ent: starting a transaction: %w", err) + } + cfg := c.config + cfg.driver = &txDriver{tx: tx, drv: c.driver} + return &Tx{ + ctx: ctx, + config: cfg, + Guild: NewGuildClient(cfg), + Member: NewMemberClient(cfg), + MessagePin: NewMessagePinClient(cfg), + MessageRemind: NewMessageRemindClient(cfg), + RolePanel: NewRolePanelClient(cfg), + RolePanelEdit: NewRolePanelEditClient(cfg), + RolePanelPlaced: NewRolePanelPlacedClient(cfg), + User: NewUserClient(cfg), + WordSuffix: NewWordSuffixClient(cfg), + }, nil +} + +// Debug returns a new debug-client. It's used to get verbose logging on specific operations. +// +// client.Debug(). +// Guild. +// Query(). +// Count(ctx) +func (c *Client) Debug() *Client { + if c.debug { + return c + } + cfg := c.config + cfg.driver = dialect.Debug(c.driver, c.log) + client := &Client{config: cfg} + client.init() + return client +} + +// Close closes the database connection and prevents new queries from starting. +func (c *Client) Close() error { + return c.driver.Close() +} + +// Use adds the mutation hooks to all the entity clients. +// In order to add hooks to a specific client, call: `client.Node.Use(...)`. +func (c *Client) Use(hooks ...Hook) { + for _, n := range []interface{ Use(...Hook) }{ + c.Guild, c.Member, c.MessagePin, c.MessageRemind, c.RolePanel, c.RolePanelEdit, + c.RolePanelPlaced, c.User, c.WordSuffix, + } { + n.Use(hooks...) + } +} + +// Intercept adds the query interceptors to all the entity clients. +// In order to add interceptors to a specific client, call: `client.Node.Intercept(...)`. +func (c *Client) Intercept(interceptors ...Interceptor) { + for _, n := range []interface{ Intercept(...Interceptor) }{ + c.Guild, c.Member, c.MessagePin, c.MessageRemind, c.RolePanel, c.RolePanelEdit, + c.RolePanelPlaced, c.User, c.WordSuffix, + } { + n.Intercept(interceptors...) + } +} + +// Mutate implements the ent.Mutator interface. +func (c *Client) Mutate(ctx context.Context, m Mutation) (Value, error) { + switch m := m.(type) { + case *GuildMutation: + return c.Guild.mutate(ctx, m) + case *MemberMutation: + return c.Member.mutate(ctx, m) + case *MessagePinMutation: + return c.MessagePin.mutate(ctx, m) + case *MessageRemindMutation: + return c.MessageRemind.mutate(ctx, m) + case *RolePanelMutation: + return c.RolePanel.mutate(ctx, m) + case *RolePanelEditMutation: + return c.RolePanelEdit.mutate(ctx, m) + case *RolePanelPlacedMutation: + return c.RolePanelPlaced.mutate(ctx, m) + case *UserMutation: + return c.User.mutate(ctx, m) + case *WordSuffixMutation: + return c.WordSuffix.mutate(ctx, m) + default: + return nil, fmt.Errorf("ent: unknown mutation type %T", m) + } +} + +// GuildClient is a client for the Guild schema. +type GuildClient struct { + config +} + +// NewGuildClient returns a client for the Guild from the given config. +func NewGuildClient(c config) *GuildClient { + return &GuildClient{config: c} +} + +// Use adds a list of mutation hooks to the hooks stack. +// A call to `Use(f, g, h)` equals to `guild.Hooks(f(g(h())))`. +func (c *GuildClient) Use(hooks ...Hook) { + c.hooks.Guild = append(c.hooks.Guild, hooks...) +} + +// Intercept adds a list of query interceptors to the interceptors stack. +// A call to `Intercept(f, g, h)` equals to `guild.Intercept(f(g(h())))`. +func (c *GuildClient) Intercept(interceptors ...Interceptor) { + c.inters.Guild = append(c.inters.Guild, interceptors...) +} + +// Create returns a builder for creating a Guild entity. +func (c *GuildClient) Create() *GuildCreate { + mutation := newGuildMutation(c.config, OpCreate) + return &GuildCreate{config: c.config, hooks: c.Hooks(), mutation: mutation} +} + +// CreateBulk returns a builder for creating a bulk of Guild entities. +func (c *GuildClient) CreateBulk(builders ...*GuildCreate) *GuildCreateBulk { + return &GuildCreateBulk{config: c.config, builders: builders} +} + +// MapCreateBulk creates a bulk creation builder from the given slice. For each item in the slice, the function creates +// a builder and applies setFunc on it. +func (c *GuildClient) MapCreateBulk(slice any, setFunc func(*GuildCreate, int)) *GuildCreateBulk { + rv := reflect.ValueOf(slice) + if rv.Kind() != reflect.Slice { + return &GuildCreateBulk{err: fmt.Errorf("calling to GuildClient.MapCreateBulk with wrong type %T, need slice", slice)} + } + builders := make([]*GuildCreate, rv.Len()) + for i := 0; i < rv.Len(); i++ { + builders[i] = c.Create() + setFunc(builders[i], i) + } + return &GuildCreateBulk{config: c.config, builders: builders} +} + +// Update returns an update builder for Guild. +func (c *GuildClient) Update() *GuildUpdate { + mutation := newGuildMutation(c.config, OpUpdate) + return &GuildUpdate{config: c.config, hooks: c.Hooks(), mutation: mutation} +} + +// UpdateOne returns an update builder for the given entity. +func (c *GuildClient) UpdateOne(gu *Guild) *GuildUpdateOne { + mutation := newGuildMutation(c.config, OpUpdateOne, withGuild(gu)) + return &GuildUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation} +} + +// UpdateOneID returns an update builder for the given id. +func (c *GuildClient) UpdateOneID(id snowflake.ID) *GuildUpdateOne { + mutation := newGuildMutation(c.config, OpUpdateOne, withGuildID(id)) + return &GuildUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation} +} + +// Delete returns a delete builder for Guild. +func (c *GuildClient) Delete() *GuildDelete { + mutation := newGuildMutation(c.config, OpDelete) + return &GuildDelete{config: c.config, hooks: c.Hooks(), mutation: mutation} +} + +// DeleteOne returns a builder for deleting the given entity. +func (c *GuildClient) DeleteOne(gu *Guild) *GuildDeleteOne { + return c.DeleteOneID(gu.ID) +} + +// DeleteOneID returns a builder for deleting the given entity by its id. +func (c *GuildClient) DeleteOneID(id snowflake.ID) *GuildDeleteOne { + builder := c.Delete().Where(guild.ID(id)) + builder.mutation.id = &id + builder.mutation.op = OpDeleteOne + return &GuildDeleteOne{builder} +} + +// Query returns a query builder for Guild. +func (c *GuildClient) Query() *GuildQuery { + return &GuildQuery{ + config: c.config, + ctx: &QueryContext{Type: TypeGuild}, + inters: c.Interceptors(), + } +} + +// Get returns a Guild entity by its id. +func (c *GuildClient) Get(ctx context.Context, id snowflake.ID) (*Guild, error) { + return c.Query().Where(guild.ID(id)).Only(ctx) +} + +// GetX is like Get, but panics if an error occurs. +func (c *GuildClient) GetX(ctx context.Context, id snowflake.ID) *Guild { + obj, err := c.Get(ctx, id) + if err != nil { + panic(err) + } + return obj +} + +// QueryOwner queries the owner edge of a Guild. +func (c *GuildClient) QueryOwner(gu *Guild) *UserQuery { + query := (&UserClient{config: c.config}).Query() + query.path = func(context.Context) (fromV *sql.Selector, _ error) { + id := gu.ID + step := sqlgraph.NewStep( + sqlgraph.From(guild.Table, guild.FieldID, id), + sqlgraph.To(user.Table, user.FieldID), + sqlgraph.Edge(sqlgraph.M2O, true, guild.OwnerTable, guild.OwnerColumn), + ) + fromV = sqlgraph.Neighbors(gu.driver.Dialect(), step) + return fromV, nil + } + return query +} + +// QueryMembers queries the members edge of a Guild. +func (c *GuildClient) QueryMembers(gu *Guild) *MemberQuery { + query := (&MemberClient{config: c.config}).Query() + query.path = func(context.Context) (fromV *sql.Selector, _ error) { + id := gu.ID + step := sqlgraph.NewStep( + sqlgraph.From(guild.Table, guild.FieldID, id), + sqlgraph.To(member.Table, member.FieldID), + sqlgraph.Edge(sqlgraph.O2M, false, guild.MembersTable, guild.MembersColumn), + ) + fromV = sqlgraph.Neighbors(gu.driver.Dialect(), step) + return fromV, nil + } + return query +} + +// QueryMessagePins queries the message_pins edge of a Guild. +func (c *GuildClient) QueryMessagePins(gu *Guild) *MessagePinQuery { + query := (&MessagePinClient{config: c.config}).Query() + query.path = func(context.Context) (fromV *sql.Selector, _ error) { + id := gu.ID + step := sqlgraph.NewStep( + sqlgraph.From(guild.Table, guild.FieldID, id), + sqlgraph.To(messagepin.Table, messagepin.FieldID), + sqlgraph.Edge(sqlgraph.O2M, false, guild.MessagePinsTable, guild.MessagePinsColumn), + ) + fromV = sqlgraph.Neighbors(gu.driver.Dialect(), step) + return fromV, nil + } + return query +} + +// QueryReminds queries the reminds edge of a Guild. +func (c *GuildClient) QueryReminds(gu *Guild) *MessageRemindQuery { + query := (&MessageRemindClient{config: c.config}).Query() + query.path = func(context.Context) (fromV *sql.Selector, _ error) { + id := gu.ID + step := sqlgraph.NewStep( + sqlgraph.From(guild.Table, guild.FieldID, id), + sqlgraph.To(messageremind.Table, messageremind.FieldID), + sqlgraph.Edge(sqlgraph.O2M, false, guild.RemindsTable, guild.RemindsColumn), + ) + fromV = sqlgraph.Neighbors(gu.driver.Dialect(), step) + return fromV, nil + } + return query +} + +// QueryRolePanels queries the role_panels edge of a Guild. +func (c *GuildClient) QueryRolePanels(gu *Guild) *RolePanelQuery { + query := (&RolePanelClient{config: c.config}).Query() + query.path = func(context.Context) (fromV *sql.Selector, _ error) { + id := gu.ID + step := sqlgraph.NewStep( + sqlgraph.From(guild.Table, guild.FieldID, id), + sqlgraph.To(rolepanel.Table, rolepanel.FieldID), + sqlgraph.Edge(sqlgraph.O2M, false, guild.RolePanelsTable, guild.RolePanelsColumn), + ) + fromV = sqlgraph.Neighbors(gu.driver.Dialect(), step) + return fromV, nil + } + return query +} + +// QueryRolePanelPlacements queries the role_panel_placements edge of a Guild. +func (c *GuildClient) QueryRolePanelPlacements(gu *Guild) *RolePanelPlacedQuery { + query := (&RolePanelPlacedClient{config: c.config}).Query() + query.path = func(context.Context) (fromV *sql.Selector, _ error) { + id := gu.ID + step := sqlgraph.NewStep( + sqlgraph.From(guild.Table, guild.FieldID, id), + sqlgraph.To(rolepanelplaced.Table, rolepanelplaced.FieldID), + sqlgraph.Edge(sqlgraph.O2M, false, guild.RolePanelPlacementsTable, guild.RolePanelPlacementsColumn), + ) + fromV = sqlgraph.Neighbors(gu.driver.Dialect(), step) + return fromV, nil + } + return query +} + +// QueryRolePanelEdits queries the role_panel_edits edge of a Guild. +func (c *GuildClient) QueryRolePanelEdits(gu *Guild) *RolePanelEditQuery { + query := (&RolePanelEditClient{config: c.config}).Query() + query.path = func(context.Context) (fromV *sql.Selector, _ error) { + id := gu.ID + step := sqlgraph.NewStep( + sqlgraph.From(guild.Table, guild.FieldID, id), + sqlgraph.To(rolepaneledit.Table, rolepaneledit.FieldID), + sqlgraph.Edge(sqlgraph.O2M, false, guild.RolePanelEditsTable, guild.RolePanelEditsColumn), + ) + fromV = sqlgraph.Neighbors(gu.driver.Dialect(), step) + return fromV, nil + } + return query +} + +// Hooks returns the client hooks. +func (c *GuildClient) Hooks() []Hook { + return c.hooks.Guild +} + +// Interceptors returns the client interceptors. +func (c *GuildClient) Interceptors() []Interceptor { + return c.inters.Guild +} + +func (c *GuildClient) mutate(ctx context.Context, m *GuildMutation) (Value, error) { + switch m.Op() { + case OpCreate: + return (&GuildCreate{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx) + case OpUpdate: + return (&GuildUpdate{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx) + case OpUpdateOne: + return (&GuildUpdateOne{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx) + case OpDelete, OpDeleteOne: + return (&GuildDelete{config: c.config, hooks: c.Hooks(), mutation: m}).Exec(ctx) + default: + return nil, fmt.Errorf("ent: unknown Guild mutation op: %q", m.Op()) + } +} + +// MemberClient is a client for the Member schema. +type MemberClient struct { + config +} + +// NewMemberClient returns a client for the Member from the given config. +func NewMemberClient(c config) *MemberClient { + return &MemberClient{config: c} +} + +// Use adds a list of mutation hooks to the hooks stack. +// A call to `Use(f, g, h)` equals to `member.Hooks(f(g(h())))`. +func (c *MemberClient) Use(hooks ...Hook) { + c.hooks.Member = append(c.hooks.Member, hooks...) +} + +// Intercept adds a list of query interceptors to the interceptors stack. +// A call to `Intercept(f, g, h)` equals to `member.Intercept(f(g(h())))`. +func (c *MemberClient) Intercept(interceptors ...Interceptor) { + c.inters.Member = append(c.inters.Member, interceptors...) +} + +// Create returns a builder for creating a Member entity. +func (c *MemberClient) Create() *MemberCreate { + mutation := newMemberMutation(c.config, OpCreate) + return &MemberCreate{config: c.config, hooks: c.Hooks(), mutation: mutation} +} + +// CreateBulk returns a builder for creating a bulk of Member entities. +func (c *MemberClient) CreateBulk(builders ...*MemberCreate) *MemberCreateBulk { + return &MemberCreateBulk{config: c.config, builders: builders} +} + +// MapCreateBulk creates a bulk creation builder from the given slice. For each item in the slice, the function creates +// a builder and applies setFunc on it. +func (c *MemberClient) MapCreateBulk(slice any, setFunc func(*MemberCreate, int)) *MemberCreateBulk { + rv := reflect.ValueOf(slice) + if rv.Kind() != reflect.Slice { + return &MemberCreateBulk{err: fmt.Errorf("calling to MemberClient.MapCreateBulk with wrong type %T, need slice", slice)} + } + builders := make([]*MemberCreate, rv.Len()) + for i := 0; i < rv.Len(); i++ { + builders[i] = c.Create() + setFunc(builders[i], i) + } + return &MemberCreateBulk{config: c.config, builders: builders} +} + +// Update returns an update builder for Member. +func (c *MemberClient) Update() *MemberUpdate { + mutation := newMemberMutation(c.config, OpUpdate) + return &MemberUpdate{config: c.config, hooks: c.Hooks(), mutation: mutation} +} + +// UpdateOne returns an update builder for the given entity. +func (c *MemberClient) UpdateOne(m *Member) *MemberUpdateOne { + mutation := newMemberMutation(c.config, OpUpdateOne, withMember(m)) + return &MemberUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation} +} + +// UpdateOneID returns an update builder for the given id. +func (c *MemberClient) UpdateOneID(id int) *MemberUpdateOne { + mutation := newMemberMutation(c.config, OpUpdateOne, withMemberID(id)) + return &MemberUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation} +} + +// Delete returns a delete builder for Member. +func (c *MemberClient) Delete() *MemberDelete { + mutation := newMemberMutation(c.config, OpDelete) + return &MemberDelete{config: c.config, hooks: c.Hooks(), mutation: mutation} +} + +// DeleteOne returns a builder for deleting the given entity. +func (c *MemberClient) DeleteOne(m *Member) *MemberDeleteOne { + return c.DeleteOneID(m.ID) +} + +// DeleteOneID returns a builder for deleting the given entity by its id. +func (c *MemberClient) DeleteOneID(id int) *MemberDeleteOne { + builder := c.Delete().Where(member.ID(id)) + builder.mutation.id = &id + builder.mutation.op = OpDeleteOne + return &MemberDeleteOne{builder} +} + +// Query returns a query builder for Member. +func (c *MemberClient) Query() *MemberQuery { + return &MemberQuery{ + config: c.config, + ctx: &QueryContext{Type: TypeMember}, + inters: c.Interceptors(), + } +} + +// Get returns a Member entity by its id. +func (c *MemberClient) Get(ctx context.Context, id int) (*Member, error) { + return c.Query().Where(member.ID(id)).Only(ctx) +} + +// GetX is like Get, but panics if an error occurs. +func (c *MemberClient) GetX(ctx context.Context, id int) *Member { + obj, err := c.Get(ctx, id) + if err != nil { + panic(err) + } + return obj +} + +// QueryGuild queries the guild edge of a Member. +func (c *MemberClient) QueryGuild(m *Member) *GuildQuery { + query := (&GuildClient{config: c.config}).Query() + query.path = func(context.Context) (fromV *sql.Selector, _ error) { + id := m.ID + step := sqlgraph.NewStep( + sqlgraph.From(member.Table, member.FieldID, id), + sqlgraph.To(guild.Table, guild.FieldID), + sqlgraph.Edge(sqlgraph.M2O, true, member.GuildTable, member.GuildColumn), + ) + fromV = sqlgraph.Neighbors(m.driver.Dialect(), step) + return fromV, nil + } + return query +} + +// QueryUser queries the user edge of a Member. +func (c *MemberClient) QueryUser(m *Member) *UserQuery { + query := (&UserClient{config: c.config}).Query() + query.path = func(context.Context) (fromV *sql.Selector, _ error) { + id := m.ID + step := sqlgraph.NewStep( + sqlgraph.From(member.Table, member.FieldID, id), + sqlgraph.To(user.Table, user.FieldID), + sqlgraph.Edge(sqlgraph.M2O, true, member.UserTable, member.UserColumn), + ) + fromV = sqlgraph.Neighbors(m.driver.Dialect(), step) + return fromV, nil + } + return query +} + +// Hooks returns the client hooks. +func (c *MemberClient) Hooks() []Hook { + return c.hooks.Member +} + +// Interceptors returns the client interceptors. +func (c *MemberClient) Interceptors() []Interceptor { + return c.inters.Member +} + +func (c *MemberClient) mutate(ctx context.Context, m *MemberMutation) (Value, error) { + switch m.Op() { + case OpCreate: + return (&MemberCreate{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx) + case OpUpdate: + return (&MemberUpdate{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx) + case OpUpdateOne: + return (&MemberUpdateOne{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx) + case OpDelete, OpDeleteOne: + return (&MemberDelete{config: c.config, hooks: c.Hooks(), mutation: m}).Exec(ctx) + default: + return nil, fmt.Errorf("ent: unknown Member mutation op: %q", m.Op()) + } +} + +// MessagePinClient is a client for the MessagePin schema. +type MessagePinClient struct { + config +} + +// NewMessagePinClient returns a client for the MessagePin from the given config. +func NewMessagePinClient(c config) *MessagePinClient { + return &MessagePinClient{config: c} +} + +// Use adds a list of mutation hooks to the hooks stack. +// A call to `Use(f, g, h)` equals to `messagepin.Hooks(f(g(h())))`. +func (c *MessagePinClient) Use(hooks ...Hook) { + c.hooks.MessagePin = append(c.hooks.MessagePin, hooks...) +} + +// Intercept adds a list of query interceptors to the interceptors stack. +// A call to `Intercept(f, g, h)` equals to `messagepin.Intercept(f(g(h())))`. +func (c *MessagePinClient) Intercept(interceptors ...Interceptor) { + c.inters.MessagePin = append(c.inters.MessagePin, interceptors...) +} + +// Create returns a builder for creating a MessagePin entity. +func (c *MessagePinClient) Create() *MessagePinCreate { + mutation := newMessagePinMutation(c.config, OpCreate) + return &MessagePinCreate{config: c.config, hooks: c.Hooks(), mutation: mutation} +} + +// CreateBulk returns a builder for creating a bulk of MessagePin entities. +func (c *MessagePinClient) CreateBulk(builders ...*MessagePinCreate) *MessagePinCreateBulk { + return &MessagePinCreateBulk{config: c.config, builders: builders} +} + +// MapCreateBulk creates a bulk creation builder from the given slice. For each item in the slice, the function creates +// a builder and applies setFunc on it. +func (c *MessagePinClient) MapCreateBulk(slice any, setFunc func(*MessagePinCreate, int)) *MessagePinCreateBulk { + rv := reflect.ValueOf(slice) + if rv.Kind() != reflect.Slice { + return &MessagePinCreateBulk{err: fmt.Errorf("calling to MessagePinClient.MapCreateBulk with wrong type %T, need slice", slice)} + } + builders := make([]*MessagePinCreate, rv.Len()) + for i := 0; i < rv.Len(); i++ { + builders[i] = c.Create() + setFunc(builders[i], i) + } + return &MessagePinCreateBulk{config: c.config, builders: builders} +} + +// Update returns an update builder for MessagePin. +func (c *MessagePinClient) Update() *MessagePinUpdate { + mutation := newMessagePinMutation(c.config, OpUpdate) + return &MessagePinUpdate{config: c.config, hooks: c.Hooks(), mutation: mutation} +} + +// UpdateOne returns an update builder for the given entity. +func (c *MessagePinClient) UpdateOne(mp *MessagePin) *MessagePinUpdateOne { + mutation := newMessagePinMutation(c.config, OpUpdateOne, withMessagePin(mp)) + return &MessagePinUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation} +} + +// UpdateOneID returns an update builder for the given id. +func (c *MessagePinClient) UpdateOneID(id uuid.UUID) *MessagePinUpdateOne { + mutation := newMessagePinMutation(c.config, OpUpdateOne, withMessagePinID(id)) + return &MessagePinUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation} +} + +// Delete returns a delete builder for MessagePin. +func (c *MessagePinClient) Delete() *MessagePinDelete { + mutation := newMessagePinMutation(c.config, OpDelete) + return &MessagePinDelete{config: c.config, hooks: c.Hooks(), mutation: mutation} +} + +// DeleteOne returns a builder for deleting the given entity. +func (c *MessagePinClient) DeleteOne(mp *MessagePin) *MessagePinDeleteOne { + return c.DeleteOneID(mp.ID) +} + +// DeleteOneID returns a builder for deleting the given entity by its id. +func (c *MessagePinClient) DeleteOneID(id uuid.UUID) *MessagePinDeleteOne { + builder := c.Delete().Where(messagepin.ID(id)) + builder.mutation.id = &id + builder.mutation.op = OpDeleteOne + return &MessagePinDeleteOne{builder} +} + +// Query returns a query builder for MessagePin. +func (c *MessagePinClient) Query() *MessagePinQuery { + return &MessagePinQuery{ + config: c.config, + ctx: &QueryContext{Type: TypeMessagePin}, + inters: c.Interceptors(), + } +} + +// Get returns a MessagePin entity by its id. +func (c *MessagePinClient) Get(ctx context.Context, id uuid.UUID) (*MessagePin, error) { + return c.Query().Where(messagepin.ID(id)).Only(ctx) +} + +// GetX is like Get, but panics if an error occurs. +func (c *MessagePinClient) GetX(ctx context.Context, id uuid.UUID) *MessagePin { + obj, err := c.Get(ctx, id) + if err != nil { + panic(err) + } + return obj +} + +// QueryGuild queries the guild edge of a MessagePin. +func (c *MessagePinClient) QueryGuild(mp *MessagePin) *GuildQuery { + query := (&GuildClient{config: c.config}).Query() + query.path = func(context.Context) (fromV *sql.Selector, _ error) { + id := mp.ID + step := sqlgraph.NewStep( + sqlgraph.From(messagepin.Table, messagepin.FieldID, id), + sqlgraph.To(guild.Table, guild.FieldID), + sqlgraph.Edge(sqlgraph.M2O, true, messagepin.GuildTable, messagepin.GuildColumn), + ) + fromV = sqlgraph.Neighbors(mp.driver.Dialect(), step) + return fromV, nil + } + return query +} + +// Hooks returns the client hooks. +func (c *MessagePinClient) Hooks() []Hook { + return c.hooks.MessagePin +} + +// Interceptors returns the client interceptors. +func (c *MessagePinClient) Interceptors() []Interceptor { + return c.inters.MessagePin +} + +func (c *MessagePinClient) mutate(ctx context.Context, m *MessagePinMutation) (Value, error) { + switch m.Op() { + case OpCreate: + return (&MessagePinCreate{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx) + case OpUpdate: + return (&MessagePinUpdate{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx) + case OpUpdateOne: + return (&MessagePinUpdateOne{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx) + case OpDelete, OpDeleteOne: + return (&MessagePinDelete{config: c.config, hooks: c.Hooks(), mutation: m}).Exec(ctx) + default: + return nil, fmt.Errorf("ent: unknown MessagePin mutation op: %q", m.Op()) + } +} + +// MessageRemindClient is a client for the MessageRemind schema. +type MessageRemindClient struct { + config +} + +// NewMessageRemindClient returns a client for the MessageRemind from the given config. +func NewMessageRemindClient(c config) *MessageRemindClient { + return &MessageRemindClient{config: c} +} + +// Use adds a list of mutation hooks to the hooks stack. +// A call to `Use(f, g, h)` equals to `messageremind.Hooks(f(g(h())))`. +func (c *MessageRemindClient) Use(hooks ...Hook) { + c.hooks.MessageRemind = append(c.hooks.MessageRemind, hooks...) +} + +// Intercept adds a list of query interceptors to the interceptors stack. +// A call to `Intercept(f, g, h)` equals to `messageremind.Intercept(f(g(h())))`. +func (c *MessageRemindClient) Intercept(interceptors ...Interceptor) { + c.inters.MessageRemind = append(c.inters.MessageRemind, interceptors...) +} + +// Create returns a builder for creating a MessageRemind entity. +func (c *MessageRemindClient) Create() *MessageRemindCreate { + mutation := newMessageRemindMutation(c.config, OpCreate) + return &MessageRemindCreate{config: c.config, hooks: c.Hooks(), mutation: mutation} +} + +// CreateBulk returns a builder for creating a bulk of MessageRemind entities. +func (c *MessageRemindClient) CreateBulk(builders ...*MessageRemindCreate) *MessageRemindCreateBulk { + return &MessageRemindCreateBulk{config: c.config, builders: builders} +} + +// MapCreateBulk creates a bulk creation builder from the given slice. For each item in the slice, the function creates +// a builder and applies setFunc on it. +func (c *MessageRemindClient) MapCreateBulk(slice any, setFunc func(*MessageRemindCreate, int)) *MessageRemindCreateBulk { + rv := reflect.ValueOf(slice) + if rv.Kind() != reflect.Slice { + return &MessageRemindCreateBulk{err: fmt.Errorf("calling to MessageRemindClient.MapCreateBulk with wrong type %T, need slice", slice)} + } + builders := make([]*MessageRemindCreate, rv.Len()) + for i := 0; i < rv.Len(); i++ { + builders[i] = c.Create() + setFunc(builders[i], i) + } + return &MessageRemindCreateBulk{config: c.config, builders: builders} +} + +// Update returns an update builder for MessageRemind. +func (c *MessageRemindClient) Update() *MessageRemindUpdate { + mutation := newMessageRemindMutation(c.config, OpUpdate) + return &MessageRemindUpdate{config: c.config, hooks: c.Hooks(), mutation: mutation} +} + +// UpdateOne returns an update builder for the given entity. +func (c *MessageRemindClient) UpdateOne(mr *MessageRemind) *MessageRemindUpdateOne { + mutation := newMessageRemindMutation(c.config, OpUpdateOne, withMessageRemind(mr)) + return &MessageRemindUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation} +} + +// UpdateOneID returns an update builder for the given id. +func (c *MessageRemindClient) UpdateOneID(id uuid.UUID) *MessageRemindUpdateOne { + mutation := newMessageRemindMutation(c.config, OpUpdateOne, withMessageRemindID(id)) + return &MessageRemindUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation} +} + +// Delete returns a delete builder for MessageRemind. +func (c *MessageRemindClient) Delete() *MessageRemindDelete { + mutation := newMessageRemindMutation(c.config, OpDelete) + return &MessageRemindDelete{config: c.config, hooks: c.Hooks(), mutation: mutation} +} + +// DeleteOne returns a builder for deleting the given entity. +func (c *MessageRemindClient) DeleteOne(mr *MessageRemind) *MessageRemindDeleteOne { + return c.DeleteOneID(mr.ID) +} + +// DeleteOneID returns a builder for deleting the given entity by its id. +func (c *MessageRemindClient) DeleteOneID(id uuid.UUID) *MessageRemindDeleteOne { + builder := c.Delete().Where(messageremind.ID(id)) + builder.mutation.id = &id + builder.mutation.op = OpDeleteOne + return &MessageRemindDeleteOne{builder} +} + +// Query returns a query builder for MessageRemind. +func (c *MessageRemindClient) Query() *MessageRemindQuery { + return &MessageRemindQuery{ + config: c.config, + ctx: &QueryContext{Type: TypeMessageRemind}, + inters: c.Interceptors(), + } +} + +// Get returns a MessageRemind entity by its id. +func (c *MessageRemindClient) Get(ctx context.Context, id uuid.UUID) (*MessageRemind, error) { + return c.Query().Where(messageremind.ID(id)).Only(ctx) +} + +// GetX is like Get, but panics if an error occurs. +func (c *MessageRemindClient) GetX(ctx context.Context, id uuid.UUID) *MessageRemind { + obj, err := c.Get(ctx, id) + if err != nil { + panic(err) + } + return obj +} + +// QueryGuild queries the guild edge of a MessageRemind. +func (c *MessageRemindClient) QueryGuild(mr *MessageRemind) *GuildQuery { + query := (&GuildClient{config: c.config}).Query() + query.path = func(context.Context) (fromV *sql.Selector, _ error) { + id := mr.ID + step := sqlgraph.NewStep( + sqlgraph.From(messageremind.Table, messageremind.FieldID, id), + sqlgraph.To(guild.Table, guild.FieldID), + sqlgraph.Edge(sqlgraph.M2O, true, messageremind.GuildTable, messageremind.GuildColumn), + ) + fromV = sqlgraph.Neighbors(mr.driver.Dialect(), step) + return fromV, nil + } + return query +} + +// Hooks returns the client hooks. +func (c *MessageRemindClient) Hooks() []Hook { + return c.hooks.MessageRemind +} + +// Interceptors returns the client interceptors. +func (c *MessageRemindClient) Interceptors() []Interceptor { + return c.inters.MessageRemind +} + +func (c *MessageRemindClient) mutate(ctx context.Context, m *MessageRemindMutation) (Value, error) { + switch m.Op() { + case OpCreate: + return (&MessageRemindCreate{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx) + case OpUpdate: + return (&MessageRemindUpdate{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx) + case OpUpdateOne: + return (&MessageRemindUpdateOne{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx) + case OpDelete, OpDeleteOne: + return (&MessageRemindDelete{config: c.config, hooks: c.Hooks(), mutation: m}).Exec(ctx) + default: + return nil, fmt.Errorf("ent: unknown MessageRemind mutation op: %q", m.Op()) + } +} + +// RolePanelClient is a client for the RolePanel schema. +type RolePanelClient struct { + config +} + +// NewRolePanelClient returns a client for the RolePanel from the given config. +func NewRolePanelClient(c config) *RolePanelClient { + return &RolePanelClient{config: c} +} + +// Use adds a list of mutation hooks to the hooks stack. +// A call to `Use(f, g, h)` equals to `rolepanel.Hooks(f(g(h())))`. +func (c *RolePanelClient) Use(hooks ...Hook) { + c.hooks.RolePanel = append(c.hooks.RolePanel, hooks...) +} + +// Intercept adds a list of query interceptors to the interceptors stack. +// A call to `Intercept(f, g, h)` equals to `rolepanel.Intercept(f(g(h())))`. +func (c *RolePanelClient) Intercept(interceptors ...Interceptor) { + c.inters.RolePanel = append(c.inters.RolePanel, interceptors...) +} + +// Create returns a builder for creating a RolePanel entity. +func (c *RolePanelClient) Create() *RolePanelCreate { + mutation := newRolePanelMutation(c.config, OpCreate) + return &RolePanelCreate{config: c.config, hooks: c.Hooks(), mutation: mutation} +} + +// CreateBulk returns a builder for creating a bulk of RolePanel entities. +func (c *RolePanelClient) CreateBulk(builders ...*RolePanelCreate) *RolePanelCreateBulk { + return &RolePanelCreateBulk{config: c.config, builders: builders} +} + +// MapCreateBulk creates a bulk creation builder from the given slice. For each item in the slice, the function creates +// a builder and applies setFunc on it. +func (c *RolePanelClient) MapCreateBulk(slice any, setFunc func(*RolePanelCreate, int)) *RolePanelCreateBulk { + rv := reflect.ValueOf(slice) + if rv.Kind() != reflect.Slice { + return &RolePanelCreateBulk{err: fmt.Errorf("calling to RolePanelClient.MapCreateBulk with wrong type %T, need slice", slice)} + } + builders := make([]*RolePanelCreate, rv.Len()) + for i := 0; i < rv.Len(); i++ { + builders[i] = c.Create() + setFunc(builders[i], i) + } + return &RolePanelCreateBulk{config: c.config, builders: builders} +} + +// Update returns an update builder for RolePanel. +func (c *RolePanelClient) Update() *RolePanelUpdate { + mutation := newRolePanelMutation(c.config, OpUpdate) + return &RolePanelUpdate{config: c.config, hooks: c.Hooks(), mutation: mutation} +} + +// UpdateOne returns an update builder for the given entity. +func (c *RolePanelClient) UpdateOne(rp *RolePanel) *RolePanelUpdateOne { + mutation := newRolePanelMutation(c.config, OpUpdateOne, withRolePanel(rp)) + return &RolePanelUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation} +} + +// UpdateOneID returns an update builder for the given id. +func (c *RolePanelClient) UpdateOneID(id uuid.UUID) *RolePanelUpdateOne { + mutation := newRolePanelMutation(c.config, OpUpdateOne, withRolePanelID(id)) + return &RolePanelUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation} +} + +// Delete returns a delete builder for RolePanel. +func (c *RolePanelClient) Delete() *RolePanelDelete { + mutation := newRolePanelMutation(c.config, OpDelete) + return &RolePanelDelete{config: c.config, hooks: c.Hooks(), mutation: mutation} +} + +// DeleteOne returns a builder for deleting the given entity. +func (c *RolePanelClient) DeleteOne(rp *RolePanel) *RolePanelDeleteOne { + return c.DeleteOneID(rp.ID) +} + +// DeleteOneID returns a builder for deleting the given entity by its id. +func (c *RolePanelClient) DeleteOneID(id uuid.UUID) *RolePanelDeleteOne { + builder := c.Delete().Where(rolepanel.ID(id)) + builder.mutation.id = &id + builder.mutation.op = OpDeleteOne + return &RolePanelDeleteOne{builder} +} + +// Query returns a query builder for RolePanel. +func (c *RolePanelClient) Query() *RolePanelQuery { + return &RolePanelQuery{ + config: c.config, + ctx: &QueryContext{Type: TypeRolePanel}, + inters: c.Interceptors(), + } +} + +// Get returns a RolePanel entity by its id. +func (c *RolePanelClient) Get(ctx context.Context, id uuid.UUID) (*RolePanel, error) { + return c.Query().Where(rolepanel.ID(id)).Only(ctx) +} + +// GetX is like Get, but panics if an error occurs. +func (c *RolePanelClient) GetX(ctx context.Context, id uuid.UUID) *RolePanel { + obj, err := c.Get(ctx, id) + if err != nil { + panic(err) + } + return obj +} + +// QueryGuild queries the guild edge of a RolePanel. +func (c *RolePanelClient) QueryGuild(rp *RolePanel) *GuildQuery { + query := (&GuildClient{config: c.config}).Query() + query.path = func(context.Context) (fromV *sql.Selector, _ error) { + id := rp.ID + step := sqlgraph.NewStep( + sqlgraph.From(rolepanel.Table, rolepanel.FieldID, id), + sqlgraph.To(guild.Table, guild.FieldID), + sqlgraph.Edge(sqlgraph.M2O, true, rolepanel.GuildTable, rolepanel.GuildColumn), + ) + fromV = sqlgraph.Neighbors(rp.driver.Dialect(), step) + return fromV, nil + } + return query +} + +// QueryPlacements queries the placements edge of a RolePanel. +func (c *RolePanelClient) QueryPlacements(rp *RolePanel) *RolePanelPlacedQuery { + query := (&RolePanelPlacedClient{config: c.config}).Query() + query.path = func(context.Context) (fromV *sql.Selector, _ error) { + id := rp.ID + step := sqlgraph.NewStep( + sqlgraph.From(rolepanel.Table, rolepanel.FieldID, id), + sqlgraph.To(rolepanelplaced.Table, rolepanelplaced.FieldID), + sqlgraph.Edge(sqlgraph.O2M, false, rolepanel.PlacementsTable, rolepanel.PlacementsColumn), + ) + fromV = sqlgraph.Neighbors(rp.driver.Dialect(), step) + return fromV, nil + } + return query +} + +// QueryEdit queries the edit edge of a RolePanel. +func (c *RolePanelClient) QueryEdit(rp *RolePanel) *RolePanelEditQuery { + query := (&RolePanelEditClient{config: c.config}).Query() + query.path = func(context.Context) (fromV *sql.Selector, _ error) { + id := rp.ID + step := sqlgraph.NewStep( + sqlgraph.From(rolepanel.Table, rolepanel.FieldID, id), + sqlgraph.To(rolepaneledit.Table, rolepaneledit.FieldID), + sqlgraph.Edge(sqlgraph.O2O, false, rolepanel.EditTable, rolepanel.EditColumn), + ) + fromV = sqlgraph.Neighbors(rp.driver.Dialect(), step) + return fromV, nil + } + return query +} + +// Hooks returns the client hooks. +func (c *RolePanelClient) Hooks() []Hook { + return c.hooks.RolePanel +} + +// Interceptors returns the client interceptors. +func (c *RolePanelClient) Interceptors() []Interceptor { + return c.inters.RolePanel +} + +func (c *RolePanelClient) mutate(ctx context.Context, m *RolePanelMutation) (Value, error) { + switch m.Op() { + case OpCreate: + return (&RolePanelCreate{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx) + case OpUpdate: + return (&RolePanelUpdate{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx) + case OpUpdateOne: + return (&RolePanelUpdateOne{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx) + case OpDelete, OpDeleteOne: + return (&RolePanelDelete{config: c.config, hooks: c.Hooks(), mutation: m}).Exec(ctx) + default: + return nil, fmt.Errorf("ent: unknown RolePanel mutation op: %q", m.Op()) + } +} + +// RolePanelEditClient is a client for the RolePanelEdit schema. +type RolePanelEditClient struct { + config +} + +// NewRolePanelEditClient returns a client for the RolePanelEdit from the given config. +func NewRolePanelEditClient(c config) *RolePanelEditClient { + return &RolePanelEditClient{config: c} +} + +// Use adds a list of mutation hooks to the hooks stack. +// A call to `Use(f, g, h)` equals to `rolepaneledit.Hooks(f(g(h())))`. +func (c *RolePanelEditClient) Use(hooks ...Hook) { + c.hooks.RolePanelEdit = append(c.hooks.RolePanelEdit, hooks...) +} + +// Intercept adds a list of query interceptors to the interceptors stack. +// A call to `Intercept(f, g, h)` equals to `rolepaneledit.Intercept(f(g(h())))`. +func (c *RolePanelEditClient) Intercept(interceptors ...Interceptor) { + c.inters.RolePanelEdit = append(c.inters.RolePanelEdit, interceptors...) +} + +// Create returns a builder for creating a RolePanelEdit entity. +func (c *RolePanelEditClient) Create() *RolePanelEditCreate { + mutation := newRolePanelEditMutation(c.config, OpCreate) + return &RolePanelEditCreate{config: c.config, hooks: c.Hooks(), mutation: mutation} +} + +// CreateBulk returns a builder for creating a bulk of RolePanelEdit entities. +func (c *RolePanelEditClient) CreateBulk(builders ...*RolePanelEditCreate) *RolePanelEditCreateBulk { + return &RolePanelEditCreateBulk{config: c.config, builders: builders} +} + +// MapCreateBulk creates a bulk creation builder from the given slice. For each item in the slice, the function creates +// a builder and applies setFunc on it. +func (c *RolePanelEditClient) MapCreateBulk(slice any, setFunc func(*RolePanelEditCreate, int)) *RolePanelEditCreateBulk { + rv := reflect.ValueOf(slice) + if rv.Kind() != reflect.Slice { + return &RolePanelEditCreateBulk{err: fmt.Errorf("calling to RolePanelEditClient.MapCreateBulk with wrong type %T, need slice", slice)} + } + builders := make([]*RolePanelEditCreate, rv.Len()) + for i := 0; i < rv.Len(); i++ { + builders[i] = c.Create() + setFunc(builders[i], i) + } + return &RolePanelEditCreateBulk{config: c.config, builders: builders} +} + +// Update returns an update builder for RolePanelEdit. +func (c *RolePanelEditClient) Update() *RolePanelEditUpdate { + mutation := newRolePanelEditMutation(c.config, OpUpdate) + return &RolePanelEditUpdate{config: c.config, hooks: c.Hooks(), mutation: mutation} +} + +// UpdateOne returns an update builder for the given entity. +func (c *RolePanelEditClient) UpdateOne(rpe *RolePanelEdit) *RolePanelEditUpdateOne { + mutation := newRolePanelEditMutation(c.config, OpUpdateOne, withRolePanelEdit(rpe)) + return &RolePanelEditUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation} +} + +// UpdateOneID returns an update builder for the given id. +func (c *RolePanelEditClient) UpdateOneID(id uuid.UUID) *RolePanelEditUpdateOne { + mutation := newRolePanelEditMutation(c.config, OpUpdateOne, withRolePanelEditID(id)) + return &RolePanelEditUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation} +} + +// Delete returns a delete builder for RolePanelEdit. +func (c *RolePanelEditClient) Delete() *RolePanelEditDelete { + mutation := newRolePanelEditMutation(c.config, OpDelete) + return &RolePanelEditDelete{config: c.config, hooks: c.Hooks(), mutation: mutation} +} + +// DeleteOne returns a builder for deleting the given entity. +func (c *RolePanelEditClient) DeleteOne(rpe *RolePanelEdit) *RolePanelEditDeleteOne { + return c.DeleteOneID(rpe.ID) +} + +// DeleteOneID returns a builder for deleting the given entity by its id. +func (c *RolePanelEditClient) DeleteOneID(id uuid.UUID) *RolePanelEditDeleteOne { + builder := c.Delete().Where(rolepaneledit.ID(id)) + builder.mutation.id = &id + builder.mutation.op = OpDeleteOne + return &RolePanelEditDeleteOne{builder} +} + +// Query returns a query builder for RolePanelEdit. +func (c *RolePanelEditClient) Query() *RolePanelEditQuery { + return &RolePanelEditQuery{ + config: c.config, + ctx: &QueryContext{Type: TypeRolePanelEdit}, + inters: c.Interceptors(), + } +} + +// Get returns a RolePanelEdit entity by its id. +func (c *RolePanelEditClient) Get(ctx context.Context, id uuid.UUID) (*RolePanelEdit, error) { + return c.Query().Where(rolepaneledit.ID(id)).Only(ctx) +} + +// GetX is like Get, but panics if an error occurs. +func (c *RolePanelEditClient) GetX(ctx context.Context, id uuid.UUID) *RolePanelEdit { + obj, err := c.Get(ctx, id) + if err != nil { + panic(err) + } + return obj +} + +// QueryGuild queries the guild edge of a RolePanelEdit. +func (c *RolePanelEditClient) QueryGuild(rpe *RolePanelEdit) *GuildQuery { + query := (&GuildClient{config: c.config}).Query() + query.path = func(context.Context) (fromV *sql.Selector, _ error) { + id := rpe.ID + step := sqlgraph.NewStep( + sqlgraph.From(rolepaneledit.Table, rolepaneledit.FieldID, id), + sqlgraph.To(guild.Table, guild.FieldID), + sqlgraph.Edge(sqlgraph.M2O, true, rolepaneledit.GuildTable, rolepaneledit.GuildColumn), + ) + fromV = sqlgraph.Neighbors(rpe.driver.Dialect(), step) + return fromV, nil + } + return query +} + +// QueryParent queries the parent edge of a RolePanelEdit. +func (c *RolePanelEditClient) QueryParent(rpe *RolePanelEdit) *RolePanelQuery { + query := (&RolePanelClient{config: c.config}).Query() + query.path = func(context.Context) (fromV *sql.Selector, _ error) { + id := rpe.ID + step := sqlgraph.NewStep( + sqlgraph.From(rolepaneledit.Table, rolepaneledit.FieldID, id), + sqlgraph.To(rolepanel.Table, rolepanel.FieldID), + sqlgraph.Edge(sqlgraph.O2O, true, rolepaneledit.ParentTable, rolepaneledit.ParentColumn), + ) + fromV = sqlgraph.Neighbors(rpe.driver.Dialect(), step) + return fromV, nil + } + return query +} + +// Hooks returns the client hooks. +func (c *RolePanelEditClient) Hooks() []Hook { + return c.hooks.RolePanelEdit +} + +// Interceptors returns the client interceptors. +func (c *RolePanelEditClient) Interceptors() []Interceptor { + return c.inters.RolePanelEdit +} + +func (c *RolePanelEditClient) mutate(ctx context.Context, m *RolePanelEditMutation) (Value, error) { + switch m.Op() { + case OpCreate: + return (&RolePanelEditCreate{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx) + case OpUpdate: + return (&RolePanelEditUpdate{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx) + case OpUpdateOne: + return (&RolePanelEditUpdateOne{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx) + case OpDelete, OpDeleteOne: + return (&RolePanelEditDelete{config: c.config, hooks: c.Hooks(), mutation: m}).Exec(ctx) + default: + return nil, fmt.Errorf("ent: unknown RolePanelEdit mutation op: %q", m.Op()) + } +} + +// RolePanelPlacedClient is a client for the RolePanelPlaced schema. +type RolePanelPlacedClient struct { + config +} + +// NewRolePanelPlacedClient returns a client for the RolePanelPlaced from the given config. +func NewRolePanelPlacedClient(c config) *RolePanelPlacedClient { + return &RolePanelPlacedClient{config: c} +} + +// Use adds a list of mutation hooks to the hooks stack. +// A call to `Use(f, g, h)` equals to `rolepanelplaced.Hooks(f(g(h())))`. +func (c *RolePanelPlacedClient) Use(hooks ...Hook) { + c.hooks.RolePanelPlaced = append(c.hooks.RolePanelPlaced, hooks...) +} + +// Intercept adds a list of query interceptors to the interceptors stack. +// A call to `Intercept(f, g, h)` equals to `rolepanelplaced.Intercept(f(g(h())))`. +func (c *RolePanelPlacedClient) Intercept(interceptors ...Interceptor) { + c.inters.RolePanelPlaced = append(c.inters.RolePanelPlaced, interceptors...) +} + +// Create returns a builder for creating a RolePanelPlaced entity. +func (c *RolePanelPlacedClient) Create() *RolePanelPlacedCreate { + mutation := newRolePanelPlacedMutation(c.config, OpCreate) + return &RolePanelPlacedCreate{config: c.config, hooks: c.Hooks(), mutation: mutation} +} + +// CreateBulk returns a builder for creating a bulk of RolePanelPlaced entities. +func (c *RolePanelPlacedClient) CreateBulk(builders ...*RolePanelPlacedCreate) *RolePanelPlacedCreateBulk { + return &RolePanelPlacedCreateBulk{config: c.config, builders: builders} +} + +// MapCreateBulk creates a bulk creation builder from the given slice. For each item in the slice, the function creates +// a builder and applies setFunc on it. +func (c *RolePanelPlacedClient) MapCreateBulk(slice any, setFunc func(*RolePanelPlacedCreate, int)) *RolePanelPlacedCreateBulk { + rv := reflect.ValueOf(slice) + if rv.Kind() != reflect.Slice { + return &RolePanelPlacedCreateBulk{err: fmt.Errorf("calling to RolePanelPlacedClient.MapCreateBulk with wrong type %T, need slice", slice)} + } + builders := make([]*RolePanelPlacedCreate, rv.Len()) + for i := 0; i < rv.Len(); i++ { + builders[i] = c.Create() + setFunc(builders[i], i) + } + return &RolePanelPlacedCreateBulk{config: c.config, builders: builders} +} + +// Update returns an update builder for RolePanelPlaced. +func (c *RolePanelPlacedClient) Update() *RolePanelPlacedUpdate { + mutation := newRolePanelPlacedMutation(c.config, OpUpdate) + return &RolePanelPlacedUpdate{config: c.config, hooks: c.Hooks(), mutation: mutation} +} + +// UpdateOne returns an update builder for the given entity. +func (c *RolePanelPlacedClient) UpdateOne(rpp *RolePanelPlaced) *RolePanelPlacedUpdateOne { + mutation := newRolePanelPlacedMutation(c.config, OpUpdateOne, withRolePanelPlaced(rpp)) + return &RolePanelPlacedUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation} +} + +// UpdateOneID returns an update builder for the given id. +func (c *RolePanelPlacedClient) UpdateOneID(id uuid.UUID) *RolePanelPlacedUpdateOne { + mutation := newRolePanelPlacedMutation(c.config, OpUpdateOne, withRolePanelPlacedID(id)) + return &RolePanelPlacedUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation} +} + +// Delete returns a delete builder for RolePanelPlaced. +func (c *RolePanelPlacedClient) Delete() *RolePanelPlacedDelete { + mutation := newRolePanelPlacedMutation(c.config, OpDelete) + return &RolePanelPlacedDelete{config: c.config, hooks: c.Hooks(), mutation: mutation} +} + +// DeleteOne returns a builder for deleting the given entity. +func (c *RolePanelPlacedClient) DeleteOne(rpp *RolePanelPlaced) *RolePanelPlacedDeleteOne { + return c.DeleteOneID(rpp.ID) +} + +// DeleteOneID returns a builder for deleting the given entity by its id. +func (c *RolePanelPlacedClient) DeleteOneID(id uuid.UUID) *RolePanelPlacedDeleteOne { + builder := c.Delete().Where(rolepanelplaced.ID(id)) + builder.mutation.id = &id + builder.mutation.op = OpDeleteOne + return &RolePanelPlacedDeleteOne{builder} +} + +// Query returns a query builder for RolePanelPlaced. +func (c *RolePanelPlacedClient) Query() *RolePanelPlacedQuery { + return &RolePanelPlacedQuery{ + config: c.config, + ctx: &QueryContext{Type: TypeRolePanelPlaced}, + inters: c.Interceptors(), + } +} + +// Get returns a RolePanelPlaced entity by its id. +func (c *RolePanelPlacedClient) Get(ctx context.Context, id uuid.UUID) (*RolePanelPlaced, error) { + return c.Query().Where(rolepanelplaced.ID(id)).Only(ctx) +} + +// GetX is like Get, but panics if an error occurs. +func (c *RolePanelPlacedClient) GetX(ctx context.Context, id uuid.UUID) *RolePanelPlaced { + obj, err := c.Get(ctx, id) + if err != nil { + panic(err) + } + return obj +} + +// QueryGuild queries the guild edge of a RolePanelPlaced. +func (c *RolePanelPlacedClient) QueryGuild(rpp *RolePanelPlaced) *GuildQuery { + query := (&GuildClient{config: c.config}).Query() + query.path = func(context.Context) (fromV *sql.Selector, _ error) { + id := rpp.ID + step := sqlgraph.NewStep( + sqlgraph.From(rolepanelplaced.Table, rolepanelplaced.FieldID, id), + sqlgraph.To(guild.Table, guild.FieldID), + sqlgraph.Edge(sqlgraph.M2O, true, rolepanelplaced.GuildTable, rolepanelplaced.GuildColumn), + ) + fromV = sqlgraph.Neighbors(rpp.driver.Dialect(), step) + return fromV, nil + } + return query +} + +// QueryRolePanel queries the role_panel edge of a RolePanelPlaced. +func (c *RolePanelPlacedClient) QueryRolePanel(rpp *RolePanelPlaced) *RolePanelQuery { + query := (&RolePanelClient{config: c.config}).Query() + query.path = func(context.Context) (fromV *sql.Selector, _ error) { + id := rpp.ID + step := sqlgraph.NewStep( + sqlgraph.From(rolepanelplaced.Table, rolepanelplaced.FieldID, id), + sqlgraph.To(rolepanel.Table, rolepanel.FieldID), + sqlgraph.Edge(sqlgraph.M2O, true, rolepanelplaced.RolePanelTable, rolepanelplaced.RolePanelColumn), + ) + fromV = sqlgraph.Neighbors(rpp.driver.Dialect(), step) + return fromV, nil + } + return query +} + +// Hooks returns the client hooks. +func (c *RolePanelPlacedClient) Hooks() []Hook { + return c.hooks.RolePanelPlaced +} + +// Interceptors returns the client interceptors. +func (c *RolePanelPlacedClient) Interceptors() []Interceptor { + return c.inters.RolePanelPlaced +} + +func (c *RolePanelPlacedClient) mutate(ctx context.Context, m *RolePanelPlacedMutation) (Value, error) { + switch m.Op() { + case OpCreate: + return (&RolePanelPlacedCreate{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx) + case OpUpdate: + return (&RolePanelPlacedUpdate{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx) + case OpUpdateOne: + return (&RolePanelPlacedUpdateOne{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx) + case OpDelete, OpDeleteOne: + return (&RolePanelPlacedDelete{config: c.config, hooks: c.Hooks(), mutation: m}).Exec(ctx) + default: + return nil, fmt.Errorf("ent: unknown RolePanelPlaced mutation op: %q", m.Op()) + } +} + +// UserClient is a client for the User schema. +type UserClient struct { + config +} + +// NewUserClient returns a client for the User from the given config. +func NewUserClient(c config) *UserClient { + return &UserClient{config: c} +} + +// Use adds a list of mutation hooks to the hooks stack. +// A call to `Use(f, g, h)` equals to `user.Hooks(f(g(h())))`. +func (c *UserClient) Use(hooks ...Hook) { + c.hooks.User = append(c.hooks.User, hooks...) +} + +// Intercept adds a list of query interceptors to the interceptors stack. +// A call to `Intercept(f, g, h)` equals to `user.Intercept(f(g(h())))`. +func (c *UserClient) Intercept(interceptors ...Interceptor) { + c.inters.User = append(c.inters.User, interceptors...) +} + +// Create returns a builder for creating a User entity. +func (c *UserClient) Create() *UserCreate { + mutation := newUserMutation(c.config, OpCreate) + return &UserCreate{config: c.config, hooks: c.Hooks(), mutation: mutation} +} + +// CreateBulk returns a builder for creating a bulk of User entities. +func (c *UserClient) CreateBulk(builders ...*UserCreate) *UserCreateBulk { + return &UserCreateBulk{config: c.config, builders: builders} +} + +// MapCreateBulk creates a bulk creation builder from the given slice. For each item in the slice, the function creates +// a builder and applies setFunc on it. +func (c *UserClient) MapCreateBulk(slice any, setFunc func(*UserCreate, int)) *UserCreateBulk { + rv := reflect.ValueOf(slice) + if rv.Kind() != reflect.Slice { + return &UserCreateBulk{err: fmt.Errorf("calling to UserClient.MapCreateBulk with wrong type %T, need slice", slice)} + } + builders := make([]*UserCreate, rv.Len()) + for i := 0; i < rv.Len(); i++ { + builders[i] = c.Create() + setFunc(builders[i], i) + } + return &UserCreateBulk{config: c.config, builders: builders} +} + +// Update returns an update builder for User. +func (c *UserClient) Update() *UserUpdate { + mutation := newUserMutation(c.config, OpUpdate) + return &UserUpdate{config: c.config, hooks: c.Hooks(), mutation: mutation} +} + +// UpdateOne returns an update builder for the given entity. +func (c *UserClient) UpdateOne(u *User) *UserUpdateOne { + mutation := newUserMutation(c.config, OpUpdateOne, withUser(u)) + return &UserUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation} +} + +// UpdateOneID returns an update builder for the given id. +func (c *UserClient) UpdateOneID(id snowflake.ID) *UserUpdateOne { + mutation := newUserMutation(c.config, OpUpdateOne, withUserID(id)) + return &UserUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation} +} + +// Delete returns a delete builder for User. +func (c *UserClient) Delete() *UserDelete { + mutation := newUserMutation(c.config, OpDelete) + return &UserDelete{config: c.config, hooks: c.Hooks(), mutation: mutation} +} + +// DeleteOne returns a builder for deleting the given entity. +func (c *UserClient) DeleteOne(u *User) *UserDeleteOne { + return c.DeleteOneID(u.ID) +} + +// DeleteOneID returns a builder for deleting the given entity by its id. +func (c *UserClient) DeleteOneID(id snowflake.ID) *UserDeleteOne { + builder := c.Delete().Where(user.ID(id)) + builder.mutation.id = &id + builder.mutation.op = OpDeleteOne + return &UserDeleteOne{builder} +} + +// Query returns a query builder for User. +func (c *UserClient) Query() *UserQuery { + return &UserQuery{ + config: c.config, + ctx: &QueryContext{Type: TypeUser}, + inters: c.Interceptors(), + } +} + +// Get returns a User entity by its id. +func (c *UserClient) Get(ctx context.Context, id snowflake.ID) (*User, error) { + return c.Query().Where(user.ID(id)).Only(ctx) +} + +// GetX is like Get, but panics if an error occurs. +func (c *UserClient) GetX(ctx context.Context, id snowflake.ID) *User { + obj, err := c.Get(ctx, id) + if err != nil { + panic(err) + } + return obj +} + +// QueryOwnGuilds queries the own_guilds edge of a User. +func (c *UserClient) QueryOwnGuilds(u *User) *GuildQuery { + query := (&GuildClient{config: c.config}).Query() + query.path = func(context.Context) (fromV *sql.Selector, _ error) { + id := u.ID + step := sqlgraph.NewStep( + sqlgraph.From(user.Table, user.FieldID, id), + sqlgraph.To(guild.Table, guild.FieldID), + sqlgraph.Edge(sqlgraph.O2M, false, user.OwnGuildsTable, user.OwnGuildsColumn), + ) + fromV = sqlgraph.Neighbors(u.driver.Dialect(), step) + return fromV, nil + } + return query +} + +// QueryGuilds queries the guilds edge of a User. +func (c *UserClient) QueryGuilds(u *User) *MemberQuery { + query := (&MemberClient{config: c.config}).Query() + query.path = func(context.Context) (fromV *sql.Selector, _ error) { + id := u.ID + step := sqlgraph.NewStep( + sqlgraph.From(user.Table, user.FieldID, id), + sqlgraph.To(member.Table, member.FieldID), + sqlgraph.Edge(sqlgraph.O2M, false, user.GuildsTable, user.GuildsColumn), + ) + fromV = sqlgraph.Neighbors(u.driver.Dialect(), step) + return fromV, nil + } + return query +} + +// QueryWordSuffix queries the word_suffix edge of a User. +func (c *UserClient) QueryWordSuffix(u *User) *WordSuffixQuery { + query := (&WordSuffixClient{config: c.config}).Query() + query.path = func(context.Context) (fromV *sql.Selector, _ error) { + id := u.ID + step := sqlgraph.NewStep( + sqlgraph.From(user.Table, user.FieldID, id), + sqlgraph.To(wordsuffix.Table, wordsuffix.FieldID), + sqlgraph.Edge(sqlgraph.O2M, false, user.WordSuffixTable, user.WordSuffixColumn), + ) + fromV = sqlgraph.Neighbors(u.driver.Dialect(), step) + return fromV, nil + } + return query +} + +// Hooks returns the client hooks. +func (c *UserClient) Hooks() []Hook { + return c.hooks.User +} + +// Interceptors returns the client interceptors. +func (c *UserClient) Interceptors() []Interceptor { + return c.inters.User +} + +func (c *UserClient) mutate(ctx context.Context, m *UserMutation) (Value, error) { + switch m.Op() { + case OpCreate: + return (&UserCreate{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx) + case OpUpdate: + return (&UserUpdate{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx) + case OpUpdateOne: + return (&UserUpdateOne{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx) + case OpDelete, OpDeleteOne: + return (&UserDelete{config: c.config, hooks: c.Hooks(), mutation: m}).Exec(ctx) + default: + return nil, fmt.Errorf("ent: unknown User mutation op: %q", m.Op()) + } +} + +// WordSuffixClient is a client for the WordSuffix schema. +type WordSuffixClient struct { + config +} + +// NewWordSuffixClient returns a client for the WordSuffix from the given config. +func NewWordSuffixClient(c config) *WordSuffixClient { + return &WordSuffixClient{config: c} +} + +// Use adds a list of mutation hooks to the hooks stack. +// A call to `Use(f, g, h)` equals to `wordsuffix.Hooks(f(g(h())))`. +func (c *WordSuffixClient) Use(hooks ...Hook) { + c.hooks.WordSuffix = append(c.hooks.WordSuffix, hooks...) +} + +// Intercept adds a list of query interceptors to the interceptors stack. +// A call to `Intercept(f, g, h)` equals to `wordsuffix.Intercept(f(g(h())))`. +func (c *WordSuffixClient) Intercept(interceptors ...Interceptor) { + c.inters.WordSuffix = append(c.inters.WordSuffix, interceptors...) +} + +// Create returns a builder for creating a WordSuffix entity. +func (c *WordSuffixClient) Create() *WordSuffixCreate { + mutation := newWordSuffixMutation(c.config, OpCreate) + return &WordSuffixCreate{config: c.config, hooks: c.Hooks(), mutation: mutation} +} + +// CreateBulk returns a builder for creating a bulk of WordSuffix entities. +func (c *WordSuffixClient) CreateBulk(builders ...*WordSuffixCreate) *WordSuffixCreateBulk { + return &WordSuffixCreateBulk{config: c.config, builders: builders} +} + +// MapCreateBulk creates a bulk creation builder from the given slice. For each item in the slice, the function creates +// a builder and applies setFunc on it. +func (c *WordSuffixClient) MapCreateBulk(slice any, setFunc func(*WordSuffixCreate, int)) *WordSuffixCreateBulk { + rv := reflect.ValueOf(slice) + if rv.Kind() != reflect.Slice { + return &WordSuffixCreateBulk{err: fmt.Errorf("calling to WordSuffixClient.MapCreateBulk with wrong type %T, need slice", slice)} + } + builders := make([]*WordSuffixCreate, rv.Len()) + for i := 0; i < rv.Len(); i++ { + builders[i] = c.Create() + setFunc(builders[i], i) + } + return &WordSuffixCreateBulk{config: c.config, builders: builders} +} + +// Update returns an update builder for WordSuffix. +func (c *WordSuffixClient) Update() *WordSuffixUpdate { + mutation := newWordSuffixMutation(c.config, OpUpdate) + return &WordSuffixUpdate{config: c.config, hooks: c.Hooks(), mutation: mutation} +} + +// UpdateOne returns an update builder for the given entity. +func (c *WordSuffixClient) UpdateOne(ws *WordSuffix) *WordSuffixUpdateOne { + mutation := newWordSuffixMutation(c.config, OpUpdateOne, withWordSuffix(ws)) + return &WordSuffixUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation} +} + +// UpdateOneID returns an update builder for the given id. +func (c *WordSuffixClient) UpdateOneID(id uuid.UUID) *WordSuffixUpdateOne { + mutation := newWordSuffixMutation(c.config, OpUpdateOne, withWordSuffixID(id)) + return &WordSuffixUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation} +} + +// Delete returns a delete builder for WordSuffix. +func (c *WordSuffixClient) Delete() *WordSuffixDelete { + mutation := newWordSuffixMutation(c.config, OpDelete) + return &WordSuffixDelete{config: c.config, hooks: c.Hooks(), mutation: mutation} +} + +// DeleteOne returns a builder for deleting the given entity. +func (c *WordSuffixClient) DeleteOne(ws *WordSuffix) *WordSuffixDeleteOne { + return c.DeleteOneID(ws.ID) +} + +// DeleteOneID returns a builder for deleting the given entity by its id. +func (c *WordSuffixClient) DeleteOneID(id uuid.UUID) *WordSuffixDeleteOne { + builder := c.Delete().Where(wordsuffix.ID(id)) + builder.mutation.id = &id + builder.mutation.op = OpDeleteOne + return &WordSuffixDeleteOne{builder} +} + +// Query returns a query builder for WordSuffix. +func (c *WordSuffixClient) Query() *WordSuffixQuery { + return &WordSuffixQuery{ + config: c.config, + ctx: &QueryContext{Type: TypeWordSuffix}, + inters: c.Interceptors(), + } +} + +// Get returns a WordSuffix entity by its id. +func (c *WordSuffixClient) Get(ctx context.Context, id uuid.UUID) (*WordSuffix, error) { + return c.Query().Where(wordsuffix.ID(id)).Only(ctx) +} + +// GetX is like Get, but panics if an error occurs. +func (c *WordSuffixClient) GetX(ctx context.Context, id uuid.UUID) *WordSuffix { + obj, err := c.Get(ctx, id) + if err != nil { + panic(err) + } + return obj +} + +// QueryGuild queries the guild edge of a WordSuffix. +func (c *WordSuffixClient) QueryGuild(ws *WordSuffix) *GuildQuery { + query := (&GuildClient{config: c.config}).Query() + query.path = func(context.Context) (fromV *sql.Selector, _ error) { + id := ws.ID + step := sqlgraph.NewStep( + sqlgraph.From(wordsuffix.Table, wordsuffix.FieldID, id), + sqlgraph.To(guild.Table, guild.FieldID), + sqlgraph.Edge(sqlgraph.M2O, false, wordsuffix.GuildTable, wordsuffix.GuildColumn), + ) + fromV = sqlgraph.Neighbors(ws.driver.Dialect(), step) + return fromV, nil + } + return query +} + +// QueryOwner queries the owner edge of a WordSuffix. +func (c *WordSuffixClient) QueryOwner(ws *WordSuffix) *UserQuery { + query := (&UserClient{config: c.config}).Query() + query.path = func(context.Context) (fromV *sql.Selector, _ error) { + id := ws.ID + step := sqlgraph.NewStep( + sqlgraph.From(wordsuffix.Table, wordsuffix.FieldID, id), + sqlgraph.To(user.Table, user.FieldID), + sqlgraph.Edge(sqlgraph.M2O, true, wordsuffix.OwnerTable, wordsuffix.OwnerColumn), + ) + fromV = sqlgraph.Neighbors(ws.driver.Dialect(), step) + return fromV, nil + } + return query +} + +// Hooks returns the client hooks. +func (c *WordSuffixClient) Hooks() []Hook { + return c.hooks.WordSuffix +} + +// Interceptors returns the client interceptors. +func (c *WordSuffixClient) Interceptors() []Interceptor { + return c.inters.WordSuffix +} + +func (c *WordSuffixClient) mutate(ctx context.Context, m *WordSuffixMutation) (Value, error) { + switch m.Op() { + case OpCreate: + return (&WordSuffixCreate{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx) + case OpUpdate: + return (&WordSuffixUpdate{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx) + case OpUpdateOne: + return (&WordSuffixUpdateOne{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx) + case OpDelete, OpDeleteOne: + return (&WordSuffixDelete{config: c.config, hooks: c.Hooks(), mutation: m}).Exec(ctx) + default: + return nil, fmt.Errorf("ent: unknown WordSuffix mutation op: %q", m.Op()) + } +} + +// hooks and interceptors per client, for fast access. +type ( + hooks struct { + Guild, Member, MessagePin, MessageRemind, RolePanel, RolePanelEdit, + RolePanelPlaced, User, WordSuffix []ent.Hook + } + inters struct { + Guild, Member, MessagePin, MessageRemind, RolePanel, RolePanelEdit, + RolePanelPlaced, User, WordSuffix []ent.Interceptor + } +) diff --git a/ent/ent.go b/ent/ent.go new file mode 100644 index 00000000..2cc54633 --- /dev/null +++ b/ent/ent.go @@ -0,0 +1,624 @@ +// Code generated by ent, DO NOT EDIT. + +package ent + +import ( + "context" + "errors" + "fmt" + "reflect" + "sync" + + "entgo.io/ent" + "entgo.io/ent/dialect/sql" + "entgo.io/ent/dialect/sql/sqlgraph" + "github.com/sabafly/gobot/ent/guild" + "github.com/sabafly/gobot/ent/member" + "github.com/sabafly/gobot/ent/messagepin" + "github.com/sabafly/gobot/ent/messageremind" + "github.com/sabafly/gobot/ent/rolepanel" + "github.com/sabafly/gobot/ent/rolepaneledit" + "github.com/sabafly/gobot/ent/rolepanelplaced" + "github.com/sabafly/gobot/ent/user" + "github.com/sabafly/gobot/ent/wordsuffix" +) + +// ent aliases to avoid import conflicts in user's code. +type ( + Op = ent.Op + Hook = ent.Hook + Value = ent.Value + Query = ent.Query + QueryContext = ent.QueryContext + Querier = ent.Querier + QuerierFunc = ent.QuerierFunc + Interceptor = ent.Interceptor + InterceptFunc = ent.InterceptFunc + Traverser = ent.Traverser + TraverseFunc = ent.TraverseFunc + Policy = ent.Policy + Mutator = ent.Mutator + Mutation = ent.Mutation + MutateFunc = ent.MutateFunc +) + +type clientCtxKey struct{} + +// FromContext returns a Client stored inside a context, or nil if there isn't one. +func FromContext(ctx context.Context) *Client { + c, _ := ctx.Value(clientCtxKey{}).(*Client) + return c +} + +// NewContext returns a new context with the given Client attached. +func NewContext(parent context.Context, c *Client) context.Context { + return context.WithValue(parent, clientCtxKey{}, c) +} + +type txCtxKey struct{} + +// TxFromContext returns a Tx stored inside a context, or nil if there isn't one. +func TxFromContext(ctx context.Context) *Tx { + tx, _ := ctx.Value(txCtxKey{}).(*Tx) + return tx +} + +// NewTxContext returns a new context with the given Tx attached. +func NewTxContext(parent context.Context, tx *Tx) context.Context { + return context.WithValue(parent, txCtxKey{}, tx) +} + +// OrderFunc applies an ordering on the sql selector. +// Deprecated: Use Asc/Desc functions or the package builders instead. +type OrderFunc func(*sql.Selector) + +var ( + initCheck sync.Once + columnCheck sql.ColumnCheck +) + +// columnChecker checks if the column exists in the given table. +func checkColumn(table, column string) error { + initCheck.Do(func() { + columnCheck = sql.NewColumnCheck(map[string]func(string) bool{ + guild.Table: guild.ValidColumn, + member.Table: member.ValidColumn, + messagepin.Table: messagepin.ValidColumn, + messageremind.Table: messageremind.ValidColumn, + rolepanel.Table: rolepanel.ValidColumn, + rolepaneledit.Table: rolepaneledit.ValidColumn, + rolepanelplaced.Table: rolepanelplaced.ValidColumn, + user.Table: user.ValidColumn, + wordsuffix.Table: wordsuffix.ValidColumn, + }) + }) + return columnCheck(table, column) +} + +// Asc applies the given fields in ASC order. +func Asc(fields ...string) func(*sql.Selector) { + return func(s *sql.Selector) { + for _, f := range fields { + if err := checkColumn(s.TableName(), f); err != nil { + s.AddError(&ValidationError{Name: f, err: fmt.Errorf("ent: %w", err)}) + } + s.OrderBy(sql.Asc(s.C(f))) + } + } +} + +// Desc applies the given fields in DESC order. +func Desc(fields ...string) func(*sql.Selector) { + return func(s *sql.Selector) { + for _, f := range fields { + if err := checkColumn(s.TableName(), f); err != nil { + s.AddError(&ValidationError{Name: f, err: fmt.Errorf("ent: %w", err)}) + } + s.OrderBy(sql.Desc(s.C(f))) + } + } +} + +// AggregateFunc applies an aggregation step on the group-by traversal/selector. +type AggregateFunc func(*sql.Selector) string + +// As is a pseudo aggregation function for renaming another other functions with custom names. For example: +// +// GroupBy(field1, field2). +// Aggregate(ent.As(ent.Sum(field1), "sum_field1"), (ent.As(ent.Sum(field2), "sum_field2")). +// Scan(ctx, &v) +func As(fn AggregateFunc, end string) AggregateFunc { + return func(s *sql.Selector) string { + return sql.As(fn(s), end) + } +} + +// Count applies the "count" aggregation function on each group. +func Count() AggregateFunc { + return func(s *sql.Selector) string { + return sql.Count("*") + } +} + +// Max applies the "max" aggregation function on the given field of each group. +func Max(field string) AggregateFunc { + return func(s *sql.Selector) string { + if err := checkColumn(s.TableName(), field); err != nil { + s.AddError(&ValidationError{Name: field, err: fmt.Errorf("ent: %w", err)}) + return "" + } + return sql.Max(s.C(field)) + } +} + +// Mean applies the "mean" aggregation function on the given field of each group. +func Mean(field string) AggregateFunc { + return func(s *sql.Selector) string { + if err := checkColumn(s.TableName(), field); err != nil { + s.AddError(&ValidationError{Name: field, err: fmt.Errorf("ent: %w", err)}) + return "" + } + return sql.Avg(s.C(field)) + } +} + +// Min applies the "min" aggregation function on the given field of each group. +func Min(field string) AggregateFunc { + return func(s *sql.Selector) string { + if err := checkColumn(s.TableName(), field); err != nil { + s.AddError(&ValidationError{Name: field, err: fmt.Errorf("ent: %w", err)}) + return "" + } + return sql.Min(s.C(field)) + } +} + +// Sum applies the "sum" aggregation function on the given field of each group. +func Sum(field string) AggregateFunc { + return func(s *sql.Selector) string { + if err := checkColumn(s.TableName(), field); err != nil { + s.AddError(&ValidationError{Name: field, err: fmt.Errorf("ent: %w", err)}) + return "" + } + return sql.Sum(s.C(field)) + } +} + +// ValidationError returns when validating a field or edge fails. +type ValidationError struct { + Name string // Field or edge name. + err error +} + +// Error implements the error interface. +func (e *ValidationError) Error() string { + return e.err.Error() +} + +// Unwrap implements the errors.Wrapper interface. +func (e *ValidationError) Unwrap() error { + return e.err +} + +// IsValidationError returns a boolean indicating whether the error is a validation error. +func IsValidationError(err error) bool { + if err == nil { + return false + } + var e *ValidationError + return errors.As(err, &e) +} + +// NotFoundError returns when trying to fetch a specific entity and it was not found in the database. +type NotFoundError struct { + label string +} + +// Error implements the error interface. +func (e *NotFoundError) Error() string { + return "ent: " + e.label + " not found" +} + +// IsNotFound returns a boolean indicating whether the error is a not found error. +func IsNotFound(err error) bool { + if err == nil { + return false + } + var e *NotFoundError + return errors.As(err, &e) +} + +// MaskNotFound masks not found error. +func MaskNotFound(err error) error { + if IsNotFound(err) { + return nil + } + return err +} + +// NotSingularError returns when trying to fetch a singular entity and more then one was found in the database. +type NotSingularError struct { + label string +} + +// Error implements the error interface. +func (e *NotSingularError) Error() string { + return "ent: " + e.label + " not singular" +} + +// IsNotSingular returns a boolean indicating whether the error is a not singular error. +func IsNotSingular(err error) bool { + if err == nil { + return false + } + var e *NotSingularError + return errors.As(err, &e) +} + +// NotLoadedError returns when trying to get a node that was not loaded by the query. +type NotLoadedError struct { + edge string +} + +// Error implements the error interface. +func (e *NotLoadedError) Error() string { + return "ent: " + e.edge + " edge was not loaded" +} + +// IsNotLoaded returns a boolean indicating whether the error is a not loaded error. +func IsNotLoaded(err error) bool { + if err == nil { + return false + } + var e *NotLoadedError + return errors.As(err, &e) +} + +// ConstraintError returns when trying to create/update one or more entities and +// one or more of their constraints failed. For example, violation of edge or +// field uniqueness. +type ConstraintError struct { + msg string + wrap error +} + +// Error implements the error interface. +func (e ConstraintError) Error() string { + return "ent: constraint failed: " + e.msg +} + +// Unwrap implements the errors.Wrapper interface. +func (e *ConstraintError) Unwrap() error { + return e.wrap +} + +// IsConstraintError returns a boolean indicating whether the error is a constraint failure. +func IsConstraintError(err error) bool { + if err == nil { + return false + } + var e *ConstraintError + return errors.As(err, &e) +} + +// selector embedded by the different Select/GroupBy builders. +type selector struct { + label string + flds *[]string + fns []AggregateFunc + scan func(context.Context, any) error +} + +// ScanX is like Scan, but panics if an error occurs. +func (s *selector) ScanX(ctx context.Context, v any) { + if err := s.scan(ctx, v); err != nil { + panic(err) + } +} + +// Strings returns list of strings from a selector. It is only allowed when selecting one field. +func (s *selector) Strings(ctx context.Context) ([]string, error) { + if len(*s.flds) > 1 { + return nil, errors.New("ent: Strings is not achievable when selecting more than 1 field") + } + var v []string + if err := s.scan(ctx, &v); err != nil { + return nil, err + } + return v, nil +} + +// StringsX is like Strings, but panics if an error occurs. +func (s *selector) StringsX(ctx context.Context) []string { + v, err := s.Strings(ctx) + if err != nil { + panic(err) + } + return v +} + +// String returns a single string from a selector. It is only allowed when selecting one field. +func (s *selector) String(ctx context.Context) (_ string, err error) { + var v []string + if v, err = s.Strings(ctx); err != nil { + return + } + switch len(v) { + case 1: + return v[0], nil + case 0: + err = &NotFoundError{s.label} + default: + err = fmt.Errorf("ent: Strings returned %d results when one was expected", len(v)) + } + return +} + +// StringX is like String, but panics if an error occurs. +func (s *selector) StringX(ctx context.Context) string { + v, err := s.String(ctx) + if err != nil { + panic(err) + } + return v +} + +// Ints returns list of ints from a selector. It is only allowed when selecting one field. +func (s *selector) Ints(ctx context.Context) ([]int, error) { + if len(*s.flds) > 1 { + return nil, errors.New("ent: Ints is not achievable when selecting more than 1 field") + } + var v []int + if err := s.scan(ctx, &v); err != nil { + return nil, err + } + return v, nil +} + +// IntsX is like Ints, but panics if an error occurs. +func (s *selector) IntsX(ctx context.Context) []int { + v, err := s.Ints(ctx) + if err != nil { + panic(err) + } + return v +} + +// Int returns a single int from a selector. It is only allowed when selecting one field. +func (s *selector) Int(ctx context.Context) (_ int, err error) { + var v []int + if v, err = s.Ints(ctx); err != nil { + return + } + switch len(v) { + case 1: + return v[0], nil + case 0: + err = &NotFoundError{s.label} + default: + err = fmt.Errorf("ent: Ints returned %d results when one was expected", len(v)) + } + return +} + +// IntX is like Int, but panics if an error occurs. +func (s *selector) IntX(ctx context.Context) int { + v, err := s.Int(ctx) + if err != nil { + panic(err) + } + return v +} + +// Float64s returns list of float64s from a selector. It is only allowed when selecting one field. +func (s *selector) Float64s(ctx context.Context) ([]float64, error) { + if len(*s.flds) > 1 { + return nil, errors.New("ent: Float64s is not achievable when selecting more than 1 field") + } + var v []float64 + if err := s.scan(ctx, &v); err != nil { + return nil, err + } + return v, nil +} + +// Float64sX is like Float64s, but panics if an error occurs. +func (s *selector) Float64sX(ctx context.Context) []float64 { + v, err := s.Float64s(ctx) + if err != nil { + panic(err) + } + return v +} + +// Float64 returns a single float64 from a selector. It is only allowed when selecting one field. +func (s *selector) Float64(ctx context.Context) (_ float64, err error) { + var v []float64 + if v, err = s.Float64s(ctx); err != nil { + return + } + switch len(v) { + case 1: + return v[0], nil + case 0: + err = &NotFoundError{s.label} + default: + err = fmt.Errorf("ent: Float64s returned %d results when one was expected", len(v)) + } + return +} + +// Float64X is like Float64, but panics if an error occurs. +func (s *selector) Float64X(ctx context.Context) float64 { + v, err := s.Float64(ctx) + if err != nil { + panic(err) + } + return v +} + +// Bools returns list of bools from a selector. It is only allowed when selecting one field. +func (s *selector) Bools(ctx context.Context) ([]bool, error) { + if len(*s.flds) > 1 { + return nil, errors.New("ent: Bools is not achievable when selecting more than 1 field") + } + var v []bool + if err := s.scan(ctx, &v); err != nil { + return nil, err + } + return v, nil +} + +// BoolsX is like Bools, but panics if an error occurs. +func (s *selector) BoolsX(ctx context.Context) []bool { + v, err := s.Bools(ctx) + if err != nil { + panic(err) + } + return v +} + +// Bool returns a single bool from a selector. It is only allowed when selecting one field. +func (s *selector) Bool(ctx context.Context) (_ bool, err error) { + var v []bool + if v, err = s.Bools(ctx); err != nil { + return + } + switch len(v) { + case 1: + return v[0], nil + case 0: + err = &NotFoundError{s.label} + default: + err = fmt.Errorf("ent: Bools returned %d results when one was expected", len(v)) + } + return +} + +// BoolX is like Bool, but panics if an error occurs. +func (s *selector) BoolX(ctx context.Context) bool { + v, err := s.Bool(ctx) + if err != nil { + panic(err) + } + return v +} + +// withHooks invokes the builder operation with the given hooks, if any. +func withHooks[V Value, M any, PM interface { + *M + Mutation +}](ctx context.Context, exec func(context.Context) (V, error), mutation PM, hooks []Hook) (value V, err error) { + if len(hooks) == 0 { + return exec(ctx) + } + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutationT, ok := any(m).(PM) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + // Set the mutation to the builder. + *mutation = *mutationT + return exec(ctx) + }) + for i := len(hooks) - 1; i >= 0; i-- { + if hooks[i] == nil { + return value, fmt.Errorf("ent: uninitialized hook (forgotten import ent/runtime?)") + } + mut = hooks[i](mut) + } + v, err := mut.Mutate(ctx, mutation) + if err != nil { + return value, err + } + nv, ok := v.(V) + if !ok { + return value, fmt.Errorf("unexpected node type %T returned from %T", v, mutation) + } + return nv, nil +} + +// setContextOp returns a new context with the given QueryContext attached (including its op) in case it does not exist. +func setContextOp(ctx context.Context, qc *QueryContext, op string) context.Context { + if ent.QueryFromContext(ctx) == nil { + qc.Op = op + ctx = ent.NewQueryContext(ctx, qc) + } + return ctx +} + +func querierAll[V Value, Q interface { + sqlAll(context.Context, ...queryHook) (V, error) +}]() Querier { + return QuerierFunc(func(ctx context.Context, q Query) (Value, error) { + query, ok := q.(Q) + if !ok { + return nil, fmt.Errorf("unexpected query type %T", q) + } + return query.sqlAll(ctx) + }) +} + +func querierCount[Q interface { + sqlCount(context.Context) (int, error) +}]() Querier { + return QuerierFunc(func(ctx context.Context, q Query) (Value, error) { + query, ok := q.(Q) + if !ok { + return nil, fmt.Errorf("unexpected query type %T", q) + } + return query.sqlCount(ctx) + }) +} + +func withInterceptors[V Value](ctx context.Context, q Query, qr Querier, inters []Interceptor) (v V, err error) { + for i := len(inters) - 1; i >= 0; i-- { + qr = inters[i].Intercept(qr) + } + rv, err := qr.Query(ctx, q) + if err != nil { + return v, err + } + vt, ok := rv.(V) + if !ok { + return v, fmt.Errorf("unexpected type %T returned from %T. expected type: %T", vt, q, v) + } + return vt, nil +} + +func scanWithInterceptors[Q1 ent.Query, Q2 interface { + sqlScan(context.Context, Q1, any) error +}](ctx context.Context, rootQuery Q1, selectOrGroup Q2, inters []Interceptor, v any) error { + rv := reflect.ValueOf(v) + var qr Querier = QuerierFunc(func(ctx context.Context, q Query) (Value, error) { + query, ok := q.(Q1) + if !ok { + return nil, fmt.Errorf("unexpected query type %T", q) + } + if err := selectOrGroup.sqlScan(ctx, query, v); err != nil { + return nil, err + } + if k := rv.Kind(); k == reflect.Pointer && rv.Elem().CanInterface() { + return rv.Elem().Interface(), nil + } + return v, nil + }) + for i := len(inters) - 1; i >= 0; i-- { + qr = inters[i].Intercept(qr) + } + vv, err := qr.Query(ctx, rootQuery) + if err != nil { + return err + } + switch rv2 := reflect.ValueOf(vv); { + case rv.IsNil(), rv2.IsNil(), rv.Kind() != reflect.Pointer: + case rv.Type() == rv2.Type(): + rv.Elem().Set(rv2.Elem()) + case rv.Elem().Type() == rv2.Type(): + rv.Elem().Set(rv2) + } + return nil +} + +// queryHook describes an internal hook for the different sqlAll methods. +type queryHook func(context.Context, *sqlgraph.QuerySpec) diff --git a/ent/enttest/enttest.go b/ent/enttest/enttest.go new file mode 100644 index 00000000..190b4a7c --- /dev/null +++ b/ent/enttest/enttest.go @@ -0,0 +1,84 @@ +// Code generated by ent, DO NOT EDIT. + +package enttest + +import ( + "context" + + "github.com/sabafly/gobot/ent" + // required by schema hooks. + _ "github.com/sabafly/gobot/ent/runtime" + + "entgo.io/ent/dialect/sql/schema" + "github.com/sabafly/gobot/ent/migrate" +) + +type ( + // TestingT is the interface that is shared between + // testing.T and testing.B and used by enttest. + TestingT interface { + FailNow() + Error(...any) + } + + // Option configures client creation. + Option func(*options) + + options struct { + opts []ent.Option + migrateOpts []schema.MigrateOption + } +) + +// WithOptions forwards options to client creation. +func WithOptions(opts ...ent.Option) Option { + return func(o *options) { + o.opts = append(o.opts, opts...) + } +} + +// WithMigrateOptions forwards options to auto migration. +func WithMigrateOptions(opts ...schema.MigrateOption) Option { + return func(o *options) { + o.migrateOpts = append(o.migrateOpts, opts...) + } +} + +func newOptions(opts []Option) *options { + o := &options{} + for _, opt := range opts { + opt(o) + } + return o +} + +// Open calls ent.Open and auto-run migration. +func Open(t TestingT, driverName, dataSourceName string, opts ...Option) *ent.Client { + o := newOptions(opts) + c, err := ent.Open(driverName, dataSourceName, o.opts...) + if err != nil { + t.Error(err) + t.FailNow() + } + migrateSchema(t, c, o) + return c +} + +// NewClient calls ent.NewClient and auto-run migration. +func NewClient(t TestingT, opts ...Option) *ent.Client { + o := newOptions(opts) + c := ent.NewClient(o.opts...) + migrateSchema(t, c, o) + return c +} +func migrateSchema(t TestingT, c *ent.Client, o *options) { + tables, err := schema.CopyTables(migrate.Tables) + if err != nil { + t.Error(err) + t.FailNow() + } + if err := migrate.Create(context.Background(), c.Schema, tables, o.migrateOpts...); err != nil { + t.Error(err) + t.FailNow() + } +} diff --git a/ent/generate.go b/ent/generate.go new file mode 100644 index 00000000..8d3fdfdc --- /dev/null +++ b/ent/generate.go @@ -0,0 +1,3 @@ +package ent + +//go:generate go run -mod=mod entgo.io/ent/cmd/ent generate ./schema diff --git a/ent/guild.go b/ent/guild.go new file mode 100644 index 00000000..786b58b9 --- /dev/null +++ b/ent/guild.go @@ -0,0 +1,495 @@ +// Code generated by ent, DO NOT EDIT. + +package ent + +import ( + "encoding/json" + "fmt" + "strings" + "time" + + "entgo.io/ent" + "entgo.io/ent/dialect/sql" + "github.com/disgoorg/disgo/discord" + snowflake "github.com/disgoorg/snowflake/v2" + "github.com/sabafly/gobot/ent/guild" + "github.com/sabafly/gobot/ent/user" + "github.com/sabafly/gobot/internal/permissions" +) + +// Guild is the model entity for the Guild schema. +type Guild struct { + config `json:"-"` + // ID of the ent. + ID snowflake.ID `json:"id,omitempty"` + // Name holds the value of the "name" field. + Name string `json:"name,omitempty"` + // Locale holds the value of the "locale" field. + Locale discord.Locale `json:"locale,omitempty"` + // LevelUpMessage holds the value of the "level_up_message" field. + LevelUpMessage string `json:"level_up_message,omitempty"` + // LevelUpChannel holds the value of the "level_up_channel" field. + LevelUpChannel *snowflake.ID `json:"level_up_channel,omitempty"` + // LevelUpExcludeChannel holds the value of the "level_up_exclude_channel" field. + LevelUpExcludeChannel []snowflake.ID `json:"level_up_exclude_channel,omitempty"` + // LevelMee6Imported holds the value of the "level_mee6_imported" field. + LevelMee6Imported bool `json:"level_mee6_imported,omitempty"` + // LevelRole holds the value of the "level_role" field. + LevelRole map[int]snowflake.ID `json:"level_role,omitempty"` + // Permissions holds the value of the "permissions" field. + Permissions map[snowflake.ID]permissions.Permission `json:"permissions,omitempty"` + // RemindCount holds the value of the "remind_count" field. + RemindCount int `json:"remind_count,omitempty"` + // RolePanelEditTimes holds the value of the "role_panel_edit_times" field. + RolePanelEditTimes []time.Time `json:"role_panel_edit_times,omitempty"` + // BumpEnabled holds the value of the "bump_enabled" field. + BumpEnabled bool `json:"bump_enabled,omitempty"` + // BumpMessageTitle holds the value of the "bump_message_title" field. + BumpMessageTitle string `json:"bump_message_title,omitempty"` + // BumpMessage holds the value of the "bump_message" field. + BumpMessage string `json:"bump_message,omitempty"` + // BumpRemindMessageTitle holds the value of the "bump_remind_message_title" field. + BumpRemindMessageTitle string `json:"bump_remind_message_title,omitempty"` + // BumpRemindMessage holds the value of the "bump_remind_message" field. + BumpRemindMessage string `json:"bump_remind_message,omitempty"` + // UpEnabled holds the value of the "up_enabled" field. + UpEnabled bool `json:"up_enabled,omitempty"` + // UpMessageTitle holds the value of the "up_message_title" field. + UpMessageTitle string `json:"up_message_title,omitempty"` + // UpMessage holds the value of the "up_message" field. + UpMessage string `json:"up_message,omitempty"` + // UpRemindMessageTitle holds the value of the "up_remind_message_title" field. + UpRemindMessageTitle string `json:"up_remind_message_title,omitempty"` + // UpRemindMessage holds the value of the "up_remind_message" field. + UpRemindMessage string `json:"up_remind_message,omitempty"` + // BumpMention holds the value of the "bump_mention" field. + BumpMention *snowflake.ID `json:"bump_mention,omitempty"` + // UpMention holds the value of the "up_mention" field. + UpMention *snowflake.ID `json:"up_mention,omitempty"` + // Edges holds the relations/edges for other nodes in the graph. + // The values are being populated by the GuildQuery when eager-loading is set. + Edges GuildEdges `json:"edges"` + user_own_guilds *snowflake.ID + selectValues sql.SelectValues +} + +// GuildEdges holds the relations/edges for other nodes in the graph. +type GuildEdges struct { + // Owner holds the value of the owner edge. + Owner *User `json:"owner,omitempty"` + // Members holds the value of the members edge. + Members []*Member `json:"members,omitempty"` + // MessagePins holds the value of the message_pins edge. + MessagePins []*MessagePin `json:"message_pins,omitempty"` + // Reminds holds the value of the reminds edge. + Reminds []*MessageRemind `json:"reminds,omitempty"` + // RolePanels holds the value of the role_panels edge. + RolePanels []*RolePanel `json:"role_panels,omitempty"` + // RolePanelPlacements holds the value of the role_panel_placements edge. + RolePanelPlacements []*RolePanelPlaced `json:"role_panel_placements,omitempty"` + // RolePanelEdits holds the value of the role_panel_edits edge. + RolePanelEdits []*RolePanelEdit `json:"role_panel_edits,omitempty"` + // loadedTypes holds the information for reporting if a + // type was loaded (or requested) in eager-loading or not. + loadedTypes [7]bool +} + +// OwnerOrErr returns the Owner value or an error if the edge +// was not loaded in eager-loading, or loaded but was not found. +func (e GuildEdges) OwnerOrErr() (*User, error) { + if e.Owner != nil { + return e.Owner, nil + } else if e.loadedTypes[0] { + return nil, &NotFoundError{label: user.Label} + } + return nil, &NotLoadedError{edge: "owner"} +} + +// MembersOrErr returns the Members value or an error if the edge +// was not loaded in eager-loading. +func (e GuildEdges) MembersOrErr() ([]*Member, error) { + if e.loadedTypes[1] { + return e.Members, nil + } + return nil, &NotLoadedError{edge: "members"} +} + +// MessagePinsOrErr returns the MessagePins value or an error if the edge +// was not loaded in eager-loading. +func (e GuildEdges) MessagePinsOrErr() ([]*MessagePin, error) { + if e.loadedTypes[2] { + return e.MessagePins, nil + } + return nil, &NotLoadedError{edge: "message_pins"} +} + +// RemindsOrErr returns the Reminds value or an error if the edge +// was not loaded in eager-loading. +func (e GuildEdges) RemindsOrErr() ([]*MessageRemind, error) { + if e.loadedTypes[3] { + return e.Reminds, nil + } + return nil, &NotLoadedError{edge: "reminds"} +} + +// RolePanelsOrErr returns the RolePanels value or an error if the edge +// was not loaded in eager-loading. +func (e GuildEdges) RolePanelsOrErr() ([]*RolePanel, error) { + if e.loadedTypes[4] { + return e.RolePanels, nil + } + return nil, &NotLoadedError{edge: "role_panels"} +} + +// RolePanelPlacementsOrErr returns the RolePanelPlacements value or an error if the edge +// was not loaded in eager-loading. +func (e GuildEdges) RolePanelPlacementsOrErr() ([]*RolePanelPlaced, error) { + if e.loadedTypes[5] { + return e.RolePanelPlacements, nil + } + return nil, &NotLoadedError{edge: "role_panel_placements"} +} + +// RolePanelEditsOrErr returns the RolePanelEdits value or an error if the edge +// was not loaded in eager-loading. +func (e GuildEdges) RolePanelEditsOrErr() ([]*RolePanelEdit, error) { + if e.loadedTypes[6] { + return e.RolePanelEdits, nil + } + return nil, &NotLoadedError{edge: "role_panel_edits"} +} + +// scanValues returns the types for scanning values from sql.Rows. +func (*Guild) scanValues(columns []string) ([]any, error) { + values := make([]any, len(columns)) + for i := range columns { + switch columns[i] { + case guild.FieldLevelUpExcludeChannel, guild.FieldLevelRole, guild.FieldPermissions, guild.FieldRolePanelEditTimes: + values[i] = new([]byte) + case guild.FieldLevelMee6Imported, guild.FieldBumpEnabled, guild.FieldUpEnabled: + values[i] = new(sql.NullBool) + case guild.FieldID, guild.FieldLevelUpChannel, guild.FieldRemindCount, guild.FieldBumpMention, guild.FieldUpMention: + values[i] = new(sql.NullInt64) + case guild.FieldName, guild.FieldLocale, guild.FieldLevelUpMessage, guild.FieldBumpMessageTitle, guild.FieldBumpMessage, guild.FieldBumpRemindMessageTitle, guild.FieldBumpRemindMessage, guild.FieldUpMessageTitle, guild.FieldUpMessage, guild.FieldUpRemindMessageTitle, guild.FieldUpRemindMessage: + values[i] = new(sql.NullString) + case guild.ForeignKeys[0]: // user_own_guilds + values[i] = new(sql.NullInt64) + default: + values[i] = new(sql.UnknownType) + } + } + return values, nil +} + +// assignValues assigns the values that were returned from sql.Rows (after scanning) +// to the Guild fields. +func (gu *Guild) assignValues(columns []string, values []any) error { + if m, n := len(values), len(columns); m < n { + return fmt.Errorf("mismatch number of scan values: %d != %d", m, n) + } + for i := range columns { + switch columns[i] { + case guild.FieldID: + if value, ok := values[i].(*sql.NullInt64); !ok { + return fmt.Errorf("unexpected type %T for field id", values[i]) + } else if value.Valid { + gu.ID = snowflake.ID(value.Int64) + } + case guild.FieldName: + if value, ok := values[i].(*sql.NullString); !ok { + return fmt.Errorf("unexpected type %T for field name", values[i]) + } else if value.Valid { + gu.Name = value.String + } + case guild.FieldLocale: + if value, ok := values[i].(*sql.NullString); !ok { + return fmt.Errorf("unexpected type %T for field locale", values[i]) + } else if value.Valid { + gu.Locale = discord.Locale(value.String) + } + case guild.FieldLevelUpMessage: + if value, ok := values[i].(*sql.NullString); !ok { + return fmt.Errorf("unexpected type %T for field level_up_message", values[i]) + } else if value.Valid { + gu.LevelUpMessage = value.String + } + case guild.FieldLevelUpChannel: + if value, ok := values[i].(*sql.NullInt64); !ok { + return fmt.Errorf("unexpected type %T for field level_up_channel", values[i]) + } else if value.Valid { + gu.LevelUpChannel = new(snowflake.ID) + *gu.LevelUpChannel = snowflake.ID(value.Int64) + } + case guild.FieldLevelUpExcludeChannel: + if value, ok := values[i].(*[]byte); !ok { + return fmt.Errorf("unexpected type %T for field level_up_exclude_channel", values[i]) + } else if value != nil && len(*value) > 0 { + if err := json.Unmarshal(*value, &gu.LevelUpExcludeChannel); err != nil { + return fmt.Errorf("unmarshal field level_up_exclude_channel: %w", err) + } + } + case guild.FieldLevelMee6Imported: + if value, ok := values[i].(*sql.NullBool); !ok { + return fmt.Errorf("unexpected type %T for field level_mee6_imported", values[i]) + } else if value.Valid { + gu.LevelMee6Imported = value.Bool + } + case guild.FieldLevelRole: + if value, ok := values[i].(*[]byte); !ok { + return fmt.Errorf("unexpected type %T for field level_role", values[i]) + } else if value != nil && len(*value) > 0 { + if err := json.Unmarshal(*value, &gu.LevelRole); err != nil { + return fmt.Errorf("unmarshal field level_role: %w", err) + } + } + case guild.FieldPermissions: + if value, ok := values[i].(*[]byte); !ok { + return fmt.Errorf("unexpected type %T for field permissions", values[i]) + } else if value != nil && len(*value) > 0 { + if err := json.Unmarshal(*value, &gu.Permissions); err != nil { + return fmt.Errorf("unmarshal field permissions: %w", err) + } + } + case guild.FieldRemindCount: + if value, ok := values[i].(*sql.NullInt64); !ok { + return fmt.Errorf("unexpected type %T for field remind_count", values[i]) + } else if value.Valid { + gu.RemindCount = int(value.Int64) + } + case guild.FieldRolePanelEditTimes: + if value, ok := values[i].(*[]byte); !ok { + return fmt.Errorf("unexpected type %T for field role_panel_edit_times", values[i]) + } else if value != nil && len(*value) > 0 { + if err := json.Unmarshal(*value, &gu.RolePanelEditTimes); err != nil { + return fmt.Errorf("unmarshal field role_panel_edit_times: %w", err) + } + } + case guild.FieldBumpEnabled: + if value, ok := values[i].(*sql.NullBool); !ok { + return fmt.Errorf("unexpected type %T for field bump_enabled", values[i]) + } else if value.Valid { + gu.BumpEnabled = value.Bool + } + case guild.FieldBumpMessageTitle: + if value, ok := values[i].(*sql.NullString); !ok { + return fmt.Errorf("unexpected type %T for field bump_message_title", values[i]) + } else if value.Valid { + gu.BumpMessageTitle = value.String + } + case guild.FieldBumpMessage: + if value, ok := values[i].(*sql.NullString); !ok { + return fmt.Errorf("unexpected type %T for field bump_message", values[i]) + } else if value.Valid { + gu.BumpMessage = value.String + } + case guild.FieldBumpRemindMessageTitle: + if value, ok := values[i].(*sql.NullString); !ok { + return fmt.Errorf("unexpected type %T for field bump_remind_message_title", values[i]) + } else if value.Valid { + gu.BumpRemindMessageTitle = value.String + } + case guild.FieldBumpRemindMessage: + if value, ok := values[i].(*sql.NullString); !ok { + return fmt.Errorf("unexpected type %T for field bump_remind_message", values[i]) + } else if value.Valid { + gu.BumpRemindMessage = value.String + } + case guild.FieldUpEnabled: + if value, ok := values[i].(*sql.NullBool); !ok { + return fmt.Errorf("unexpected type %T for field up_enabled", values[i]) + } else if value.Valid { + gu.UpEnabled = value.Bool + } + case guild.FieldUpMessageTitle: + if value, ok := values[i].(*sql.NullString); !ok { + return fmt.Errorf("unexpected type %T for field up_message_title", values[i]) + } else if value.Valid { + gu.UpMessageTitle = value.String + } + case guild.FieldUpMessage: + if value, ok := values[i].(*sql.NullString); !ok { + return fmt.Errorf("unexpected type %T for field up_message", values[i]) + } else if value.Valid { + gu.UpMessage = value.String + } + case guild.FieldUpRemindMessageTitle: + if value, ok := values[i].(*sql.NullString); !ok { + return fmt.Errorf("unexpected type %T for field up_remind_message_title", values[i]) + } else if value.Valid { + gu.UpRemindMessageTitle = value.String + } + case guild.FieldUpRemindMessage: + if value, ok := values[i].(*sql.NullString); !ok { + return fmt.Errorf("unexpected type %T for field up_remind_message", values[i]) + } else if value.Valid { + gu.UpRemindMessage = value.String + } + case guild.FieldBumpMention: + if value, ok := values[i].(*sql.NullInt64); !ok { + return fmt.Errorf("unexpected type %T for field bump_mention", values[i]) + } else if value.Valid { + gu.BumpMention = new(snowflake.ID) + *gu.BumpMention = snowflake.ID(value.Int64) + } + case guild.FieldUpMention: + if value, ok := values[i].(*sql.NullInt64); !ok { + return fmt.Errorf("unexpected type %T for field up_mention", values[i]) + } else if value.Valid { + gu.UpMention = new(snowflake.ID) + *gu.UpMention = snowflake.ID(value.Int64) + } + case guild.ForeignKeys[0]: + if value, ok := values[i].(*sql.NullInt64); !ok { + return fmt.Errorf("unexpected type %T for field user_own_guilds", values[i]) + } else if value.Valid { + gu.user_own_guilds = new(snowflake.ID) + *gu.user_own_guilds = snowflake.ID(value.Int64) + } + default: + gu.selectValues.Set(columns[i], values[i]) + } + } + return nil +} + +// Value returns the ent.Value that was dynamically selected and assigned to the Guild. +// This includes values selected through modifiers, order, etc. +func (gu *Guild) Value(name string) (ent.Value, error) { + return gu.selectValues.Get(name) +} + +// QueryOwner queries the "owner" edge of the Guild entity. +func (gu *Guild) QueryOwner() *UserQuery { + return NewGuildClient(gu.config).QueryOwner(gu) +} + +// QueryMembers queries the "members" edge of the Guild entity. +func (gu *Guild) QueryMembers() *MemberQuery { + return NewGuildClient(gu.config).QueryMembers(gu) +} + +// QueryMessagePins queries the "message_pins" edge of the Guild entity. +func (gu *Guild) QueryMessagePins() *MessagePinQuery { + return NewGuildClient(gu.config).QueryMessagePins(gu) +} + +// QueryReminds queries the "reminds" edge of the Guild entity. +func (gu *Guild) QueryReminds() *MessageRemindQuery { + return NewGuildClient(gu.config).QueryReminds(gu) +} + +// QueryRolePanels queries the "role_panels" edge of the Guild entity. +func (gu *Guild) QueryRolePanels() *RolePanelQuery { + return NewGuildClient(gu.config).QueryRolePanels(gu) +} + +// QueryRolePanelPlacements queries the "role_panel_placements" edge of the Guild entity. +func (gu *Guild) QueryRolePanelPlacements() *RolePanelPlacedQuery { + return NewGuildClient(gu.config).QueryRolePanelPlacements(gu) +} + +// QueryRolePanelEdits queries the "role_panel_edits" edge of the Guild entity. +func (gu *Guild) QueryRolePanelEdits() *RolePanelEditQuery { + return NewGuildClient(gu.config).QueryRolePanelEdits(gu) +} + +// Update returns a builder for updating this Guild. +// Note that you need to call Guild.Unwrap() before calling this method if this Guild +// was returned from a transaction, and the transaction was committed or rolled back. +func (gu *Guild) Update() *GuildUpdateOne { + return NewGuildClient(gu.config).UpdateOne(gu) +} + +// Unwrap unwraps the Guild entity that was returned from a transaction after it was closed, +// so that all future queries will be executed through the driver which created the transaction. +func (gu *Guild) Unwrap() *Guild { + _tx, ok := gu.config.driver.(*txDriver) + if !ok { + panic("ent: Guild is not a transactional entity") + } + gu.config.driver = _tx.drv + return gu +} + +// String implements the fmt.Stringer. +func (gu *Guild) String() string { + var builder strings.Builder + builder.WriteString("Guild(") + builder.WriteString(fmt.Sprintf("id=%v, ", gu.ID)) + builder.WriteString("name=") + builder.WriteString(gu.Name) + builder.WriteString(", ") + builder.WriteString("locale=") + builder.WriteString(fmt.Sprintf("%v", gu.Locale)) + builder.WriteString(", ") + builder.WriteString("level_up_message=") + builder.WriteString(gu.LevelUpMessage) + builder.WriteString(", ") + if v := gu.LevelUpChannel; v != nil { + builder.WriteString("level_up_channel=") + builder.WriteString(fmt.Sprintf("%v", *v)) + } + builder.WriteString(", ") + builder.WriteString("level_up_exclude_channel=") + builder.WriteString(fmt.Sprintf("%v", gu.LevelUpExcludeChannel)) + builder.WriteString(", ") + builder.WriteString("level_mee6_imported=") + builder.WriteString(fmt.Sprintf("%v", gu.LevelMee6Imported)) + builder.WriteString(", ") + builder.WriteString("level_role=") + builder.WriteString(fmt.Sprintf("%v", gu.LevelRole)) + builder.WriteString(", ") + builder.WriteString("permissions=") + builder.WriteString(fmt.Sprintf("%v", gu.Permissions)) + builder.WriteString(", ") + builder.WriteString("remind_count=") + builder.WriteString(fmt.Sprintf("%v", gu.RemindCount)) + builder.WriteString(", ") + builder.WriteString("role_panel_edit_times=") + builder.WriteString(fmt.Sprintf("%v", gu.RolePanelEditTimes)) + builder.WriteString(", ") + builder.WriteString("bump_enabled=") + builder.WriteString(fmt.Sprintf("%v", gu.BumpEnabled)) + builder.WriteString(", ") + builder.WriteString("bump_message_title=") + builder.WriteString(gu.BumpMessageTitle) + builder.WriteString(", ") + builder.WriteString("bump_message=") + builder.WriteString(gu.BumpMessage) + builder.WriteString(", ") + builder.WriteString("bump_remind_message_title=") + builder.WriteString(gu.BumpRemindMessageTitle) + builder.WriteString(", ") + builder.WriteString("bump_remind_message=") + builder.WriteString(gu.BumpRemindMessage) + builder.WriteString(", ") + builder.WriteString("up_enabled=") + builder.WriteString(fmt.Sprintf("%v", gu.UpEnabled)) + builder.WriteString(", ") + builder.WriteString("up_message_title=") + builder.WriteString(gu.UpMessageTitle) + builder.WriteString(", ") + builder.WriteString("up_message=") + builder.WriteString(gu.UpMessage) + builder.WriteString(", ") + builder.WriteString("up_remind_message_title=") + builder.WriteString(gu.UpRemindMessageTitle) + builder.WriteString(", ") + builder.WriteString("up_remind_message=") + builder.WriteString(gu.UpRemindMessage) + builder.WriteString(", ") + if v := gu.BumpMention; v != nil { + builder.WriteString("bump_mention=") + builder.WriteString(fmt.Sprintf("%v", *v)) + } + builder.WriteString(", ") + if v := gu.UpMention; v != nil { + builder.WriteString("up_mention=") + builder.WriteString(fmt.Sprintf("%v", *v)) + } + builder.WriteByte(')') + return builder.String() +} + +// Guilds is a parsable slice of Guild. +type Guilds []*Guild diff --git a/ent/guild/guild.go b/ent/guild/guild.go new file mode 100644 index 00000000..4581a272 --- /dev/null +++ b/ent/guild/guild.go @@ -0,0 +1,474 @@ +// Code generated by ent, DO NOT EDIT. + +package guild + +import ( + "time" + + "entgo.io/ent/dialect/sql" + "entgo.io/ent/dialect/sql/sqlgraph" + "github.com/disgoorg/disgo/discord" + snowflake "github.com/disgoorg/snowflake/v2" + "github.com/sabafly/gobot/internal/permissions" +) + +const ( + // Label holds the string label denoting the guild type in the database. + Label = "guild" + // FieldID holds the string denoting the id field in the database. + FieldID = "id" + // FieldName holds the string denoting the name field in the database. + FieldName = "name" + // FieldLocale holds the string denoting the locale field in the database. + FieldLocale = "locale" + // FieldLevelUpMessage holds the string denoting the level_up_message field in the database. + FieldLevelUpMessage = "level_up_message" + // FieldLevelUpChannel holds the string denoting the level_up_channel field in the database. + FieldLevelUpChannel = "level_up_channel" + // FieldLevelUpExcludeChannel holds the string denoting the level_up_exclude_channel field in the database. + FieldLevelUpExcludeChannel = "level_up_exclude_channel" + // FieldLevelMee6Imported holds the string denoting the level_mee6_imported field in the database. + FieldLevelMee6Imported = "level_mee6_imported" + // FieldLevelRole holds the string denoting the level_role field in the database. + FieldLevelRole = "level_role" + // FieldPermissions holds the string denoting the permissions field in the database. + FieldPermissions = "permissions" + // FieldRemindCount holds the string denoting the remind_count field in the database. + FieldRemindCount = "remind_count" + // FieldRolePanelEditTimes holds the string denoting the role_panel_edit_times field in the database. + FieldRolePanelEditTimes = "role_panel_edit_times" + // FieldBumpEnabled holds the string denoting the bump_enabled field in the database. + FieldBumpEnabled = "bump_enabled" + // FieldBumpMessageTitle holds the string denoting the bump_message_title field in the database. + FieldBumpMessageTitle = "bump_message_title" + // FieldBumpMessage holds the string denoting the bump_message field in the database. + FieldBumpMessage = "bump_message" + // FieldBumpRemindMessageTitle holds the string denoting the bump_remind_message_title field in the database. + FieldBumpRemindMessageTitle = "bump_remind_message_title" + // FieldBumpRemindMessage holds the string denoting the bump_remind_message field in the database. + FieldBumpRemindMessage = "bump_remind_message" + // FieldUpEnabled holds the string denoting the up_enabled field in the database. + FieldUpEnabled = "up_enabled" + // FieldUpMessageTitle holds the string denoting the up_message_title field in the database. + FieldUpMessageTitle = "up_message_title" + // FieldUpMessage holds the string denoting the up_message field in the database. + FieldUpMessage = "up_message" + // FieldUpRemindMessageTitle holds the string denoting the up_remind_message_title field in the database. + FieldUpRemindMessageTitle = "up_remind_message_title" + // FieldUpRemindMessage holds the string denoting the up_remind_message field in the database. + FieldUpRemindMessage = "up_remind_message" + // FieldBumpMention holds the string denoting the bump_mention field in the database. + FieldBumpMention = "bump_mention" + // FieldUpMention holds the string denoting the up_mention field in the database. + FieldUpMention = "up_mention" + // EdgeOwner holds the string denoting the owner edge name in mutations. + EdgeOwner = "owner" + // EdgeMembers holds the string denoting the members edge name in mutations. + EdgeMembers = "members" + // EdgeMessagePins holds the string denoting the message_pins edge name in mutations. + EdgeMessagePins = "message_pins" + // EdgeReminds holds the string denoting the reminds edge name in mutations. + EdgeReminds = "reminds" + // EdgeRolePanels holds the string denoting the role_panels edge name in mutations. + EdgeRolePanels = "role_panels" + // EdgeRolePanelPlacements holds the string denoting the role_panel_placements edge name in mutations. + EdgeRolePanelPlacements = "role_panel_placements" + // EdgeRolePanelEdits holds the string denoting the role_panel_edits edge name in mutations. + EdgeRolePanelEdits = "role_panel_edits" + // Table holds the table name of the guild in the database. + Table = "guilds" + // OwnerTable is the table that holds the owner relation/edge. + OwnerTable = "guilds" + // OwnerInverseTable is the table name for the User entity. + // It exists in this package in order to avoid circular dependency with the "user" package. + OwnerInverseTable = "users" + // OwnerColumn is the table column denoting the owner relation/edge. + OwnerColumn = "user_own_guilds" + // MembersTable is the table that holds the members relation/edge. + MembersTable = "members" + // MembersInverseTable is the table name for the Member entity. + // It exists in this package in order to avoid circular dependency with the "member" package. + MembersInverseTable = "members" + // MembersColumn is the table column denoting the members relation/edge. + MembersColumn = "guild_members" + // MessagePinsTable is the table that holds the message_pins relation/edge. + MessagePinsTable = "message_pins" + // MessagePinsInverseTable is the table name for the MessagePin entity. + // It exists in this package in order to avoid circular dependency with the "messagepin" package. + MessagePinsInverseTable = "message_pins" + // MessagePinsColumn is the table column denoting the message_pins relation/edge. + MessagePinsColumn = "guild_message_pins" + // RemindsTable is the table that holds the reminds relation/edge. + RemindsTable = "message_reminds" + // RemindsInverseTable is the table name for the MessageRemind entity. + // It exists in this package in order to avoid circular dependency with the "messageremind" package. + RemindsInverseTable = "message_reminds" + // RemindsColumn is the table column denoting the reminds relation/edge. + RemindsColumn = "guild_reminds" + // RolePanelsTable is the table that holds the role_panels relation/edge. + RolePanelsTable = "role_panels" + // RolePanelsInverseTable is the table name for the RolePanel entity. + // It exists in this package in order to avoid circular dependency with the "rolepanel" package. + RolePanelsInverseTable = "role_panels" + // RolePanelsColumn is the table column denoting the role_panels relation/edge. + RolePanelsColumn = "guild_role_panels" + // RolePanelPlacementsTable is the table that holds the role_panel_placements relation/edge. + RolePanelPlacementsTable = "role_panel_placeds" + // RolePanelPlacementsInverseTable is the table name for the RolePanelPlaced entity. + // It exists in this package in order to avoid circular dependency with the "rolepanelplaced" package. + RolePanelPlacementsInverseTable = "role_panel_placeds" + // RolePanelPlacementsColumn is the table column denoting the role_panel_placements relation/edge. + RolePanelPlacementsColumn = "guild_role_panel_placements" + // RolePanelEditsTable is the table that holds the role_panel_edits relation/edge. + RolePanelEditsTable = "role_panel_edits" + // RolePanelEditsInverseTable is the table name for the RolePanelEdit entity. + // It exists in this package in order to avoid circular dependency with the "rolepaneledit" package. + RolePanelEditsInverseTable = "role_panel_edits" + // RolePanelEditsColumn is the table column denoting the role_panel_edits relation/edge. + RolePanelEditsColumn = "guild_role_panel_edits" +) + +// Columns holds all SQL columns for guild fields. +var Columns = []string{ + FieldID, + FieldName, + FieldLocale, + FieldLevelUpMessage, + FieldLevelUpChannel, + FieldLevelUpExcludeChannel, + FieldLevelMee6Imported, + FieldLevelRole, + FieldPermissions, + FieldRemindCount, + FieldRolePanelEditTimes, + FieldBumpEnabled, + FieldBumpMessageTitle, + FieldBumpMessage, + FieldBumpRemindMessageTitle, + FieldBumpRemindMessage, + FieldUpEnabled, + FieldUpMessageTitle, + FieldUpMessage, + FieldUpRemindMessageTitle, + FieldUpRemindMessage, + FieldBumpMention, + FieldUpMention, +} + +// ForeignKeys holds the SQL foreign-keys that are owned by the "guilds" +// table and are not defined as standalone fields in the schema. +var ForeignKeys = []string{ + "user_own_guilds", +} + +// ValidColumn reports if the column name is valid (part of the table columns). +func ValidColumn(column string) bool { + for i := range Columns { + if column == Columns[i] { + return true + } + } + for i := range ForeignKeys { + if column == ForeignKeys[i] { + return true + } + } + return false +} + +var ( + // NameValidator is a validator for the "name" field. It is called by the builders before save. + NameValidator func(string) error + // DefaultLocale holds the default value on creation for the "locale" field. + DefaultLocale discord.Locale + // LocaleValidator is a validator for the "locale" field. It is called by the builders before save. + LocaleValidator func(string) error + // DefaultLevelUpMessage holds the default value on creation for the "level_up_message" field. + DefaultLevelUpMessage string + // LevelUpMessageValidator is a validator for the "level_up_message" field. It is called by the builders before save. + LevelUpMessageValidator func(string) error + // DefaultLevelMee6Imported holds the default value on creation for the "level_mee6_imported" field. + DefaultLevelMee6Imported bool + // DefaultLevelRole holds the default value on creation for the "level_role" field. + DefaultLevelRole map[int]snowflake.ID + // DefaultPermissions holds the default value on creation for the "permissions" field. + DefaultPermissions map[snowflake.ID]permissions.Permission + // DefaultRemindCount holds the default value on creation for the "remind_count" field. + DefaultRemindCount int + // DefaultRolePanelEditTimes holds the default value on creation for the "role_panel_edit_times" field. + DefaultRolePanelEditTimes []time.Time + // DefaultBumpEnabled holds the default value on creation for the "bump_enabled" field. + DefaultBumpEnabled bool + // DefaultBumpMessageTitle holds the default value on creation for the "bump_message_title" field. + DefaultBumpMessageTitle string + // BumpMessageTitleValidator is a validator for the "bump_message_title" field. It is called by the builders before save. + BumpMessageTitleValidator func(string) error + // DefaultBumpMessage holds the default value on creation for the "bump_message" field. + DefaultBumpMessage string + // BumpMessageValidator is a validator for the "bump_message" field. It is called by the builders before save. + BumpMessageValidator func(string) error + // DefaultBumpRemindMessageTitle holds the default value on creation for the "bump_remind_message_title" field. + DefaultBumpRemindMessageTitle string + // BumpRemindMessageTitleValidator is a validator for the "bump_remind_message_title" field. It is called by the builders before save. + BumpRemindMessageTitleValidator func(string) error + // DefaultBumpRemindMessage holds the default value on creation for the "bump_remind_message" field. + DefaultBumpRemindMessage string + // BumpRemindMessageValidator is a validator for the "bump_remind_message" field. It is called by the builders before save. + BumpRemindMessageValidator func(string) error + // DefaultUpEnabled holds the default value on creation for the "up_enabled" field. + DefaultUpEnabled bool + // DefaultUpMessageTitle holds the default value on creation for the "up_message_title" field. + DefaultUpMessageTitle string + // UpMessageTitleValidator is a validator for the "up_message_title" field. It is called by the builders before save. + UpMessageTitleValidator func(string) error + // DefaultUpMessage holds the default value on creation for the "up_message" field. + DefaultUpMessage string + // UpMessageValidator is a validator for the "up_message" field. It is called by the builders before save. + UpMessageValidator func(string) error + // DefaultUpRemindMessageTitle holds the default value on creation for the "up_remind_message_title" field. + DefaultUpRemindMessageTitle string + // UpRemindMessageTitleValidator is a validator for the "up_remind_message_title" field. It is called by the builders before save. + UpRemindMessageTitleValidator func(string) error + // DefaultUpRemindMessage holds the default value on creation for the "up_remind_message" field. + DefaultUpRemindMessage string + // UpRemindMessageValidator is a validator for the "up_remind_message" field. It is called by the builders before save. + UpRemindMessageValidator func(string) error +) + +// OrderOption defines the ordering options for the Guild queries. +type OrderOption func(*sql.Selector) + +// ByID orders the results by the id field. +func ByID(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldID, opts...).ToFunc() +} + +// ByName orders the results by the name field. +func ByName(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldName, opts...).ToFunc() +} + +// ByLocale orders the results by the locale field. +func ByLocale(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldLocale, opts...).ToFunc() +} + +// ByLevelUpMessage orders the results by the level_up_message field. +func ByLevelUpMessage(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldLevelUpMessage, opts...).ToFunc() +} + +// ByLevelUpChannel orders the results by the level_up_channel field. +func ByLevelUpChannel(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldLevelUpChannel, opts...).ToFunc() +} + +// ByLevelMee6Imported orders the results by the level_mee6_imported field. +func ByLevelMee6Imported(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldLevelMee6Imported, opts...).ToFunc() +} + +// ByRemindCount orders the results by the remind_count field. +func ByRemindCount(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldRemindCount, opts...).ToFunc() +} + +// ByBumpEnabled orders the results by the bump_enabled field. +func ByBumpEnabled(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldBumpEnabled, opts...).ToFunc() +} + +// ByBumpMessageTitle orders the results by the bump_message_title field. +func ByBumpMessageTitle(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldBumpMessageTitle, opts...).ToFunc() +} + +// ByBumpMessage orders the results by the bump_message field. +func ByBumpMessage(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldBumpMessage, opts...).ToFunc() +} + +// ByBumpRemindMessageTitle orders the results by the bump_remind_message_title field. +func ByBumpRemindMessageTitle(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldBumpRemindMessageTitle, opts...).ToFunc() +} + +// ByBumpRemindMessage orders the results by the bump_remind_message field. +func ByBumpRemindMessage(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldBumpRemindMessage, opts...).ToFunc() +} + +// ByUpEnabled orders the results by the up_enabled field. +func ByUpEnabled(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldUpEnabled, opts...).ToFunc() +} + +// ByUpMessageTitle orders the results by the up_message_title field. +func ByUpMessageTitle(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldUpMessageTitle, opts...).ToFunc() +} + +// ByUpMessage orders the results by the up_message field. +func ByUpMessage(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldUpMessage, opts...).ToFunc() +} + +// ByUpRemindMessageTitle orders the results by the up_remind_message_title field. +func ByUpRemindMessageTitle(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldUpRemindMessageTitle, opts...).ToFunc() +} + +// ByUpRemindMessage orders the results by the up_remind_message field. +func ByUpRemindMessage(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldUpRemindMessage, opts...).ToFunc() +} + +// ByBumpMention orders the results by the bump_mention field. +func ByBumpMention(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldBumpMention, opts...).ToFunc() +} + +// ByUpMention orders the results by the up_mention field. +func ByUpMention(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldUpMention, opts...).ToFunc() +} + +// ByOwnerField orders the results by owner field. +func ByOwnerField(field string, opts ...sql.OrderTermOption) OrderOption { + return func(s *sql.Selector) { + sqlgraph.OrderByNeighborTerms(s, newOwnerStep(), sql.OrderByField(field, opts...)) + } +} + +// ByMembersCount orders the results by members count. +func ByMembersCount(opts ...sql.OrderTermOption) OrderOption { + return func(s *sql.Selector) { + sqlgraph.OrderByNeighborsCount(s, newMembersStep(), opts...) + } +} + +// ByMembers orders the results by members terms. +func ByMembers(term sql.OrderTerm, terms ...sql.OrderTerm) OrderOption { + return func(s *sql.Selector) { + sqlgraph.OrderByNeighborTerms(s, newMembersStep(), append([]sql.OrderTerm{term}, terms...)...) + } +} + +// ByMessagePinsCount orders the results by message_pins count. +func ByMessagePinsCount(opts ...sql.OrderTermOption) OrderOption { + return func(s *sql.Selector) { + sqlgraph.OrderByNeighborsCount(s, newMessagePinsStep(), opts...) + } +} + +// ByMessagePins orders the results by message_pins terms. +func ByMessagePins(term sql.OrderTerm, terms ...sql.OrderTerm) OrderOption { + return func(s *sql.Selector) { + sqlgraph.OrderByNeighborTerms(s, newMessagePinsStep(), append([]sql.OrderTerm{term}, terms...)...) + } +} + +// ByRemindsCount orders the results by reminds count. +func ByRemindsCount(opts ...sql.OrderTermOption) OrderOption { + return func(s *sql.Selector) { + sqlgraph.OrderByNeighborsCount(s, newRemindsStep(), opts...) + } +} + +// ByReminds orders the results by reminds terms. +func ByReminds(term sql.OrderTerm, terms ...sql.OrderTerm) OrderOption { + return func(s *sql.Selector) { + sqlgraph.OrderByNeighborTerms(s, newRemindsStep(), append([]sql.OrderTerm{term}, terms...)...) + } +} + +// ByRolePanelsCount orders the results by role_panels count. +func ByRolePanelsCount(opts ...sql.OrderTermOption) OrderOption { + return func(s *sql.Selector) { + sqlgraph.OrderByNeighborsCount(s, newRolePanelsStep(), opts...) + } +} + +// ByRolePanels orders the results by role_panels terms. +func ByRolePanels(term sql.OrderTerm, terms ...sql.OrderTerm) OrderOption { + return func(s *sql.Selector) { + sqlgraph.OrderByNeighborTerms(s, newRolePanelsStep(), append([]sql.OrderTerm{term}, terms...)...) + } +} + +// ByRolePanelPlacementsCount orders the results by role_panel_placements count. +func ByRolePanelPlacementsCount(opts ...sql.OrderTermOption) OrderOption { + return func(s *sql.Selector) { + sqlgraph.OrderByNeighborsCount(s, newRolePanelPlacementsStep(), opts...) + } +} + +// ByRolePanelPlacements orders the results by role_panel_placements terms. +func ByRolePanelPlacements(term sql.OrderTerm, terms ...sql.OrderTerm) OrderOption { + return func(s *sql.Selector) { + sqlgraph.OrderByNeighborTerms(s, newRolePanelPlacementsStep(), append([]sql.OrderTerm{term}, terms...)...) + } +} + +// ByRolePanelEditsCount orders the results by role_panel_edits count. +func ByRolePanelEditsCount(opts ...sql.OrderTermOption) OrderOption { + return func(s *sql.Selector) { + sqlgraph.OrderByNeighborsCount(s, newRolePanelEditsStep(), opts...) + } +} + +// ByRolePanelEdits orders the results by role_panel_edits terms. +func ByRolePanelEdits(term sql.OrderTerm, terms ...sql.OrderTerm) OrderOption { + return func(s *sql.Selector) { + sqlgraph.OrderByNeighborTerms(s, newRolePanelEditsStep(), append([]sql.OrderTerm{term}, terms...)...) + } +} +func newOwnerStep() *sqlgraph.Step { + return sqlgraph.NewStep( + sqlgraph.From(Table, FieldID), + sqlgraph.To(OwnerInverseTable, FieldID), + sqlgraph.Edge(sqlgraph.M2O, true, OwnerTable, OwnerColumn), + ) +} +func newMembersStep() *sqlgraph.Step { + return sqlgraph.NewStep( + sqlgraph.From(Table, FieldID), + sqlgraph.To(MembersInverseTable, FieldID), + sqlgraph.Edge(sqlgraph.O2M, false, MembersTable, MembersColumn), + ) +} +func newMessagePinsStep() *sqlgraph.Step { + return sqlgraph.NewStep( + sqlgraph.From(Table, FieldID), + sqlgraph.To(MessagePinsInverseTable, FieldID), + sqlgraph.Edge(sqlgraph.O2M, false, MessagePinsTable, MessagePinsColumn), + ) +} +func newRemindsStep() *sqlgraph.Step { + return sqlgraph.NewStep( + sqlgraph.From(Table, FieldID), + sqlgraph.To(RemindsInverseTable, FieldID), + sqlgraph.Edge(sqlgraph.O2M, false, RemindsTable, RemindsColumn), + ) +} +func newRolePanelsStep() *sqlgraph.Step { + return sqlgraph.NewStep( + sqlgraph.From(Table, FieldID), + sqlgraph.To(RolePanelsInverseTable, FieldID), + sqlgraph.Edge(sqlgraph.O2M, false, RolePanelsTable, RolePanelsColumn), + ) +} +func newRolePanelPlacementsStep() *sqlgraph.Step { + return sqlgraph.NewStep( + sqlgraph.From(Table, FieldID), + sqlgraph.To(RolePanelPlacementsInverseTable, FieldID), + sqlgraph.Edge(sqlgraph.O2M, false, RolePanelPlacementsTable, RolePanelPlacementsColumn), + ) +} +func newRolePanelEditsStep() *sqlgraph.Step { + return sqlgraph.NewStep( + sqlgraph.From(Table, FieldID), + sqlgraph.To(RolePanelEditsInverseTable, FieldID), + sqlgraph.Edge(sqlgraph.O2M, false, RolePanelEditsTable, RolePanelEditsColumn), + ) +} diff --git a/ent/guild/where.go b/ent/guild/where.go new file mode 100644 index 00000000..67060170 --- /dev/null +++ b/ent/guild/where.go @@ -0,0 +1,1342 @@ +// Code generated by ent, DO NOT EDIT. + +package guild + +import ( + "entgo.io/ent/dialect/sql" + "entgo.io/ent/dialect/sql/sqlgraph" + "github.com/disgoorg/disgo/discord" + snowflake "github.com/disgoorg/snowflake/v2" + "github.com/sabafly/gobot/ent/predicate" +) + +// ID filters vertices based on their ID field. +func ID(id snowflake.ID) predicate.Guild { + return predicate.Guild(sql.FieldEQ(FieldID, id)) +} + +// IDEQ applies the EQ predicate on the ID field. +func IDEQ(id snowflake.ID) predicate.Guild { + return predicate.Guild(sql.FieldEQ(FieldID, id)) +} + +// IDNEQ applies the NEQ predicate on the ID field. +func IDNEQ(id snowflake.ID) predicate.Guild { + return predicate.Guild(sql.FieldNEQ(FieldID, id)) +} + +// IDIn applies the In predicate on the ID field. +func IDIn(ids ...snowflake.ID) predicate.Guild { + return predicate.Guild(sql.FieldIn(FieldID, ids...)) +} + +// IDNotIn applies the NotIn predicate on the ID field. +func IDNotIn(ids ...snowflake.ID) predicate.Guild { + return predicate.Guild(sql.FieldNotIn(FieldID, ids...)) +} + +// IDGT applies the GT predicate on the ID field. +func IDGT(id snowflake.ID) predicate.Guild { + return predicate.Guild(sql.FieldGT(FieldID, id)) +} + +// IDGTE applies the GTE predicate on the ID field. +func IDGTE(id snowflake.ID) predicate.Guild { + return predicate.Guild(sql.FieldGTE(FieldID, id)) +} + +// IDLT applies the LT predicate on the ID field. +func IDLT(id snowflake.ID) predicate.Guild { + return predicate.Guild(sql.FieldLT(FieldID, id)) +} + +// IDLTE applies the LTE predicate on the ID field. +func IDLTE(id snowflake.ID) predicate.Guild { + return predicate.Guild(sql.FieldLTE(FieldID, id)) +} + +// Name applies equality check predicate on the "name" field. It's identical to NameEQ. +func Name(v string) predicate.Guild { + return predicate.Guild(sql.FieldEQ(FieldName, v)) +} + +// Locale applies equality check predicate on the "locale" field. It's identical to LocaleEQ. +func Locale(v discord.Locale) predicate.Guild { + vc := string(v) + return predicate.Guild(sql.FieldEQ(FieldLocale, vc)) +} + +// LevelUpMessage applies equality check predicate on the "level_up_message" field. It's identical to LevelUpMessageEQ. +func LevelUpMessage(v string) predicate.Guild { + return predicate.Guild(sql.FieldEQ(FieldLevelUpMessage, v)) +} + +// LevelUpChannel applies equality check predicate on the "level_up_channel" field. It's identical to LevelUpChannelEQ. +func LevelUpChannel(v snowflake.ID) predicate.Guild { + vc := uint64(v) + return predicate.Guild(sql.FieldEQ(FieldLevelUpChannel, vc)) +} + +// LevelMee6Imported applies equality check predicate on the "level_mee6_imported" field. It's identical to LevelMee6ImportedEQ. +func LevelMee6Imported(v bool) predicate.Guild { + return predicate.Guild(sql.FieldEQ(FieldLevelMee6Imported, v)) +} + +// RemindCount applies equality check predicate on the "remind_count" field. It's identical to RemindCountEQ. +func RemindCount(v int) predicate.Guild { + return predicate.Guild(sql.FieldEQ(FieldRemindCount, v)) +} + +// BumpEnabled applies equality check predicate on the "bump_enabled" field. It's identical to BumpEnabledEQ. +func BumpEnabled(v bool) predicate.Guild { + return predicate.Guild(sql.FieldEQ(FieldBumpEnabled, v)) +} + +// BumpMessageTitle applies equality check predicate on the "bump_message_title" field. It's identical to BumpMessageTitleEQ. +func BumpMessageTitle(v string) predicate.Guild { + return predicate.Guild(sql.FieldEQ(FieldBumpMessageTitle, v)) +} + +// BumpMessage applies equality check predicate on the "bump_message" field. It's identical to BumpMessageEQ. +func BumpMessage(v string) predicate.Guild { + return predicate.Guild(sql.FieldEQ(FieldBumpMessage, v)) +} + +// BumpRemindMessageTitle applies equality check predicate on the "bump_remind_message_title" field. It's identical to BumpRemindMessageTitleEQ. +func BumpRemindMessageTitle(v string) predicate.Guild { + return predicate.Guild(sql.FieldEQ(FieldBumpRemindMessageTitle, v)) +} + +// BumpRemindMessage applies equality check predicate on the "bump_remind_message" field. It's identical to BumpRemindMessageEQ. +func BumpRemindMessage(v string) predicate.Guild { + return predicate.Guild(sql.FieldEQ(FieldBumpRemindMessage, v)) +} + +// UpEnabled applies equality check predicate on the "up_enabled" field. It's identical to UpEnabledEQ. +func UpEnabled(v bool) predicate.Guild { + return predicate.Guild(sql.FieldEQ(FieldUpEnabled, v)) +} + +// UpMessageTitle applies equality check predicate on the "up_message_title" field. It's identical to UpMessageTitleEQ. +func UpMessageTitle(v string) predicate.Guild { + return predicate.Guild(sql.FieldEQ(FieldUpMessageTitle, v)) +} + +// UpMessage applies equality check predicate on the "up_message" field. It's identical to UpMessageEQ. +func UpMessage(v string) predicate.Guild { + return predicate.Guild(sql.FieldEQ(FieldUpMessage, v)) +} + +// UpRemindMessageTitle applies equality check predicate on the "up_remind_message_title" field. It's identical to UpRemindMessageTitleEQ. +func UpRemindMessageTitle(v string) predicate.Guild { + return predicate.Guild(sql.FieldEQ(FieldUpRemindMessageTitle, v)) +} + +// UpRemindMessage applies equality check predicate on the "up_remind_message" field. It's identical to UpRemindMessageEQ. +func UpRemindMessage(v string) predicate.Guild { + return predicate.Guild(sql.FieldEQ(FieldUpRemindMessage, v)) +} + +// BumpMention applies equality check predicate on the "bump_mention" field. It's identical to BumpMentionEQ. +func BumpMention(v snowflake.ID) predicate.Guild { + vc := uint64(v) + return predicate.Guild(sql.FieldEQ(FieldBumpMention, vc)) +} + +// UpMention applies equality check predicate on the "up_mention" field. It's identical to UpMentionEQ. +func UpMention(v snowflake.ID) predicate.Guild { + vc := uint64(v) + return predicate.Guild(sql.FieldEQ(FieldUpMention, vc)) +} + +// NameEQ applies the EQ predicate on the "name" field. +func NameEQ(v string) predicate.Guild { + return predicate.Guild(sql.FieldEQ(FieldName, v)) +} + +// NameNEQ applies the NEQ predicate on the "name" field. +func NameNEQ(v string) predicate.Guild { + return predicate.Guild(sql.FieldNEQ(FieldName, v)) +} + +// NameIn applies the In predicate on the "name" field. +func NameIn(vs ...string) predicate.Guild { + return predicate.Guild(sql.FieldIn(FieldName, vs...)) +} + +// NameNotIn applies the NotIn predicate on the "name" field. +func NameNotIn(vs ...string) predicate.Guild { + return predicate.Guild(sql.FieldNotIn(FieldName, vs...)) +} + +// NameGT applies the GT predicate on the "name" field. +func NameGT(v string) predicate.Guild { + return predicate.Guild(sql.FieldGT(FieldName, v)) +} + +// NameGTE applies the GTE predicate on the "name" field. +func NameGTE(v string) predicate.Guild { + return predicate.Guild(sql.FieldGTE(FieldName, v)) +} + +// NameLT applies the LT predicate on the "name" field. +func NameLT(v string) predicate.Guild { + return predicate.Guild(sql.FieldLT(FieldName, v)) +} + +// NameLTE applies the LTE predicate on the "name" field. +func NameLTE(v string) predicate.Guild { + return predicate.Guild(sql.FieldLTE(FieldName, v)) +} + +// NameContains applies the Contains predicate on the "name" field. +func NameContains(v string) predicate.Guild { + return predicate.Guild(sql.FieldContains(FieldName, v)) +} + +// NameHasPrefix applies the HasPrefix predicate on the "name" field. +func NameHasPrefix(v string) predicate.Guild { + return predicate.Guild(sql.FieldHasPrefix(FieldName, v)) +} + +// NameHasSuffix applies the HasSuffix predicate on the "name" field. +func NameHasSuffix(v string) predicate.Guild { + return predicate.Guild(sql.FieldHasSuffix(FieldName, v)) +} + +// NameEqualFold applies the EqualFold predicate on the "name" field. +func NameEqualFold(v string) predicate.Guild { + return predicate.Guild(sql.FieldEqualFold(FieldName, v)) +} + +// NameContainsFold applies the ContainsFold predicate on the "name" field. +func NameContainsFold(v string) predicate.Guild { + return predicate.Guild(sql.FieldContainsFold(FieldName, v)) +} + +// LocaleEQ applies the EQ predicate on the "locale" field. +func LocaleEQ(v discord.Locale) predicate.Guild { + vc := string(v) + return predicate.Guild(sql.FieldEQ(FieldLocale, vc)) +} + +// LocaleNEQ applies the NEQ predicate on the "locale" field. +func LocaleNEQ(v discord.Locale) predicate.Guild { + vc := string(v) + return predicate.Guild(sql.FieldNEQ(FieldLocale, vc)) +} + +// LocaleIn applies the In predicate on the "locale" field. +func LocaleIn(vs ...discord.Locale) predicate.Guild { + v := make([]any, len(vs)) + for i := range v { + v[i] = string(vs[i]) + } + return predicate.Guild(sql.FieldIn(FieldLocale, v...)) +} + +// LocaleNotIn applies the NotIn predicate on the "locale" field. +func LocaleNotIn(vs ...discord.Locale) predicate.Guild { + v := make([]any, len(vs)) + for i := range v { + v[i] = string(vs[i]) + } + return predicate.Guild(sql.FieldNotIn(FieldLocale, v...)) +} + +// LocaleGT applies the GT predicate on the "locale" field. +func LocaleGT(v discord.Locale) predicate.Guild { + vc := string(v) + return predicate.Guild(sql.FieldGT(FieldLocale, vc)) +} + +// LocaleGTE applies the GTE predicate on the "locale" field. +func LocaleGTE(v discord.Locale) predicate.Guild { + vc := string(v) + return predicate.Guild(sql.FieldGTE(FieldLocale, vc)) +} + +// LocaleLT applies the LT predicate on the "locale" field. +func LocaleLT(v discord.Locale) predicate.Guild { + vc := string(v) + return predicate.Guild(sql.FieldLT(FieldLocale, vc)) +} + +// LocaleLTE applies the LTE predicate on the "locale" field. +func LocaleLTE(v discord.Locale) predicate.Guild { + vc := string(v) + return predicate.Guild(sql.FieldLTE(FieldLocale, vc)) +} + +// LocaleContains applies the Contains predicate on the "locale" field. +func LocaleContains(v discord.Locale) predicate.Guild { + vc := string(v) + return predicate.Guild(sql.FieldContains(FieldLocale, vc)) +} + +// LocaleHasPrefix applies the HasPrefix predicate on the "locale" field. +func LocaleHasPrefix(v discord.Locale) predicate.Guild { + vc := string(v) + return predicate.Guild(sql.FieldHasPrefix(FieldLocale, vc)) +} + +// LocaleHasSuffix applies the HasSuffix predicate on the "locale" field. +func LocaleHasSuffix(v discord.Locale) predicate.Guild { + vc := string(v) + return predicate.Guild(sql.FieldHasSuffix(FieldLocale, vc)) +} + +// LocaleEqualFold applies the EqualFold predicate on the "locale" field. +func LocaleEqualFold(v discord.Locale) predicate.Guild { + vc := string(v) + return predicate.Guild(sql.FieldEqualFold(FieldLocale, vc)) +} + +// LocaleContainsFold applies the ContainsFold predicate on the "locale" field. +func LocaleContainsFold(v discord.Locale) predicate.Guild { + vc := string(v) + return predicate.Guild(sql.FieldContainsFold(FieldLocale, vc)) +} + +// LevelUpMessageEQ applies the EQ predicate on the "level_up_message" field. +func LevelUpMessageEQ(v string) predicate.Guild { + return predicate.Guild(sql.FieldEQ(FieldLevelUpMessage, v)) +} + +// LevelUpMessageNEQ applies the NEQ predicate on the "level_up_message" field. +func LevelUpMessageNEQ(v string) predicate.Guild { + return predicate.Guild(sql.FieldNEQ(FieldLevelUpMessage, v)) +} + +// LevelUpMessageIn applies the In predicate on the "level_up_message" field. +func LevelUpMessageIn(vs ...string) predicate.Guild { + return predicate.Guild(sql.FieldIn(FieldLevelUpMessage, vs...)) +} + +// LevelUpMessageNotIn applies the NotIn predicate on the "level_up_message" field. +func LevelUpMessageNotIn(vs ...string) predicate.Guild { + return predicate.Guild(sql.FieldNotIn(FieldLevelUpMessage, vs...)) +} + +// LevelUpMessageGT applies the GT predicate on the "level_up_message" field. +func LevelUpMessageGT(v string) predicate.Guild { + return predicate.Guild(sql.FieldGT(FieldLevelUpMessage, v)) +} + +// LevelUpMessageGTE applies the GTE predicate on the "level_up_message" field. +func LevelUpMessageGTE(v string) predicate.Guild { + return predicate.Guild(sql.FieldGTE(FieldLevelUpMessage, v)) +} + +// LevelUpMessageLT applies the LT predicate on the "level_up_message" field. +func LevelUpMessageLT(v string) predicate.Guild { + return predicate.Guild(sql.FieldLT(FieldLevelUpMessage, v)) +} + +// LevelUpMessageLTE applies the LTE predicate on the "level_up_message" field. +func LevelUpMessageLTE(v string) predicate.Guild { + return predicate.Guild(sql.FieldLTE(FieldLevelUpMessage, v)) +} + +// LevelUpMessageContains applies the Contains predicate on the "level_up_message" field. +func LevelUpMessageContains(v string) predicate.Guild { + return predicate.Guild(sql.FieldContains(FieldLevelUpMessage, v)) +} + +// LevelUpMessageHasPrefix applies the HasPrefix predicate on the "level_up_message" field. +func LevelUpMessageHasPrefix(v string) predicate.Guild { + return predicate.Guild(sql.FieldHasPrefix(FieldLevelUpMessage, v)) +} + +// LevelUpMessageHasSuffix applies the HasSuffix predicate on the "level_up_message" field. +func LevelUpMessageHasSuffix(v string) predicate.Guild { + return predicate.Guild(sql.FieldHasSuffix(FieldLevelUpMessage, v)) +} + +// LevelUpMessageEqualFold applies the EqualFold predicate on the "level_up_message" field. +func LevelUpMessageEqualFold(v string) predicate.Guild { + return predicate.Guild(sql.FieldEqualFold(FieldLevelUpMessage, v)) +} + +// LevelUpMessageContainsFold applies the ContainsFold predicate on the "level_up_message" field. +func LevelUpMessageContainsFold(v string) predicate.Guild { + return predicate.Guild(sql.FieldContainsFold(FieldLevelUpMessage, v)) +} + +// LevelUpChannelEQ applies the EQ predicate on the "level_up_channel" field. +func LevelUpChannelEQ(v snowflake.ID) predicate.Guild { + vc := uint64(v) + return predicate.Guild(sql.FieldEQ(FieldLevelUpChannel, vc)) +} + +// LevelUpChannelNEQ applies the NEQ predicate on the "level_up_channel" field. +func LevelUpChannelNEQ(v snowflake.ID) predicate.Guild { + vc := uint64(v) + return predicate.Guild(sql.FieldNEQ(FieldLevelUpChannel, vc)) +} + +// LevelUpChannelIn applies the In predicate on the "level_up_channel" field. +func LevelUpChannelIn(vs ...snowflake.ID) predicate.Guild { + v := make([]any, len(vs)) + for i := range v { + v[i] = uint64(vs[i]) + } + return predicate.Guild(sql.FieldIn(FieldLevelUpChannel, v...)) +} + +// LevelUpChannelNotIn applies the NotIn predicate on the "level_up_channel" field. +func LevelUpChannelNotIn(vs ...snowflake.ID) predicate.Guild { + v := make([]any, len(vs)) + for i := range v { + v[i] = uint64(vs[i]) + } + return predicate.Guild(sql.FieldNotIn(FieldLevelUpChannel, v...)) +} + +// LevelUpChannelGT applies the GT predicate on the "level_up_channel" field. +func LevelUpChannelGT(v snowflake.ID) predicate.Guild { + vc := uint64(v) + return predicate.Guild(sql.FieldGT(FieldLevelUpChannel, vc)) +} + +// LevelUpChannelGTE applies the GTE predicate on the "level_up_channel" field. +func LevelUpChannelGTE(v snowflake.ID) predicate.Guild { + vc := uint64(v) + return predicate.Guild(sql.FieldGTE(FieldLevelUpChannel, vc)) +} + +// LevelUpChannelLT applies the LT predicate on the "level_up_channel" field. +func LevelUpChannelLT(v snowflake.ID) predicate.Guild { + vc := uint64(v) + return predicate.Guild(sql.FieldLT(FieldLevelUpChannel, vc)) +} + +// LevelUpChannelLTE applies the LTE predicate on the "level_up_channel" field. +func LevelUpChannelLTE(v snowflake.ID) predicate.Guild { + vc := uint64(v) + return predicate.Guild(sql.FieldLTE(FieldLevelUpChannel, vc)) +} + +// LevelUpChannelIsNil applies the IsNil predicate on the "level_up_channel" field. +func LevelUpChannelIsNil() predicate.Guild { + return predicate.Guild(sql.FieldIsNull(FieldLevelUpChannel)) +} + +// LevelUpChannelNotNil applies the NotNil predicate on the "level_up_channel" field. +func LevelUpChannelNotNil() predicate.Guild { + return predicate.Guild(sql.FieldNotNull(FieldLevelUpChannel)) +} + +// LevelUpExcludeChannelIsNil applies the IsNil predicate on the "level_up_exclude_channel" field. +func LevelUpExcludeChannelIsNil() predicate.Guild { + return predicate.Guild(sql.FieldIsNull(FieldLevelUpExcludeChannel)) +} + +// LevelUpExcludeChannelNotNil applies the NotNil predicate on the "level_up_exclude_channel" field. +func LevelUpExcludeChannelNotNil() predicate.Guild { + return predicate.Guild(sql.FieldNotNull(FieldLevelUpExcludeChannel)) +} + +// LevelMee6ImportedEQ applies the EQ predicate on the "level_mee6_imported" field. +func LevelMee6ImportedEQ(v bool) predicate.Guild { + return predicate.Guild(sql.FieldEQ(FieldLevelMee6Imported, v)) +} + +// LevelMee6ImportedNEQ applies the NEQ predicate on the "level_mee6_imported" field. +func LevelMee6ImportedNEQ(v bool) predicate.Guild { + return predicate.Guild(sql.FieldNEQ(FieldLevelMee6Imported, v)) +} + +// LevelRoleIsNil applies the IsNil predicate on the "level_role" field. +func LevelRoleIsNil() predicate.Guild { + return predicate.Guild(sql.FieldIsNull(FieldLevelRole)) +} + +// LevelRoleNotNil applies the NotNil predicate on the "level_role" field. +func LevelRoleNotNil() predicate.Guild { + return predicate.Guild(sql.FieldNotNull(FieldLevelRole)) +} + +// RemindCountEQ applies the EQ predicate on the "remind_count" field. +func RemindCountEQ(v int) predicate.Guild { + return predicate.Guild(sql.FieldEQ(FieldRemindCount, v)) +} + +// RemindCountNEQ applies the NEQ predicate on the "remind_count" field. +func RemindCountNEQ(v int) predicate.Guild { + return predicate.Guild(sql.FieldNEQ(FieldRemindCount, v)) +} + +// RemindCountIn applies the In predicate on the "remind_count" field. +func RemindCountIn(vs ...int) predicate.Guild { + return predicate.Guild(sql.FieldIn(FieldRemindCount, vs...)) +} + +// RemindCountNotIn applies the NotIn predicate on the "remind_count" field. +func RemindCountNotIn(vs ...int) predicate.Guild { + return predicate.Guild(sql.FieldNotIn(FieldRemindCount, vs...)) +} + +// RemindCountGT applies the GT predicate on the "remind_count" field. +func RemindCountGT(v int) predicate.Guild { + return predicate.Guild(sql.FieldGT(FieldRemindCount, v)) +} + +// RemindCountGTE applies the GTE predicate on the "remind_count" field. +func RemindCountGTE(v int) predicate.Guild { + return predicate.Guild(sql.FieldGTE(FieldRemindCount, v)) +} + +// RemindCountLT applies the LT predicate on the "remind_count" field. +func RemindCountLT(v int) predicate.Guild { + return predicate.Guild(sql.FieldLT(FieldRemindCount, v)) +} + +// RemindCountLTE applies the LTE predicate on the "remind_count" field. +func RemindCountLTE(v int) predicate.Guild { + return predicate.Guild(sql.FieldLTE(FieldRemindCount, v)) +} + +// BumpEnabledEQ applies the EQ predicate on the "bump_enabled" field. +func BumpEnabledEQ(v bool) predicate.Guild { + return predicate.Guild(sql.FieldEQ(FieldBumpEnabled, v)) +} + +// BumpEnabledNEQ applies the NEQ predicate on the "bump_enabled" field. +func BumpEnabledNEQ(v bool) predicate.Guild { + return predicate.Guild(sql.FieldNEQ(FieldBumpEnabled, v)) +} + +// BumpMessageTitleEQ applies the EQ predicate on the "bump_message_title" field. +func BumpMessageTitleEQ(v string) predicate.Guild { + return predicate.Guild(sql.FieldEQ(FieldBumpMessageTitle, v)) +} + +// BumpMessageTitleNEQ applies the NEQ predicate on the "bump_message_title" field. +func BumpMessageTitleNEQ(v string) predicate.Guild { + return predicate.Guild(sql.FieldNEQ(FieldBumpMessageTitle, v)) +} + +// BumpMessageTitleIn applies the In predicate on the "bump_message_title" field. +func BumpMessageTitleIn(vs ...string) predicate.Guild { + return predicate.Guild(sql.FieldIn(FieldBumpMessageTitle, vs...)) +} + +// BumpMessageTitleNotIn applies the NotIn predicate on the "bump_message_title" field. +func BumpMessageTitleNotIn(vs ...string) predicate.Guild { + return predicate.Guild(sql.FieldNotIn(FieldBumpMessageTitle, vs...)) +} + +// BumpMessageTitleGT applies the GT predicate on the "bump_message_title" field. +func BumpMessageTitleGT(v string) predicate.Guild { + return predicate.Guild(sql.FieldGT(FieldBumpMessageTitle, v)) +} + +// BumpMessageTitleGTE applies the GTE predicate on the "bump_message_title" field. +func BumpMessageTitleGTE(v string) predicate.Guild { + return predicate.Guild(sql.FieldGTE(FieldBumpMessageTitle, v)) +} + +// BumpMessageTitleLT applies the LT predicate on the "bump_message_title" field. +func BumpMessageTitleLT(v string) predicate.Guild { + return predicate.Guild(sql.FieldLT(FieldBumpMessageTitle, v)) +} + +// BumpMessageTitleLTE applies the LTE predicate on the "bump_message_title" field. +func BumpMessageTitleLTE(v string) predicate.Guild { + return predicate.Guild(sql.FieldLTE(FieldBumpMessageTitle, v)) +} + +// BumpMessageTitleContains applies the Contains predicate on the "bump_message_title" field. +func BumpMessageTitleContains(v string) predicate.Guild { + return predicate.Guild(sql.FieldContains(FieldBumpMessageTitle, v)) +} + +// BumpMessageTitleHasPrefix applies the HasPrefix predicate on the "bump_message_title" field. +func BumpMessageTitleHasPrefix(v string) predicate.Guild { + return predicate.Guild(sql.FieldHasPrefix(FieldBumpMessageTitle, v)) +} + +// BumpMessageTitleHasSuffix applies the HasSuffix predicate on the "bump_message_title" field. +func BumpMessageTitleHasSuffix(v string) predicate.Guild { + return predicate.Guild(sql.FieldHasSuffix(FieldBumpMessageTitle, v)) +} + +// BumpMessageTitleEqualFold applies the EqualFold predicate on the "bump_message_title" field. +func BumpMessageTitleEqualFold(v string) predicate.Guild { + return predicate.Guild(sql.FieldEqualFold(FieldBumpMessageTitle, v)) +} + +// BumpMessageTitleContainsFold applies the ContainsFold predicate on the "bump_message_title" field. +func BumpMessageTitleContainsFold(v string) predicate.Guild { + return predicate.Guild(sql.FieldContainsFold(FieldBumpMessageTitle, v)) +} + +// BumpMessageEQ applies the EQ predicate on the "bump_message" field. +func BumpMessageEQ(v string) predicate.Guild { + return predicate.Guild(sql.FieldEQ(FieldBumpMessage, v)) +} + +// BumpMessageNEQ applies the NEQ predicate on the "bump_message" field. +func BumpMessageNEQ(v string) predicate.Guild { + return predicate.Guild(sql.FieldNEQ(FieldBumpMessage, v)) +} + +// BumpMessageIn applies the In predicate on the "bump_message" field. +func BumpMessageIn(vs ...string) predicate.Guild { + return predicate.Guild(sql.FieldIn(FieldBumpMessage, vs...)) +} + +// BumpMessageNotIn applies the NotIn predicate on the "bump_message" field. +func BumpMessageNotIn(vs ...string) predicate.Guild { + return predicate.Guild(sql.FieldNotIn(FieldBumpMessage, vs...)) +} + +// BumpMessageGT applies the GT predicate on the "bump_message" field. +func BumpMessageGT(v string) predicate.Guild { + return predicate.Guild(sql.FieldGT(FieldBumpMessage, v)) +} + +// BumpMessageGTE applies the GTE predicate on the "bump_message" field. +func BumpMessageGTE(v string) predicate.Guild { + return predicate.Guild(sql.FieldGTE(FieldBumpMessage, v)) +} + +// BumpMessageLT applies the LT predicate on the "bump_message" field. +func BumpMessageLT(v string) predicate.Guild { + return predicate.Guild(sql.FieldLT(FieldBumpMessage, v)) +} + +// BumpMessageLTE applies the LTE predicate on the "bump_message" field. +func BumpMessageLTE(v string) predicate.Guild { + return predicate.Guild(sql.FieldLTE(FieldBumpMessage, v)) +} + +// BumpMessageContains applies the Contains predicate on the "bump_message" field. +func BumpMessageContains(v string) predicate.Guild { + return predicate.Guild(sql.FieldContains(FieldBumpMessage, v)) +} + +// BumpMessageHasPrefix applies the HasPrefix predicate on the "bump_message" field. +func BumpMessageHasPrefix(v string) predicate.Guild { + return predicate.Guild(sql.FieldHasPrefix(FieldBumpMessage, v)) +} + +// BumpMessageHasSuffix applies the HasSuffix predicate on the "bump_message" field. +func BumpMessageHasSuffix(v string) predicate.Guild { + return predicate.Guild(sql.FieldHasSuffix(FieldBumpMessage, v)) +} + +// BumpMessageEqualFold applies the EqualFold predicate on the "bump_message" field. +func BumpMessageEqualFold(v string) predicate.Guild { + return predicate.Guild(sql.FieldEqualFold(FieldBumpMessage, v)) +} + +// BumpMessageContainsFold applies the ContainsFold predicate on the "bump_message" field. +func BumpMessageContainsFold(v string) predicate.Guild { + return predicate.Guild(sql.FieldContainsFold(FieldBumpMessage, v)) +} + +// BumpRemindMessageTitleEQ applies the EQ predicate on the "bump_remind_message_title" field. +func BumpRemindMessageTitleEQ(v string) predicate.Guild { + return predicate.Guild(sql.FieldEQ(FieldBumpRemindMessageTitle, v)) +} + +// BumpRemindMessageTitleNEQ applies the NEQ predicate on the "bump_remind_message_title" field. +func BumpRemindMessageTitleNEQ(v string) predicate.Guild { + return predicate.Guild(sql.FieldNEQ(FieldBumpRemindMessageTitle, v)) +} + +// BumpRemindMessageTitleIn applies the In predicate on the "bump_remind_message_title" field. +func BumpRemindMessageTitleIn(vs ...string) predicate.Guild { + return predicate.Guild(sql.FieldIn(FieldBumpRemindMessageTitle, vs...)) +} + +// BumpRemindMessageTitleNotIn applies the NotIn predicate on the "bump_remind_message_title" field. +func BumpRemindMessageTitleNotIn(vs ...string) predicate.Guild { + return predicate.Guild(sql.FieldNotIn(FieldBumpRemindMessageTitle, vs...)) +} + +// BumpRemindMessageTitleGT applies the GT predicate on the "bump_remind_message_title" field. +func BumpRemindMessageTitleGT(v string) predicate.Guild { + return predicate.Guild(sql.FieldGT(FieldBumpRemindMessageTitle, v)) +} + +// BumpRemindMessageTitleGTE applies the GTE predicate on the "bump_remind_message_title" field. +func BumpRemindMessageTitleGTE(v string) predicate.Guild { + return predicate.Guild(sql.FieldGTE(FieldBumpRemindMessageTitle, v)) +} + +// BumpRemindMessageTitleLT applies the LT predicate on the "bump_remind_message_title" field. +func BumpRemindMessageTitleLT(v string) predicate.Guild { + return predicate.Guild(sql.FieldLT(FieldBumpRemindMessageTitle, v)) +} + +// BumpRemindMessageTitleLTE applies the LTE predicate on the "bump_remind_message_title" field. +func BumpRemindMessageTitleLTE(v string) predicate.Guild { + return predicate.Guild(sql.FieldLTE(FieldBumpRemindMessageTitle, v)) +} + +// BumpRemindMessageTitleContains applies the Contains predicate on the "bump_remind_message_title" field. +func BumpRemindMessageTitleContains(v string) predicate.Guild { + return predicate.Guild(sql.FieldContains(FieldBumpRemindMessageTitle, v)) +} + +// BumpRemindMessageTitleHasPrefix applies the HasPrefix predicate on the "bump_remind_message_title" field. +func BumpRemindMessageTitleHasPrefix(v string) predicate.Guild { + return predicate.Guild(sql.FieldHasPrefix(FieldBumpRemindMessageTitle, v)) +} + +// BumpRemindMessageTitleHasSuffix applies the HasSuffix predicate on the "bump_remind_message_title" field. +func BumpRemindMessageTitleHasSuffix(v string) predicate.Guild { + return predicate.Guild(sql.FieldHasSuffix(FieldBumpRemindMessageTitle, v)) +} + +// BumpRemindMessageTitleEqualFold applies the EqualFold predicate on the "bump_remind_message_title" field. +func BumpRemindMessageTitleEqualFold(v string) predicate.Guild { + return predicate.Guild(sql.FieldEqualFold(FieldBumpRemindMessageTitle, v)) +} + +// BumpRemindMessageTitleContainsFold applies the ContainsFold predicate on the "bump_remind_message_title" field. +func BumpRemindMessageTitleContainsFold(v string) predicate.Guild { + return predicate.Guild(sql.FieldContainsFold(FieldBumpRemindMessageTitle, v)) +} + +// BumpRemindMessageEQ applies the EQ predicate on the "bump_remind_message" field. +func BumpRemindMessageEQ(v string) predicate.Guild { + return predicate.Guild(sql.FieldEQ(FieldBumpRemindMessage, v)) +} + +// BumpRemindMessageNEQ applies the NEQ predicate on the "bump_remind_message" field. +func BumpRemindMessageNEQ(v string) predicate.Guild { + return predicate.Guild(sql.FieldNEQ(FieldBumpRemindMessage, v)) +} + +// BumpRemindMessageIn applies the In predicate on the "bump_remind_message" field. +func BumpRemindMessageIn(vs ...string) predicate.Guild { + return predicate.Guild(sql.FieldIn(FieldBumpRemindMessage, vs...)) +} + +// BumpRemindMessageNotIn applies the NotIn predicate on the "bump_remind_message" field. +func BumpRemindMessageNotIn(vs ...string) predicate.Guild { + return predicate.Guild(sql.FieldNotIn(FieldBumpRemindMessage, vs...)) +} + +// BumpRemindMessageGT applies the GT predicate on the "bump_remind_message" field. +func BumpRemindMessageGT(v string) predicate.Guild { + return predicate.Guild(sql.FieldGT(FieldBumpRemindMessage, v)) +} + +// BumpRemindMessageGTE applies the GTE predicate on the "bump_remind_message" field. +func BumpRemindMessageGTE(v string) predicate.Guild { + return predicate.Guild(sql.FieldGTE(FieldBumpRemindMessage, v)) +} + +// BumpRemindMessageLT applies the LT predicate on the "bump_remind_message" field. +func BumpRemindMessageLT(v string) predicate.Guild { + return predicate.Guild(sql.FieldLT(FieldBumpRemindMessage, v)) +} + +// BumpRemindMessageLTE applies the LTE predicate on the "bump_remind_message" field. +func BumpRemindMessageLTE(v string) predicate.Guild { + return predicate.Guild(sql.FieldLTE(FieldBumpRemindMessage, v)) +} + +// BumpRemindMessageContains applies the Contains predicate on the "bump_remind_message" field. +func BumpRemindMessageContains(v string) predicate.Guild { + return predicate.Guild(sql.FieldContains(FieldBumpRemindMessage, v)) +} + +// BumpRemindMessageHasPrefix applies the HasPrefix predicate on the "bump_remind_message" field. +func BumpRemindMessageHasPrefix(v string) predicate.Guild { + return predicate.Guild(sql.FieldHasPrefix(FieldBumpRemindMessage, v)) +} + +// BumpRemindMessageHasSuffix applies the HasSuffix predicate on the "bump_remind_message" field. +func BumpRemindMessageHasSuffix(v string) predicate.Guild { + return predicate.Guild(sql.FieldHasSuffix(FieldBumpRemindMessage, v)) +} + +// BumpRemindMessageEqualFold applies the EqualFold predicate on the "bump_remind_message" field. +func BumpRemindMessageEqualFold(v string) predicate.Guild { + return predicate.Guild(sql.FieldEqualFold(FieldBumpRemindMessage, v)) +} + +// BumpRemindMessageContainsFold applies the ContainsFold predicate on the "bump_remind_message" field. +func BumpRemindMessageContainsFold(v string) predicate.Guild { + return predicate.Guild(sql.FieldContainsFold(FieldBumpRemindMessage, v)) +} + +// UpEnabledEQ applies the EQ predicate on the "up_enabled" field. +func UpEnabledEQ(v bool) predicate.Guild { + return predicate.Guild(sql.FieldEQ(FieldUpEnabled, v)) +} + +// UpEnabledNEQ applies the NEQ predicate on the "up_enabled" field. +func UpEnabledNEQ(v bool) predicate.Guild { + return predicate.Guild(sql.FieldNEQ(FieldUpEnabled, v)) +} + +// UpMessageTitleEQ applies the EQ predicate on the "up_message_title" field. +func UpMessageTitleEQ(v string) predicate.Guild { + return predicate.Guild(sql.FieldEQ(FieldUpMessageTitle, v)) +} + +// UpMessageTitleNEQ applies the NEQ predicate on the "up_message_title" field. +func UpMessageTitleNEQ(v string) predicate.Guild { + return predicate.Guild(sql.FieldNEQ(FieldUpMessageTitle, v)) +} + +// UpMessageTitleIn applies the In predicate on the "up_message_title" field. +func UpMessageTitleIn(vs ...string) predicate.Guild { + return predicate.Guild(sql.FieldIn(FieldUpMessageTitle, vs...)) +} + +// UpMessageTitleNotIn applies the NotIn predicate on the "up_message_title" field. +func UpMessageTitleNotIn(vs ...string) predicate.Guild { + return predicate.Guild(sql.FieldNotIn(FieldUpMessageTitle, vs...)) +} + +// UpMessageTitleGT applies the GT predicate on the "up_message_title" field. +func UpMessageTitleGT(v string) predicate.Guild { + return predicate.Guild(sql.FieldGT(FieldUpMessageTitle, v)) +} + +// UpMessageTitleGTE applies the GTE predicate on the "up_message_title" field. +func UpMessageTitleGTE(v string) predicate.Guild { + return predicate.Guild(sql.FieldGTE(FieldUpMessageTitle, v)) +} + +// UpMessageTitleLT applies the LT predicate on the "up_message_title" field. +func UpMessageTitleLT(v string) predicate.Guild { + return predicate.Guild(sql.FieldLT(FieldUpMessageTitle, v)) +} + +// UpMessageTitleLTE applies the LTE predicate on the "up_message_title" field. +func UpMessageTitleLTE(v string) predicate.Guild { + return predicate.Guild(sql.FieldLTE(FieldUpMessageTitle, v)) +} + +// UpMessageTitleContains applies the Contains predicate on the "up_message_title" field. +func UpMessageTitleContains(v string) predicate.Guild { + return predicate.Guild(sql.FieldContains(FieldUpMessageTitle, v)) +} + +// UpMessageTitleHasPrefix applies the HasPrefix predicate on the "up_message_title" field. +func UpMessageTitleHasPrefix(v string) predicate.Guild { + return predicate.Guild(sql.FieldHasPrefix(FieldUpMessageTitle, v)) +} + +// UpMessageTitleHasSuffix applies the HasSuffix predicate on the "up_message_title" field. +func UpMessageTitleHasSuffix(v string) predicate.Guild { + return predicate.Guild(sql.FieldHasSuffix(FieldUpMessageTitle, v)) +} + +// UpMessageTitleEqualFold applies the EqualFold predicate on the "up_message_title" field. +func UpMessageTitleEqualFold(v string) predicate.Guild { + return predicate.Guild(sql.FieldEqualFold(FieldUpMessageTitle, v)) +} + +// UpMessageTitleContainsFold applies the ContainsFold predicate on the "up_message_title" field. +func UpMessageTitleContainsFold(v string) predicate.Guild { + return predicate.Guild(sql.FieldContainsFold(FieldUpMessageTitle, v)) +} + +// UpMessageEQ applies the EQ predicate on the "up_message" field. +func UpMessageEQ(v string) predicate.Guild { + return predicate.Guild(sql.FieldEQ(FieldUpMessage, v)) +} + +// UpMessageNEQ applies the NEQ predicate on the "up_message" field. +func UpMessageNEQ(v string) predicate.Guild { + return predicate.Guild(sql.FieldNEQ(FieldUpMessage, v)) +} + +// UpMessageIn applies the In predicate on the "up_message" field. +func UpMessageIn(vs ...string) predicate.Guild { + return predicate.Guild(sql.FieldIn(FieldUpMessage, vs...)) +} + +// UpMessageNotIn applies the NotIn predicate on the "up_message" field. +func UpMessageNotIn(vs ...string) predicate.Guild { + return predicate.Guild(sql.FieldNotIn(FieldUpMessage, vs...)) +} + +// UpMessageGT applies the GT predicate on the "up_message" field. +func UpMessageGT(v string) predicate.Guild { + return predicate.Guild(sql.FieldGT(FieldUpMessage, v)) +} + +// UpMessageGTE applies the GTE predicate on the "up_message" field. +func UpMessageGTE(v string) predicate.Guild { + return predicate.Guild(sql.FieldGTE(FieldUpMessage, v)) +} + +// UpMessageLT applies the LT predicate on the "up_message" field. +func UpMessageLT(v string) predicate.Guild { + return predicate.Guild(sql.FieldLT(FieldUpMessage, v)) +} + +// UpMessageLTE applies the LTE predicate on the "up_message" field. +func UpMessageLTE(v string) predicate.Guild { + return predicate.Guild(sql.FieldLTE(FieldUpMessage, v)) +} + +// UpMessageContains applies the Contains predicate on the "up_message" field. +func UpMessageContains(v string) predicate.Guild { + return predicate.Guild(sql.FieldContains(FieldUpMessage, v)) +} + +// UpMessageHasPrefix applies the HasPrefix predicate on the "up_message" field. +func UpMessageHasPrefix(v string) predicate.Guild { + return predicate.Guild(sql.FieldHasPrefix(FieldUpMessage, v)) +} + +// UpMessageHasSuffix applies the HasSuffix predicate on the "up_message" field. +func UpMessageHasSuffix(v string) predicate.Guild { + return predicate.Guild(sql.FieldHasSuffix(FieldUpMessage, v)) +} + +// UpMessageEqualFold applies the EqualFold predicate on the "up_message" field. +func UpMessageEqualFold(v string) predicate.Guild { + return predicate.Guild(sql.FieldEqualFold(FieldUpMessage, v)) +} + +// UpMessageContainsFold applies the ContainsFold predicate on the "up_message" field. +func UpMessageContainsFold(v string) predicate.Guild { + return predicate.Guild(sql.FieldContainsFold(FieldUpMessage, v)) +} + +// UpRemindMessageTitleEQ applies the EQ predicate on the "up_remind_message_title" field. +func UpRemindMessageTitleEQ(v string) predicate.Guild { + return predicate.Guild(sql.FieldEQ(FieldUpRemindMessageTitle, v)) +} + +// UpRemindMessageTitleNEQ applies the NEQ predicate on the "up_remind_message_title" field. +func UpRemindMessageTitleNEQ(v string) predicate.Guild { + return predicate.Guild(sql.FieldNEQ(FieldUpRemindMessageTitle, v)) +} + +// UpRemindMessageTitleIn applies the In predicate on the "up_remind_message_title" field. +func UpRemindMessageTitleIn(vs ...string) predicate.Guild { + return predicate.Guild(sql.FieldIn(FieldUpRemindMessageTitle, vs...)) +} + +// UpRemindMessageTitleNotIn applies the NotIn predicate on the "up_remind_message_title" field. +func UpRemindMessageTitleNotIn(vs ...string) predicate.Guild { + return predicate.Guild(sql.FieldNotIn(FieldUpRemindMessageTitle, vs...)) +} + +// UpRemindMessageTitleGT applies the GT predicate on the "up_remind_message_title" field. +func UpRemindMessageTitleGT(v string) predicate.Guild { + return predicate.Guild(sql.FieldGT(FieldUpRemindMessageTitle, v)) +} + +// UpRemindMessageTitleGTE applies the GTE predicate on the "up_remind_message_title" field. +func UpRemindMessageTitleGTE(v string) predicate.Guild { + return predicate.Guild(sql.FieldGTE(FieldUpRemindMessageTitle, v)) +} + +// UpRemindMessageTitleLT applies the LT predicate on the "up_remind_message_title" field. +func UpRemindMessageTitleLT(v string) predicate.Guild { + return predicate.Guild(sql.FieldLT(FieldUpRemindMessageTitle, v)) +} + +// UpRemindMessageTitleLTE applies the LTE predicate on the "up_remind_message_title" field. +func UpRemindMessageTitleLTE(v string) predicate.Guild { + return predicate.Guild(sql.FieldLTE(FieldUpRemindMessageTitle, v)) +} + +// UpRemindMessageTitleContains applies the Contains predicate on the "up_remind_message_title" field. +func UpRemindMessageTitleContains(v string) predicate.Guild { + return predicate.Guild(sql.FieldContains(FieldUpRemindMessageTitle, v)) +} + +// UpRemindMessageTitleHasPrefix applies the HasPrefix predicate on the "up_remind_message_title" field. +func UpRemindMessageTitleHasPrefix(v string) predicate.Guild { + return predicate.Guild(sql.FieldHasPrefix(FieldUpRemindMessageTitle, v)) +} + +// UpRemindMessageTitleHasSuffix applies the HasSuffix predicate on the "up_remind_message_title" field. +func UpRemindMessageTitleHasSuffix(v string) predicate.Guild { + return predicate.Guild(sql.FieldHasSuffix(FieldUpRemindMessageTitle, v)) +} + +// UpRemindMessageTitleEqualFold applies the EqualFold predicate on the "up_remind_message_title" field. +func UpRemindMessageTitleEqualFold(v string) predicate.Guild { + return predicate.Guild(sql.FieldEqualFold(FieldUpRemindMessageTitle, v)) +} + +// UpRemindMessageTitleContainsFold applies the ContainsFold predicate on the "up_remind_message_title" field. +func UpRemindMessageTitleContainsFold(v string) predicate.Guild { + return predicate.Guild(sql.FieldContainsFold(FieldUpRemindMessageTitle, v)) +} + +// UpRemindMessageEQ applies the EQ predicate on the "up_remind_message" field. +func UpRemindMessageEQ(v string) predicate.Guild { + return predicate.Guild(sql.FieldEQ(FieldUpRemindMessage, v)) +} + +// UpRemindMessageNEQ applies the NEQ predicate on the "up_remind_message" field. +func UpRemindMessageNEQ(v string) predicate.Guild { + return predicate.Guild(sql.FieldNEQ(FieldUpRemindMessage, v)) +} + +// UpRemindMessageIn applies the In predicate on the "up_remind_message" field. +func UpRemindMessageIn(vs ...string) predicate.Guild { + return predicate.Guild(sql.FieldIn(FieldUpRemindMessage, vs...)) +} + +// UpRemindMessageNotIn applies the NotIn predicate on the "up_remind_message" field. +func UpRemindMessageNotIn(vs ...string) predicate.Guild { + return predicate.Guild(sql.FieldNotIn(FieldUpRemindMessage, vs...)) +} + +// UpRemindMessageGT applies the GT predicate on the "up_remind_message" field. +func UpRemindMessageGT(v string) predicate.Guild { + return predicate.Guild(sql.FieldGT(FieldUpRemindMessage, v)) +} + +// UpRemindMessageGTE applies the GTE predicate on the "up_remind_message" field. +func UpRemindMessageGTE(v string) predicate.Guild { + return predicate.Guild(sql.FieldGTE(FieldUpRemindMessage, v)) +} + +// UpRemindMessageLT applies the LT predicate on the "up_remind_message" field. +func UpRemindMessageLT(v string) predicate.Guild { + return predicate.Guild(sql.FieldLT(FieldUpRemindMessage, v)) +} + +// UpRemindMessageLTE applies the LTE predicate on the "up_remind_message" field. +func UpRemindMessageLTE(v string) predicate.Guild { + return predicate.Guild(sql.FieldLTE(FieldUpRemindMessage, v)) +} + +// UpRemindMessageContains applies the Contains predicate on the "up_remind_message" field. +func UpRemindMessageContains(v string) predicate.Guild { + return predicate.Guild(sql.FieldContains(FieldUpRemindMessage, v)) +} + +// UpRemindMessageHasPrefix applies the HasPrefix predicate on the "up_remind_message" field. +func UpRemindMessageHasPrefix(v string) predicate.Guild { + return predicate.Guild(sql.FieldHasPrefix(FieldUpRemindMessage, v)) +} + +// UpRemindMessageHasSuffix applies the HasSuffix predicate on the "up_remind_message" field. +func UpRemindMessageHasSuffix(v string) predicate.Guild { + return predicate.Guild(sql.FieldHasSuffix(FieldUpRemindMessage, v)) +} + +// UpRemindMessageEqualFold applies the EqualFold predicate on the "up_remind_message" field. +func UpRemindMessageEqualFold(v string) predicate.Guild { + return predicate.Guild(sql.FieldEqualFold(FieldUpRemindMessage, v)) +} + +// UpRemindMessageContainsFold applies the ContainsFold predicate on the "up_remind_message" field. +func UpRemindMessageContainsFold(v string) predicate.Guild { + return predicate.Guild(sql.FieldContainsFold(FieldUpRemindMessage, v)) +} + +// BumpMentionEQ applies the EQ predicate on the "bump_mention" field. +func BumpMentionEQ(v snowflake.ID) predicate.Guild { + vc := uint64(v) + return predicate.Guild(sql.FieldEQ(FieldBumpMention, vc)) +} + +// BumpMentionNEQ applies the NEQ predicate on the "bump_mention" field. +func BumpMentionNEQ(v snowflake.ID) predicate.Guild { + vc := uint64(v) + return predicate.Guild(sql.FieldNEQ(FieldBumpMention, vc)) +} + +// BumpMentionIn applies the In predicate on the "bump_mention" field. +func BumpMentionIn(vs ...snowflake.ID) predicate.Guild { + v := make([]any, len(vs)) + for i := range v { + v[i] = uint64(vs[i]) + } + return predicate.Guild(sql.FieldIn(FieldBumpMention, v...)) +} + +// BumpMentionNotIn applies the NotIn predicate on the "bump_mention" field. +func BumpMentionNotIn(vs ...snowflake.ID) predicate.Guild { + v := make([]any, len(vs)) + for i := range v { + v[i] = uint64(vs[i]) + } + return predicate.Guild(sql.FieldNotIn(FieldBumpMention, v...)) +} + +// BumpMentionGT applies the GT predicate on the "bump_mention" field. +func BumpMentionGT(v snowflake.ID) predicate.Guild { + vc := uint64(v) + return predicate.Guild(sql.FieldGT(FieldBumpMention, vc)) +} + +// BumpMentionGTE applies the GTE predicate on the "bump_mention" field. +func BumpMentionGTE(v snowflake.ID) predicate.Guild { + vc := uint64(v) + return predicate.Guild(sql.FieldGTE(FieldBumpMention, vc)) +} + +// BumpMentionLT applies the LT predicate on the "bump_mention" field. +func BumpMentionLT(v snowflake.ID) predicate.Guild { + vc := uint64(v) + return predicate.Guild(sql.FieldLT(FieldBumpMention, vc)) +} + +// BumpMentionLTE applies the LTE predicate on the "bump_mention" field. +func BumpMentionLTE(v snowflake.ID) predicate.Guild { + vc := uint64(v) + return predicate.Guild(sql.FieldLTE(FieldBumpMention, vc)) +} + +// BumpMentionIsNil applies the IsNil predicate on the "bump_mention" field. +func BumpMentionIsNil() predicate.Guild { + return predicate.Guild(sql.FieldIsNull(FieldBumpMention)) +} + +// BumpMentionNotNil applies the NotNil predicate on the "bump_mention" field. +func BumpMentionNotNil() predicate.Guild { + return predicate.Guild(sql.FieldNotNull(FieldBumpMention)) +} + +// UpMentionEQ applies the EQ predicate on the "up_mention" field. +func UpMentionEQ(v snowflake.ID) predicate.Guild { + vc := uint64(v) + return predicate.Guild(sql.FieldEQ(FieldUpMention, vc)) +} + +// UpMentionNEQ applies the NEQ predicate on the "up_mention" field. +func UpMentionNEQ(v snowflake.ID) predicate.Guild { + vc := uint64(v) + return predicate.Guild(sql.FieldNEQ(FieldUpMention, vc)) +} + +// UpMentionIn applies the In predicate on the "up_mention" field. +func UpMentionIn(vs ...snowflake.ID) predicate.Guild { + v := make([]any, len(vs)) + for i := range v { + v[i] = uint64(vs[i]) + } + return predicate.Guild(sql.FieldIn(FieldUpMention, v...)) +} + +// UpMentionNotIn applies the NotIn predicate on the "up_mention" field. +func UpMentionNotIn(vs ...snowflake.ID) predicate.Guild { + v := make([]any, len(vs)) + for i := range v { + v[i] = uint64(vs[i]) + } + return predicate.Guild(sql.FieldNotIn(FieldUpMention, v...)) +} + +// UpMentionGT applies the GT predicate on the "up_mention" field. +func UpMentionGT(v snowflake.ID) predicate.Guild { + vc := uint64(v) + return predicate.Guild(sql.FieldGT(FieldUpMention, vc)) +} + +// UpMentionGTE applies the GTE predicate on the "up_mention" field. +func UpMentionGTE(v snowflake.ID) predicate.Guild { + vc := uint64(v) + return predicate.Guild(sql.FieldGTE(FieldUpMention, vc)) +} + +// UpMentionLT applies the LT predicate on the "up_mention" field. +func UpMentionLT(v snowflake.ID) predicate.Guild { + vc := uint64(v) + return predicate.Guild(sql.FieldLT(FieldUpMention, vc)) +} + +// UpMentionLTE applies the LTE predicate on the "up_mention" field. +func UpMentionLTE(v snowflake.ID) predicate.Guild { + vc := uint64(v) + return predicate.Guild(sql.FieldLTE(FieldUpMention, vc)) +} + +// UpMentionIsNil applies the IsNil predicate on the "up_mention" field. +func UpMentionIsNil() predicate.Guild { + return predicate.Guild(sql.FieldIsNull(FieldUpMention)) +} + +// UpMentionNotNil applies the NotNil predicate on the "up_mention" field. +func UpMentionNotNil() predicate.Guild { + return predicate.Guild(sql.FieldNotNull(FieldUpMention)) +} + +// HasOwner applies the HasEdge predicate on the "owner" edge. +func HasOwner() predicate.Guild { + return predicate.Guild(func(s *sql.Selector) { + step := sqlgraph.NewStep( + sqlgraph.From(Table, FieldID), + sqlgraph.Edge(sqlgraph.M2O, true, OwnerTable, OwnerColumn), + ) + sqlgraph.HasNeighbors(s, step) + }) +} + +// HasOwnerWith applies the HasEdge predicate on the "owner" edge with a given conditions (other predicates). +func HasOwnerWith(preds ...predicate.User) predicate.Guild { + return predicate.Guild(func(s *sql.Selector) { + step := newOwnerStep() + sqlgraph.HasNeighborsWith(s, step, func(s *sql.Selector) { + for _, p := range preds { + p(s) + } + }) + }) +} + +// HasMembers applies the HasEdge predicate on the "members" edge. +func HasMembers() predicate.Guild { + return predicate.Guild(func(s *sql.Selector) { + step := sqlgraph.NewStep( + sqlgraph.From(Table, FieldID), + sqlgraph.Edge(sqlgraph.O2M, false, MembersTable, MembersColumn), + ) + sqlgraph.HasNeighbors(s, step) + }) +} + +// HasMembersWith applies the HasEdge predicate on the "members" edge with a given conditions (other predicates). +func HasMembersWith(preds ...predicate.Member) predicate.Guild { + return predicate.Guild(func(s *sql.Selector) { + step := newMembersStep() + sqlgraph.HasNeighborsWith(s, step, func(s *sql.Selector) { + for _, p := range preds { + p(s) + } + }) + }) +} + +// HasMessagePins applies the HasEdge predicate on the "message_pins" edge. +func HasMessagePins() predicate.Guild { + return predicate.Guild(func(s *sql.Selector) { + step := sqlgraph.NewStep( + sqlgraph.From(Table, FieldID), + sqlgraph.Edge(sqlgraph.O2M, false, MessagePinsTable, MessagePinsColumn), + ) + sqlgraph.HasNeighbors(s, step) + }) +} + +// HasMessagePinsWith applies the HasEdge predicate on the "message_pins" edge with a given conditions (other predicates). +func HasMessagePinsWith(preds ...predicate.MessagePin) predicate.Guild { + return predicate.Guild(func(s *sql.Selector) { + step := newMessagePinsStep() + sqlgraph.HasNeighborsWith(s, step, func(s *sql.Selector) { + for _, p := range preds { + p(s) + } + }) + }) +} + +// HasReminds applies the HasEdge predicate on the "reminds" edge. +func HasReminds() predicate.Guild { + return predicate.Guild(func(s *sql.Selector) { + step := sqlgraph.NewStep( + sqlgraph.From(Table, FieldID), + sqlgraph.Edge(sqlgraph.O2M, false, RemindsTable, RemindsColumn), + ) + sqlgraph.HasNeighbors(s, step) + }) +} + +// HasRemindsWith applies the HasEdge predicate on the "reminds" edge with a given conditions (other predicates). +func HasRemindsWith(preds ...predicate.MessageRemind) predicate.Guild { + return predicate.Guild(func(s *sql.Selector) { + step := newRemindsStep() + sqlgraph.HasNeighborsWith(s, step, func(s *sql.Selector) { + for _, p := range preds { + p(s) + } + }) + }) +} + +// HasRolePanels applies the HasEdge predicate on the "role_panels" edge. +func HasRolePanels() predicate.Guild { + return predicate.Guild(func(s *sql.Selector) { + step := sqlgraph.NewStep( + sqlgraph.From(Table, FieldID), + sqlgraph.Edge(sqlgraph.O2M, false, RolePanelsTable, RolePanelsColumn), + ) + sqlgraph.HasNeighbors(s, step) + }) +} + +// HasRolePanelsWith applies the HasEdge predicate on the "role_panels" edge with a given conditions (other predicates). +func HasRolePanelsWith(preds ...predicate.RolePanel) predicate.Guild { + return predicate.Guild(func(s *sql.Selector) { + step := newRolePanelsStep() + sqlgraph.HasNeighborsWith(s, step, func(s *sql.Selector) { + for _, p := range preds { + p(s) + } + }) + }) +} + +// HasRolePanelPlacements applies the HasEdge predicate on the "role_panel_placements" edge. +func HasRolePanelPlacements() predicate.Guild { + return predicate.Guild(func(s *sql.Selector) { + step := sqlgraph.NewStep( + sqlgraph.From(Table, FieldID), + sqlgraph.Edge(sqlgraph.O2M, false, RolePanelPlacementsTable, RolePanelPlacementsColumn), + ) + sqlgraph.HasNeighbors(s, step) + }) +} + +// HasRolePanelPlacementsWith applies the HasEdge predicate on the "role_panel_placements" edge with a given conditions (other predicates). +func HasRolePanelPlacementsWith(preds ...predicate.RolePanelPlaced) predicate.Guild { + return predicate.Guild(func(s *sql.Selector) { + step := newRolePanelPlacementsStep() + sqlgraph.HasNeighborsWith(s, step, func(s *sql.Selector) { + for _, p := range preds { + p(s) + } + }) + }) +} + +// HasRolePanelEdits applies the HasEdge predicate on the "role_panel_edits" edge. +func HasRolePanelEdits() predicate.Guild { + return predicate.Guild(func(s *sql.Selector) { + step := sqlgraph.NewStep( + sqlgraph.From(Table, FieldID), + sqlgraph.Edge(sqlgraph.O2M, false, RolePanelEditsTable, RolePanelEditsColumn), + ) + sqlgraph.HasNeighbors(s, step) + }) +} + +// HasRolePanelEditsWith applies the HasEdge predicate on the "role_panel_edits" edge with a given conditions (other predicates). +func HasRolePanelEditsWith(preds ...predicate.RolePanelEdit) predicate.Guild { + return predicate.Guild(func(s *sql.Selector) { + step := newRolePanelEditsStep() + sqlgraph.HasNeighborsWith(s, step, func(s *sql.Selector) { + for _, p := range preds { + p(s) + } + }) + }) +} + +// And groups predicates with the AND operator between them. +func And(predicates ...predicate.Guild) predicate.Guild { + return predicate.Guild(sql.AndPredicates(predicates...)) +} + +// Or groups predicates with the OR operator between them. +func Or(predicates ...predicate.Guild) predicate.Guild { + return predicate.Guild(sql.OrPredicates(predicates...)) +} + +// Not applies the not operator on the given predicate. +func Not(p predicate.Guild) predicate.Guild { + return predicate.Guild(sql.NotPredicates(p)) +} diff --git a/ent/guild_create.go b/ent/guild_create.go new file mode 100644 index 00000000..0639d7b0 --- /dev/null +++ b/ent/guild_create.go @@ -0,0 +1,947 @@ +// Code generated by ent, DO NOT EDIT. + +package ent + +import ( + "context" + "errors" + "fmt" + "time" + + "entgo.io/ent/dialect/sql/sqlgraph" + "entgo.io/ent/schema/field" + "github.com/disgoorg/disgo/discord" + snowflake "github.com/disgoorg/snowflake/v2" + "github.com/google/uuid" + "github.com/sabafly/gobot/ent/guild" + "github.com/sabafly/gobot/ent/member" + "github.com/sabafly/gobot/ent/messagepin" + "github.com/sabafly/gobot/ent/messageremind" + "github.com/sabafly/gobot/ent/rolepanel" + "github.com/sabafly/gobot/ent/rolepaneledit" + "github.com/sabafly/gobot/ent/rolepanelplaced" + "github.com/sabafly/gobot/ent/user" + "github.com/sabafly/gobot/internal/permissions" +) + +// GuildCreate is the builder for creating a Guild entity. +type GuildCreate struct { + config + mutation *GuildMutation + hooks []Hook +} + +// SetName sets the "name" field. +func (gc *GuildCreate) SetName(s string) *GuildCreate { + gc.mutation.SetName(s) + return gc +} + +// SetLocale sets the "locale" field. +func (gc *GuildCreate) SetLocale(d discord.Locale) *GuildCreate { + gc.mutation.SetLocale(d) + return gc +} + +// SetNillableLocale sets the "locale" field if the given value is not nil. +func (gc *GuildCreate) SetNillableLocale(d *discord.Locale) *GuildCreate { + if d != nil { + gc.SetLocale(*d) + } + return gc +} + +// SetLevelUpMessage sets the "level_up_message" field. +func (gc *GuildCreate) SetLevelUpMessage(s string) *GuildCreate { + gc.mutation.SetLevelUpMessage(s) + return gc +} + +// SetNillableLevelUpMessage sets the "level_up_message" field if the given value is not nil. +func (gc *GuildCreate) SetNillableLevelUpMessage(s *string) *GuildCreate { + if s != nil { + gc.SetLevelUpMessage(*s) + } + return gc +} + +// SetLevelUpChannel sets the "level_up_channel" field. +func (gc *GuildCreate) SetLevelUpChannel(s snowflake.ID) *GuildCreate { + gc.mutation.SetLevelUpChannel(s) + return gc +} + +// SetNillableLevelUpChannel sets the "level_up_channel" field if the given value is not nil. +func (gc *GuildCreate) SetNillableLevelUpChannel(s *snowflake.ID) *GuildCreate { + if s != nil { + gc.SetLevelUpChannel(*s) + } + return gc +} + +// SetLevelUpExcludeChannel sets the "level_up_exclude_channel" field. +func (gc *GuildCreate) SetLevelUpExcludeChannel(s []snowflake.ID) *GuildCreate { + gc.mutation.SetLevelUpExcludeChannel(s) + return gc +} + +// SetLevelMee6Imported sets the "level_mee6_imported" field. +func (gc *GuildCreate) SetLevelMee6Imported(b bool) *GuildCreate { + gc.mutation.SetLevelMee6Imported(b) + return gc +} + +// SetNillableLevelMee6Imported sets the "level_mee6_imported" field if the given value is not nil. +func (gc *GuildCreate) SetNillableLevelMee6Imported(b *bool) *GuildCreate { + if b != nil { + gc.SetLevelMee6Imported(*b) + } + return gc +} + +// SetLevelRole sets the "level_role" field. +func (gc *GuildCreate) SetLevelRole(m map[int]snowflake.ID) *GuildCreate { + gc.mutation.SetLevelRole(m) + return gc +} + +// SetPermissions sets the "permissions" field. +func (gc *GuildCreate) SetPermissions(m map[snowflake.ID]permissions.Permission) *GuildCreate { + gc.mutation.SetPermissions(m) + return gc +} + +// SetRemindCount sets the "remind_count" field. +func (gc *GuildCreate) SetRemindCount(i int) *GuildCreate { + gc.mutation.SetRemindCount(i) + return gc +} + +// SetNillableRemindCount sets the "remind_count" field if the given value is not nil. +func (gc *GuildCreate) SetNillableRemindCount(i *int) *GuildCreate { + if i != nil { + gc.SetRemindCount(*i) + } + return gc +} + +// SetRolePanelEditTimes sets the "role_panel_edit_times" field. +func (gc *GuildCreate) SetRolePanelEditTimes(t []time.Time) *GuildCreate { + gc.mutation.SetRolePanelEditTimes(t) + return gc +} + +// SetBumpEnabled sets the "bump_enabled" field. +func (gc *GuildCreate) SetBumpEnabled(b bool) *GuildCreate { + gc.mutation.SetBumpEnabled(b) + return gc +} + +// SetNillableBumpEnabled sets the "bump_enabled" field if the given value is not nil. +func (gc *GuildCreate) SetNillableBumpEnabled(b *bool) *GuildCreate { + if b != nil { + gc.SetBumpEnabled(*b) + } + return gc +} + +// SetBumpMessageTitle sets the "bump_message_title" field. +func (gc *GuildCreate) SetBumpMessageTitle(s string) *GuildCreate { + gc.mutation.SetBumpMessageTitle(s) + return gc +} + +// SetNillableBumpMessageTitle sets the "bump_message_title" field if the given value is not nil. +func (gc *GuildCreate) SetNillableBumpMessageTitle(s *string) *GuildCreate { + if s != nil { + gc.SetBumpMessageTitle(*s) + } + return gc +} + +// SetBumpMessage sets the "bump_message" field. +func (gc *GuildCreate) SetBumpMessage(s string) *GuildCreate { + gc.mutation.SetBumpMessage(s) + return gc +} + +// SetNillableBumpMessage sets the "bump_message" field if the given value is not nil. +func (gc *GuildCreate) SetNillableBumpMessage(s *string) *GuildCreate { + if s != nil { + gc.SetBumpMessage(*s) + } + return gc +} + +// SetBumpRemindMessageTitle sets the "bump_remind_message_title" field. +func (gc *GuildCreate) SetBumpRemindMessageTitle(s string) *GuildCreate { + gc.mutation.SetBumpRemindMessageTitle(s) + return gc +} + +// SetNillableBumpRemindMessageTitle sets the "bump_remind_message_title" field if the given value is not nil. +func (gc *GuildCreate) SetNillableBumpRemindMessageTitle(s *string) *GuildCreate { + if s != nil { + gc.SetBumpRemindMessageTitle(*s) + } + return gc +} + +// SetBumpRemindMessage sets the "bump_remind_message" field. +func (gc *GuildCreate) SetBumpRemindMessage(s string) *GuildCreate { + gc.mutation.SetBumpRemindMessage(s) + return gc +} + +// SetNillableBumpRemindMessage sets the "bump_remind_message" field if the given value is not nil. +func (gc *GuildCreate) SetNillableBumpRemindMessage(s *string) *GuildCreate { + if s != nil { + gc.SetBumpRemindMessage(*s) + } + return gc +} + +// SetUpEnabled sets the "up_enabled" field. +func (gc *GuildCreate) SetUpEnabled(b bool) *GuildCreate { + gc.mutation.SetUpEnabled(b) + return gc +} + +// SetNillableUpEnabled sets the "up_enabled" field if the given value is not nil. +func (gc *GuildCreate) SetNillableUpEnabled(b *bool) *GuildCreate { + if b != nil { + gc.SetUpEnabled(*b) + } + return gc +} + +// SetUpMessageTitle sets the "up_message_title" field. +func (gc *GuildCreate) SetUpMessageTitle(s string) *GuildCreate { + gc.mutation.SetUpMessageTitle(s) + return gc +} + +// SetNillableUpMessageTitle sets the "up_message_title" field if the given value is not nil. +func (gc *GuildCreate) SetNillableUpMessageTitle(s *string) *GuildCreate { + if s != nil { + gc.SetUpMessageTitle(*s) + } + return gc +} + +// SetUpMessage sets the "up_message" field. +func (gc *GuildCreate) SetUpMessage(s string) *GuildCreate { + gc.mutation.SetUpMessage(s) + return gc +} + +// SetNillableUpMessage sets the "up_message" field if the given value is not nil. +func (gc *GuildCreate) SetNillableUpMessage(s *string) *GuildCreate { + if s != nil { + gc.SetUpMessage(*s) + } + return gc +} + +// SetUpRemindMessageTitle sets the "up_remind_message_title" field. +func (gc *GuildCreate) SetUpRemindMessageTitle(s string) *GuildCreate { + gc.mutation.SetUpRemindMessageTitle(s) + return gc +} + +// SetNillableUpRemindMessageTitle sets the "up_remind_message_title" field if the given value is not nil. +func (gc *GuildCreate) SetNillableUpRemindMessageTitle(s *string) *GuildCreate { + if s != nil { + gc.SetUpRemindMessageTitle(*s) + } + return gc +} + +// SetUpRemindMessage sets the "up_remind_message" field. +func (gc *GuildCreate) SetUpRemindMessage(s string) *GuildCreate { + gc.mutation.SetUpRemindMessage(s) + return gc +} + +// SetNillableUpRemindMessage sets the "up_remind_message" field if the given value is not nil. +func (gc *GuildCreate) SetNillableUpRemindMessage(s *string) *GuildCreate { + if s != nil { + gc.SetUpRemindMessage(*s) + } + return gc +} + +// SetBumpMention sets the "bump_mention" field. +func (gc *GuildCreate) SetBumpMention(s snowflake.ID) *GuildCreate { + gc.mutation.SetBumpMention(s) + return gc +} + +// SetNillableBumpMention sets the "bump_mention" field if the given value is not nil. +func (gc *GuildCreate) SetNillableBumpMention(s *snowflake.ID) *GuildCreate { + if s != nil { + gc.SetBumpMention(*s) + } + return gc +} + +// SetUpMention sets the "up_mention" field. +func (gc *GuildCreate) SetUpMention(s snowflake.ID) *GuildCreate { + gc.mutation.SetUpMention(s) + return gc +} + +// SetNillableUpMention sets the "up_mention" field if the given value is not nil. +func (gc *GuildCreate) SetNillableUpMention(s *snowflake.ID) *GuildCreate { + if s != nil { + gc.SetUpMention(*s) + } + return gc +} + +// SetID sets the "id" field. +func (gc *GuildCreate) SetID(s snowflake.ID) *GuildCreate { + gc.mutation.SetID(s) + return gc +} + +// SetOwnerID sets the "owner" edge to the User entity by ID. +func (gc *GuildCreate) SetOwnerID(id snowflake.ID) *GuildCreate { + gc.mutation.SetOwnerID(id) + return gc +} + +// SetOwner sets the "owner" edge to the User entity. +func (gc *GuildCreate) SetOwner(u *User) *GuildCreate { + return gc.SetOwnerID(u.ID) +} + +// AddMemberIDs adds the "members" edge to the Member entity by IDs. +func (gc *GuildCreate) AddMemberIDs(ids ...int) *GuildCreate { + gc.mutation.AddMemberIDs(ids...) + return gc +} + +// AddMembers adds the "members" edges to the Member entity. +func (gc *GuildCreate) AddMembers(m ...*Member) *GuildCreate { + ids := make([]int, len(m)) + for i := range m { + ids[i] = m[i].ID + } + return gc.AddMemberIDs(ids...) +} + +// AddMessagePinIDs adds the "message_pins" edge to the MessagePin entity by IDs. +func (gc *GuildCreate) AddMessagePinIDs(ids ...uuid.UUID) *GuildCreate { + gc.mutation.AddMessagePinIDs(ids...) + return gc +} + +// AddMessagePins adds the "message_pins" edges to the MessagePin entity. +func (gc *GuildCreate) AddMessagePins(m ...*MessagePin) *GuildCreate { + ids := make([]uuid.UUID, len(m)) + for i := range m { + ids[i] = m[i].ID + } + return gc.AddMessagePinIDs(ids...) +} + +// AddRemindIDs adds the "reminds" edge to the MessageRemind entity by IDs. +func (gc *GuildCreate) AddRemindIDs(ids ...uuid.UUID) *GuildCreate { + gc.mutation.AddRemindIDs(ids...) + return gc +} + +// AddReminds adds the "reminds" edges to the MessageRemind entity. +func (gc *GuildCreate) AddReminds(m ...*MessageRemind) *GuildCreate { + ids := make([]uuid.UUID, len(m)) + for i := range m { + ids[i] = m[i].ID + } + return gc.AddRemindIDs(ids...) +} + +// AddRolePanelIDs adds the "role_panels" edge to the RolePanel entity by IDs. +func (gc *GuildCreate) AddRolePanelIDs(ids ...uuid.UUID) *GuildCreate { + gc.mutation.AddRolePanelIDs(ids...) + return gc +} + +// AddRolePanels adds the "role_panels" edges to the RolePanel entity. +func (gc *GuildCreate) AddRolePanels(r ...*RolePanel) *GuildCreate { + ids := make([]uuid.UUID, len(r)) + for i := range r { + ids[i] = r[i].ID + } + return gc.AddRolePanelIDs(ids...) +} + +// AddRolePanelPlacementIDs adds the "role_panel_placements" edge to the RolePanelPlaced entity by IDs. +func (gc *GuildCreate) AddRolePanelPlacementIDs(ids ...uuid.UUID) *GuildCreate { + gc.mutation.AddRolePanelPlacementIDs(ids...) + return gc +} + +// AddRolePanelPlacements adds the "role_panel_placements" edges to the RolePanelPlaced entity. +func (gc *GuildCreate) AddRolePanelPlacements(r ...*RolePanelPlaced) *GuildCreate { + ids := make([]uuid.UUID, len(r)) + for i := range r { + ids[i] = r[i].ID + } + return gc.AddRolePanelPlacementIDs(ids...) +} + +// AddRolePanelEditIDs adds the "role_panel_edits" edge to the RolePanelEdit entity by IDs. +func (gc *GuildCreate) AddRolePanelEditIDs(ids ...uuid.UUID) *GuildCreate { + gc.mutation.AddRolePanelEditIDs(ids...) + return gc +} + +// AddRolePanelEdits adds the "role_panel_edits" edges to the RolePanelEdit entity. +func (gc *GuildCreate) AddRolePanelEdits(r ...*RolePanelEdit) *GuildCreate { + ids := make([]uuid.UUID, len(r)) + for i := range r { + ids[i] = r[i].ID + } + return gc.AddRolePanelEditIDs(ids...) +} + +// Mutation returns the GuildMutation object of the builder. +func (gc *GuildCreate) Mutation() *GuildMutation { + return gc.mutation +} + +// Save creates the Guild in the database. +func (gc *GuildCreate) Save(ctx context.Context) (*Guild, error) { + gc.defaults() + return withHooks(ctx, gc.sqlSave, gc.mutation, gc.hooks) +} + +// SaveX calls Save and panics if Save returns an error. +func (gc *GuildCreate) SaveX(ctx context.Context) *Guild { + v, err := gc.Save(ctx) + if err != nil { + panic(err) + } + return v +} + +// Exec executes the query. +func (gc *GuildCreate) Exec(ctx context.Context) error { + _, err := gc.Save(ctx) + return err +} + +// ExecX is like Exec, but panics if an error occurs. +func (gc *GuildCreate) ExecX(ctx context.Context) { + if err := gc.Exec(ctx); err != nil { + panic(err) + } +} + +// defaults sets the default values of the builder before save. +func (gc *GuildCreate) defaults() { + if _, ok := gc.mutation.Locale(); !ok { + v := guild.DefaultLocale + gc.mutation.SetLocale(v) + } + if _, ok := gc.mutation.LevelUpMessage(); !ok { + v := guild.DefaultLevelUpMessage + gc.mutation.SetLevelUpMessage(v) + } + if _, ok := gc.mutation.LevelMee6Imported(); !ok { + v := guild.DefaultLevelMee6Imported + gc.mutation.SetLevelMee6Imported(v) + } + if _, ok := gc.mutation.LevelRole(); !ok { + v := guild.DefaultLevelRole + gc.mutation.SetLevelRole(v) + } + if _, ok := gc.mutation.Permissions(); !ok { + v := guild.DefaultPermissions + gc.mutation.SetPermissions(v) + } + if _, ok := gc.mutation.RemindCount(); !ok { + v := guild.DefaultRemindCount + gc.mutation.SetRemindCount(v) + } + if _, ok := gc.mutation.RolePanelEditTimes(); !ok { + v := guild.DefaultRolePanelEditTimes + gc.mutation.SetRolePanelEditTimes(v) + } + if _, ok := gc.mutation.BumpEnabled(); !ok { + v := guild.DefaultBumpEnabled + gc.mutation.SetBumpEnabled(v) + } + if _, ok := gc.mutation.BumpMessageTitle(); !ok { + v := guild.DefaultBumpMessageTitle + gc.mutation.SetBumpMessageTitle(v) + } + if _, ok := gc.mutation.BumpMessage(); !ok { + v := guild.DefaultBumpMessage + gc.mutation.SetBumpMessage(v) + } + if _, ok := gc.mutation.BumpRemindMessageTitle(); !ok { + v := guild.DefaultBumpRemindMessageTitle + gc.mutation.SetBumpRemindMessageTitle(v) + } + if _, ok := gc.mutation.BumpRemindMessage(); !ok { + v := guild.DefaultBumpRemindMessage + gc.mutation.SetBumpRemindMessage(v) + } + if _, ok := gc.mutation.UpEnabled(); !ok { + v := guild.DefaultUpEnabled + gc.mutation.SetUpEnabled(v) + } + if _, ok := gc.mutation.UpMessageTitle(); !ok { + v := guild.DefaultUpMessageTitle + gc.mutation.SetUpMessageTitle(v) + } + if _, ok := gc.mutation.UpMessage(); !ok { + v := guild.DefaultUpMessage + gc.mutation.SetUpMessage(v) + } + if _, ok := gc.mutation.UpRemindMessageTitle(); !ok { + v := guild.DefaultUpRemindMessageTitle + gc.mutation.SetUpRemindMessageTitle(v) + } + if _, ok := gc.mutation.UpRemindMessage(); !ok { + v := guild.DefaultUpRemindMessage + gc.mutation.SetUpRemindMessage(v) + } +} + +// check runs all checks and user-defined validators on the builder. +func (gc *GuildCreate) check() error { + if _, ok := gc.mutation.Name(); !ok { + return &ValidationError{Name: "name", err: errors.New(`ent: missing required field "Guild.name"`)} + } + if v, ok := gc.mutation.Name(); ok { + if err := guild.NameValidator(v); err != nil { + return &ValidationError{Name: "name", err: fmt.Errorf(`ent: validator failed for field "Guild.name": %w`, err)} + } + } + if _, ok := gc.mutation.Locale(); !ok { + return &ValidationError{Name: "locale", err: errors.New(`ent: missing required field "Guild.locale"`)} + } + if v, ok := gc.mutation.Locale(); ok { + if err := guild.LocaleValidator(string(v)); err != nil { + return &ValidationError{Name: "locale", err: fmt.Errorf(`ent: validator failed for field "Guild.locale": %w`, err)} + } + } + if _, ok := gc.mutation.LevelUpMessage(); !ok { + return &ValidationError{Name: "level_up_message", err: errors.New(`ent: missing required field "Guild.level_up_message"`)} + } + if v, ok := gc.mutation.LevelUpMessage(); ok { + if err := guild.LevelUpMessageValidator(v); err != nil { + return &ValidationError{Name: "level_up_message", err: fmt.Errorf(`ent: validator failed for field "Guild.level_up_message": %w`, err)} + } + } + if _, ok := gc.mutation.LevelMee6Imported(); !ok { + return &ValidationError{Name: "level_mee6_imported", err: errors.New(`ent: missing required field "Guild.level_mee6_imported"`)} + } + if _, ok := gc.mutation.Permissions(); !ok { + return &ValidationError{Name: "permissions", err: errors.New(`ent: missing required field "Guild.permissions"`)} + } + if _, ok := gc.mutation.RemindCount(); !ok { + return &ValidationError{Name: "remind_count", err: errors.New(`ent: missing required field "Guild.remind_count"`)} + } + if _, ok := gc.mutation.RolePanelEditTimes(); !ok { + return &ValidationError{Name: "role_panel_edit_times", err: errors.New(`ent: missing required field "Guild.role_panel_edit_times"`)} + } + if _, ok := gc.mutation.BumpEnabled(); !ok { + return &ValidationError{Name: "bump_enabled", err: errors.New(`ent: missing required field "Guild.bump_enabled"`)} + } + if _, ok := gc.mutation.BumpMessageTitle(); !ok { + return &ValidationError{Name: "bump_message_title", err: errors.New(`ent: missing required field "Guild.bump_message_title"`)} + } + if v, ok := gc.mutation.BumpMessageTitle(); ok { + if err := guild.BumpMessageTitleValidator(v); err != nil { + return &ValidationError{Name: "bump_message_title", err: fmt.Errorf(`ent: validator failed for field "Guild.bump_message_title": %w`, err)} + } + } + if _, ok := gc.mutation.BumpMessage(); !ok { + return &ValidationError{Name: "bump_message", err: errors.New(`ent: missing required field "Guild.bump_message"`)} + } + if v, ok := gc.mutation.BumpMessage(); ok { + if err := guild.BumpMessageValidator(v); err != nil { + return &ValidationError{Name: "bump_message", err: fmt.Errorf(`ent: validator failed for field "Guild.bump_message": %w`, err)} + } + } + if _, ok := gc.mutation.BumpRemindMessageTitle(); !ok { + return &ValidationError{Name: "bump_remind_message_title", err: errors.New(`ent: missing required field "Guild.bump_remind_message_title"`)} + } + if v, ok := gc.mutation.BumpRemindMessageTitle(); ok { + if err := guild.BumpRemindMessageTitleValidator(v); err != nil { + return &ValidationError{Name: "bump_remind_message_title", err: fmt.Errorf(`ent: validator failed for field "Guild.bump_remind_message_title": %w`, err)} + } + } + if _, ok := gc.mutation.BumpRemindMessage(); !ok { + return &ValidationError{Name: "bump_remind_message", err: errors.New(`ent: missing required field "Guild.bump_remind_message"`)} + } + if v, ok := gc.mutation.BumpRemindMessage(); ok { + if err := guild.BumpRemindMessageValidator(v); err != nil { + return &ValidationError{Name: "bump_remind_message", err: fmt.Errorf(`ent: validator failed for field "Guild.bump_remind_message": %w`, err)} + } + } + if _, ok := gc.mutation.UpEnabled(); !ok { + return &ValidationError{Name: "up_enabled", err: errors.New(`ent: missing required field "Guild.up_enabled"`)} + } + if _, ok := gc.mutation.UpMessageTitle(); !ok { + return &ValidationError{Name: "up_message_title", err: errors.New(`ent: missing required field "Guild.up_message_title"`)} + } + if v, ok := gc.mutation.UpMessageTitle(); ok { + if err := guild.UpMessageTitleValidator(v); err != nil { + return &ValidationError{Name: "up_message_title", err: fmt.Errorf(`ent: validator failed for field "Guild.up_message_title": %w`, err)} + } + } + if _, ok := gc.mutation.UpMessage(); !ok { + return &ValidationError{Name: "up_message", err: errors.New(`ent: missing required field "Guild.up_message"`)} + } + if v, ok := gc.mutation.UpMessage(); ok { + if err := guild.UpMessageValidator(v); err != nil { + return &ValidationError{Name: "up_message", err: fmt.Errorf(`ent: validator failed for field "Guild.up_message": %w`, err)} + } + } + if _, ok := gc.mutation.UpRemindMessageTitle(); !ok { + return &ValidationError{Name: "up_remind_message_title", err: errors.New(`ent: missing required field "Guild.up_remind_message_title"`)} + } + if v, ok := gc.mutation.UpRemindMessageTitle(); ok { + if err := guild.UpRemindMessageTitleValidator(v); err != nil { + return &ValidationError{Name: "up_remind_message_title", err: fmt.Errorf(`ent: validator failed for field "Guild.up_remind_message_title": %w`, err)} + } + } + if _, ok := gc.mutation.UpRemindMessage(); !ok { + return &ValidationError{Name: "up_remind_message", err: errors.New(`ent: missing required field "Guild.up_remind_message"`)} + } + if v, ok := gc.mutation.UpRemindMessage(); ok { + if err := guild.UpRemindMessageValidator(v); err != nil { + return &ValidationError{Name: "up_remind_message", err: fmt.Errorf(`ent: validator failed for field "Guild.up_remind_message": %w`, err)} + } + } + if _, ok := gc.mutation.OwnerID(); !ok { + return &ValidationError{Name: "owner", err: errors.New(`ent: missing required edge "Guild.owner"`)} + } + return nil +} + +func (gc *GuildCreate) sqlSave(ctx context.Context) (*Guild, error) { + if err := gc.check(); err != nil { + return nil, err + } + _node, _spec := gc.createSpec() + if err := sqlgraph.CreateNode(ctx, gc.driver, _spec); err != nil { + if sqlgraph.IsConstraintError(err) { + err = &ConstraintError{msg: err.Error(), wrap: err} + } + return nil, err + } + if _spec.ID.Value != _node.ID { + id := _spec.ID.Value.(int64) + _node.ID = snowflake.ID(id) + } + gc.mutation.id = &_node.ID + gc.mutation.done = true + return _node, nil +} + +func (gc *GuildCreate) createSpec() (*Guild, *sqlgraph.CreateSpec) { + var ( + _node = &Guild{config: gc.config} + _spec = sqlgraph.NewCreateSpec(guild.Table, sqlgraph.NewFieldSpec(guild.FieldID, field.TypeUint64)) + ) + if id, ok := gc.mutation.ID(); ok { + _node.ID = id + _spec.ID.Value = id + } + if value, ok := gc.mutation.Name(); ok { + _spec.SetField(guild.FieldName, field.TypeString, value) + _node.Name = value + } + if value, ok := gc.mutation.Locale(); ok { + _spec.SetField(guild.FieldLocale, field.TypeString, value) + _node.Locale = value + } + if value, ok := gc.mutation.LevelUpMessage(); ok { + _spec.SetField(guild.FieldLevelUpMessage, field.TypeString, value) + _node.LevelUpMessage = value + } + if value, ok := gc.mutation.LevelUpChannel(); ok { + _spec.SetField(guild.FieldLevelUpChannel, field.TypeUint64, value) + _node.LevelUpChannel = &value + } + if value, ok := gc.mutation.LevelUpExcludeChannel(); ok { + _spec.SetField(guild.FieldLevelUpExcludeChannel, field.TypeJSON, value) + _node.LevelUpExcludeChannel = value + } + if value, ok := gc.mutation.LevelMee6Imported(); ok { + _spec.SetField(guild.FieldLevelMee6Imported, field.TypeBool, value) + _node.LevelMee6Imported = value + } + if value, ok := gc.mutation.LevelRole(); ok { + _spec.SetField(guild.FieldLevelRole, field.TypeJSON, value) + _node.LevelRole = value + } + if value, ok := gc.mutation.Permissions(); ok { + _spec.SetField(guild.FieldPermissions, field.TypeJSON, value) + _node.Permissions = value + } + if value, ok := gc.mutation.RemindCount(); ok { + _spec.SetField(guild.FieldRemindCount, field.TypeInt, value) + _node.RemindCount = value + } + if value, ok := gc.mutation.RolePanelEditTimes(); ok { + _spec.SetField(guild.FieldRolePanelEditTimes, field.TypeJSON, value) + _node.RolePanelEditTimes = value + } + if value, ok := gc.mutation.BumpEnabled(); ok { + _spec.SetField(guild.FieldBumpEnabled, field.TypeBool, value) + _node.BumpEnabled = value + } + if value, ok := gc.mutation.BumpMessageTitle(); ok { + _spec.SetField(guild.FieldBumpMessageTitle, field.TypeString, value) + _node.BumpMessageTitle = value + } + if value, ok := gc.mutation.BumpMessage(); ok { + _spec.SetField(guild.FieldBumpMessage, field.TypeString, value) + _node.BumpMessage = value + } + if value, ok := gc.mutation.BumpRemindMessageTitle(); ok { + _spec.SetField(guild.FieldBumpRemindMessageTitle, field.TypeString, value) + _node.BumpRemindMessageTitle = value + } + if value, ok := gc.mutation.BumpRemindMessage(); ok { + _spec.SetField(guild.FieldBumpRemindMessage, field.TypeString, value) + _node.BumpRemindMessage = value + } + if value, ok := gc.mutation.UpEnabled(); ok { + _spec.SetField(guild.FieldUpEnabled, field.TypeBool, value) + _node.UpEnabled = value + } + if value, ok := gc.mutation.UpMessageTitle(); ok { + _spec.SetField(guild.FieldUpMessageTitle, field.TypeString, value) + _node.UpMessageTitle = value + } + if value, ok := gc.mutation.UpMessage(); ok { + _spec.SetField(guild.FieldUpMessage, field.TypeString, value) + _node.UpMessage = value + } + if value, ok := gc.mutation.UpRemindMessageTitle(); ok { + _spec.SetField(guild.FieldUpRemindMessageTitle, field.TypeString, value) + _node.UpRemindMessageTitle = value + } + if value, ok := gc.mutation.UpRemindMessage(); ok { + _spec.SetField(guild.FieldUpRemindMessage, field.TypeString, value) + _node.UpRemindMessage = value + } + if value, ok := gc.mutation.BumpMention(); ok { + _spec.SetField(guild.FieldBumpMention, field.TypeUint64, value) + _node.BumpMention = &value + } + if value, ok := gc.mutation.UpMention(); ok { + _spec.SetField(guild.FieldUpMention, field.TypeUint64, value) + _node.UpMention = &value + } + if nodes := gc.mutation.OwnerIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.M2O, + Inverse: true, + Table: guild.OwnerTable, + Columns: []string{guild.OwnerColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(user.FieldID, field.TypeUint64), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _node.user_own_guilds = &nodes[0] + _spec.Edges = append(_spec.Edges, edge) + } + if nodes := gc.mutation.MembersIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: false, + Table: guild.MembersTable, + Columns: []string{guild.MembersColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(member.FieldID, field.TypeInt), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges = append(_spec.Edges, edge) + } + if nodes := gc.mutation.MessagePinsIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: false, + Table: guild.MessagePinsTable, + Columns: []string{guild.MessagePinsColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(messagepin.FieldID, field.TypeUUID), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges = append(_spec.Edges, edge) + } + if nodes := gc.mutation.RemindsIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: false, + Table: guild.RemindsTable, + Columns: []string{guild.RemindsColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(messageremind.FieldID, field.TypeUUID), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges = append(_spec.Edges, edge) + } + if nodes := gc.mutation.RolePanelsIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: false, + Table: guild.RolePanelsTable, + Columns: []string{guild.RolePanelsColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(rolepanel.FieldID, field.TypeUUID), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges = append(_spec.Edges, edge) + } + if nodes := gc.mutation.RolePanelPlacementsIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: false, + Table: guild.RolePanelPlacementsTable, + Columns: []string{guild.RolePanelPlacementsColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(rolepanelplaced.FieldID, field.TypeUUID), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges = append(_spec.Edges, edge) + } + if nodes := gc.mutation.RolePanelEditsIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: false, + Table: guild.RolePanelEditsTable, + Columns: []string{guild.RolePanelEditsColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(rolepaneledit.FieldID, field.TypeUUID), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges = append(_spec.Edges, edge) + } + return _node, _spec +} + +// GuildCreateBulk is the builder for creating many Guild entities in bulk. +type GuildCreateBulk struct { + config + err error + builders []*GuildCreate +} + +// Save creates the Guild entities in the database. +func (gcb *GuildCreateBulk) Save(ctx context.Context) ([]*Guild, error) { + if gcb.err != nil { + return nil, gcb.err + } + specs := make([]*sqlgraph.CreateSpec, len(gcb.builders)) + nodes := make([]*Guild, len(gcb.builders)) + mutators := make([]Mutator, len(gcb.builders)) + for i := range gcb.builders { + func(i int, root context.Context) { + builder := gcb.builders[i] + builder.defaults() + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*GuildMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + if err := builder.check(); err != nil { + return nil, err + } + builder.mutation = mutation + var err error + nodes[i], specs[i] = builder.createSpec() + if i < len(mutators)-1 { + _, err = mutators[i+1].Mutate(root, gcb.builders[i+1].mutation) + } else { + spec := &sqlgraph.BatchCreateSpec{Nodes: specs} + // Invoke the actual operation on the latest mutation in the chain. + if err = sqlgraph.BatchCreate(ctx, gcb.driver, spec); err != nil { + if sqlgraph.IsConstraintError(err) { + err = &ConstraintError{msg: err.Error(), wrap: err} + } + } + } + if err != nil { + return nil, err + } + mutation.id = &nodes[i].ID + if specs[i].ID.Value != nil && nodes[i].ID == 0 { + id := specs[i].ID.Value.(int64) + nodes[i].ID = snowflake.ID(id) + } + mutation.done = true + return nodes[i], nil + }) + for i := len(builder.hooks) - 1; i >= 0; i-- { + mut = builder.hooks[i](mut) + } + mutators[i] = mut + }(i, ctx) + } + if len(mutators) > 0 { + if _, err := mutators[0].Mutate(ctx, gcb.builders[0].mutation); err != nil { + return nil, err + } + } + return nodes, nil +} + +// SaveX is like Save, but panics if an error occurs. +func (gcb *GuildCreateBulk) SaveX(ctx context.Context) []*Guild { + v, err := gcb.Save(ctx) + if err != nil { + panic(err) + } + return v +} + +// Exec executes the query. +func (gcb *GuildCreateBulk) Exec(ctx context.Context) error { + _, err := gcb.Save(ctx) + return err +} + +// ExecX is like Exec, but panics if an error occurs. +func (gcb *GuildCreateBulk) ExecX(ctx context.Context) { + if err := gcb.Exec(ctx); err != nil { + panic(err) + } +} diff --git a/ent/guild_delete.go b/ent/guild_delete.go new file mode 100644 index 00000000..33a67ff0 --- /dev/null +++ b/ent/guild_delete.go @@ -0,0 +1,88 @@ +// Code generated by ent, DO NOT EDIT. + +package ent + +import ( + "context" + + "entgo.io/ent/dialect/sql" + "entgo.io/ent/dialect/sql/sqlgraph" + "entgo.io/ent/schema/field" + "github.com/sabafly/gobot/ent/guild" + "github.com/sabafly/gobot/ent/predicate" +) + +// GuildDelete is the builder for deleting a Guild entity. +type GuildDelete struct { + config + hooks []Hook + mutation *GuildMutation +} + +// Where appends a list predicates to the GuildDelete builder. +func (gd *GuildDelete) Where(ps ...predicate.Guild) *GuildDelete { + gd.mutation.Where(ps...) + return gd +} + +// Exec executes the deletion query and returns how many vertices were deleted. +func (gd *GuildDelete) Exec(ctx context.Context) (int, error) { + return withHooks(ctx, gd.sqlExec, gd.mutation, gd.hooks) +} + +// ExecX is like Exec, but panics if an error occurs. +func (gd *GuildDelete) ExecX(ctx context.Context) int { + n, err := gd.Exec(ctx) + if err != nil { + panic(err) + } + return n +} + +func (gd *GuildDelete) sqlExec(ctx context.Context) (int, error) { + _spec := sqlgraph.NewDeleteSpec(guild.Table, sqlgraph.NewFieldSpec(guild.FieldID, field.TypeUint64)) + if ps := gd.mutation.predicates; len(ps) > 0 { + _spec.Predicate = func(selector *sql.Selector) { + for i := range ps { + ps[i](selector) + } + } + } + affected, err := sqlgraph.DeleteNodes(ctx, gd.driver, _spec) + if err != nil && sqlgraph.IsConstraintError(err) { + err = &ConstraintError{msg: err.Error(), wrap: err} + } + gd.mutation.done = true + return affected, err +} + +// GuildDeleteOne is the builder for deleting a single Guild entity. +type GuildDeleteOne struct { + gd *GuildDelete +} + +// Where appends a list predicates to the GuildDelete builder. +func (gdo *GuildDeleteOne) Where(ps ...predicate.Guild) *GuildDeleteOne { + gdo.gd.mutation.Where(ps...) + return gdo +} + +// Exec executes the deletion query. +func (gdo *GuildDeleteOne) Exec(ctx context.Context) error { + n, err := gdo.gd.Exec(ctx) + switch { + case err != nil: + return err + case n == 0: + return &NotFoundError{guild.Label} + default: + return nil + } +} + +// ExecX is like Exec, but panics if an error occurs. +func (gdo *GuildDeleteOne) ExecX(ctx context.Context) { + if err := gdo.Exec(ctx); err != nil { + panic(err) + } +} diff --git a/ent/guild_query.go b/ent/guild_query.go new file mode 100644 index 00000000..7c64eaf1 --- /dev/null +++ b/ent/guild_query.go @@ -0,0 +1,1067 @@ +// Code generated by ent, DO NOT EDIT. + +package ent + +import ( + "context" + "database/sql/driver" + "fmt" + "math" + + "entgo.io/ent/dialect/sql" + "entgo.io/ent/dialect/sql/sqlgraph" + "entgo.io/ent/schema/field" + snowflake "github.com/disgoorg/snowflake/v2" + "github.com/sabafly/gobot/ent/guild" + "github.com/sabafly/gobot/ent/member" + "github.com/sabafly/gobot/ent/messagepin" + "github.com/sabafly/gobot/ent/messageremind" + "github.com/sabafly/gobot/ent/predicate" + "github.com/sabafly/gobot/ent/rolepanel" + "github.com/sabafly/gobot/ent/rolepaneledit" + "github.com/sabafly/gobot/ent/rolepanelplaced" + "github.com/sabafly/gobot/ent/user" +) + +// GuildQuery is the builder for querying Guild entities. +type GuildQuery struct { + config + ctx *QueryContext + order []guild.OrderOption + inters []Interceptor + predicates []predicate.Guild + withOwner *UserQuery + withMembers *MemberQuery + withMessagePins *MessagePinQuery + withReminds *MessageRemindQuery + withRolePanels *RolePanelQuery + withRolePanelPlacements *RolePanelPlacedQuery + withRolePanelEdits *RolePanelEditQuery + withFKs bool + // intermediate query (i.e. traversal path). + sql *sql.Selector + path func(context.Context) (*sql.Selector, error) +} + +// Where adds a new predicate for the GuildQuery builder. +func (gq *GuildQuery) Where(ps ...predicate.Guild) *GuildQuery { + gq.predicates = append(gq.predicates, ps...) + return gq +} + +// Limit the number of records to be returned by this query. +func (gq *GuildQuery) Limit(limit int) *GuildQuery { + gq.ctx.Limit = &limit + return gq +} + +// Offset to start from. +func (gq *GuildQuery) Offset(offset int) *GuildQuery { + gq.ctx.Offset = &offset + return gq +} + +// Unique configures the query builder to filter duplicate records on query. +// By default, unique is set to true, and can be disabled using this method. +func (gq *GuildQuery) Unique(unique bool) *GuildQuery { + gq.ctx.Unique = &unique + return gq +} + +// Order specifies how the records should be ordered. +func (gq *GuildQuery) Order(o ...guild.OrderOption) *GuildQuery { + gq.order = append(gq.order, o...) + return gq +} + +// QueryOwner chains the current query on the "owner" edge. +func (gq *GuildQuery) QueryOwner() *UserQuery { + query := (&UserClient{config: gq.config}).Query() + query.path = func(ctx context.Context) (fromU *sql.Selector, err error) { + if err := gq.prepareQuery(ctx); err != nil { + return nil, err + } + selector := gq.sqlQuery(ctx) + if err := selector.Err(); err != nil { + return nil, err + } + step := sqlgraph.NewStep( + sqlgraph.From(guild.Table, guild.FieldID, selector), + sqlgraph.To(user.Table, user.FieldID), + sqlgraph.Edge(sqlgraph.M2O, true, guild.OwnerTable, guild.OwnerColumn), + ) + fromU = sqlgraph.SetNeighbors(gq.driver.Dialect(), step) + return fromU, nil + } + return query +} + +// QueryMembers chains the current query on the "members" edge. +func (gq *GuildQuery) QueryMembers() *MemberQuery { + query := (&MemberClient{config: gq.config}).Query() + query.path = func(ctx context.Context) (fromU *sql.Selector, err error) { + if err := gq.prepareQuery(ctx); err != nil { + return nil, err + } + selector := gq.sqlQuery(ctx) + if err := selector.Err(); err != nil { + return nil, err + } + step := sqlgraph.NewStep( + sqlgraph.From(guild.Table, guild.FieldID, selector), + sqlgraph.To(member.Table, member.FieldID), + sqlgraph.Edge(sqlgraph.O2M, false, guild.MembersTable, guild.MembersColumn), + ) + fromU = sqlgraph.SetNeighbors(gq.driver.Dialect(), step) + return fromU, nil + } + return query +} + +// QueryMessagePins chains the current query on the "message_pins" edge. +func (gq *GuildQuery) QueryMessagePins() *MessagePinQuery { + query := (&MessagePinClient{config: gq.config}).Query() + query.path = func(ctx context.Context) (fromU *sql.Selector, err error) { + if err := gq.prepareQuery(ctx); err != nil { + return nil, err + } + selector := gq.sqlQuery(ctx) + if err := selector.Err(); err != nil { + return nil, err + } + step := sqlgraph.NewStep( + sqlgraph.From(guild.Table, guild.FieldID, selector), + sqlgraph.To(messagepin.Table, messagepin.FieldID), + sqlgraph.Edge(sqlgraph.O2M, false, guild.MessagePinsTable, guild.MessagePinsColumn), + ) + fromU = sqlgraph.SetNeighbors(gq.driver.Dialect(), step) + return fromU, nil + } + return query +} + +// QueryReminds chains the current query on the "reminds" edge. +func (gq *GuildQuery) QueryReminds() *MessageRemindQuery { + query := (&MessageRemindClient{config: gq.config}).Query() + query.path = func(ctx context.Context) (fromU *sql.Selector, err error) { + if err := gq.prepareQuery(ctx); err != nil { + return nil, err + } + selector := gq.sqlQuery(ctx) + if err := selector.Err(); err != nil { + return nil, err + } + step := sqlgraph.NewStep( + sqlgraph.From(guild.Table, guild.FieldID, selector), + sqlgraph.To(messageremind.Table, messageremind.FieldID), + sqlgraph.Edge(sqlgraph.O2M, false, guild.RemindsTable, guild.RemindsColumn), + ) + fromU = sqlgraph.SetNeighbors(gq.driver.Dialect(), step) + return fromU, nil + } + return query +} + +// QueryRolePanels chains the current query on the "role_panels" edge. +func (gq *GuildQuery) QueryRolePanels() *RolePanelQuery { + query := (&RolePanelClient{config: gq.config}).Query() + query.path = func(ctx context.Context) (fromU *sql.Selector, err error) { + if err := gq.prepareQuery(ctx); err != nil { + return nil, err + } + selector := gq.sqlQuery(ctx) + if err := selector.Err(); err != nil { + return nil, err + } + step := sqlgraph.NewStep( + sqlgraph.From(guild.Table, guild.FieldID, selector), + sqlgraph.To(rolepanel.Table, rolepanel.FieldID), + sqlgraph.Edge(sqlgraph.O2M, false, guild.RolePanelsTable, guild.RolePanelsColumn), + ) + fromU = sqlgraph.SetNeighbors(gq.driver.Dialect(), step) + return fromU, nil + } + return query +} + +// QueryRolePanelPlacements chains the current query on the "role_panel_placements" edge. +func (gq *GuildQuery) QueryRolePanelPlacements() *RolePanelPlacedQuery { + query := (&RolePanelPlacedClient{config: gq.config}).Query() + query.path = func(ctx context.Context) (fromU *sql.Selector, err error) { + if err := gq.prepareQuery(ctx); err != nil { + return nil, err + } + selector := gq.sqlQuery(ctx) + if err := selector.Err(); err != nil { + return nil, err + } + step := sqlgraph.NewStep( + sqlgraph.From(guild.Table, guild.FieldID, selector), + sqlgraph.To(rolepanelplaced.Table, rolepanelplaced.FieldID), + sqlgraph.Edge(sqlgraph.O2M, false, guild.RolePanelPlacementsTable, guild.RolePanelPlacementsColumn), + ) + fromU = sqlgraph.SetNeighbors(gq.driver.Dialect(), step) + return fromU, nil + } + return query +} + +// QueryRolePanelEdits chains the current query on the "role_panel_edits" edge. +func (gq *GuildQuery) QueryRolePanelEdits() *RolePanelEditQuery { + query := (&RolePanelEditClient{config: gq.config}).Query() + query.path = func(ctx context.Context) (fromU *sql.Selector, err error) { + if err := gq.prepareQuery(ctx); err != nil { + return nil, err + } + selector := gq.sqlQuery(ctx) + if err := selector.Err(); err != nil { + return nil, err + } + step := sqlgraph.NewStep( + sqlgraph.From(guild.Table, guild.FieldID, selector), + sqlgraph.To(rolepaneledit.Table, rolepaneledit.FieldID), + sqlgraph.Edge(sqlgraph.O2M, false, guild.RolePanelEditsTable, guild.RolePanelEditsColumn), + ) + fromU = sqlgraph.SetNeighbors(gq.driver.Dialect(), step) + return fromU, nil + } + return query +} + +// First returns the first Guild entity from the query. +// Returns a *NotFoundError when no Guild was found. +func (gq *GuildQuery) First(ctx context.Context) (*Guild, error) { + nodes, err := gq.Limit(1).All(setContextOp(ctx, gq.ctx, "First")) + if err != nil { + return nil, err + } + if len(nodes) == 0 { + return nil, &NotFoundError{guild.Label} + } + return nodes[0], nil +} + +// FirstX is like First, but panics if an error occurs. +func (gq *GuildQuery) FirstX(ctx context.Context) *Guild { + node, err := gq.First(ctx) + if err != nil && !IsNotFound(err) { + panic(err) + } + return node +} + +// FirstID returns the first Guild ID from the query. +// Returns a *NotFoundError when no Guild ID was found. +func (gq *GuildQuery) FirstID(ctx context.Context) (id snowflake.ID, err error) { + var ids []snowflake.ID + if ids, err = gq.Limit(1).IDs(setContextOp(ctx, gq.ctx, "FirstID")); err != nil { + return + } + if len(ids) == 0 { + err = &NotFoundError{guild.Label} + return + } + return ids[0], nil +} + +// FirstIDX is like FirstID, but panics if an error occurs. +func (gq *GuildQuery) FirstIDX(ctx context.Context) snowflake.ID { + id, err := gq.FirstID(ctx) + if err != nil && !IsNotFound(err) { + panic(err) + } + return id +} + +// Only returns a single Guild entity found by the query, ensuring it only returns one. +// Returns a *NotSingularError when more than one Guild entity is found. +// Returns a *NotFoundError when no Guild entities are found. +func (gq *GuildQuery) Only(ctx context.Context) (*Guild, error) { + nodes, err := gq.Limit(2).All(setContextOp(ctx, gq.ctx, "Only")) + if err != nil { + return nil, err + } + switch len(nodes) { + case 1: + return nodes[0], nil + case 0: + return nil, &NotFoundError{guild.Label} + default: + return nil, &NotSingularError{guild.Label} + } +} + +// OnlyX is like Only, but panics if an error occurs. +func (gq *GuildQuery) OnlyX(ctx context.Context) *Guild { + node, err := gq.Only(ctx) + if err != nil { + panic(err) + } + return node +} + +// OnlyID is like Only, but returns the only Guild ID in the query. +// Returns a *NotSingularError when more than one Guild ID is found. +// Returns a *NotFoundError when no entities are found. +func (gq *GuildQuery) OnlyID(ctx context.Context) (id snowflake.ID, err error) { + var ids []snowflake.ID + if ids, err = gq.Limit(2).IDs(setContextOp(ctx, gq.ctx, "OnlyID")); err != nil { + return + } + switch len(ids) { + case 1: + id = ids[0] + case 0: + err = &NotFoundError{guild.Label} + default: + err = &NotSingularError{guild.Label} + } + return +} + +// OnlyIDX is like OnlyID, but panics if an error occurs. +func (gq *GuildQuery) OnlyIDX(ctx context.Context) snowflake.ID { + id, err := gq.OnlyID(ctx) + if err != nil { + panic(err) + } + return id +} + +// All executes the query and returns a list of Guilds. +func (gq *GuildQuery) All(ctx context.Context) ([]*Guild, error) { + ctx = setContextOp(ctx, gq.ctx, "All") + if err := gq.prepareQuery(ctx); err != nil { + return nil, err + } + qr := querierAll[[]*Guild, *GuildQuery]() + return withInterceptors[[]*Guild](ctx, gq, qr, gq.inters) +} + +// AllX is like All, but panics if an error occurs. +func (gq *GuildQuery) AllX(ctx context.Context) []*Guild { + nodes, err := gq.All(ctx) + if err != nil { + panic(err) + } + return nodes +} + +// IDs executes the query and returns a list of Guild IDs. +func (gq *GuildQuery) IDs(ctx context.Context) (ids []snowflake.ID, err error) { + if gq.ctx.Unique == nil && gq.path != nil { + gq.Unique(true) + } + ctx = setContextOp(ctx, gq.ctx, "IDs") + if err = gq.Select(guild.FieldID).Scan(ctx, &ids); err != nil { + return nil, err + } + return ids, nil +} + +// IDsX is like IDs, but panics if an error occurs. +func (gq *GuildQuery) IDsX(ctx context.Context) []snowflake.ID { + ids, err := gq.IDs(ctx) + if err != nil { + panic(err) + } + return ids +} + +// Count returns the count of the given query. +func (gq *GuildQuery) Count(ctx context.Context) (int, error) { + ctx = setContextOp(ctx, gq.ctx, "Count") + if err := gq.prepareQuery(ctx); err != nil { + return 0, err + } + return withInterceptors[int](ctx, gq, querierCount[*GuildQuery](), gq.inters) +} + +// CountX is like Count, but panics if an error occurs. +func (gq *GuildQuery) CountX(ctx context.Context) int { + count, err := gq.Count(ctx) + if err != nil { + panic(err) + } + return count +} + +// Exist returns true if the query has elements in the graph. +func (gq *GuildQuery) Exist(ctx context.Context) (bool, error) { + ctx = setContextOp(ctx, gq.ctx, "Exist") + switch _, err := gq.FirstID(ctx); { + case IsNotFound(err): + return false, nil + case err != nil: + return false, fmt.Errorf("ent: check existence: %w", err) + default: + return true, nil + } +} + +// ExistX is like Exist, but panics if an error occurs. +func (gq *GuildQuery) ExistX(ctx context.Context) bool { + exist, err := gq.Exist(ctx) + if err != nil { + panic(err) + } + return exist +} + +// Clone returns a duplicate of the GuildQuery builder, including all associated steps. It can be +// used to prepare common query builders and use them differently after the clone is made. +func (gq *GuildQuery) Clone() *GuildQuery { + if gq == nil { + return nil + } + return &GuildQuery{ + config: gq.config, + ctx: gq.ctx.Clone(), + order: append([]guild.OrderOption{}, gq.order...), + inters: append([]Interceptor{}, gq.inters...), + predicates: append([]predicate.Guild{}, gq.predicates...), + withOwner: gq.withOwner.Clone(), + withMembers: gq.withMembers.Clone(), + withMessagePins: gq.withMessagePins.Clone(), + withReminds: gq.withReminds.Clone(), + withRolePanels: gq.withRolePanels.Clone(), + withRolePanelPlacements: gq.withRolePanelPlacements.Clone(), + withRolePanelEdits: gq.withRolePanelEdits.Clone(), + // clone intermediate query. + sql: gq.sql.Clone(), + path: gq.path, + } +} + +// WithOwner tells the query-builder to eager-load the nodes that are connected to +// the "owner" edge. The optional arguments are used to configure the query builder of the edge. +func (gq *GuildQuery) WithOwner(opts ...func(*UserQuery)) *GuildQuery { + query := (&UserClient{config: gq.config}).Query() + for _, opt := range opts { + opt(query) + } + gq.withOwner = query + return gq +} + +// WithMembers tells the query-builder to eager-load the nodes that are connected to +// the "members" edge. The optional arguments are used to configure the query builder of the edge. +func (gq *GuildQuery) WithMembers(opts ...func(*MemberQuery)) *GuildQuery { + query := (&MemberClient{config: gq.config}).Query() + for _, opt := range opts { + opt(query) + } + gq.withMembers = query + return gq +} + +// WithMessagePins tells the query-builder to eager-load the nodes that are connected to +// the "message_pins" edge. The optional arguments are used to configure the query builder of the edge. +func (gq *GuildQuery) WithMessagePins(opts ...func(*MessagePinQuery)) *GuildQuery { + query := (&MessagePinClient{config: gq.config}).Query() + for _, opt := range opts { + opt(query) + } + gq.withMessagePins = query + return gq +} + +// WithReminds tells the query-builder to eager-load the nodes that are connected to +// the "reminds" edge. The optional arguments are used to configure the query builder of the edge. +func (gq *GuildQuery) WithReminds(opts ...func(*MessageRemindQuery)) *GuildQuery { + query := (&MessageRemindClient{config: gq.config}).Query() + for _, opt := range opts { + opt(query) + } + gq.withReminds = query + return gq +} + +// WithRolePanels tells the query-builder to eager-load the nodes that are connected to +// the "role_panels" edge. The optional arguments are used to configure the query builder of the edge. +func (gq *GuildQuery) WithRolePanels(opts ...func(*RolePanelQuery)) *GuildQuery { + query := (&RolePanelClient{config: gq.config}).Query() + for _, opt := range opts { + opt(query) + } + gq.withRolePanels = query + return gq +} + +// WithRolePanelPlacements tells the query-builder to eager-load the nodes that are connected to +// the "role_panel_placements" edge. The optional arguments are used to configure the query builder of the edge. +func (gq *GuildQuery) WithRolePanelPlacements(opts ...func(*RolePanelPlacedQuery)) *GuildQuery { + query := (&RolePanelPlacedClient{config: gq.config}).Query() + for _, opt := range opts { + opt(query) + } + gq.withRolePanelPlacements = query + return gq +} + +// WithRolePanelEdits tells the query-builder to eager-load the nodes that are connected to +// the "role_panel_edits" edge. The optional arguments are used to configure the query builder of the edge. +func (gq *GuildQuery) WithRolePanelEdits(opts ...func(*RolePanelEditQuery)) *GuildQuery { + query := (&RolePanelEditClient{config: gq.config}).Query() + for _, opt := range opts { + opt(query) + } + gq.withRolePanelEdits = query + return gq +} + +// GroupBy is used to group vertices by one or more fields/columns. +// It is often used with aggregate functions, like: count, max, mean, min, sum. +// +// Example: +// +// var v []struct { +// Name string `json:"name,omitempty"` +// Count int `json:"count,omitempty"` +// } +// +// client.Guild.Query(). +// GroupBy(guild.FieldName). +// Aggregate(ent.Count()). +// Scan(ctx, &v) +func (gq *GuildQuery) GroupBy(field string, fields ...string) *GuildGroupBy { + gq.ctx.Fields = append([]string{field}, fields...) + grbuild := &GuildGroupBy{build: gq} + grbuild.flds = &gq.ctx.Fields + grbuild.label = guild.Label + grbuild.scan = grbuild.Scan + return grbuild +} + +// Select allows the selection one or more fields/columns for the given query, +// instead of selecting all fields in the entity. +// +// Example: +// +// var v []struct { +// Name string `json:"name,omitempty"` +// } +// +// client.Guild.Query(). +// Select(guild.FieldName). +// Scan(ctx, &v) +func (gq *GuildQuery) Select(fields ...string) *GuildSelect { + gq.ctx.Fields = append(gq.ctx.Fields, fields...) + sbuild := &GuildSelect{GuildQuery: gq} + sbuild.label = guild.Label + sbuild.flds, sbuild.scan = &gq.ctx.Fields, sbuild.Scan + return sbuild +} + +// Aggregate returns a GuildSelect configured with the given aggregations. +func (gq *GuildQuery) Aggregate(fns ...AggregateFunc) *GuildSelect { + return gq.Select().Aggregate(fns...) +} + +func (gq *GuildQuery) prepareQuery(ctx context.Context) error { + for _, inter := range gq.inters { + if inter == nil { + return fmt.Errorf("ent: uninitialized interceptor (forgotten import ent/runtime?)") + } + if trv, ok := inter.(Traverser); ok { + if err := trv.Traverse(ctx, gq); err != nil { + return err + } + } + } + for _, f := range gq.ctx.Fields { + if !guild.ValidColumn(f) { + return &ValidationError{Name: f, err: fmt.Errorf("ent: invalid field %q for query", f)} + } + } + if gq.path != nil { + prev, err := gq.path(ctx) + if err != nil { + return err + } + gq.sql = prev + } + return nil +} + +func (gq *GuildQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*Guild, error) { + var ( + nodes = []*Guild{} + withFKs = gq.withFKs + _spec = gq.querySpec() + loadedTypes = [7]bool{ + gq.withOwner != nil, + gq.withMembers != nil, + gq.withMessagePins != nil, + gq.withReminds != nil, + gq.withRolePanels != nil, + gq.withRolePanelPlacements != nil, + gq.withRolePanelEdits != nil, + } + ) + if gq.withOwner != nil { + withFKs = true + } + if withFKs { + _spec.Node.Columns = append(_spec.Node.Columns, guild.ForeignKeys...) + } + _spec.ScanValues = func(columns []string) ([]any, error) { + return (*Guild).scanValues(nil, columns) + } + _spec.Assign = func(columns []string, values []any) error { + node := &Guild{config: gq.config} + nodes = append(nodes, node) + node.Edges.loadedTypes = loadedTypes + return node.assignValues(columns, values) + } + for i := range hooks { + hooks[i](ctx, _spec) + } + if err := sqlgraph.QueryNodes(ctx, gq.driver, _spec); err != nil { + return nil, err + } + if len(nodes) == 0 { + return nodes, nil + } + if query := gq.withOwner; query != nil { + if err := gq.loadOwner(ctx, query, nodes, nil, + func(n *Guild, e *User) { n.Edges.Owner = e }); err != nil { + return nil, err + } + } + if query := gq.withMembers; query != nil { + if err := gq.loadMembers(ctx, query, nodes, + func(n *Guild) { n.Edges.Members = []*Member{} }, + func(n *Guild, e *Member) { n.Edges.Members = append(n.Edges.Members, e) }); err != nil { + return nil, err + } + } + if query := gq.withMessagePins; query != nil { + if err := gq.loadMessagePins(ctx, query, nodes, + func(n *Guild) { n.Edges.MessagePins = []*MessagePin{} }, + func(n *Guild, e *MessagePin) { n.Edges.MessagePins = append(n.Edges.MessagePins, e) }); err != nil { + return nil, err + } + } + if query := gq.withReminds; query != nil { + if err := gq.loadReminds(ctx, query, nodes, + func(n *Guild) { n.Edges.Reminds = []*MessageRemind{} }, + func(n *Guild, e *MessageRemind) { n.Edges.Reminds = append(n.Edges.Reminds, e) }); err != nil { + return nil, err + } + } + if query := gq.withRolePanels; query != nil { + if err := gq.loadRolePanels(ctx, query, nodes, + func(n *Guild) { n.Edges.RolePanels = []*RolePanel{} }, + func(n *Guild, e *RolePanel) { n.Edges.RolePanels = append(n.Edges.RolePanels, e) }); err != nil { + return nil, err + } + } + if query := gq.withRolePanelPlacements; query != nil { + if err := gq.loadRolePanelPlacements(ctx, query, nodes, + func(n *Guild) { n.Edges.RolePanelPlacements = []*RolePanelPlaced{} }, + func(n *Guild, e *RolePanelPlaced) { + n.Edges.RolePanelPlacements = append(n.Edges.RolePanelPlacements, e) + }); err != nil { + return nil, err + } + } + if query := gq.withRolePanelEdits; query != nil { + if err := gq.loadRolePanelEdits(ctx, query, nodes, + func(n *Guild) { n.Edges.RolePanelEdits = []*RolePanelEdit{} }, + func(n *Guild, e *RolePanelEdit) { n.Edges.RolePanelEdits = append(n.Edges.RolePanelEdits, e) }); err != nil { + return nil, err + } + } + return nodes, nil +} + +func (gq *GuildQuery) loadOwner(ctx context.Context, query *UserQuery, nodes []*Guild, init func(*Guild), assign func(*Guild, *User)) error { + ids := make([]snowflake.ID, 0, len(nodes)) + nodeids := make(map[snowflake.ID][]*Guild) + for i := range nodes { + if nodes[i].user_own_guilds == nil { + continue + } + fk := *nodes[i].user_own_guilds + if _, ok := nodeids[fk]; !ok { + ids = append(ids, fk) + } + nodeids[fk] = append(nodeids[fk], nodes[i]) + } + if len(ids) == 0 { + return nil + } + query.Where(user.IDIn(ids...)) + neighbors, err := query.All(ctx) + if err != nil { + return err + } + for _, n := range neighbors { + nodes, ok := nodeids[n.ID] + if !ok { + return fmt.Errorf(`unexpected foreign-key "user_own_guilds" returned %v`, n.ID) + } + for i := range nodes { + assign(nodes[i], n) + } + } + return nil +} +func (gq *GuildQuery) loadMembers(ctx context.Context, query *MemberQuery, nodes []*Guild, init func(*Guild), assign func(*Guild, *Member)) error { + fks := make([]driver.Value, 0, len(nodes)) + nodeids := make(map[snowflake.ID]*Guild) + for i := range nodes { + fks = append(fks, nodes[i].ID) + nodeids[nodes[i].ID] = nodes[i] + if init != nil { + init(nodes[i]) + } + } + query.withFKs = true + query.Where(predicate.Member(func(s *sql.Selector) { + s.Where(sql.InValues(s.C(guild.MembersColumn), fks...)) + })) + neighbors, err := query.All(ctx) + if err != nil { + return err + } + for _, n := range neighbors { + fk := n.guild_members + if fk == nil { + return fmt.Errorf(`foreign-key "guild_members" is nil for node %v`, n.ID) + } + node, ok := nodeids[*fk] + if !ok { + return fmt.Errorf(`unexpected referenced foreign-key "guild_members" returned %v for node %v`, *fk, n.ID) + } + assign(node, n) + } + return nil +} +func (gq *GuildQuery) loadMessagePins(ctx context.Context, query *MessagePinQuery, nodes []*Guild, init func(*Guild), assign func(*Guild, *MessagePin)) error { + fks := make([]driver.Value, 0, len(nodes)) + nodeids := make(map[snowflake.ID]*Guild) + for i := range nodes { + fks = append(fks, nodes[i].ID) + nodeids[nodes[i].ID] = nodes[i] + if init != nil { + init(nodes[i]) + } + } + query.withFKs = true + query.Where(predicate.MessagePin(func(s *sql.Selector) { + s.Where(sql.InValues(s.C(guild.MessagePinsColumn), fks...)) + })) + neighbors, err := query.All(ctx) + if err != nil { + return err + } + for _, n := range neighbors { + fk := n.guild_message_pins + if fk == nil { + return fmt.Errorf(`foreign-key "guild_message_pins" is nil for node %v`, n.ID) + } + node, ok := nodeids[*fk] + if !ok { + return fmt.Errorf(`unexpected referenced foreign-key "guild_message_pins" returned %v for node %v`, *fk, n.ID) + } + assign(node, n) + } + return nil +} +func (gq *GuildQuery) loadReminds(ctx context.Context, query *MessageRemindQuery, nodes []*Guild, init func(*Guild), assign func(*Guild, *MessageRemind)) error { + fks := make([]driver.Value, 0, len(nodes)) + nodeids := make(map[snowflake.ID]*Guild) + for i := range nodes { + fks = append(fks, nodes[i].ID) + nodeids[nodes[i].ID] = nodes[i] + if init != nil { + init(nodes[i]) + } + } + query.withFKs = true + query.Where(predicate.MessageRemind(func(s *sql.Selector) { + s.Where(sql.InValues(s.C(guild.RemindsColumn), fks...)) + })) + neighbors, err := query.All(ctx) + if err != nil { + return err + } + for _, n := range neighbors { + fk := n.guild_reminds + if fk == nil { + return fmt.Errorf(`foreign-key "guild_reminds" is nil for node %v`, n.ID) + } + node, ok := nodeids[*fk] + if !ok { + return fmt.Errorf(`unexpected referenced foreign-key "guild_reminds" returned %v for node %v`, *fk, n.ID) + } + assign(node, n) + } + return nil +} +func (gq *GuildQuery) loadRolePanels(ctx context.Context, query *RolePanelQuery, nodes []*Guild, init func(*Guild), assign func(*Guild, *RolePanel)) error { + fks := make([]driver.Value, 0, len(nodes)) + nodeids := make(map[snowflake.ID]*Guild) + for i := range nodes { + fks = append(fks, nodes[i].ID) + nodeids[nodes[i].ID] = nodes[i] + if init != nil { + init(nodes[i]) + } + } + query.withFKs = true + query.Where(predicate.RolePanel(func(s *sql.Selector) { + s.Where(sql.InValues(s.C(guild.RolePanelsColumn), fks...)) + })) + neighbors, err := query.All(ctx) + if err != nil { + return err + } + for _, n := range neighbors { + fk := n.guild_role_panels + if fk == nil { + return fmt.Errorf(`foreign-key "guild_role_panels" is nil for node %v`, n.ID) + } + node, ok := nodeids[*fk] + if !ok { + return fmt.Errorf(`unexpected referenced foreign-key "guild_role_panels" returned %v for node %v`, *fk, n.ID) + } + assign(node, n) + } + return nil +} +func (gq *GuildQuery) loadRolePanelPlacements(ctx context.Context, query *RolePanelPlacedQuery, nodes []*Guild, init func(*Guild), assign func(*Guild, *RolePanelPlaced)) error { + fks := make([]driver.Value, 0, len(nodes)) + nodeids := make(map[snowflake.ID]*Guild) + for i := range nodes { + fks = append(fks, nodes[i].ID) + nodeids[nodes[i].ID] = nodes[i] + if init != nil { + init(nodes[i]) + } + } + query.withFKs = true + query.Where(predicate.RolePanelPlaced(func(s *sql.Selector) { + s.Where(sql.InValues(s.C(guild.RolePanelPlacementsColumn), fks...)) + })) + neighbors, err := query.All(ctx) + if err != nil { + return err + } + for _, n := range neighbors { + fk := n.guild_role_panel_placements + if fk == nil { + return fmt.Errorf(`foreign-key "guild_role_panel_placements" is nil for node %v`, n.ID) + } + node, ok := nodeids[*fk] + if !ok { + return fmt.Errorf(`unexpected referenced foreign-key "guild_role_panel_placements" returned %v for node %v`, *fk, n.ID) + } + assign(node, n) + } + return nil +} +func (gq *GuildQuery) loadRolePanelEdits(ctx context.Context, query *RolePanelEditQuery, nodes []*Guild, init func(*Guild), assign func(*Guild, *RolePanelEdit)) error { + fks := make([]driver.Value, 0, len(nodes)) + nodeids := make(map[snowflake.ID]*Guild) + for i := range nodes { + fks = append(fks, nodes[i].ID) + nodeids[nodes[i].ID] = nodes[i] + if init != nil { + init(nodes[i]) + } + } + query.withFKs = true + query.Where(predicate.RolePanelEdit(func(s *sql.Selector) { + s.Where(sql.InValues(s.C(guild.RolePanelEditsColumn), fks...)) + })) + neighbors, err := query.All(ctx) + if err != nil { + return err + } + for _, n := range neighbors { + fk := n.guild_role_panel_edits + if fk == nil { + return fmt.Errorf(`foreign-key "guild_role_panel_edits" is nil for node %v`, n.ID) + } + node, ok := nodeids[*fk] + if !ok { + return fmt.Errorf(`unexpected referenced foreign-key "guild_role_panel_edits" returned %v for node %v`, *fk, n.ID) + } + assign(node, n) + } + return nil +} + +func (gq *GuildQuery) sqlCount(ctx context.Context) (int, error) { + _spec := gq.querySpec() + _spec.Node.Columns = gq.ctx.Fields + if len(gq.ctx.Fields) > 0 { + _spec.Unique = gq.ctx.Unique != nil && *gq.ctx.Unique + } + return sqlgraph.CountNodes(ctx, gq.driver, _spec) +} + +func (gq *GuildQuery) querySpec() *sqlgraph.QuerySpec { + _spec := sqlgraph.NewQuerySpec(guild.Table, guild.Columns, sqlgraph.NewFieldSpec(guild.FieldID, field.TypeUint64)) + _spec.From = gq.sql + if unique := gq.ctx.Unique; unique != nil { + _spec.Unique = *unique + } else if gq.path != nil { + _spec.Unique = true + } + if fields := gq.ctx.Fields; len(fields) > 0 { + _spec.Node.Columns = make([]string, 0, len(fields)) + _spec.Node.Columns = append(_spec.Node.Columns, guild.FieldID) + for i := range fields { + if fields[i] != guild.FieldID { + _spec.Node.Columns = append(_spec.Node.Columns, fields[i]) + } + } + } + if ps := gq.predicates; len(ps) > 0 { + _spec.Predicate = func(selector *sql.Selector) { + for i := range ps { + ps[i](selector) + } + } + } + if limit := gq.ctx.Limit; limit != nil { + _spec.Limit = *limit + } + if offset := gq.ctx.Offset; offset != nil { + _spec.Offset = *offset + } + if ps := gq.order; len(ps) > 0 { + _spec.Order = func(selector *sql.Selector) { + for i := range ps { + ps[i](selector) + } + } + } + return _spec +} + +func (gq *GuildQuery) sqlQuery(ctx context.Context) *sql.Selector { + builder := sql.Dialect(gq.driver.Dialect()) + t1 := builder.Table(guild.Table) + columns := gq.ctx.Fields + if len(columns) == 0 { + columns = guild.Columns + } + selector := builder.Select(t1.Columns(columns...)...).From(t1) + if gq.sql != nil { + selector = gq.sql + selector.Select(selector.Columns(columns...)...) + } + if gq.ctx.Unique != nil && *gq.ctx.Unique { + selector.Distinct() + } + for _, p := range gq.predicates { + p(selector) + } + for _, p := range gq.order { + p(selector) + } + if offset := gq.ctx.Offset; offset != nil { + // limit is mandatory for offset clause. We start + // with default value, and override it below if needed. + selector.Offset(*offset).Limit(math.MaxInt32) + } + if limit := gq.ctx.Limit; limit != nil { + selector.Limit(*limit) + } + return selector +} + +// GuildGroupBy is the group-by builder for Guild entities. +type GuildGroupBy struct { + selector + build *GuildQuery +} + +// Aggregate adds the given aggregation functions to the group-by query. +func (ggb *GuildGroupBy) Aggregate(fns ...AggregateFunc) *GuildGroupBy { + ggb.fns = append(ggb.fns, fns...) + return ggb +} + +// Scan applies the selector query and scans the result into the given value. +func (ggb *GuildGroupBy) Scan(ctx context.Context, v any) error { + ctx = setContextOp(ctx, ggb.build.ctx, "GroupBy") + if err := ggb.build.prepareQuery(ctx); err != nil { + return err + } + return scanWithInterceptors[*GuildQuery, *GuildGroupBy](ctx, ggb.build, ggb, ggb.build.inters, v) +} + +func (ggb *GuildGroupBy) sqlScan(ctx context.Context, root *GuildQuery, v any) error { + selector := root.sqlQuery(ctx).Select() + aggregation := make([]string, 0, len(ggb.fns)) + for _, fn := range ggb.fns { + aggregation = append(aggregation, fn(selector)) + } + if len(selector.SelectedColumns()) == 0 { + columns := make([]string, 0, len(*ggb.flds)+len(ggb.fns)) + for _, f := range *ggb.flds { + columns = append(columns, selector.C(f)) + } + columns = append(columns, aggregation...) + selector.Select(columns...) + } + selector.GroupBy(selector.Columns(*ggb.flds...)...) + if err := selector.Err(); err != nil { + return err + } + rows := &sql.Rows{} + query, args := selector.Query() + if err := ggb.build.driver.Query(ctx, query, args, rows); err != nil { + return err + } + defer rows.Close() + return sql.ScanSlice(rows, v) +} + +// GuildSelect is the builder for selecting fields of Guild entities. +type GuildSelect struct { + *GuildQuery + selector +} + +// Aggregate adds the given aggregation functions to the selector query. +func (gs *GuildSelect) Aggregate(fns ...AggregateFunc) *GuildSelect { + gs.fns = append(gs.fns, fns...) + return gs +} + +// Scan applies the selector query and scans the result into the given value. +func (gs *GuildSelect) Scan(ctx context.Context, v any) error { + ctx = setContextOp(ctx, gs.ctx, "Select") + if err := gs.prepareQuery(ctx); err != nil { + return err + } + return scanWithInterceptors[*GuildQuery, *GuildSelect](ctx, gs.GuildQuery, gs, gs.inters, v) +} + +func (gs *GuildSelect) sqlScan(ctx context.Context, root *GuildQuery, v any) error { + selector := root.sqlQuery(ctx) + aggregation := make([]string, 0, len(gs.fns)) + for _, fn := range gs.fns { + aggregation = append(aggregation, fn(selector)) + } + switch n := len(*gs.selector.flds); { + case n == 0 && len(aggregation) > 0: + selector.Select(aggregation...) + case n != 0 && len(aggregation) > 0: + selector.AppendSelect(aggregation...) + } + rows := &sql.Rows{} + query, args := selector.Query() + if err := gs.driver.Query(ctx, query, args, rows); err != nil { + return err + } + defer rows.Close() + return sql.ScanSlice(rows, v) +} diff --git a/ent/guild_update.go b/ent/guild_update.go new file mode 100644 index 00000000..588e7780 --- /dev/null +++ b/ent/guild_update.go @@ -0,0 +1,2282 @@ +// Code generated by ent, DO NOT EDIT. + +package ent + +import ( + "context" + "errors" + "fmt" + "time" + + "entgo.io/ent/dialect/sql" + "entgo.io/ent/dialect/sql/sqlgraph" + "entgo.io/ent/dialect/sql/sqljson" + "entgo.io/ent/schema/field" + "github.com/disgoorg/disgo/discord" + snowflake "github.com/disgoorg/snowflake/v2" + "github.com/google/uuid" + "github.com/sabafly/gobot/ent/guild" + "github.com/sabafly/gobot/ent/member" + "github.com/sabafly/gobot/ent/messagepin" + "github.com/sabafly/gobot/ent/messageremind" + "github.com/sabafly/gobot/ent/predicate" + "github.com/sabafly/gobot/ent/rolepanel" + "github.com/sabafly/gobot/ent/rolepaneledit" + "github.com/sabafly/gobot/ent/rolepanelplaced" + "github.com/sabafly/gobot/ent/user" + "github.com/sabafly/gobot/internal/permissions" +) + +// GuildUpdate is the builder for updating Guild entities. +type GuildUpdate struct { + config + hooks []Hook + mutation *GuildMutation +} + +// Where appends a list predicates to the GuildUpdate builder. +func (gu *GuildUpdate) Where(ps ...predicate.Guild) *GuildUpdate { + gu.mutation.Where(ps...) + return gu +} + +// SetName sets the "name" field. +func (gu *GuildUpdate) SetName(s string) *GuildUpdate { + gu.mutation.SetName(s) + return gu +} + +// SetNillableName sets the "name" field if the given value is not nil. +func (gu *GuildUpdate) SetNillableName(s *string) *GuildUpdate { + if s != nil { + gu.SetName(*s) + } + return gu +} + +// SetLocale sets the "locale" field. +func (gu *GuildUpdate) SetLocale(d discord.Locale) *GuildUpdate { + gu.mutation.SetLocale(d) + return gu +} + +// SetNillableLocale sets the "locale" field if the given value is not nil. +func (gu *GuildUpdate) SetNillableLocale(d *discord.Locale) *GuildUpdate { + if d != nil { + gu.SetLocale(*d) + } + return gu +} + +// SetLevelUpMessage sets the "level_up_message" field. +func (gu *GuildUpdate) SetLevelUpMessage(s string) *GuildUpdate { + gu.mutation.SetLevelUpMessage(s) + return gu +} + +// SetNillableLevelUpMessage sets the "level_up_message" field if the given value is not nil. +func (gu *GuildUpdate) SetNillableLevelUpMessage(s *string) *GuildUpdate { + if s != nil { + gu.SetLevelUpMessage(*s) + } + return gu +} + +// SetLevelUpChannel sets the "level_up_channel" field. +func (gu *GuildUpdate) SetLevelUpChannel(s snowflake.ID) *GuildUpdate { + gu.mutation.ResetLevelUpChannel() + gu.mutation.SetLevelUpChannel(s) + return gu +} + +// SetNillableLevelUpChannel sets the "level_up_channel" field if the given value is not nil. +func (gu *GuildUpdate) SetNillableLevelUpChannel(s *snowflake.ID) *GuildUpdate { + if s != nil { + gu.SetLevelUpChannel(*s) + } + return gu +} + +// AddLevelUpChannel adds s to the "level_up_channel" field. +func (gu *GuildUpdate) AddLevelUpChannel(s snowflake.ID) *GuildUpdate { + gu.mutation.AddLevelUpChannel(s) + return gu +} + +// ClearLevelUpChannel clears the value of the "level_up_channel" field. +func (gu *GuildUpdate) ClearLevelUpChannel() *GuildUpdate { + gu.mutation.ClearLevelUpChannel() + return gu +} + +// SetLevelUpExcludeChannel sets the "level_up_exclude_channel" field. +func (gu *GuildUpdate) SetLevelUpExcludeChannel(s []snowflake.ID) *GuildUpdate { + gu.mutation.SetLevelUpExcludeChannel(s) + return gu +} + +// AppendLevelUpExcludeChannel appends s to the "level_up_exclude_channel" field. +func (gu *GuildUpdate) AppendLevelUpExcludeChannel(s []snowflake.ID) *GuildUpdate { + gu.mutation.AppendLevelUpExcludeChannel(s) + return gu +} + +// ClearLevelUpExcludeChannel clears the value of the "level_up_exclude_channel" field. +func (gu *GuildUpdate) ClearLevelUpExcludeChannel() *GuildUpdate { + gu.mutation.ClearLevelUpExcludeChannel() + return gu +} + +// SetLevelMee6Imported sets the "level_mee6_imported" field. +func (gu *GuildUpdate) SetLevelMee6Imported(b bool) *GuildUpdate { + gu.mutation.SetLevelMee6Imported(b) + return gu +} + +// SetNillableLevelMee6Imported sets the "level_mee6_imported" field if the given value is not nil. +func (gu *GuildUpdate) SetNillableLevelMee6Imported(b *bool) *GuildUpdate { + if b != nil { + gu.SetLevelMee6Imported(*b) + } + return gu +} + +// SetLevelRole sets the "level_role" field. +func (gu *GuildUpdate) SetLevelRole(m map[int]snowflake.ID) *GuildUpdate { + gu.mutation.SetLevelRole(m) + return gu +} + +// ClearLevelRole clears the value of the "level_role" field. +func (gu *GuildUpdate) ClearLevelRole() *GuildUpdate { + gu.mutation.ClearLevelRole() + return gu +} + +// SetPermissions sets the "permissions" field. +func (gu *GuildUpdate) SetPermissions(m map[snowflake.ID]permissions.Permission) *GuildUpdate { + gu.mutation.SetPermissions(m) + return gu +} + +// SetRemindCount sets the "remind_count" field. +func (gu *GuildUpdate) SetRemindCount(i int) *GuildUpdate { + gu.mutation.ResetRemindCount() + gu.mutation.SetRemindCount(i) + return gu +} + +// SetNillableRemindCount sets the "remind_count" field if the given value is not nil. +func (gu *GuildUpdate) SetNillableRemindCount(i *int) *GuildUpdate { + if i != nil { + gu.SetRemindCount(*i) + } + return gu +} + +// AddRemindCount adds i to the "remind_count" field. +func (gu *GuildUpdate) AddRemindCount(i int) *GuildUpdate { + gu.mutation.AddRemindCount(i) + return gu +} + +// SetRolePanelEditTimes sets the "role_panel_edit_times" field. +func (gu *GuildUpdate) SetRolePanelEditTimes(t []time.Time) *GuildUpdate { + gu.mutation.SetRolePanelEditTimes(t) + return gu +} + +// AppendRolePanelEditTimes appends t to the "role_panel_edit_times" field. +func (gu *GuildUpdate) AppendRolePanelEditTimes(t []time.Time) *GuildUpdate { + gu.mutation.AppendRolePanelEditTimes(t) + return gu +} + +// SetBumpEnabled sets the "bump_enabled" field. +func (gu *GuildUpdate) SetBumpEnabled(b bool) *GuildUpdate { + gu.mutation.SetBumpEnabled(b) + return gu +} + +// SetNillableBumpEnabled sets the "bump_enabled" field if the given value is not nil. +func (gu *GuildUpdate) SetNillableBumpEnabled(b *bool) *GuildUpdate { + if b != nil { + gu.SetBumpEnabled(*b) + } + return gu +} + +// SetBumpMessageTitle sets the "bump_message_title" field. +func (gu *GuildUpdate) SetBumpMessageTitle(s string) *GuildUpdate { + gu.mutation.SetBumpMessageTitle(s) + return gu +} + +// SetNillableBumpMessageTitle sets the "bump_message_title" field if the given value is not nil. +func (gu *GuildUpdate) SetNillableBumpMessageTitle(s *string) *GuildUpdate { + if s != nil { + gu.SetBumpMessageTitle(*s) + } + return gu +} + +// SetBumpMessage sets the "bump_message" field. +func (gu *GuildUpdate) SetBumpMessage(s string) *GuildUpdate { + gu.mutation.SetBumpMessage(s) + return gu +} + +// SetNillableBumpMessage sets the "bump_message" field if the given value is not nil. +func (gu *GuildUpdate) SetNillableBumpMessage(s *string) *GuildUpdate { + if s != nil { + gu.SetBumpMessage(*s) + } + return gu +} + +// SetBumpRemindMessageTitle sets the "bump_remind_message_title" field. +func (gu *GuildUpdate) SetBumpRemindMessageTitle(s string) *GuildUpdate { + gu.mutation.SetBumpRemindMessageTitle(s) + return gu +} + +// SetNillableBumpRemindMessageTitle sets the "bump_remind_message_title" field if the given value is not nil. +func (gu *GuildUpdate) SetNillableBumpRemindMessageTitle(s *string) *GuildUpdate { + if s != nil { + gu.SetBumpRemindMessageTitle(*s) + } + return gu +} + +// SetBumpRemindMessage sets the "bump_remind_message" field. +func (gu *GuildUpdate) SetBumpRemindMessage(s string) *GuildUpdate { + gu.mutation.SetBumpRemindMessage(s) + return gu +} + +// SetNillableBumpRemindMessage sets the "bump_remind_message" field if the given value is not nil. +func (gu *GuildUpdate) SetNillableBumpRemindMessage(s *string) *GuildUpdate { + if s != nil { + gu.SetBumpRemindMessage(*s) + } + return gu +} + +// SetUpEnabled sets the "up_enabled" field. +func (gu *GuildUpdate) SetUpEnabled(b bool) *GuildUpdate { + gu.mutation.SetUpEnabled(b) + return gu +} + +// SetNillableUpEnabled sets the "up_enabled" field if the given value is not nil. +func (gu *GuildUpdate) SetNillableUpEnabled(b *bool) *GuildUpdate { + if b != nil { + gu.SetUpEnabled(*b) + } + return gu +} + +// SetUpMessageTitle sets the "up_message_title" field. +func (gu *GuildUpdate) SetUpMessageTitle(s string) *GuildUpdate { + gu.mutation.SetUpMessageTitle(s) + return gu +} + +// SetNillableUpMessageTitle sets the "up_message_title" field if the given value is not nil. +func (gu *GuildUpdate) SetNillableUpMessageTitle(s *string) *GuildUpdate { + if s != nil { + gu.SetUpMessageTitle(*s) + } + return gu +} + +// SetUpMessage sets the "up_message" field. +func (gu *GuildUpdate) SetUpMessage(s string) *GuildUpdate { + gu.mutation.SetUpMessage(s) + return gu +} + +// SetNillableUpMessage sets the "up_message" field if the given value is not nil. +func (gu *GuildUpdate) SetNillableUpMessage(s *string) *GuildUpdate { + if s != nil { + gu.SetUpMessage(*s) + } + return gu +} + +// SetUpRemindMessageTitle sets the "up_remind_message_title" field. +func (gu *GuildUpdate) SetUpRemindMessageTitle(s string) *GuildUpdate { + gu.mutation.SetUpRemindMessageTitle(s) + return gu +} + +// SetNillableUpRemindMessageTitle sets the "up_remind_message_title" field if the given value is not nil. +func (gu *GuildUpdate) SetNillableUpRemindMessageTitle(s *string) *GuildUpdate { + if s != nil { + gu.SetUpRemindMessageTitle(*s) + } + return gu +} + +// SetUpRemindMessage sets the "up_remind_message" field. +func (gu *GuildUpdate) SetUpRemindMessage(s string) *GuildUpdate { + gu.mutation.SetUpRemindMessage(s) + return gu +} + +// SetNillableUpRemindMessage sets the "up_remind_message" field if the given value is not nil. +func (gu *GuildUpdate) SetNillableUpRemindMessage(s *string) *GuildUpdate { + if s != nil { + gu.SetUpRemindMessage(*s) + } + return gu +} + +// SetBumpMention sets the "bump_mention" field. +func (gu *GuildUpdate) SetBumpMention(s snowflake.ID) *GuildUpdate { + gu.mutation.ResetBumpMention() + gu.mutation.SetBumpMention(s) + return gu +} + +// SetNillableBumpMention sets the "bump_mention" field if the given value is not nil. +func (gu *GuildUpdate) SetNillableBumpMention(s *snowflake.ID) *GuildUpdate { + if s != nil { + gu.SetBumpMention(*s) + } + return gu +} + +// AddBumpMention adds s to the "bump_mention" field. +func (gu *GuildUpdate) AddBumpMention(s snowflake.ID) *GuildUpdate { + gu.mutation.AddBumpMention(s) + return gu +} + +// ClearBumpMention clears the value of the "bump_mention" field. +func (gu *GuildUpdate) ClearBumpMention() *GuildUpdate { + gu.mutation.ClearBumpMention() + return gu +} + +// SetUpMention sets the "up_mention" field. +func (gu *GuildUpdate) SetUpMention(s snowflake.ID) *GuildUpdate { + gu.mutation.ResetUpMention() + gu.mutation.SetUpMention(s) + return gu +} + +// SetNillableUpMention sets the "up_mention" field if the given value is not nil. +func (gu *GuildUpdate) SetNillableUpMention(s *snowflake.ID) *GuildUpdate { + if s != nil { + gu.SetUpMention(*s) + } + return gu +} + +// AddUpMention adds s to the "up_mention" field. +func (gu *GuildUpdate) AddUpMention(s snowflake.ID) *GuildUpdate { + gu.mutation.AddUpMention(s) + return gu +} + +// ClearUpMention clears the value of the "up_mention" field. +func (gu *GuildUpdate) ClearUpMention() *GuildUpdate { + gu.mutation.ClearUpMention() + return gu +} + +// SetOwnerID sets the "owner" edge to the User entity by ID. +func (gu *GuildUpdate) SetOwnerID(id snowflake.ID) *GuildUpdate { + gu.mutation.SetOwnerID(id) + return gu +} + +// SetOwner sets the "owner" edge to the User entity. +func (gu *GuildUpdate) SetOwner(u *User) *GuildUpdate { + return gu.SetOwnerID(u.ID) +} + +// AddMemberIDs adds the "members" edge to the Member entity by IDs. +func (gu *GuildUpdate) AddMemberIDs(ids ...int) *GuildUpdate { + gu.mutation.AddMemberIDs(ids...) + return gu +} + +// AddMembers adds the "members" edges to the Member entity. +func (gu *GuildUpdate) AddMembers(m ...*Member) *GuildUpdate { + ids := make([]int, len(m)) + for i := range m { + ids[i] = m[i].ID + } + return gu.AddMemberIDs(ids...) +} + +// AddMessagePinIDs adds the "message_pins" edge to the MessagePin entity by IDs. +func (gu *GuildUpdate) AddMessagePinIDs(ids ...uuid.UUID) *GuildUpdate { + gu.mutation.AddMessagePinIDs(ids...) + return gu +} + +// AddMessagePins adds the "message_pins" edges to the MessagePin entity. +func (gu *GuildUpdate) AddMessagePins(m ...*MessagePin) *GuildUpdate { + ids := make([]uuid.UUID, len(m)) + for i := range m { + ids[i] = m[i].ID + } + return gu.AddMessagePinIDs(ids...) +} + +// AddRemindIDs adds the "reminds" edge to the MessageRemind entity by IDs. +func (gu *GuildUpdate) AddRemindIDs(ids ...uuid.UUID) *GuildUpdate { + gu.mutation.AddRemindIDs(ids...) + return gu +} + +// AddReminds adds the "reminds" edges to the MessageRemind entity. +func (gu *GuildUpdate) AddReminds(m ...*MessageRemind) *GuildUpdate { + ids := make([]uuid.UUID, len(m)) + for i := range m { + ids[i] = m[i].ID + } + return gu.AddRemindIDs(ids...) +} + +// AddRolePanelIDs adds the "role_panels" edge to the RolePanel entity by IDs. +func (gu *GuildUpdate) AddRolePanelIDs(ids ...uuid.UUID) *GuildUpdate { + gu.mutation.AddRolePanelIDs(ids...) + return gu +} + +// AddRolePanels adds the "role_panels" edges to the RolePanel entity. +func (gu *GuildUpdate) AddRolePanels(r ...*RolePanel) *GuildUpdate { + ids := make([]uuid.UUID, len(r)) + for i := range r { + ids[i] = r[i].ID + } + return gu.AddRolePanelIDs(ids...) +} + +// AddRolePanelPlacementIDs adds the "role_panel_placements" edge to the RolePanelPlaced entity by IDs. +func (gu *GuildUpdate) AddRolePanelPlacementIDs(ids ...uuid.UUID) *GuildUpdate { + gu.mutation.AddRolePanelPlacementIDs(ids...) + return gu +} + +// AddRolePanelPlacements adds the "role_panel_placements" edges to the RolePanelPlaced entity. +func (gu *GuildUpdate) AddRolePanelPlacements(r ...*RolePanelPlaced) *GuildUpdate { + ids := make([]uuid.UUID, len(r)) + for i := range r { + ids[i] = r[i].ID + } + return gu.AddRolePanelPlacementIDs(ids...) +} + +// AddRolePanelEditIDs adds the "role_panel_edits" edge to the RolePanelEdit entity by IDs. +func (gu *GuildUpdate) AddRolePanelEditIDs(ids ...uuid.UUID) *GuildUpdate { + gu.mutation.AddRolePanelEditIDs(ids...) + return gu +} + +// AddRolePanelEdits adds the "role_panel_edits" edges to the RolePanelEdit entity. +func (gu *GuildUpdate) AddRolePanelEdits(r ...*RolePanelEdit) *GuildUpdate { + ids := make([]uuid.UUID, len(r)) + for i := range r { + ids[i] = r[i].ID + } + return gu.AddRolePanelEditIDs(ids...) +} + +// Mutation returns the GuildMutation object of the builder. +func (gu *GuildUpdate) Mutation() *GuildMutation { + return gu.mutation +} + +// ClearOwner clears the "owner" edge to the User entity. +func (gu *GuildUpdate) ClearOwner() *GuildUpdate { + gu.mutation.ClearOwner() + return gu +} + +// ClearMembers clears all "members" edges to the Member entity. +func (gu *GuildUpdate) ClearMembers() *GuildUpdate { + gu.mutation.ClearMembers() + return gu +} + +// RemoveMemberIDs removes the "members" edge to Member entities by IDs. +func (gu *GuildUpdate) RemoveMemberIDs(ids ...int) *GuildUpdate { + gu.mutation.RemoveMemberIDs(ids...) + return gu +} + +// RemoveMembers removes "members" edges to Member entities. +func (gu *GuildUpdate) RemoveMembers(m ...*Member) *GuildUpdate { + ids := make([]int, len(m)) + for i := range m { + ids[i] = m[i].ID + } + return gu.RemoveMemberIDs(ids...) +} + +// ClearMessagePins clears all "message_pins" edges to the MessagePin entity. +func (gu *GuildUpdate) ClearMessagePins() *GuildUpdate { + gu.mutation.ClearMessagePins() + return gu +} + +// RemoveMessagePinIDs removes the "message_pins" edge to MessagePin entities by IDs. +func (gu *GuildUpdate) RemoveMessagePinIDs(ids ...uuid.UUID) *GuildUpdate { + gu.mutation.RemoveMessagePinIDs(ids...) + return gu +} + +// RemoveMessagePins removes "message_pins" edges to MessagePin entities. +func (gu *GuildUpdate) RemoveMessagePins(m ...*MessagePin) *GuildUpdate { + ids := make([]uuid.UUID, len(m)) + for i := range m { + ids[i] = m[i].ID + } + return gu.RemoveMessagePinIDs(ids...) +} + +// ClearReminds clears all "reminds" edges to the MessageRemind entity. +func (gu *GuildUpdate) ClearReminds() *GuildUpdate { + gu.mutation.ClearReminds() + return gu +} + +// RemoveRemindIDs removes the "reminds" edge to MessageRemind entities by IDs. +func (gu *GuildUpdate) RemoveRemindIDs(ids ...uuid.UUID) *GuildUpdate { + gu.mutation.RemoveRemindIDs(ids...) + return gu +} + +// RemoveReminds removes "reminds" edges to MessageRemind entities. +func (gu *GuildUpdate) RemoveReminds(m ...*MessageRemind) *GuildUpdate { + ids := make([]uuid.UUID, len(m)) + for i := range m { + ids[i] = m[i].ID + } + return gu.RemoveRemindIDs(ids...) +} + +// ClearRolePanels clears all "role_panels" edges to the RolePanel entity. +func (gu *GuildUpdate) ClearRolePanels() *GuildUpdate { + gu.mutation.ClearRolePanels() + return gu +} + +// RemoveRolePanelIDs removes the "role_panels" edge to RolePanel entities by IDs. +func (gu *GuildUpdate) RemoveRolePanelIDs(ids ...uuid.UUID) *GuildUpdate { + gu.mutation.RemoveRolePanelIDs(ids...) + return gu +} + +// RemoveRolePanels removes "role_panels" edges to RolePanel entities. +func (gu *GuildUpdate) RemoveRolePanels(r ...*RolePanel) *GuildUpdate { + ids := make([]uuid.UUID, len(r)) + for i := range r { + ids[i] = r[i].ID + } + return gu.RemoveRolePanelIDs(ids...) +} + +// ClearRolePanelPlacements clears all "role_panel_placements" edges to the RolePanelPlaced entity. +func (gu *GuildUpdate) ClearRolePanelPlacements() *GuildUpdate { + gu.mutation.ClearRolePanelPlacements() + return gu +} + +// RemoveRolePanelPlacementIDs removes the "role_panel_placements" edge to RolePanelPlaced entities by IDs. +func (gu *GuildUpdate) RemoveRolePanelPlacementIDs(ids ...uuid.UUID) *GuildUpdate { + gu.mutation.RemoveRolePanelPlacementIDs(ids...) + return gu +} + +// RemoveRolePanelPlacements removes "role_panel_placements" edges to RolePanelPlaced entities. +func (gu *GuildUpdate) RemoveRolePanelPlacements(r ...*RolePanelPlaced) *GuildUpdate { + ids := make([]uuid.UUID, len(r)) + for i := range r { + ids[i] = r[i].ID + } + return gu.RemoveRolePanelPlacementIDs(ids...) +} + +// ClearRolePanelEdits clears all "role_panel_edits" edges to the RolePanelEdit entity. +func (gu *GuildUpdate) ClearRolePanelEdits() *GuildUpdate { + gu.mutation.ClearRolePanelEdits() + return gu +} + +// RemoveRolePanelEditIDs removes the "role_panel_edits" edge to RolePanelEdit entities by IDs. +func (gu *GuildUpdate) RemoveRolePanelEditIDs(ids ...uuid.UUID) *GuildUpdate { + gu.mutation.RemoveRolePanelEditIDs(ids...) + return gu +} + +// RemoveRolePanelEdits removes "role_panel_edits" edges to RolePanelEdit entities. +func (gu *GuildUpdate) RemoveRolePanelEdits(r ...*RolePanelEdit) *GuildUpdate { + ids := make([]uuid.UUID, len(r)) + for i := range r { + ids[i] = r[i].ID + } + return gu.RemoveRolePanelEditIDs(ids...) +} + +// Save executes the query and returns the number of nodes affected by the update operation. +func (gu *GuildUpdate) Save(ctx context.Context) (int, error) { + return withHooks(ctx, gu.sqlSave, gu.mutation, gu.hooks) +} + +// SaveX is like Save, but panics if an error occurs. +func (gu *GuildUpdate) SaveX(ctx context.Context) int { + affected, err := gu.Save(ctx) + if err != nil { + panic(err) + } + return affected +} + +// Exec executes the query. +func (gu *GuildUpdate) Exec(ctx context.Context) error { + _, err := gu.Save(ctx) + return err +} + +// ExecX is like Exec, but panics if an error occurs. +func (gu *GuildUpdate) ExecX(ctx context.Context) { + if err := gu.Exec(ctx); err != nil { + panic(err) + } +} + +// check runs all checks and user-defined validators on the builder. +func (gu *GuildUpdate) check() error { + if v, ok := gu.mutation.Name(); ok { + if err := guild.NameValidator(v); err != nil { + return &ValidationError{Name: "name", err: fmt.Errorf(`ent: validator failed for field "Guild.name": %w`, err)} + } + } + if v, ok := gu.mutation.Locale(); ok { + if err := guild.LocaleValidator(string(v)); err != nil { + return &ValidationError{Name: "locale", err: fmt.Errorf(`ent: validator failed for field "Guild.locale": %w`, err)} + } + } + if v, ok := gu.mutation.LevelUpMessage(); ok { + if err := guild.LevelUpMessageValidator(v); err != nil { + return &ValidationError{Name: "level_up_message", err: fmt.Errorf(`ent: validator failed for field "Guild.level_up_message": %w`, err)} + } + } + if v, ok := gu.mutation.BumpMessageTitle(); ok { + if err := guild.BumpMessageTitleValidator(v); err != nil { + return &ValidationError{Name: "bump_message_title", err: fmt.Errorf(`ent: validator failed for field "Guild.bump_message_title": %w`, err)} + } + } + if v, ok := gu.mutation.BumpMessage(); ok { + if err := guild.BumpMessageValidator(v); err != nil { + return &ValidationError{Name: "bump_message", err: fmt.Errorf(`ent: validator failed for field "Guild.bump_message": %w`, err)} + } + } + if v, ok := gu.mutation.BumpRemindMessageTitle(); ok { + if err := guild.BumpRemindMessageTitleValidator(v); err != nil { + return &ValidationError{Name: "bump_remind_message_title", err: fmt.Errorf(`ent: validator failed for field "Guild.bump_remind_message_title": %w`, err)} + } + } + if v, ok := gu.mutation.BumpRemindMessage(); ok { + if err := guild.BumpRemindMessageValidator(v); err != nil { + return &ValidationError{Name: "bump_remind_message", err: fmt.Errorf(`ent: validator failed for field "Guild.bump_remind_message": %w`, err)} + } + } + if v, ok := gu.mutation.UpMessageTitle(); ok { + if err := guild.UpMessageTitleValidator(v); err != nil { + return &ValidationError{Name: "up_message_title", err: fmt.Errorf(`ent: validator failed for field "Guild.up_message_title": %w`, err)} + } + } + if v, ok := gu.mutation.UpMessage(); ok { + if err := guild.UpMessageValidator(v); err != nil { + return &ValidationError{Name: "up_message", err: fmt.Errorf(`ent: validator failed for field "Guild.up_message": %w`, err)} + } + } + if v, ok := gu.mutation.UpRemindMessageTitle(); ok { + if err := guild.UpRemindMessageTitleValidator(v); err != nil { + return &ValidationError{Name: "up_remind_message_title", err: fmt.Errorf(`ent: validator failed for field "Guild.up_remind_message_title": %w`, err)} + } + } + if v, ok := gu.mutation.UpRemindMessage(); ok { + if err := guild.UpRemindMessageValidator(v); err != nil { + return &ValidationError{Name: "up_remind_message", err: fmt.Errorf(`ent: validator failed for field "Guild.up_remind_message": %w`, err)} + } + } + if _, ok := gu.mutation.OwnerID(); gu.mutation.OwnerCleared() && !ok { + return errors.New(`ent: clearing a required unique edge "Guild.owner"`) + } + return nil +} + +func (gu *GuildUpdate) sqlSave(ctx context.Context) (n int, err error) { + if err := gu.check(); err != nil { + return n, err + } + _spec := sqlgraph.NewUpdateSpec(guild.Table, guild.Columns, sqlgraph.NewFieldSpec(guild.FieldID, field.TypeUint64)) + if ps := gu.mutation.predicates; len(ps) > 0 { + _spec.Predicate = func(selector *sql.Selector) { + for i := range ps { + ps[i](selector) + } + } + } + if value, ok := gu.mutation.Name(); ok { + _spec.SetField(guild.FieldName, field.TypeString, value) + } + if value, ok := gu.mutation.Locale(); ok { + _spec.SetField(guild.FieldLocale, field.TypeString, value) + } + if value, ok := gu.mutation.LevelUpMessage(); ok { + _spec.SetField(guild.FieldLevelUpMessage, field.TypeString, value) + } + if value, ok := gu.mutation.LevelUpChannel(); ok { + _spec.SetField(guild.FieldLevelUpChannel, field.TypeUint64, value) + } + if value, ok := gu.mutation.AddedLevelUpChannel(); ok { + _spec.AddField(guild.FieldLevelUpChannel, field.TypeUint64, value) + } + if gu.mutation.LevelUpChannelCleared() { + _spec.ClearField(guild.FieldLevelUpChannel, field.TypeUint64) + } + if value, ok := gu.mutation.LevelUpExcludeChannel(); ok { + _spec.SetField(guild.FieldLevelUpExcludeChannel, field.TypeJSON, value) + } + if value, ok := gu.mutation.AppendedLevelUpExcludeChannel(); ok { + _spec.AddModifier(func(u *sql.UpdateBuilder) { + sqljson.Append(u, guild.FieldLevelUpExcludeChannel, value) + }) + } + if gu.mutation.LevelUpExcludeChannelCleared() { + _spec.ClearField(guild.FieldLevelUpExcludeChannel, field.TypeJSON) + } + if value, ok := gu.mutation.LevelMee6Imported(); ok { + _spec.SetField(guild.FieldLevelMee6Imported, field.TypeBool, value) + } + if value, ok := gu.mutation.LevelRole(); ok { + _spec.SetField(guild.FieldLevelRole, field.TypeJSON, value) + } + if gu.mutation.LevelRoleCleared() { + _spec.ClearField(guild.FieldLevelRole, field.TypeJSON) + } + if value, ok := gu.mutation.Permissions(); ok { + _spec.SetField(guild.FieldPermissions, field.TypeJSON, value) + } + if value, ok := gu.mutation.RemindCount(); ok { + _spec.SetField(guild.FieldRemindCount, field.TypeInt, value) + } + if value, ok := gu.mutation.AddedRemindCount(); ok { + _spec.AddField(guild.FieldRemindCount, field.TypeInt, value) + } + if value, ok := gu.mutation.RolePanelEditTimes(); ok { + _spec.SetField(guild.FieldRolePanelEditTimes, field.TypeJSON, value) + } + if value, ok := gu.mutation.AppendedRolePanelEditTimes(); ok { + _spec.AddModifier(func(u *sql.UpdateBuilder) { + sqljson.Append(u, guild.FieldRolePanelEditTimes, value) + }) + } + if value, ok := gu.mutation.BumpEnabled(); ok { + _spec.SetField(guild.FieldBumpEnabled, field.TypeBool, value) + } + if value, ok := gu.mutation.BumpMessageTitle(); ok { + _spec.SetField(guild.FieldBumpMessageTitle, field.TypeString, value) + } + if value, ok := gu.mutation.BumpMessage(); ok { + _spec.SetField(guild.FieldBumpMessage, field.TypeString, value) + } + if value, ok := gu.mutation.BumpRemindMessageTitle(); ok { + _spec.SetField(guild.FieldBumpRemindMessageTitle, field.TypeString, value) + } + if value, ok := gu.mutation.BumpRemindMessage(); ok { + _spec.SetField(guild.FieldBumpRemindMessage, field.TypeString, value) + } + if value, ok := gu.mutation.UpEnabled(); ok { + _spec.SetField(guild.FieldUpEnabled, field.TypeBool, value) + } + if value, ok := gu.mutation.UpMessageTitle(); ok { + _spec.SetField(guild.FieldUpMessageTitle, field.TypeString, value) + } + if value, ok := gu.mutation.UpMessage(); ok { + _spec.SetField(guild.FieldUpMessage, field.TypeString, value) + } + if value, ok := gu.mutation.UpRemindMessageTitle(); ok { + _spec.SetField(guild.FieldUpRemindMessageTitle, field.TypeString, value) + } + if value, ok := gu.mutation.UpRemindMessage(); ok { + _spec.SetField(guild.FieldUpRemindMessage, field.TypeString, value) + } + if value, ok := gu.mutation.BumpMention(); ok { + _spec.SetField(guild.FieldBumpMention, field.TypeUint64, value) + } + if value, ok := gu.mutation.AddedBumpMention(); ok { + _spec.AddField(guild.FieldBumpMention, field.TypeUint64, value) + } + if gu.mutation.BumpMentionCleared() { + _spec.ClearField(guild.FieldBumpMention, field.TypeUint64) + } + if value, ok := gu.mutation.UpMention(); ok { + _spec.SetField(guild.FieldUpMention, field.TypeUint64, value) + } + if value, ok := gu.mutation.AddedUpMention(); ok { + _spec.AddField(guild.FieldUpMention, field.TypeUint64, value) + } + if gu.mutation.UpMentionCleared() { + _spec.ClearField(guild.FieldUpMention, field.TypeUint64) + } + if gu.mutation.OwnerCleared() { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.M2O, + Inverse: true, + Table: guild.OwnerTable, + Columns: []string{guild.OwnerColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(user.FieldID, field.TypeUint64), + }, + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := gu.mutation.OwnerIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.M2O, + Inverse: true, + Table: guild.OwnerTable, + Columns: []string{guild.OwnerColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(user.FieldID, field.TypeUint64), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Add = append(_spec.Edges.Add, edge) + } + if gu.mutation.MembersCleared() { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: false, + Table: guild.MembersTable, + Columns: []string{guild.MembersColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(member.FieldID, field.TypeInt), + }, + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := gu.mutation.RemovedMembersIDs(); len(nodes) > 0 && !gu.mutation.MembersCleared() { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: false, + Table: guild.MembersTable, + Columns: []string{guild.MembersColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(member.FieldID, field.TypeInt), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := gu.mutation.MembersIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: false, + Table: guild.MembersTable, + Columns: []string{guild.MembersColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(member.FieldID, field.TypeInt), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Add = append(_spec.Edges.Add, edge) + } + if gu.mutation.MessagePinsCleared() { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: false, + Table: guild.MessagePinsTable, + Columns: []string{guild.MessagePinsColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(messagepin.FieldID, field.TypeUUID), + }, + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := gu.mutation.RemovedMessagePinsIDs(); len(nodes) > 0 && !gu.mutation.MessagePinsCleared() { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: false, + Table: guild.MessagePinsTable, + Columns: []string{guild.MessagePinsColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(messagepin.FieldID, field.TypeUUID), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := gu.mutation.MessagePinsIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: false, + Table: guild.MessagePinsTable, + Columns: []string{guild.MessagePinsColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(messagepin.FieldID, field.TypeUUID), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Add = append(_spec.Edges.Add, edge) + } + if gu.mutation.RemindsCleared() { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: false, + Table: guild.RemindsTable, + Columns: []string{guild.RemindsColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(messageremind.FieldID, field.TypeUUID), + }, + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := gu.mutation.RemovedRemindsIDs(); len(nodes) > 0 && !gu.mutation.RemindsCleared() { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: false, + Table: guild.RemindsTable, + Columns: []string{guild.RemindsColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(messageremind.FieldID, field.TypeUUID), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := gu.mutation.RemindsIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: false, + Table: guild.RemindsTable, + Columns: []string{guild.RemindsColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(messageremind.FieldID, field.TypeUUID), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Add = append(_spec.Edges.Add, edge) + } + if gu.mutation.RolePanelsCleared() { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: false, + Table: guild.RolePanelsTable, + Columns: []string{guild.RolePanelsColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(rolepanel.FieldID, field.TypeUUID), + }, + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := gu.mutation.RemovedRolePanelsIDs(); len(nodes) > 0 && !gu.mutation.RolePanelsCleared() { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: false, + Table: guild.RolePanelsTable, + Columns: []string{guild.RolePanelsColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(rolepanel.FieldID, field.TypeUUID), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := gu.mutation.RolePanelsIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: false, + Table: guild.RolePanelsTable, + Columns: []string{guild.RolePanelsColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(rolepanel.FieldID, field.TypeUUID), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Add = append(_spec.Edges.Add, edge) + } + if gu.mutation.RolePanelPlacementsCleared() { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: false, + Table: guild.RolePanelPlacementsTable, + Columns: []string{guild.RolePanelPlacementsColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(rolepanelplaced.FieldID, field.TypeUUID), + }, + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := gu.mutation.RemovedRolePanelPlacementsIDs(); len(nodes) > 0 && !gu.mutation.RolePanelPlacementsCleared() { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: false, + Table: guild.RolePanelPlacementsTable, + Columns: []string{guild.RolePanelPlacementsColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(rolepanelplaced.FieldID, field.TypeUUID), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := gu.mutation.RolePanelPlacementsIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: false, + Table: guild.RolePanelPlacementsTable, + Columns: []string{guild.RolePanelPlacementsColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(rolepanelplaced.FieldID, field.TypeUUID), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Add = append(_spec.Edges.Add, edge) + } + if gu.mutation.RolePanelEditsCleared() { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: false, + Table: guild.RolePanelEditsTable, + Columns: []string{guild.RolePanelEditsColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(rolepaneledit.FieldID, field.TypeUUID), + }, + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := gu.mutation.RemovedRolePanelEditsIDs(); len(nodes) > 0 && !gu.mutation.RolePanelEditsCleared() { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: false, + Table: guild.RolePanelEditsTable, + Columns: []string{guild.RolePanelEditsColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(rolepaneledit.FieldID, field.TypeUUID), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := gu.mutation.RolePanelEditsIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: false, + Table: guild.RolePanelEditsTable, + Columns: []string{guild.RolePanelEditsColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(rolepaneledit.FieldID, field.TypeUUID), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Add = append(_spec.Edges.Add, edge) + } + if n, err = sqlgraph.UpdateNodes(ctx, gu.driver, _spec); err != nil { + if _, ok := err.(*sqlgraph.NotFoundError); ok { + err = &NotFoundError{guild.Label} + } else if sqlgraph.IsConstraintError(err) { + err = &ConstraintError{msg: err.Error(), wrap: err} + } + return 0, err + } + gu.mutation.done = true + return n, nil +} + +// GuildUpdateOne is the builder for updating a single Guild entity. +type GuildUpdateOne struct { + config + fields []string + hooks []Hook + mutation *GuildMutation +} + +// SetName sets the "name" field. +func (guo *GuildUpdateOne) SetName(s string) *GuildUpdateOne { + guo.mutation.SetName(s) + return guo +} + +// SetNillableName sets the "name" field if the given value is not nil. +func (guo *GuildUpdateOne) SetNillableName(s *string) *GuildUpdateOne { + if s != nil { + guo.SetName(*s) + } + return guo +} + +// SetLocale sets the "locale" field. +func (guo *GuildUpdateOne) SetLocale(d discord.Locale) *GuildUpdateOne { + guo.mutation.SetLocale(d) + return guo +} + +// SetNillableLocale sets the "locale" field if the given value is not nil. +func (guo *GuildUpdateOne) SetNillableLocale(d *discord.Locale) *GuildUpdateOne { + if d != nil { + guo.SetLocale(*d) + } + return guo +} + +// SetLevelUpMessage sets the "level_up_message" field. +func (guo *GuildUpdateOne) SetLevelUpMessage(s string) *GuildUpdateOne { + guo.mutation.SetLevelUpMessage(s) + return guo +} + +// SetNillableLevelUpMessage sets the "level_up_message" field if the given value is not nil. +func (guo *GuildUpdateOne) SetNillableLevelUpMessage(s *string) *GuildUpdateOne { + if s != nil { + guo.SetLevelUpMessage(*s) + } + return guo +} + +// SetLevelUpChannel sets the "level_up_channel" field. +func (guo *GuildUpdateOne) SetLevelUpChannel(s snowflake.ID) *GuildUpdateOne { + guo.mutation.ResetLevelUpChannel() + guo.mutation.SetLevelUpChannel(s) + return guo +} + +// SetNillableLevelUpChannel sets the "level_up_channel" field if the given value is not nil. +func (guo *GuildUpdateOne) SetNillableLevelUpChannel(s *snowflake.ID) *GuildUpdateOne { + if s != nil { + guo.SetLevelUpChannel(*s) + } + return guo +} + +// AddLevelUpChannel adds s to the "level_up_channel" field. +func (guo *GuildUpdateOne) AddLevelUpChannel(s snowflake.ID) *GuildUpdateOne { + guo.mutation.AddLevelUpChannel(s) + return guo +} + +// ClearLevelUpChannel clears the value of the "level_up_channel" field. +func (guo *GuildUpdateOne) ClearLevelUpChannel() *GuildUpdateOne { + guo.mutation.ClearLevelUpChannel() + return guo +} + +// SetLevelUpExcludeChannel sets the "level_up_exclude_channel" field. +func (guo *GuildUpdateOne) SetLevelUpExcludeChannel(s []snowflake.ID) *GuildUpdateOne { + guo.mutation.SetLevelUpExcludeChannel(s) + return guo +} + +// AppendLevelUpExcludeChannel appends s to the "level_up_exclude_channel" field. +func (guo *GuildUpdateOne) AppendLevelUpExcludeChannel(s []snowflake.ID) *GuildUpdateOne { + guo.mutation.AppendLevelUpExcludeChannel(s) + return guo +} + +// ClearLevelUpExcludeChannel clears the value of the "level_up_exclude_channel" field. +func (guo *GuildUpdateOne) ClearLevelUpExcludeChannel() *GuildUpdateOne { + guo.mutation.ClearLevelUpExcludeChannel() + return guo +} + +// SetLevelMee6Imported sets the "level_mee6_imported" field. +func (guo *GuildUpdateOne) SetLevelMee6Imported(b bool) *GuildUpdateOne { + guo.mutation.SetLevelMee6Imported(b) + return guo +} + +// SetNillableLevelMee6Imported sets the "level_mee6_imported" field if the given value is not nil. +func (guo *GuildUpdateOne) SetNillableLevelMee6Imported(b *bool) *GuildUpdateOne { + if b != nil { + guo.SetLevelMee6Imported(*b) + } + return guo +} + +// SetLevelRole sets the "level_role" field. +func (guo *GuildUpdateOne) SetLevelRole(m map[int]snowflake.ID) *GuildUpdateOne { + guo.mutation.SetLevelRole(m) + return guo +} + +// ClearLevelRole clears the value of the "level_role" field. +func (guo *GuildUpdateOne) ClearLevelRole() *GuildUpdateOne { + guo.mutation.ClearLevelRole() + return guo +} + +// SetPermissions sets the "permissions" field. +func (guo *GuildUpdateOne) SetPermissions(m map[snowflake.ID]permissions.Permission) *GuildUpdateOne { + guo.mutation.SetPermissions(m) + return guo +} + +// SetRemindCount sets the "remind_count" field. +func (guo *GuildUpdateOne) SetRemindCount(i int) *GuildUpdateOne { + guo.mutation.ResetRemindCount() + guo.mutation.SetRemindCount(i) + return guo +} + +// SetNillableRemindCount sets the "remind_count" field if the given value is not nil. +func (guo *GuildUpdateOne) SetNillableRemindCount(i *int) *GuildUpdateOne { + if i != nil { + guo.SetRemindCount(*i) + } + return guo +} + +// AddRemindCount adds i to the "remind_count" field. +func (guo *GuildUpdateOne) AddRemindCount(i int) *GuildUpdateOne { + guo.mutation.AddRemindCount(i) + return guo +} + +// SetRolePanelEditTimes sets the "role_panel_edit_times" field. +func (guo *GuildUpdateOne) SetRolePanelEditTimes(t []time.Time) *GuildUpdateOne { + guo.mutation.SetRolePanelEditTimes(t) + return guo +} + +// AppendRolePanelEditTimes appends t to the "role_panel_edit_times" field. +func (guo *GuildUpdateOne) AppendRolePanelEditTimes(t []time.Time) *GuildUpdateOne { + guo.mutation.AppendRolePanelEditTimes(t) + return guo +} + +// SetBumpEnabled sets the "bump_enabled" field. +func (guo *GuildUpdateOne) SetBumpEnabled(b bool) *GuildUpdateOne { + guo.mutation.SetBumpEnabled(b) + return guo +} + +// SetNillableBumpEnabled sets the "bump_enabled" field if the given value is not nil. +func (guo *GuildUpdateOne) SetNillableBumpEnabled(b *bool) *GuildUpdateOne { + if b != nil { + guo.SetBumpEnabled(*b) + } + return guo +} + +// SetBumpMessageTitle sets the "bump_message_title" field. +func (guo *GuildUpdateOne) SetBumpMessageTitle(s string) *GuildUpdateOne { + guo.mutation.SetBumpMessageTitle(s) + return guo +} + +// SetNillableBumpMessageTitle sets the "bump_message_title" field if the given value is not nil. +func (guo *GuildUpdateOne) SetNillableBumpMessageTitle(s *string) *GuildUpdateOne { + if s != nil { + guo.SetBumpMessageTitle(*s) + } + return guo +} + +// SetBumpMessage sets the "bump_message" field. +func (guo *GuildUpdateOne) SetBumpMessage(s string) *GuildUpdateOne { + guo.mutation.SetBumpMessage(s) + return guo +} + +// SetNillableBumpMessage sets the "bump_message" field if the given value is not nil. +func (guo *GuildUpdateOne) SetNillableBumpMessage(s *string) *GuildUpdateOne { + if s != nil { + guo.SetBumpMessage(*s) + } + return guo +} + +// SetBumpRemindMessageTitle sets the "bump_remind_message_title" field. +func (guo *GuildUpdateOne) SetBumpRemindMessageTitle(s string) *GuildUpdateOne { + guo.mutation.SetBumpRemindMessageTitle(s) + return guo +} + +// SetNillableBumpRemindMessageTitle sets the "bump_remind_message_title" field if the given value is not nil. +func (guo *GuildUpdateOne) SetNillableBumpRemindMessageTitle(s *string) *GuildUpdateOne { + if s != nil { + guo.SetBumpRemindMessageTitle(*s) + } + return guo +} + +// SetBumpRemindMessage sets the "bump_remind_message" field. +func (guo *GuildUpdateOne) SetBumpRemindMessage(s string) *GuildUpdateOne { + guo.mutation.SetBumpRemindMessage(s) + return guo +} + +// SetNillableBumpRemindMessage sets the "bump_remind_message" field if the given value is not nil. +func (guo *GuildUpdateOne) SetNillableBumpRemindMessage(s *string) *GuildUpdateOne { + if s != nil { + guo.SetBumpRemindMessage(*s) + } + return guo +} + +// SetUpEnabled sets the "up_enabled" field. +func (guo *GuildUpdateOne) SetUpEnabled(b bool) *GuildUpdateOne { + guo.mutation.SetUpEnabled(b) + return guo +} + +// SetNillableUpEnabled sets the "up_enabled" field if the given value is not nil. +func (guo *GuildUpdateOne) SetNillableUpEnabled(b *bool) *GuildUpdateOne { + if b != nil { + guo.SetUpEnabled(*b) + } + return guo +} + +// SetUpMessageTitle sets the "up_message_title" field. +func (guo *GuildUpdateOne) SetUpMessageTitle(s string) *GuildUpdateOne { + guo.mutation.SetUpMessageTitle(s) + return guo +} + +// SetNillableUpMessageTitle sets the "up_message_title" field if the given value is not nil. +func (guo *GuildUpdateOne) SetNillableUpMessageTitle(s *string) *GuildUpdateOne { + if s != nil { + guo.SetUpMessageTitle(*s) + } + return guo +} + +// SetUpMessage sets the "up_message" field. +func (guo *GuildUpdateOne) SetUpMessage(s string) *GuildUpdateOne { + guo.mutation.SetUpMessage(s) + return guo +} + +// SetNillableUpMessage sets the "up_message" field if the given value is not nil. +func (guo *GuildUpdateOne) SetNillableUpMessage(s *string) *GuildUpdateOne { + if s != nil { + guo.SetUpMessage(*s) + } + return guo +} + +// SetUpRemindMessageTitle sets the "up_remind_message_title" field. +func (guo *GuildUpdateOne) SetUpRemindMessageTitle(s string) *GuildUpdateOne { + guo.mutation.SetUpRemindMessageTitle(s) + return guo +} + +// SetNillableUpRemindMessageTitle sets the "up_remind_message_title" field if the given value is not nil. +func (guo *GuildUpdateOne) SetNillableUpRemindMessageTitle(s *string) *GuildUpdateOne { + if s != nil { + guo.SetUpRemindMessageTitle(*s) + } + return guo +} + +// SetUpRemindMessage sets the "up_remind_message" field. +func (guo *GuildUpdateOne) SetUpRemindMessage(s string) *GuildUpdateOne { + guo.mutation.SetUpRemindMessage(s) + return guo +} + +// SetNillableUpRemindMessage sets the "up_remind_message" field if the given value is not nil. +func (guo *GuildUpdateOne) SetNillableUpRemindMessage(s *string) *GuildUpdateOne { + if s != nil { + guo.SetUpRemindMessage(*s) + } + return guo +} + +// SetBumpMention sets the "bump_mention" field. +func (guo *GuildUpdateOne) SetBumpMention(s snowflake.ID) *GuildUpdateOne { + guo.mutation.ResetBumpMention() + guo.mutation.SetBumpMention(s) + return guo +} + +// SetNillableBumpMention sets the "bump_mention" field if the given value is not nil. +func (guo *GuildUpdateOne) SetNillableBumpMention(s *snowflake.ID) *GuildUpdateOne { + if s != nil { + guo.SetBumpMention(*s) + } + return guo +} + +// AddBumpMention adds s to the "bump_mention" field. +func (guo *GuildUpdateOne) AddBumpMention(s snowflake.ID) *GuildUpdateOne { + guo.mutation.AddBumpMention(s) + return guo +} + +// ClearBumpMention clears the value of the "bump_mention" field. +func (guo *GuildUpdateOne) ClearBumpMention() *GuildUpdateOne { + guo.mutation.ClearBumpMention() + return guo +} + +// SetUpMention sets the "up_mention" field. +func (guo *GuildUpdateOne) SetUpMention(s snowflake.ID) *GuildUpdateOne { + guo.mutation.ResetUpMention() + guo.mutation.SetUpMention(s) + return guo +} + +// SetNillableUpMention sets the "up_mention" field if the given value is not nil. +func (guo *GuildUpdateOne) SetNillableUpMention(s *snowflake.ID) *GuildUpdateOne { + if s != nil { + guo.SetUpMention(*s) + } + return guo +} + +// AddUpMention adds s to the "up_mention" field. +func (guo *GuildUpdateOne) AddUpMention(s snowflake.ID) *GuildUpdateOne { + guo.mutation.AddUpMention(s) + return guo +} + +// ClearUpMention clears the value of the "up_mention" field. +func (guo *GuildUpdateOne) ClearUpMention() *GuildUpdateOne { + guo.mutation.ClearUpMention() + return guo +} + +// SetOwnerID sets the "owner" edge to the User entity by ID. +func (guo *GuildUpdateOne) SetOwnerID(id snowflake.ID) *GuildUpdateOne { + guo.mutation.SetOwnerID(id) + return guo +} + +// SetOwner sets the "owner" edge to the User entity. +func (guo *GuildUpdateOne) SetOwner(u *User) *GuildUpdateOne { + return guo.SetOwnerID(u.ID) +} + +// AddMemberIDs adds the "members" edge to the Member entity by IDs. +func (guo *GuildUpdateOne) AddMemberIDs(ids ...int) *GuildUpdateOne { + guo.mutation.AddMemberIDs(ids...) + return guo +} + +// AddMembers adds the "members" edges to the Member entity. +func (guo *GuildUpdateOne) AddMembers(m ...*Member) *GuildUpdateOne { + ids := make([]int, len(m)) + for i := range m { + ids[i] = m[i].ID + } + return guo.AddMemberIDs(ids...) +} + +// AddMessagePinIDs adds the "message_pins" edge to the MessagePin entity by IDs. +func (guo *GuildUpdateOne) AddMessagePinIDs(ids ...uuid.UUID) *GuildUpdateOne { + guo.mutation.AddMessagePinIDs(ids...) + return guo +} + +// AddMessagePins adds the "message_pins" edges to the MessagePin entity. +func (guo *GuildUpdateOne) AddMessagePins(m ...*MessagePin) *GuildUpdateOne { + ids := make([]uuid.UUID, len(m)) + for i := range m { + ids[i] = m[i].ID + } + return guo.AddMessagePinIDs(ids...) +} + +// AddRemindIDs adds the "reminds" edge to the MessageRemind entity by IDs. +func (guo *GuildUpdateOne) AddRemindIDs(ids ...uuid.UUID) *GuildUpdateOne { + guo.mutation.AddRemindIDs(ids...) + return guo +} + +// AddReminds adds the "reminds" edges to the MessageRemind entity. +func (guo *GuildUpdateOne) AddReminds(m ...*MessageRemind) *GuildUpdateOne { + ids := make([]uuid.UUID, len(m)) + for i := range m { + ids[i] = m[i].ID + } + return guo.AddRemindIDs(ids...) +} + +// AddRolePanelIDs adds the "role_panels" edge to the RolePanel entity by IDs. +func (guo *GuildUpdateOne) AddRolePanelIDs(ids ...uuid.UUID) *GuildUpdateOne { + guo.mutation.AddRolePanelIDs(ids...) + return guo +} + +// AddRolePanels adds the "role_panels" edges to the RolePanel entity. +func (guo *GuildUpdateOne) AddRolePanels(r ...*RolePanel) *GuildUpdateOne { + ids := make([]uuid.UUID, len(r)) + for i := range r { + ids[i] = r[i].ID + } + return guo.AddRolePanelIDs(ids...) +} + +// AddRolePanelPlacementIDs adds the "role_panel_placements" edge to the RolePanelPlaced entity by IDs. +func (guo *GuildUpdateOne) AddRolePanelPlacementIDs(ids ...uuid.UUID) *GuildUpdateOne { + guo.mutation.AddRolePanelPlacementIDs(ids...) + return guo +} + +// AddRolePanelPlacements adds the "role_panel_placements" edges to the RolePanelPlaced entity. +func (guo *GuildUpdateOne) AddRolePanelPlacements(r ...*RolePanelPlaced) *GuildUpdateOne { + ids := make([]uuid.UUID, len(r)) + for i := range r { + ids[i] = r[i].ID + } + return guo.AddRolePanelPlacementIDs(ids...) +} + +// AddRolePanelEditIDs adds the "role_panel_edits" edge to the RolePanelEdit entity by IDs. +func (guo *GuildUpdateOne) AddRolePanelEditIDs(ids ...uuid.UUID) *GuildUpdateOne { + guo.mutation.AddRolePanelEditIDs(ids...) + return guo +} + +// AddRolePanelEdits adds the "role_panel_edits" edges to the RolePanelEdit entity. +func (guo *GuildUpdateOne) AddRolePanelEdits(r ...*RolePanelEdit) *GuildUpdateOne { + ids := make([]uuid.UUID, len(r)) + for i := range r { + ids[i] = r[i].ID + } + return guo.AddRolePanelEditIDs(ids...) +} + +// Mutation returns the GuildMutation object of the builder. +func (guo *GuildUpdateOne) Mutation() *GuildMutation { + return guo.mutation +} + +// ClearOwner clears the "owner" edge to the User entity. +func (guo *GuildUpdateOne) ClearOwner() *GuildUpdateOne { + guo.mutation.ClearOwner() + return guo +} + +// ClearMembers clears all "members" edges to the Member entity. +func (guo *GuildUpdateOne) ClearMembers() *GuildUpdateOne { + guo.mutation.ClearMembers() + return guo +} + +// RemoveMemberIDs removes the "members" edge to Member entities by IDs. +func (guo *GuildUpdateOne) RemoveMemberIDs(ids ...int) *GuildUpdateOne { + guo.mutation.RemoveMemberIDs(ids...) + return guo +} + +// RemoveMembers removes "members" edges to Member entities. +func (guo *GuildUpdateOne) RemoveMembers(m ...*Member) *GuildUpdateOne { + ids := make([]int, len(m)) + for i := range m { + ids[i] = m[i].ID + } + return guo.RemoveMemberIDs(ids...) +} + +// ClearMessagePins clears all "message_pins" edges to the MessagePin entity. +func (guo *GuildUpdateOne) ClearMessagePins() *GuildUpdateOne { + guo.mutation.ClearMessagePins() + return guo +} + +// RemoveMessagePinIDs removes the "message_pins" edge to MessagePin entities by IDs. +func (guo *GuildUpdateOne) RemoveMessagePinIDs(ids ...uuid.UUID) *GuildUpdateOne { + guo.mutation.RemoveMessagePinIDs(ids...) + return guo +} + +// RemoveMessagePins removes "message_pins" edges to MessagePin entities. +func (guo *GuildUpdateOne) RemoveMessagePins(m ...*MessagePin) *GuildUpdateOne { + ids := make([]uuid.UUID, len(m)) + for i := range m { + ids[i] = m[i].ID + } + return guo.RemoveMessagePinIDs(ids...) +} + +// ClearReminds clears all "reminds" edges to the MessageRemind entity. +func (guo *GuildUpdateOne) ClearReminds() *GuildUpdateOne { + guo.mutation.ClearReminds() + return guo +} + +// RemoveRemindIDs removes the "reminds" edge to MessageRemind entities by IDs. +func (guo *GuildUpdateOne) RemoveRemindIDs(ids ...uuid.UUID) *GuildUpdateOne { + guo.mutation.RemoveRemindIDs(ids...) + return guo +} + +// RemoveReminds removes "reminds" edges to MessageRemind entities. +func (guo *GuildUpdateOne) RemoveReminds(m ...*MessageRemind) *GuildUpdateOne { + ids := make([]uuid.UUID, len(m)) + for i := range m { + ids[i] = m[i].ID + } + return guo.RemoveRemindIDs(ids...) +} + +// ClearRolePanels clears all "role_panels" edges to the RolePanel entity. +func (guo *GuildUpdateOne) ClearRolePanels() *GuildUpdateOne { + guo.mutation.ClearRolePanels() + return guo +} + +// RemoveRolePanelIDs removes the "role_panels" edge to RolePanel entities by IDs. +func (guo *GuildUpdateOne) RemoveRolePanelIDs(ids ...uuid.UUID) *GuildUpdateOne { + guo.mutation.RemoveRolePanelIDs(ids...) + return guo +} + +// RemoveRolePanels removes "role_panels" edges to RolePanel entities. +func (guo *GuildUpdateOne) RemoveRolePanels(r ...*RolePanel) *GuildUpdateOne { + ids := make([]uuid.UUID, len(r)) + for i := range r { + ids[i] = r[i].ID + } + return guo.RemoveRolePanelIDs(ids...) +} + +// ClearRolePanelPlacements clears all "role_panel_placements" edges to the RolePanelPlaced entity. +func (guo *GuildUpdateOne) ClearRolePanelPlacements() *GuildUpdateOne { + guo.mutation.ClearRolePanelPlacements() + return guo +} + +// RemoveRolePanelPlacementIDs removes the "role_panel_placements" edge to RolePanelPlaced entities by IDs. +func (guo *GuildUpdateOne) RemoveRolePanelPlacementIDs(ids ...uuid.UUID) *GuildUpdateOne { + guo.mutation.RemoveRolePanelPlacementIDs(ids...) + return guo +} + +// RemoveRolePanelPlacements removes "role_panel_placements" edges to RolePanelPlaced entities. +func (guo *GuildUpdateOne) RemoveRolePanelPlacements(r ...*RolePanelPlaced) *GuildUpdateOne { + ids := make([]uuid.UUID, len(r)) + for i := range r { + ids[i] = r[i].ID + } + return guo.RemoveRolePanelPlacementIDs(ids...) +} + +// ClearRolePanelEdits clears all "role_panel_edits" edges to the RolePanelEdit entity. +func (guo *GuildUpdateOne) ClearRolePanelEdits() *GuildUpdateOne { + guo.mutation.ClearRolePanelEdits() + return guo +} + +// RemoveRolePanelEditIDs removes the "role_panel_edits" edge to RolePanelEdit entities by IDs. +func (guo *GuildUpdateOne) RemoveRolePanelEditIDs(ids ...uuid.UUID) *GuildUpdateOne { + guo.mutation.RemoveRolePanelEditIDs(ids...) + return guo +} + +// RemoveRolePanelEdits removes "role_panel_edits" edges to RolePanelEdit entities. +func (guo *GuildUpdateOne) RemoveRolePanelEdits(r ...*RolePanelEdit) *GuildUpdateOne { + ids := make([]uuid.UUID, len(r)) + for i := range r { + ids[i] = r[i].ID + } + return guo.RemoveRolePanelEditIDs(ids...) +} + +// Where appends a list predicates to the GuildUpdate builder. +func (guo *GuildUpdateOne) Where(ps ...predicate.Guild) *GuildUpdateOne { + guo.mutation.Where(ps...) + return guo +} + +// Select allows selecting one or more fields (columns) of the returned entity. +// The default is selecting all fields defined in the entity schema. +func (guo *GuildUpdateOne) Select(field string, fields ...string) *GuildUpdateOne { + guo.fields = append([]string{field}, fields...) + return guo +} + +// Save executes the query and returns the updated Guild entity. +func (guo *GuildUpdateOne) Save(ctx context.Context) (*Guild, error) { + return withHooks(ctx, guo.sqlSave, guo.mutation, guo.hooks) +} + +// SaveX is like Save, but panics if an error occurs. +func (guo *GuildUpdateOne) SaveX(ctx context.Context) *Guild { + node, err := guo.Save(ctx) + if err != nil { + panic(err) + } + return node +} + +// Exec executes the query on the entity. +func (guo *GuildUpdateOne) Exec(ctx context.Context) error { + _, err := guo.Save(ctx) + return err +} + +// ExecX is like Exec, but panics if an error occurs. +func (guo *GuildUpdateOne) ExecX(ctx context.Context) { + if err := guo.Exec(ctx); err != nil { + panic(err) + } +} + +// check runs all checks and user-defined validators on the builder. +func (guo *GuildUpdateOne) check() error { + if v, ok := guo.mutation.Name(); ok { + if err := guild.NameValidator(v); err != nil { + return &ValidationError{Name: "name", err: fmt.Errorf(`ent: validator failed for field "Guild.name": %w`, err)} + } + } + if v, ok := guo.mutation.Locale(); ok { + if err := guild.LocaleValidator(string(v)); err != nil { + return &ValidationError{Name: "locale", err: fmt.Errorf(`ent: validator failed for field "Guild.locale": %w`, err)} + } + } + if v, ok := guo.mutation.LevelUpMessage(); ok { + if err := guild.LevelUpMessageValidator(v); err != nil { + return &ValidationError{Name: "level_up_message", err: fmt.Errorf(`ent: validator failed for field "Guild.level_up_message": %w`, err)} + } + } + if v, ok := guo.mutation.BumpMessageTitle(); ok { + if err := guild.BumpMessageTitleValidator(v); err != nil { + return &ValidationError{Name: "bump_message_title", err: fmt.Errorf(`ent: validator failed for field "Guild.bump_message_title": %w`, err)} + } + } + if v, ok := guo.mutation.BumpMessage(); ok { + if err := guild.BumpMessageValidator(v); err != nil { + return &ValidationError{Name: "bump_message", err: fmt.Errorf(`ent: validator failed for field "Guild.bump_message": %w`, err)} + } + } + if v, ok := guo.mutation.BumpRemindMessageTitle(); ok { + if err := guild.BumpRemindMessageTitleValidator(v); err != nil { + return &ValidationError{Name: "bump_remind_message_title", err: fmt.Errorf(`ent: validator failed for field "Guild.bump_remind_message_title": %w`, err)} + } + } + if v, ok := guo.mutation.BumpRemindMessage(); ok { + if err := guild.BumpRemindMessageValidator(v); err != nil { + return &ValidationError{Name: "bump_remind_message", err: fmt.Errorf(`ent: validator failed for field "Guild.bump_remind_message": %w`, err)} + } + } + if v, ok := guo.mutation.UpMessageTitle(); ok { + if err := guild.UpMessageTitleValidator(v); err != nil { + return &ValidationError{Name: "up_message_title", err: fmt.Errorf(`ent: validator failed for field "Guild.up_message_title": %w`, err)} + } + } + if v, ok := guo.mutation.UpMessage(); ok { + if err := guild.UpMessageValidator(v); err != nil { + return &ValidationError{Name: "up_message", err: fmt.Errorf(`ent: validator failed for field "Guild.up_message": %w`, err)} + } + } + if v, ok := guo.mutation.UpRemindMessageTitle(); ok { + if err := guild.UpRemindMessageTitleValidator(v); err != nil { + return &ValidationError{Name: "up_remind_message_title", err: fmt.Errorf(`ent: validator failed for field "Guild.up_remind_message_title": %w`, err)} + } + } + if v, ok := guo.mutation.UpRemindMessage(); ok { + if err := guild.UpRemindMessageValidator(v); err != nil { + return &ValidationError{Name: "up_remind_message", err: fmt.Errorf(`ent: validator failed for field "Guild.up_remind_message": %w`, err)} + } + } + if _, ok := guo.mutation.OwnerID(); guo.mutation.OwnerCleared() && !ok { + return errors.New(`ent: clearing a required unique edge "Guild.owner"`) + } + return nil +} + +func (guo *GuildUpdateOne) sqlSave(ctx context.Context) (_node *Guild, err error) { + if err := guo.check(); err != nil { + return _node, err + } + _spec := sqlgraph.NewUpdateSpec(guild.Table, guild.Columns, sqlgraph.NewFieldSpec(guild.FieldID, field.TypeUint64)) + id, ok := guo.mutation.ID() + if !ok { + return nil, &ValidationError{Name: "id", err: errors.New(`ent: missing "Guild.id" for update`)} + } + _spec.Node.ID.Value = id + if fields := guo.fields; len(fields) > 0 { + _spec.Node.Columns = make([]string, 0, len(fields)) + _spec.Node.Columns = append(_spec.Node.Columns, guild.FieldID) + for _, f := range fields { + if !guild.ValidColumn(f) { + return nil, &ValidationError{Name: f, err: fmt.Errorf("ent: invalid field %q for query", f)} + } + if f != guild.FieldID { + _spec.Node.Columns = append(_spec.Node.Columns, f) + } + } + } + if ps := guo.mutation.predicates; len(ps) > 0 { + _spec.Predicate = func(selector *sql.Selector) { + for i := range ps { + ps[i](selector) + } + } + } + if value, ok := guo.mutation.Name(); ok { + _spec.SetField(guild.FieldName, field.TypeString, value) + } + if value, ok := guo.mutation.Locale(); ok { + _spec.SetField(guild.FieldLocale, field.TypeString, value) + } + if value, ok := guo.mutation.LevelUpMessage(); ok { + _spec.SetField(guild.FieldLevelUpMessage, field.TypeString, value) + } + if value, ok := guo.mutation.LevelUpChannel(); ok { + _spec.SetField(guild.FieldLevelUpChannel, field.TypeUint64, value) + } + if value, ok := guo.mutation.AddedLevelUpChannel(); ok { + _spec.AddField(guild.FieldLevelUpChannel, field.TypeUint64, value) + } + if guo.mutation.LevelUpChannelCleared() { + _spec.ClearField(guild.FieldLevelUpChannel, field.TypeUint64) + } + if value, ok := guo.mutation.LevelUpExcludeChannel(); ok { + _spec.SetField(guild.FieldLevelUpExcludeChannel, field.TypeJSON, value) + } + if value, ok := guo.mutation.AppendedLevelUpExcludeChannel(); ok { + _spec.AddModifier(func(u *sql.UpdateBuilder) { + sqljson.Append(u, guild.FieldLevelUpExcludeChannel, value) + }) + } + if guo.mutation.LevelUpExcludeChannelCleared() { + _spec.ClearField(guild.FieldLevelUpExcludeChannel, field.TypeJSON) + } + if value, ok := guo.mutation.LevelMee6Imported(); ok { + _spec.SetField(guild.FieldLevelMee6Imported, field.TypeBool, value) + } + if value, ok := guo.mutation.LevelRole(); ok { + _spec.SetField(guild.FieldLevelRole, field.TypeJSON, value) + } + if guo.mutation.LevelRoleCleared() { + _spec.ClearField(guild.FieldLevelRole, field.TypeJSON) + } + if value, ok := guo.mutation.Permissions(); ok { + _spec.SetField(guild.FieldPermissions, field.TypeJSON, value) + } + if value, ok := guo.mutation.RemindCount(); ok { + _spec.SetField(guild.FieldRemindCount, field.TypeInt, value) + } + if value, ok := guo.mutation.AddedRemindCount(); ok { + _spec.AddField(guild.FieldRemindCount, field.TypeInt, value) + } + if value, ok := guo.mutation.RolePanelEditTimes(); ok { + _spec.SetField(guild.FieldRolePanelEditTimes, field.TypeJSON, value) + } + if value, ok := guo.mutation.AppendedRolePanelEditTimes(); ok { + _spec.AddModifier(func(u *sql.UpdateBuilder) { + sqljson.Append(u, guild.FieldRolePanelEditTimes, value) + }) + } + if value, ok := guo.mutation.BumpEnabled(); ok { + _spec.SetField(guild.FieldBumpEnabled, field.TypeBool, value) + } + if value, ok := guo.mutation.BumpMessageTitle(); ok { + _spec.SetField(guild.FieldBumpMessageTitle, field.TypeString, value) + } + if value, ok := guo.mutation.BumpMessage(); ok { + _spec.SetField(guild.FieldBumpMessage, field.TypeString, value) + } + if value, ok := guo.mutation.BumpRemindMessageTitle(); ok { + _spec.SetField(guild.FieldBumpRemindMessageTitle, field.TypeString, value) + } + if value, ok := guo.mutation.BumpRemindMessage(); ok { + _spec.SetField(guild.FieldBumpRemindMessage, field.TypeString, value) + } + if value, ok := guo.mutation.UpEnabled(); ok { + _spec.SetField(guild.FieldUpEnabled, field.TypeBool, value) + } + if value, ok := guo.mutation.UpMessageTitle(); ok { + _spec.SetField(guild.FieldUpMessageTitle, field.TypeString, value) + } + if value, ok := guo.mutation.UpMessage(); ok { + _spec.SetField(guild.FieldUpMessage, field.TypeString, value) + } + if value, ok := guo.mutation.UpRemindMessageTitle(); ok { + _spec.SetField(guild.FieldUpRemindMessageTitle, field.TypeString, value) + } + if value, ok := guo.mutation.UpRemindMessage(); ok { + _spec.SetField(guild.FieldUpRemindMessage, field.TypeString, value) + } + if value, ok := guo.mutation.BumpMention(); ok { + _spec.SetField(guild.FieldBumpMention, field.TypeUint64, value) + } + if value, ok := guo.mutation.AddedBumpMention(); ok { + _spec.AddField(guild.FieldBumpMention, field.TypeUint64, value) + } + if guo.mutation.BumpMentionCleared() { + _spec.ClearField(guild.FieldBumpMention, field.TypeUint64) + } + if value, ok := guo.mutation.UpMention(); ok { + _spec.SetField(guild.FieldUpMention, field.TypeUint64, value) + } + if value, ok := guo.mutation.AddedUpMention(); ok { + _spec.AddField(guild.FieldUpMention, field.TypeUint64, value) + } + if guo.mutation.UpMentionCleared() { + _spec.ClearField(guild.FieldUpMention, field.TypeUint64) + } + if guo.mutation.OwnerCleared() { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.M2O, + Inverse: true, + Table: guild.OwnerTable, + Columns: []string{guild.OwnerColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(user.FieldID, field.TypeUint64), + }, + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := guo.mutation.OwnerIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.M2O, + Inverse: true, + Table: guild.OwnerTable, + Columns: []string{guild.OwnerColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(user.FieldID, field.TypeUint64), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Add = append(_spec.Edges.Add, edge) + } + if guo.mutation.MembersCleared() { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: false, + Table: guild.MembersTable, + Columns: []string{guild.MembersColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(member.FieldID, field.TypeInt), + }, + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := guo.mutation.RemovedMembersIDs(); len(nodes) > 0 && !guo.mutation.MembersCleared() { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: false, + Table: guild.MembersTable, + Columns: []string{guild.MembersColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(member.FieldID, field.TypeInt), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := guo.mutation.MembersIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: false, + Table: guild.MembersTable, + Columns: []string{guild.MembersColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(member.FieldID, field.TypeInt), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Add = append(_spec.Edges.Add, edge) + } + if guo.mutation.MessagePinsCleared() { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: false, + Table: guild.MessagePinsTable, + Columns: []string{guild.MessagePinsColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(messagepin.FieldID, field.TypeUUID), + }, + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := guo.mutation.RemovedMessagePinsIDs(); len(nodes) > 0 && !guo.mutation.MessagePinsCleared() { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: false, + Table: guild.MessagePinsTable, + Columns: []string{guild.MessagePinsColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(messagepin.FieldID, field.TypeUUID), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := guo.mutation.MessagePinsIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: false, + Table: guild.MessagePinsTable, + Columns: []string{guild.MessagePinsColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(messagepin.FieldID, field.TypeUUID), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Add = append(_spec.Edges.Add, edge) + } + if guo.mutation.RemindsCleared() { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: false, + Table: guild.RemindsTable, + Columns: []string{guild.RemindsColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(messageremind.FieldID, field.TypeUUID), + }, + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := guo.mutation.RemovedRemindsIDs(); len(nodes) > 0 && !guo.mutation.RemindsCleared() { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: false, + Table: guild.RemindsTable, + Columns: []string{guild.RemindsColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(messageremind.FieldID, field.TypeUUID), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := guo.mutation.RemindsIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: false, + Table: guild.RemindsTable, + Columns: []string{guild.RemindsColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(messageremind.FieldID, field.TypeUUID), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Add = append(_spec.Edges.Add, edge) + } + if guo.mutation.RolePanelsCleared() { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: false, + Table: guild.RolePanelsTable, + Columns: []string{guild.RolePanelsColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(rolepanel.FieldID, field.TypeUUID), + }, + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := guo.mutation.RemovedRolePanelsIDs(); len(nodes) > 0 && !guo.mutation.RolePanelsCleared() { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: false, + Table: guild.RolePanelsTable, + Columns: []string{guild.RolePanelsColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(rolepanel.FieldID, field.TypeUUID), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := guo.mutation.RolePanelsIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: false, + Table: guild.RolePanelsTable, + Columns: []string{guild.RolePanelsColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(rolepanel.FieldID, field.TypeUUID), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Add = append(_spec.Edges.Add, edge) + } + if guo.mutation.RolePanelPlacementsCleared() { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: false, + Table: guild.RolePanelPlacementsTable, + Columns: []string{guild.RolePanelPlacementsColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(rolepanelplaced.FieldID, field.TypeUUID), + }, + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := guo.mutation.RemovedRolePanelPlacementsIDs(); len(nodes) > 0 && !guo.mutation.RolePanelPlacementsCleared() { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: false, + Table: guild.RolePanelPlacementsTable, + Columns: []string{guild.RolePanelPlacementsColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(rolepanelplaced.FieldID, field.TypeUUID), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := guo.mutation.RolePanelPlacementsIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: false, + Table: guild.RolePanelPlacementsTable, + Columns: []string{guild.RolePanelPlacementsColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(rolepanelplaced.FieldID, field.TypeUUID), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Add = append(_spec.Edges.Add, edge) + } + if guo.mutation.RolePanelEditsCleared() { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: false, + Table: guild.RolePanelEditsTable, + Columns: []string{guild.RolePanelEditsColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(rolepaneledit.FieldID, field.TypeUUID), + }, + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := guo.mutation.RemovedRolePanelEditsIDs(); len(nodes) > 0 && !guo.mutation.RolePanelEditsCleared() { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: false, + Table: guild.RolePanelEditsTable, + Columns: []string{guild.RolePanelEditsColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(rolepaneledit.FieldID, field.TypeUUID), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := guo.mutation.RolePanelEditsIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: false, + Table: guild.RolePanelEditsTable, + Columns: []string{guild.RolePanelEditsColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(rolepaneledit.FieldID, field.TypeUUID), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Add = append(_spec.Edges.Add, edge) + } + _node = &Guild{config: guo.config} + _spec.Assign = _node.assignValues + _spec.ScanValues = _node.scanValues + if err = sqlgraph.UpdateNode(ctx, guo.driver, _spec); err != nil { + if _, ok := err.(*sqlgraph.NotFoundError); ok { + err = &NotFoundError{guild.Label} + } else if sqlgraph.IsConstraintError(err) { + err = &ConstraintError{msg: err.Error(), wrap: err} + } + return nil, err + } + guo.mutation.done = true + return _node, nil +} diff --git a/ent/hook/hook.go b/ent/hook/hook.go new file mode 100644 index 00000000..f4e1960e --- /dev/null +++ b/ent/hook/hook.go @@ -0,0 +1,295 @@ +// Code generated by ent, DO NOT EDIT. + +package hook + +import ( + "context" + "fmt" + + "github.com/sabafly/gobot/ent" +) + +// The GuildFunc type is an adapter to allow the use of ordinary +// function as Guild mutator. +type GuildFunc func(context.Context, *ent.GuildMutation) (ent.Value, error) + +// Mutate calls f(ctx, m). +func (f GuildFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) { + if mv, ok := m.(*ent.GuildMutation); ok { + return f(ctx, mv) + } + return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.GuildMutation", m) +} + +// The MemberFunc type is an adapter to allow the use of ordinary +// function as Member mutator. +type MemberFunc func(context.Context, *ent.MemberMutation) (ent.Value, error) + +// Mutate calls f(ctx, m). +func (f MemberFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) { + if mv, ok := m.(*ent.MemberMutation); ok { + return f(ctx, mv) + } + return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.MemberMutation", m) +} + +// The MessagePinFunc type is an adapter to allow the use of ordinary +// function as MessagePin mutator. +type MessagePinFunc func(context.Context, *ent.MessagePinMutation) (ent.Value, error) + +// Mutate calls f(ctx, m). +func (f MessagePinFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) { + if mv, ok := m.(*ent.MessagePinMutation); ok { + return f(ctx, mv) + } + return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.MessagePinMutation", m) +} + +// The MessageRemindFunc type is an adapter to allow the use of ordinary +// function as MessageRemind mutator. +type MessageRemindFunc func(context.Context, *ent.MessageRemindMutation) (ent.Value, error) + +// Mutate calls f(ctx, m). +func (f MessageRemindFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) { + if mv, ok := m.(*ent.MessageRemindMutation); ok { + return f(ctx, mv) + } + return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.MessageRemindMutation", m) +} + +// The RolePanelFunc type is an adapter to allow the use of ordinary +// function as RolePanel mutator. +type RolePanelFunc func(context.Context, *ent.RolePanelMutation) (ent.Value, error) + +// Mutate calls f(ctx, m). +func (f RolePanelFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) { + if mv, ok := m.(*ent.RolePanelMutation); ok { + return f(ctx, mv) + } + return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.RolePanelMutation", m) +} + +// The RolePanelEditFunc type is an adapter to allow the use of ordinary +// function as RolePanelEdit mutator. +type RolePanelEditFunc func(context.Context, *ent.RolePanelEditMutation) (ent.Value, error) + +// Mutate calls f(ctx, m). +func (f RolePanelEditFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) { + if mv, ok := m.(*ent.RolePanelEditMutation); ok { + return f(ctx, mv) + } + return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.RolePanelEditMutation", m) +} + +// The RolePanelPlacedFunc type is an adapter to allow the use of ordinary +// function as RolePanelPlaced mutator. +type RolePanelPlacedFunc func(context.Context, *ent.RolePanelPlacedMutation) (ent.Value, error) + +// Mutate calls f(ctx, m). +func (f RolePanelPlacedFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) { + if mv, ok := m.(*ent.RolePanelPlacedMutation); ok { + return f(ctx, mv) + } + return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.RolePanelPlacedMutation", m) +} + +// The UserFunc type is an adapter to allow the use of ordinary +// function as User mutator. +type UserFunc func(context.Context, *ent.UserMutation) (ent.Value, error) + +// Mutate calls f(ctx, m). +func (f UserFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) { + if mv, ok := m.(*ent.UserMutation); ok { + return f(ctx, mv) + } + return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.UserMutation", m) +} + +// The WordSuffixFunc type is an adapter to allow the use of ordinary +// function as WordSuffix mutator. +type WordSuffixFunc func(context.Context, *ent.WordSuffixMutation) (ent.Value, error) + +// Mutate calls f(ctx, m). +func (f WordSuffixFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) { + if mv, ok := m.(*ent.WordSuffixMutation); ok { + return f(ctx, mv) + } + return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.WordSuffixMutation", m) +} + +// Condition is a hook condition function. +type Condition func(context.Context, ent.Mutation) bool + +// And groups conditions with the AND operator. +func And(first, second Condition, rest ...Condition) Condition { + return func(ctx context.Context, m ent.Mutation) bool { + if !first(ctx, m) || !second(ctx, m) { + return false + } + for _, cond := range rest { + if !cond(ctx, m) { + return false + } + } + return true + } +} + +// Or groups conditions with the OR operator. +func Or(first, second Condition, rest ...Condition) Condition { + return func(ctx context.Context, m ent.Mutation) bool { + if first(ctx, m) || second(ctx, m) { + return true + } + for _, cond := range rest { + if cond(ctx, m) { + return true + } + } + return false + } +} + +// Not negates a given condition. +func Not(cond Condition) Condition { + return func(ctx context.Context, m ent.Mutation) bool { + return !cond(ctx, m) + } +} + +// HasOp is a condition testing mutation operation. +func HasOp(op ent.Op) Condition { + return func(_ context.Context, m ent.Mutation) bool { + return m.Op().Is(op) + } +} + +// HasAddedFields is a condition validating `.AddedField` on fields. +func HasAddedFields(field string, fields ...string) Condition { + return func(_ context.Context, m ent.Mutation) bool { + if _, exists := m.AddedField(field); !exists { + return false + } + for _, field := range fields { + if _, exists := m.AddedField(field); !exists { + return false + } + } + return true + } +} + +// HasClearedFields is a condition validating `.FieldCleared` on fields. +func HasClearedFields(field string, fields ...string) Condition { + return func(_ context.Context, m ent.Mutation) bool { + if exists := m.FieldCleared(field); !exists { + return false + } + for _, field := range fields { + if exists := m.FieldCleared(field); !exists { + return false + } + } + return true + } +} + +// HasFields is a condition validating `.Field` on fields. +func HasFields(field string, fields ...string) Condition { + return func(_ context.Context, m ent.Mutation) bool { + if _, exists := m.Field(field); !exists { + return false + } + for _, field := range fields { + if _, exists := m.Field(field); !exists { + return false + } + } + return true + } +} + +// If executes the given hook under condition. +// +// hook.If(ComputeAverage, And(HasFields(...), HasAddedFields(...))) +func If(hk ent.Hook, cond Condition) ent.Hook { + return func(next ent.Mutator) ent.Mutator { + return ent.MutateFunc(func(ctx context.Context, m ent.Mutation) (ent.Value, error) { + if cond(ctx, m) { + return hk(next).Mutate(ctx, m) + } + return next.Mutate(ctx, m) + }) + } +} + +// On executes the given hook only for the given operation. +// +// hook.On(Log, ent.Delete|ent.Create) +func On(hk ent.Hook, op ent.Op) ent.Hook { + return If(hk, HasOp(op)) +} + +// Unless skips the given hook only for the given operation. +// +// hook.Unless(Log, ent.Update|ent.UpdateOne) +func Unless(hk ent.Hook, op ent.Op) ent.Hook { + return If(hk, Not(HasOp(op))) +} + +// FixedError is a hook returning a fixed error. +func FixedError(err error) ent.Hook { + return func(ent.Mutator) ent.Mutator { + return ent.MutateFunc(func(context.Context, ent.Mutation) (ent.Value, error) { + return nil, err + }) + } +} + +// Reject returns a hook that rejects all operations that match op. +// +// func (T) Hooks() []ent.Hook { +// return []ent.Hook{ +// Reject(ent.Delete|ent.Update), +// } +// } +func Reject(op ent.Op) ent.Hook { + hk := FixedError(fmt.Errorf("%s operation is not allowed", op)) + return On(hk, op) +} + +// Chain acts as a list of hooks and is effectively immutable. +// Once created, it will always hold the same set of hooks in the same order. +type Chain struct { + hooks []ent.Hook +} + +// NewChain creates a new chain of hooks. +func NewChain(hooks ...ent.Hook) Chain { + return Chain{append([]ent.Hook(nil), hooks...)} +} + +// Hook chains the list of hooks and returns the final hook. +func (c Chain) Hook() ent.Hook { + return func(mutator ent.Mutator) ent.Mutator { + for i := len(c.hooks) - 1; i >= 0; i-- { + mutator = c.hooks[i](mutator) + } + return mutator + } +} + +// Append extends a chain, adding the specified hook +// as the last ones in the mutation flow. +func (c Chain) Append(hooks ...ent.Hook) Chain { + newHooks := make([]ent.Hook, 0, len(c.hooks)+len(hooks)) + newHooks = append(newHooks, c.hooks...) + newHooks = append(newHooks, hooks...) + return Chain{newHooks} +} + +// Extend extends a chain, adding the specified chain +// as the last ones in the mutation flow. +func (c Chain) Extend(chain Chain) Chain { + return c.Append(chain.hooks...) +} diff --git a/ent/member.go b/ent/member.go new file mode 100644 index 00000000..02298090 --- /dev/null +++ b/ent/member.go @@ -0,0 +1,228 @@ +// Code generated by ent, DO NOT EDIT. + +package ent + +import ( + "encoding/json" + "fmt" + "strings" + "time" + + "entgo.io/ent" + "entgo.io/ent/dialect/sql" + snowflake "github.com/disgoorg/snowflake/v2" + "github.com/sabafly/gobot/ent/guild" + "github.com/sabafly/gobot/ent/member" + "github.com/sabafly/gobot/ent/user" + "github.com/sabafly/gobot/internal/permissions" + "github.com/sabafly/gobot/internal/xppoint" +) + +// Member is the model entity for the Member schema. +type Member struct { + config `json:"-"` + // ID of the ent. + ID int `json:"id,omitempty"` + // Permission holds the value of the "permission" field. + Permission permissions.Permission `json:"permission,omitempty"` + // Xp holds the value of the "xp" field. + Xp xppoint.XP `json:"xp,omitempty"` + // UserID holds the value of the "user_id" field. + UserID snowflake.ID `json:"user_id,omitempty"` + // LastXp holds the value of the "last_xp" field. + LastXp time.Time `json:"last_xp,omitempty"` + // MessageCount holds the value of the "message_count" field. + MessageCount uint64 `json:"message_count,omitempty"` + // LastNotifiedLevel holds the value of the "last_notified_level" field. + LastNotifiedLevel *uint64 `json:"last_notified_level,omitempty"` + // Edges holds the relations/edges for other nodes in the graph. + // The values are being populated by the MemberQuery when eager-loading is set. + Edges MemberEdges `json:"edges"` + guild_members *snowflake.ID + selectValues sql.SelectValues +} + +// MemberEdges holds the relations/edges for other nodes in the graph. +type MemberEdges struct { + // Guild holds the value of the guild edge. + Guild *Guild `json:"guild,omitempty"` + // User holds the value of the user edge. + User *User `json:"user,omitempty"` + // loadedTypes holds the information for reporting if a + // type was loaded (or requested) in eager-loading or not. + loadedTypes [2]bool +} + +// GuildOrErr returns the Guild value or an error if the edge +// was not loaded in eager-loading, or loaded but was not found. +func (e MemberEdges) GuildOrErr() (*Guild, error) { + if e.Guild != nil { + return e.Guild, nil + } else if e.loadedTypes[0] { + return nil, &NotFoundError{label: guild.Label} + } + return nil, &NotLoadedError{edge: "guild"} +} + +// UserOrErr returns the User value or an error if the edge +// was not loaded in eager-loading, or loaded but was not found. +func (e MemberEdges) UserOrErr() (*User, error) { + if e.User != nil { + return e.User, nil + } else if e.loadedTypes[1] { + return nil, &NotFoundError{label: user.Label} + } + return nil, &NotLoadedError{edge: "user"} +} + +// scanValues returns the types for scanning values from sql.Rows. +func (*Member) scanValues(columns []string) ([]any, error) { + values := make([]any, len(columns)) + for i := range columns { + switch columns[i] { + case member.FieldPermission: + values[i] = new([]byte) + case member.FieldID, member.FieldXp, member.FieldUserID, member.FieldMessageCount, member.FieldLastNotifiedLevel: + values[i] = new(sql.NullInt64) + case member.FieldLastXp: + values[i] = new(sql.NullTime) + case member.ForeignKeys[0]: // guild_members + values[i] = new(sql.NullInt64) + default: + values[i] = new(sql.UnknownType) + } + } + return values, nil +} + +// assignValues assigns the values that were returned from sql.Rows (after scanning) +// to the Member fields. +func (m *Member) assignValues(columns []string, values []any) error { + if m, n := len(values), len(columns); m < n { + return fmt.Errorf("mismatch number of scan values: %d != %d", m, n) + } + for i := range columns { + switch columns[i] { + case member.FieldID: + value, ok := values[i].(*sql.NullInt64) + if !ok { + return fmt.Errorf("unexpected type %T for field id", value) + } + m.ID = int(value.Int64) + case member.FieldPermission: + if value, ok := values[i].(*[]byte); !ok { + return fmt.Errorf("unexpected type %T for field permission", values[i]) + } else if value != nil && len(*value) > 0 { + if err := json.Unmarshal(*value, &m.Permission); err != nil { + return fmt.Errorf("unmarshal field permission: %w", err) + } + } + case member.FieldXp: + if value, ok := values[i].(*sql.NullInt64); !ok { + return fmt.Errorf("unexpected type %T for field xp", values[i]) + } else if value.Valid { + m.Xp = xppoint.XP(value.Int64) + } + case member.FieldUserID: + if value, ok := values[i].(*sql.NullInt64); !ok { + return fmt.Errorf("unexpected type %T for field user_id", values[i]) + } else if value.Valid { + m.UserID = snowflake.ID(value.Int64) + } + case member.FieldLastXp: + if value, ok := values[i].(*sql.NullTime); !ok { + return fmt.Errorf("unexpected type %T for field last_xp", values[i]) + } else if value.Valid { + m.LastXp = value.Time + } + case member.FieldMessageCount: + if value, ok := values[i].(*sql.NullInt64); !ok { + return fmt.Errorf("unexpected type %T for field message_count", values[i]) + } else if value.Valid { + m.MessageCount = uint64(value.Int64) + } + case member.FieldLastNotifiedLevel: + if value, ok := values[i].(*sql.NullInt64); !ok { + return fmt.Errorf("unexpected type %T for field last_notified_level", values[i]) + } else if value.Valid { + m.LastNotifiedLevel = new(uint64) + *m.LastNotifiedLevel = uint64(value.Int64) + } + case member.ForeignKeys[0]: + if value, ok := values[i].(*sql.NullInt64); !ok { + return fmt.Errorf("unexpected type %T for field guild_members", values[i]) + } else if value.Valid { + m.guild_members = new(snowflake.ID) + *m.guild_members = snowflake.ID(value.Int64) + } + default: + m.selectValues.Set(columns[i], values[i]) + } + } + return nil +} + +// Value returns the ent.Value that was dynamically selected and assigned to the Member. +// This includes values selected through modifiers, order, etc. +func (m *Member) Value(name string) (ent.Value, error) { + return m.selectValues.Get(name) +} + +// QueryGuild queries the "guild" edge of the Member entity. +func (m *Member) QueryGuild() *GuildQuery { + return NewMemberClient(m.config).QueryGuild(m) +} + +// QueryUser queries the "user" edge of the Member entity. +func (m *Member) QueryUser() *UserQuery { + return NewMemberClient(m.config).QueryUser(m) +} + +// Update returns a builder for updating this Member. +// Note that you need to call Member.Unwrap() before calling this method if this Member +// was returned from a transaction, and the transaction was committed or rolled back. +func (m *Member) Update() *MemberUpdateOne { + return NewMemberClient(m.config).UpdateOne(m) +} + +// Unwrap unwraps the Member entity that was returned from a transaction after it was closed, +// so that all future queries will be executed through the driver which created the transaction. +func (m *Member) Unwrap() *Member { + _tx, ok := m.config.driver.(*txDriver) + if !ok { + panic("ent: Member is not a transactional entity") + } + m.config.driver = _tx.drv + return m +} + +// String implements the fmt.Stringer. +func (m *Member) String() string { + var builder strings.Builder + builder.WriteString("Member(") + builder.WriteString(fmt.Sprintf("id=%v, ", m.ID)) + builder.WriteString("permission=") + builder.WriteString(fmt.Sprintf("%v", m.Permission)) + builder.WriteString(", ") + builder.WriteString("xp=") + builder.WriteString(fmt.Sprintf("%v", m.Xp)) + builder.WriteString(", ") + builder.WriteString("user_id=") + builder.WriteString(fmt.Sprintf("%v", m.UserID)) + builder.WriteString(", ") + builder.WriteString("last_xp=") + builder.WriteString(m.LastXp.Format(time.ANSIC)) + builder.WriteString(", ") + builder.WriteString("message_count=") + builder.WriteString(fmt.Sprintf("%v", m.MessageCount)) + builder.WriteString(", ") + if v := m.LastNotifiedLevel; v != nil { + builder.WriteString("last_notified_level=") + builder.WriteString(fmt.Sprintf("%v", *v)) + } + builder.WriteByte(')') + return builder.String() +} + +// Members is a parsable slice of Member. +type Members []*Member diff --git a/ent/member/member.go b/ent/member/member.go new file mode 100644 index 00000000..a27ba0af --- /dev/null +++ b/ent/member/member.go @@ -0,0 +1,151 @@ +// Code generated by ent, DO NOT EDIT. + +package member + +import ( + "entgo.io/ent/dialect/sql" + "entgo.io/ent/dialect/sql/sqlgraph" + "github.com/sabafly/gobot/internal/permissions" + "github.com/sabafly/gobot/internal/xppoint" +) + +const ( + // Label holds the string label denoting the member type in the database. + Label = "member" + // FieldID holds the string denoting the id field in the database. + FieldID = "id" + // FieldPermission holds the string denoting the permission field in the database. + FieldPermission = "permission" + // FieldXp holds the string denoting the xp field in the database. + FieldXp = "xp" + // FieldUserID holds the string denoting the user_id field in the database. + FieldUserID = "user_id" + // FieldLastXp holds the string denoting the last_xp field in the database. + FieldLastXp = "last_xp" + // FieldMessageCount holds the string denoting the message_count field in the database. + FieldMessageCount = "message_count" + // FieldLastNotifiedLevel holds the string denoting the last_notified_level field in the database. + FieldLastNotifiedLevel = "last_notified_level" + // EdgeGuild holds the string denoting the guild edge name in mutations. + EdgeGuild = "guild" + // EdgeUser holds the string denoting the user edge name in mutations. + EdgeUser = "user" + // Table holds the table name of the member in the database. + Table = "members" + // GuildTable is the table that holds the guild relation/edge. + GuildTable = "members" + // GuildInverseTable is the table name for the Guild entity. + // It exists in this package in order to avoid circular dependency with the "guild" package. + GuildInverseTable = "guilds" + // GuildColumn is the table column denoting the guild relation/edge. + GuildColumn = "guild_members" + // UserTable is the table that holds the user relation/edge. + UserTable = "members" + // UserInverseTable is the table name for the User entity. + // It exists in this package in order to avoid circular dependency with the "user" package. + UserInverseTable = "users" + // UserColumn is the table column denoting the user relation/edge. + UserColumn = "user_id" +) + +// Columns holds all SQL columns for member fields. +var Columns = []string{ + FieldID, + FieldPermission, + FieldXp, + FieldUserID, + FieldLastXp, + FieldMessageCount, + FieldLastNotifiedLevel, +} + +// ForeignKeys holds the SQL foreign-keys that are owned by the "members" +// table and are not defined as standalone fields in the schema. +var ForeignKeys = []string{ + "guild_members", +} + +// ValidColumn reports if the column name is valid (part of the table columns). +func ValidColumn(column string) bool { + for i := range Columns { + if column == Columns[i] { + return true + } + } + for i := range ForeignKeys { + if column == ForeignKeys[i] { + return true + } + } + return false +} + +var ( + // DefaultPermission holds the default value on creation for the "permission" field. + DefaultPermission permissions.Permission + // DefaultXp holds the default value on creation for the "xp" field. + DefaultXp xppoint.XP + // DefaultMessageCount holds the default value on creation for the "message_count" field. + DefaultMessageCount uint64 +) + +// OrderOption defines the ordering options for the Member queries. +type OrderOption func(*sql.Selector) + +// ByID orders the results by the id field. +func ByID(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldID, opts...).ToFunc() +} + +// ByXp orders the results by the xp field. +func ByXp(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldXp, opts...).ToFunc() +} + +// ByUserID orders the results by the user_id field. +func ByUserID(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldUserID, opts...).ToFunc() +} + +// ByLastXp orders the results by the last_xp field. +func ByLastXp(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldLastXp, opts...).ToFunc() +} + +// ByMessageCount orders the results by the message_count field. +func ByMessageCount(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldMessageCount, opts...).ToFunc() +} + +// ByLastNotifiedLevel orders the results by the last_notified_level field. +func ByLastNotifiedLevel(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldLastNotifiedLevel, opts...).ToFunc() +} + +// ByGuildField orders the results by guild field. +func ByGuildField(field string, opts ...sql.OrderTermOption) OrderOption { + return func(s *sql.Selector) { + sqlgraph.OrderByNeighborTerms(s, newGuildStep(), sql.OrderByField(field, opts...)) + } +} + +// ByUserField orders the results by user field. +func ByUserField(field string, opts ...sql.OrderTermOption) OrderOption { + return func(s *sql.Selector) { + sqlgraph.OrderByNeighborTerms(s, newUserStep(), sql.OrderByField(field, opts...)) + } +} +func newGuildStep() *sqlgraph.Step { + return sqlgraph.NewStep( + sqlgraph.From(Table, FieldID), + sqlgraph.To(GuildInverseTable, FieldID), + sqlgraph.Edge(sqlgraph.M2O, true, GuildTable, GuildColumn), + ) +} +func newUserStep() *sqlgraph.Step { + return sqlgraph.NewStep( + sqlgraph.From(Table, FieldID), + sqlgraph.To(UserInverseTable, FieldID), + sqlgraph.Edge(sqlgraph.M2O, true, UserTable, UserColumn), + ) +} diff --git a/ent/member/where.go b/ent/member/where.go new file mode 100644 index 00000000..2012af08 --- /dev/null +++ b/ent/member/where.go @@ -0,0 +1,380 @@ +// Code generated by ent, DO NOT EDIT. + +package member + +import ( + "time" + + "entgo.io/ent/dialect/sql" + "entgo.io/ent/dialect/sql/sqlgraph" + snowflake "github.com/disgoorg/snowflake/v2" + "github.com/sabafly/gobot/ent/predicate" + "github.com/sabafly/gobot/internal/xppoint" +) + +// ID filters vertices based on their ID field. +func ID(id int) predicate.Member { + return predicate.Member(sql.FieldEQ(FieldID, id)) +} + +// IDEQ applies the EQ predicate on the ID field. +func IDEQ(id int) predicate.Member { + return predicate.Member(sql.FieldEQ(FieldID, id)) +} + +// IDNEQ applies the NEQ predicate on the ID field. +func IDNEQ(id int) predicate.Member { + return predicate.Member(sql.FieldNEQ(FieldID, id)) +} + +// IDIn applies the In predicate on the ID field. +func IDIn(ids ...int) predicate.Member { + return predicate.Member(sql.FieldIn(FieldID, ids...)) +} + +// IDNotIn applies the NotIn predicate on the ID field. +func IDNotIn(ids ...int) predicate.Member { + return predicate.Member(sql.FieldNotIn(FieldID, ids...)) +} + +// IDGT applies the GT predicate on the ID field. +func IDGT(id int) predicate.Member { + return predicate.Member(sql.FieldGT(FieldID, id)) +} + +// IDGTE applies the GTE predicate on the ID field. +func IDGTE(id int) predicate.Member { + return predicate.Member(sql.FieldGTE(FieldID, id)) +} + +// IDLT applies the LT predicate on the ID field. +func IDLT(id int) predicate.Member { + return predicate.Member(sql.FieldLT(FieldID, id)) +} + +// IDLTE applies the LTE predicate on the ID field. +func IDLTE(id int) predicate.Member { + return predicate.Member(sql.FieldLTE(FieldID, id)) +} + +// Xp applies equality check predicate on the "xp" field. It's identical to XpEQ. +func Xp(v xppoint.XP) predicate.Member { + vc := uint64(v) + return predicate.Member(sql.FieldEQ(FieldXp, vc)) +} + +// UserID applies equality check predicate on the "user_id" field. It's identical to UserIDEQ. +func UserID(v snowflake.ID) predicate.Member { + vc := uint64(v) + return predicate.Member(sql.FieldEQ(FieldUserID, vc)) +} + +// LastXp applies equality check predicate on the "last_xp" field. It's identical to LastXpEQ. +func LastXp(v time.Time) predicate.Member { + return predicate.Member(sql.FieldEQ(FieldLastXp, v)) +} + +// MessageCount applies equality check predicate on the "message_count" field. It's identical to MessageCountEQ. +func MessageCount(v uint64) predicate.Member { + return predicate.Member(sql.FieldEQ(FieldMessageCount, v)) +} + +// LastNotifiedLevel applies equality check predicate on the "last_notified_level" field. It's identical to LastNotifiedLevelEQ. +func LastNotifiedLevel(v uint64) predicate.Member { + return predicate.Member(sql.FieldEQ(FieldLastNotifiedLevel, v)) +} + +// PermissionIsNil applies the IsNil predicate on the "permission" field. +func PermissionIsNil() predicate.Member { + return predicate.Member(sql.FieldIsNull(FieldPermission)) +} + +// PermissionNotNil applies the NotNil predicate on the "permission" field. +func PermissionNotNil() predicate.Member { + return predicate.Member(sql.FieldNotNull(FieldPermission)) +} + +// XpEQ applies the EQ predicate on the "xp" field. +func XpEQ(v xppoint.XP) predicate.Member { + vc := uint64(v) + return predicate.Member(sql.FieldEQ(FieldXp, vc)) +} + +// XpNEQ applies the NEQ predicate on the "xp" field. +func XpNEQ(v xppoint.XP) predicate.Member { + vc := uint64(v) + return predicate.Member(sql.FieldNEQ(FieldXp, vc)) +} + +// XpIn applies the In predicate on the "xp" field. +func XpIn(vs ...xppoint.XP) predicate.Member { + v := make([]any, len(vs)) + for i := range v { + v[i] = uint64(vs[i]) + } + return predicate.Member(sql.FieldIn(FieldXp, v...)) +} + +// XpNotIn applies the NotIn predicate on the "xp" field. +func XpNotIn(vs ...xppoint.XP) predicate.Member { + v := make([]any, len(vs)) + for i := range v { + v[i] = uint64(vs[i]) + } + return predicate.Member(sql.FieldNotIn(FieldXp, v...)) +} + +// XpGT applies the GT predicate on the "xp" field. +func XpGT(v xppoint.XP) predicate.Member { + vc := uint64(v) + return predicate.Member(sql.FieldGT(FieldXp, vc)) +} + +// XpGTE applies the GTE predicate on the "xp" field. +func XpGTE(v xppoint.XP) predicate.Member { + vc := uint64(v) + return predicate.Member(sql.FieldGTE(FieldXp, vc)) +} + +// XpLT applies the LT predicate on the "xp" field. +func XpLT(v xppoint.XP) predicate.Member { + vc := uint64(v) + return predicate.Member(sql.FieldLT(FieldXp, vc)) +} + +// XpLTE applies the LTE predicate on the "xp" field. +func XpLTE(v xppoint.XP) predicate.Member { + vc := uint64(v) + return predicate.Member(sql.FieldLTE(FieldXp, vc)) +} + +// UserIDEQ applies the EQ predicate on the "user_id" field. +func UserIDEQ(v snowflake.ID) predicate.Member { + vc := uint64(v) + return predicate.Member(sql.FieldEQ(FieldUserID, vc)) +} + +// UserIDNEQ applies the NEQ predicate on the "user_id" field. +func UserIDNEQ(v snowflake.ID) predicate.Member { + vc := uint64(v) + return predicate.Member(sql.FieldNEQ(FieldUserID, vc)) +} + +// UserIDIn applies the In predicate on the "user_id" field. +func UserIDIn(vs ...snowflake.ID) predicate.Member { + v := make([]any, len(vs)) + for i := range v { + v[i] = uint64(vs[i]) + } + return predicate.Member(sql.FieldIn(FieldUserID, v...)) +} + +// UserIDNotIn applies the NotIn predicate on the "user_id" field. +func UserIDNotIn(vs ...snowflake.ID) predicate.Member { + v := make([]any, len(vs)) + for i := range v { + v[i] = uint64(vs[i]) + } + return predicate.Member(sql.FieldNotIn(FieldUserID, v...)) +} + +// LastXpEQ applies the EQ predicate on the "last_xp" field. +func LastXpEQ(v time.Time) predicate.Member { + return predicate.Member(sql.FieldEQ(FieldLastXp, v)) +} + +// LastXpNEQ applies the NEQ predicate on the "last_xp" field. +func LastXpNEQ(v time.Time) predicate.Member { + return predicate.Member(sql.FieldNEQ(FieldLastXp, v)) +} + +// LastXpIn applies the In predicate on the "last_xp" field. +func LastXpIn(vs ...time.Time) predicate.Member { + return predicate.Member(sql.FieldIn(FieldLastXp, vs...)) +} + +// LastXpNotIn applies the NotIn predicate on the "last_xp" field. +func LastXpNotIn(vs ...time.Time) predicate.Member { + return predicate.Member(sql.FieldNotIn(FieldLastXp, vs...)) +} + +// LastXpGT applies the GT predicate on the "last_xp" field. +func LastXpGT(v time.Time) predicate.Member { + return predicate.Member(sql.FieldGT(FieldLastXp, v)) +} + +// LastXpGTE applies the GTE predicate on the "last_xp" field. +func LastXpGTE(v time.Time) predicate.Member { + return predicate.Member(sql.FieldGTE(FieldLastXp, v)) +} + +// LastXpLT applies the LT predicate on the "last_xp" field. +func LastXpLT(v time.Time) predicate.Member { + return predicate.Member(sql.FieldLT(FieldLastXp, v)) +} + +// LastXpLTE applies the LTE predicate on the "last_xp" field. +func LastXpLTE(v time.Time) predicate.Member { + return predicate.Member(sql.FieldLTE(FieldLastXp, v)) +} + +// LastXpIsNil applies the IsNil predicate on the "last_xp" field. +func LastXpIsNil() predicate.Member { + return predicate.Member(sql.FieldIsNull(FieldLastXp)) +} + +// LastXpNotNil applies the NotNil predicate on the "last_xp" field. +func LastXpNotNil() predicate.Member { + return predicate.Member(sql.FieldNotNull(FieldLastXp)) +} + +// MessageCountEQ applies the EQ predicate on the "message_count" field. +func MessageCountEQ(v uint64) predicate.Member { + return predicate.Member(sql.FieldEQ(FieldMessageCount, v)) +} + +// MessageCountNEQ applies the NEQ predicate on the "message_count" field. +func MessageCountNEQ(v uint64) predicate.Member { + return predicate.Member(sql.FieldNEQ(FieldMessageCount, v)) +} + +// MessageCountIn applies the In predicate on the "message_count" field. +func MessageCountIn(vs ...uint64) predicate.Member { + return predicate.Member(sql.FieldIn(FieldMessageCount, vs...)) +} + +// MessageCountNotIn applies the NotIn predicate on the "message_count" field. +func MessageCountNotIn(vs ...uint64) predicate.Member { + return predicate.Member(sql.FieldNotIn(FieldMessageCount, vs...)) +} + +// MessageCountGT applies the GT predicate on the "message_count" field. +func MessageCountGT(v uint64) predicate.Member { + return predicate.Member(sql.FieldGT(FieldMessageCount, v)) +} + +// MessageCountGTE applies the GTE predicate on the "message_count" field. +func MessageCountGTE(v uint64) predicate.Member { + return predicate.Member(sql.FieldGTE(FieldMessageCount, v)) +} + +// MessageCountLT applies the LT predicate on the "message_count" field. +func MessageCountLT(v uint64) predicate.Member { + return predicate.Member(sql.FieldLT(FieldMessageCount, v)) +} + +// MessageCountLTE applies the LTE predicate on the "message_count" field. +func MessageCountLTE(v uint64) predicate.Member { + return predicate.Member(sql.FieldLTE(FieldMessageCount, v)) +} + +// LastNotifiedLevelEQ applies the EQ predicate on the "last_notified_level" field. +func LastNotifiedLevelEQ(v uint64) predicate.Member { + return predicate.Member(sql.FieldEQ(FieldLastNotifiedLevel, v)) +} + +// LastNotifiedLevelNEQ applies the NEQ predicate on the "last_notified_level" field. +func LastNotifiedLevelNEQ(v uint64) predicate.Member { + return predicate.Member(sql.FieldNEQ(FieldLastNotifiedLevel, v)) +} + +// LastNotifiedLevelIn applies the In predicate on the "last_notified_level" field. +func LastNotifiedLevelIn(vs ...uint64) predicate.Member { + return predicate.Member(sql.FieldIn(FieldLastNotifiedLevel, vs...)) +} + +// LastNotifiedLevelNotIn applies the NotIn predicate on the "last_notified_level" field. +func LastNotifiedLevelNotIn(vs ...uint64) predicate.Member { + return predicate.Member(sql.FieldNotIn(FieldLastNotifiedLevel, vs...)) +} + +// LastNotifiedLevelGT applies the GT predicate on the "last_notified_level" field. +func LastNotifiedLevelGT(v uint64) predicate.Member { + return predicate.Member(sql.FieldGT(FieldLastNotifiedLevel, v)) +} + +// LastNotifiedLevelGTE applies the GTE predicate on the "last_notified_level" field. +func LastNotifiedLevelGTE(v uint64) predicate.Member { + return predicate.Member(sql.FieldGTE(FieldLastNotifiedLevel, v)) +} + +// LastNotifiedLevelLT applies the LT predicate on the "last_notified_level" field. +func LastNotifiedLevelLT(v uint64) predicate.Member { + return predicate.Member(sql.FieldLT(FieldLastNotifiedLevel, v)) +} + +// LastNotifiedLevelLTE applies the LTE predicate on the "last_notified_level" field. +func LastNotifiedLevelLTE(v uint64) predicate.Member { + return predicate.Member(sql.FieldLTE(FieldLastNotifiedLevel, v)) +} + +// LastNotifiedLevelIsNil applies the IsNil predicate on the "last_notified_level" field. +func LastNotifiedLevelIsNil() predicate.Member { + return predicate.Member(sql.FieldIsNull(FieldLastNotifiedLevel)) +} + +// LastNotifiedLevelNotNil applies the NotNil predicate on the "last_notified_level" field. +func LastNotifiedLevelNotNil() predicate.Member { + return predicate.Member(sql.FieldNotNull(FieldLastNotifiedLevel)) +} + +// HasGuild applies the HasEdge predicate on the "guild" edge. +func HasGuild() predicate.Member { + return predicate.Member(func(s *sql.Selector) { + step := sqlgraph.NewStep( + sqlgraph.From(Table, FieldID), + sqlgraph.Edge(sqlgraph.M2O, true, GuildTable, GuildColumn), + ) + sqlgraph.HasNeighbors(s, step) + }) +} + +// HasGuildWith applies the HasEdge predicate on the "guild" edge with a given conditions (other predicates). +func HasGuildWith(preds ...predicate.Guild) predicate.Member { + return predicate.Member(func(s *sql.Selector) { + step := newGuildStep() + sqlgraph.HasNeighborsWith(s, step, func(s *sql.Selector) { + for _, p := range preds { + p(s) + } + }) + }) +} + +// HasUser applies the HasEdge predicate on the "user" edge. +func HasUser() predicate.Member { + return predicate.Member(func(s *sql.Selector) { + step := sqlgraph.NewStep( + sqlgraph.From(Table, FieldID), + sqlgraph.Edge(sqlgraph.M2O, true, UserTable, UserColumn), + ) + sqlgraph.HasNeighbors(s, step) + }) +} + +// HasUserWith applies the HasEdge predicate on the "user" edge with a given conditions (other predicates). +func HasUserWith(preds ...predicate.User) predicate.Member { + return predicate.Member(func(s *sql.Selector) { + step := newUserStep() + sqlgraph.HasNeighborsWith(s, step, func(s *sql.Selector) { + for _, p := range preds { + p(s) + } + }) + }) +} + +// And groups predicates with the AND operator between them. +func And(predicates ...predicate.Member) predicate.Member { + return predicate.Member(sql.AndPredicates(predicates...)) +} + +// Or groups predicates with the OR operator between them. +func Or(predicates ...predicate.Member) predicate.Member { + return predicate.Member(sql.OrPredicates(predicates...)) +} + +// Not applies the not operator on the given predicate. +func Not(p predicate.Member) predicate.Member { + return predicate.Member(sql.NotPredicates(p)) +} diff --git a/ent/member_create.go b/ent/member_create.go new file mode 100644 index 00000000..8d1d9383 --- /dev/null +++ b/ent/member_create.go @@ -0,0 +1,355 @@ +// Code generated by ent, DO NOT EDIT. + +package ent + +import ( + "context" + "errors" + "fmt" + "time" + + "entgo.io/ent/dialect/sql/sqlgraph" + "entgo.io/ent/schema/field" + snowflake "github.com/disgoorg/snowflake/v2" + "github.com/sabafly/gobot/ent/guild" + "github.com/sabafly/gobot/ent/member" + "github.com/sabafly/gobot/ent/user" + "github.com/sabafly/gobot/internal/permissions" + "github.com/sabafly/gobot/internal/xppoint" +) + +// MemberCreate is the builder for creating a Member entity. +type MemberCreate struct { + config + mutation *MemberMutation + hooks []Hook +} + +// SetPermission sets the "permission" field. +func (mc *MemberCreate) SetPermission(pe permissions.Permission) *MemberCreate { + mc.mutation.SetPermission(pe) + return mc +} + +// SetNillablePermission sets the "permission" field if the given value is not nil. +func (mc *MemberCreate) SetNillablePermission(pe *permissions.Permission) *MemberCreate { + if pe != nil { + mc.SetPermission(*pe) + } + return mc +} + +// SetXp sets the "xp" field. +func (mc *MemberCreate) SetXp(x xppoint.XP) *MemberCreate { + mc.mutation.SetXp(x) + return mc +} + +// SetNillableXp sets the "xp" field if the given value is not nil. +func (mc *MemberCreate) SetNillableXp(x *xppoint.XP) *MemberCreate { + if x != nil { + mc.SetXp(*x) + } + return mc +} + +// SetUserID sets the "user_id" field. +func (mc *MemberCreate) SetUserID(s snowflake.ID) *MemberCreate { + mc.mutation.SetUserID(s) + return mc +} + +// SetLastXp sets the "last_xp" field. +func (mc *MemberCreate) SetLastXp(t time.Time) *MemberCreate { + mc.mutation.SetLastXp(t) + return mc +} + +// SetNillableLastXp sets the "last_xp" field if the given value is not nil. +func (mc *MemberCreate) SetNillableLastXp(t *time.Time) *MemberCreate { + if t != nil { + mc.SetLastXp(*t) + } + return mc +} + +// SetMessageCount sets the "message_count" field. +func (mc *MemberCreate) SetMessageCount(u uint64) *MemberCreate { + mc.mutation.SetMessageCount(u) + return mc +} + +// SetNillableMessageCount sets the "message_count" field if the given value is not nil. +func (mc *MemberCreate) SetNillableMessageCount(u *uint64) *MemberCreate { + if u != nil { + mc.SetMessageCount(*u) + } + return mc +} + +// SetLastNotifiedLevel sets the "last_notified_level" field. +func (mc *MemberCreate) SetLastNotifiedLevel(u uint64) *MemberCreate { + mc.mutation.SetLastNotifiedLevel(u) + return mc +} + +// SetNillableLastNotifiedLevel sets the "last_notified_level" field if the given value is not nil. +func (mc *MemberCreate) SetNillableLastNotifiedLevel(u *uint64) *MemberCreate { + if u != nil { + mc.SetLastNotifiedLevel(*u) + } + return mc +} + +// SetGuildID sets the "guild" edge to the Guild entity by ID. +func (mc *MemberCreate) SetGuildID(id snowflake.ID) *MemberCreate { + mc.mutation.SetGuildID(id) + return mc +} + +// SetGuild sets the "guild" edge to the Guild entity. +func (mc *MemberCreate) SetGuild(g *Guild) *MemberCreate { + return mc.SetGuildID(g.ID) +} + +// SetUser sets the "user" edge to the User entity. +func (mc *MemberCreate) SetUser(u *User) *MemberCreate { + return mc.SetUserID(u.ID) +} + +// Mutation returns the MemberMutation object of the builder. +func (mc *MemberCreate) Mutation() *MemberMutation { + return mc.mutation +} + +// Save creates the Member in the database. +func (mc *MemberCreate) Save(ctx context.Context) (*Member, error) { + mc.defaults() + return withHooks(ctx, mc.sqlSave, mc.mutation, mc.hooks) +} + +// SaveX calls Save and panics if Save returns an error. +func (mc *MemberCreate) SaveX(ctx context.Context) *Member { + v, err := mc.Save(ctx) + if err != nil { + panic(err) + } + return v +} + +// Exec executes the query. +func (mc *MemberCreate) Exec(ctx context.Context) error { + _, err := mc.Save(ctx) + return err +} + +// ExecX is like Exec, but panics if an error occurs. +func (mc *MemberCreate) ExecX(ctx context.Context) { + if err := mc.Exec(ctx); err != nil { + panic(err) + } +} + +// defaults sets the default values of the builder before save. +func (mc *MemberCreate) defaults() { + if _, ok := mc.mutation.Permission(); !ok { + v := member.DefaultPermission + mc.mutation.SetPermission(v) + } + if _, ok := mc.mutation.Xp(); !ok { + v := member.DefaultXp + mc.mutation.SetXp(v) + } + if _, ok := mc.mutation.MessageCount(); !ok { + v := member.DefaultMessageCount + mc.mutation.SetMessageCount(v) + } +} + +// check runs all checks and user-defined validators on the builder. +func (mc *MemberCreate) check() error { + if _, ok := mc.mutation.Xp(); !ok { + return &ValidationError{Name: "xp", err: errors.New(`ent: missing required field "Member.xp"`)} + } + if _, ok := mc.mutation.UserID(); !ok { + return &ValidationError{Name: "user_id", err: errors.New(`ent: missing required field "Member.user_id"`)} + } + if _, ok := mc.mutation.MessageCount(); !ok { + return &ValidationError{Name: "message_count", err: errors.New(`ent: missing required field "Member.message_count"`)} + } + if _, ok := mc.mutation.GuildID(); !ok { + return &ValidationError{Name: "guild", err: errors.New(`ent: missing required edge "Member.guild"`)} + } + if _, ok := mc.mutation.UserID(); !ok { + return &ValidationError{Name: "user", err: errors.New(`ent: missing required edge "Member.user"`)} + } + return nil +} + +func (mc *MemberCreate) sqlSave(ctx context.Context) (*Member, error) { + if err := mc.check(); err != nil { + return nil, err + } + _node, _spec := mc.createSpec() + if err := sqlgraph.CreateNode(ctx, mc.driver, _spec); err != nil { + if sqlgraph.IsConstraintError(err) { + err = &ConstraintError{msg: err.Error(), wrap: err} + } + return nil, err + } + id := _spec.ID.Value.(int64) + _node.ID = int(id) + mc.mutation.id = &_node.ID + mc.mutation.done = true + return _node, nil +} + +func (mc *MemberCreate) createSpec() (*Member, *sqlgraph.CreateSpec) { + var ( + _node = &Member{config: mc.config} + _spec = sqlgraph.NewCreateSpec(member.Table, sqlgraph.NewFieldSpec(member.FieldID, field.TypeInt)) + ) + if value, ok := mc.mutation.Permission(); ok { + _spec.SetField(member.FieldPermission, field.TypeJSON, value) + _node.Permission = value + } + if value, ok := mc.mutation.Xp(); ok { + _spec.SetField(member.FieldXp, field.TypeUint64, value) + _node.Xp = value + } + if value, ok := mc.mutation.LastXp(); ok { + _spec.SetField(member.FieldLastXp, field.TypeTime, value) + _node.LastXp = value + } + if value, ok := mc.mutation.MessageCount(); ok { + _spec.SetField(member.FieldMessageCount, field.TypeUint64, value) + _node.MessageCount = value + } + if value, ok := mc.mutation.LastNotifiedLevel(); ok { + _spec.SetField(member.FieldLastNotifiedLevel, field.TypeUint64, value) + _node.LastNotifiedLevel = &value + } + if nodes := mc.mutation.GuildIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.M2O, + Inverse: true, + Table: member.GuildTable, + Columns: []string{member.GuildColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(guild.FieldID, field.TypeUint64), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _node.guild_members = &nodes[0] + _spec.Edges = append(_spec.Edges, edge) + } + if nodes := mc.mutation.UserIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.M2O, + Inverse: true, + Table: member.UserTable, + Columns: []string{member.UserColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(user.FieldID, field.TypeUint64), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _node.UserID = nodes[0] + _spec.Edges = append(_spec.Edges, edge) + } + return _node, _spec +} + +// MemberCreateBulk is the builder for creating many Member entities in bulk. +type MemberCreateBulk struct { + config + err error + builders []*MemberCreate +} + +// Save creates the Member entities in the database. +func (mcb *MemberCreateBulk) Save(ctx context.Context) ([]*Member, error) { + if mcb.err != nil { + return nil, mcb.err + } + specs := make([]*sqlgraph.CreateSpec, len(mcb.builders)) + nodes := make([]*Member, len(mcb.builders)) + mutators := make([]Mutator, len(mcb.builders)) + for i := range mcb.builders { + func(i int, root context.Context) { + builder := mcb.builders[i] + builder.defaults() + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*MemberMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + if err := builder.check(); err != nil { + return nil, err + } + builder.mutation = mutation + var err error + nodes[i], specs[i] = builder.createSpec() + if i < len(mutators)-1 { + _, err = mutators[i+1].Mutate(root, mcb.builders[i+1].mutation) + } else { + spec := &sqlgraph.BatchCreateSpec{Nodes: specs} + // Invoke the actual operation on the latest mutation in the chain. + if err = sqlgraph.BatchCreate(ctx, mcb.driver, spec); err != nil { + if sqlgraph.IsConstraintError(err) { + err = &ConstraintError{msg: err.Error(), wrap: err} + } + } + } + if err != nil { + return nil, err + } + mutation.id = &nodes[i].ID + if specs[i].ID.Value != nil { + id := specs[i].ID.Value.(int64) + nodes[i].ID = int(id) + } + mutation.done = true + return nodes[i], nil + }) + for i := len(builder.hooks) - 1; i >= 0; i-- { + mut = builder.hooks[i](mut) + } + mutators[i] = mut + }(i, ctx) + } + if len(mutators) > 0 { + if _, err := mutators[0].Mutate(ctx, mcb.builders[0].mutation); err != nil { + return nil, err + } + } + return nodes, nil +} + +// SaveX is like Save, but panics if an error occurs. +func (mcb *MemberCreateBulk) SaveX(ctx context.Context) []*Member { + v, err := mcb.Save(ctx) + if err != nil { + panic(err) + } + return v +} + +// Exec executes the query. +func (mcb *MemberCreateBulk) Exec(ctx context.Context) error { + _, err := mcb.Save(ctx) + return err +} + +// ExecX is like Exec, but panics if an error occurs. +func (mcb *MemberCreateBulk) ExecX(ctx context.Context) { + if err := mcb.Exec(ctx); err != nil { + panic(err) + } +} diff --git a/ent/member_delete.go b/ent/member_delete.go new file mode 100644 index 00000000..516325a3 --- /dev/null +++ b/ent/member_delete.go @@ -0,0 +1,88 @@ +// Code generated by ent, DO NOT EDIT. + +package ent + +import ( + "context" + + "entgo.io/ent/dialect/sql" + "entgo.io/ent/dialect/sql/sqlgraph" + "entgo.io/ent/schema/field" + "github.com/sabafly/gobot/ent/member" + "github.com/sabafly/gobot/ent/predicate" +) + +// MemberDelete is the builder for deleting a Member entity. +type MemberDelete struct { + config + hooks []Hook + mutation *MemberMutation +} + +// Where appends a list predicates to the MemberDelete builder. +func (md *MemberDelete) Where(ps ...predicate.Member) *MemberDelete { + md.mutation.Where(ps...) + return md +} + +// Exec executes the deletion query and returns how many vertices were deleted. +func (md *MemberDelete) Exec(ctx context.Context) (int, error) { + return withHooks(ctx, md.sqlExec, md.mutation, md.hooks) +} + +// ExecX is like Exec, but panics if an error occurs. +func (md *MemberDelete) ExecX(ctx context.Context) int { + n, err := md.Exec(ctx) + if err != nil { + panic(err) + } + return n +} + +func (md *MemberDelete) sqlExec(ctx context.Context) (int, error) { + _spec := sqlgraph.NewDeleteSpec(member.Table, sqlgraph.NewFieldSpec(member.FieldID, field.TypeInt)) + if ps := md.mutation.predicates; len(ps) > 0 { + _spec.Predicate = func(selector *sql.Selector) { + for i := range ps { + ps[i](selector) + } + } + } + affected, err := sqlgraph.DeleteNodes(ctx, md.driver, _spec) + if err != nil && sqlgraph.IsConstraintError(err) { + err = &ConstraintError{msg: err.Error(), wrap: err} + } + md.mutation.done = true + return affected, err +} + +// MemberDeleteOne is the builder for deleting a single Member entity. +type MemberDeleteOne struct { + md *MemberDelete +} + +// Where appends a list predicates to the MemberDelete builder. +func (mdo *MemberDeleteOne) Where(ps ...predicate.Member) *MemberDeleteOne { + mdo.md.mutation.Where(ps...) + return mdo +} + +// Exec executes the deletion query. +func (mdo *MemberDeleteOne) Exec(ctx context.Context) error { + n, err := mdo.md.Exec(ctx) + switch { + case err != nil: + return err + case n == 0: + return &NotFoundError{member.Label} + default: + return nil + } +} + +// ExecX is like Exec, but panics if an error occurs. +func (mdo *MemberDeleteOne) ExecX(ctx context.Context) { + if err := mdo.Exec(ctx); err != nil { + panic(err) + } +} diff --git a/ent/member_query.go b/ent/member_query.go new file mode 100644 index 00000000..39d0c1c7 --- /dev/null +++ b/ent/member_query.go @@ -0,0 +1,689 @@ +// Code generated by ent, DO NOT EDIT. + +package ent + +import ( + "context" + "fmt" + "math" + + "entgo.io/ent/dialect/sql" + "entgo.io/ent/dialect/sql/sqlgraph" + "entgo.io/ent/schema/field" + snowflake "github.com/disgoorg/snowflake/v2" + "github.com/sabafly/gobot/ent/guild" + "github.com/sabafly/gobot/ent/member" + "github.com/sabafly/gobot/ent/predicate" + "github.com/sabafly/gobot/ent/user" +) + +// MemberQuery is the builder for querying Member entities. +type MemberQuery struct { + config + ctx *QueryContext + order []member.OrderOption + inters []Interceptor + predicates []predicate.Member + withGuild *GuildQuery + withUser *UserQuery + withFKs bool + // intermediate query (i.e. traversal path). + sql *sql.Selector + path func(context.Context) (*sql.Selector, error) +} + +// Where adds a new predicate for the MemberQuery builder. +func (mq *MemberQuery) Where(ps ...predicate.Member) *MemberQuery { + mq.predicates = append(mq.predicates, ps...) + return mq +} + +// Limit the number of records to be returned by this query. +func (mq *MemberQuery) Limit(limit int) *MemberQuery { + mq.ctx.Limit = &limit + return mq +} + +// Offset to start from. +func (mq *MemberQuery) Offset(offset int) *MemberQuery { + mq.ctx.Offset = &offset + return mq +} + +// Unique configures the query builder to filter duplicate records on query. +// By default, unique is set to true, and can be disabled using this method. +func (mq *MemberQuery) Unique(unique bool) *MemberQuery { + mq.ctx.Unique = &unique + return mq +} + +// Order specifies how the records should be ordered. +func (mq *MemberQuery) Order(o ...member.OrderOption) *MemberQuery { + mq.order = append(mq.order, o...) + return mq +} + +// QueryGuild chains the current query on the "guild" edge. +func (mq *MemberQuery) QueryGuild() *GuildQuery { + query := (&GuildClient{config: mq.config}).Query() + query.path = func(ctx context.Context) (fromU *sql.Selector, err error) { + if err := mq.prepareQuery(ctx); err != nil { + return nil, err + } + selector := mq.sqlQuery(ctx) + if err := selector.Err(); err != nil { + return nil, err + } + step := sqlgraph.NewStep( + sqlgraph.From(member.Table, member.FieldID, selector), + sqlgraph.To(guild.Table, guild.FieldID), + sqlgraph.Edge(sqlgraph.M2O, true, member.GuildTable, member.GuildColumn), + ) + fromU = sqlgraph.SetNeighbors(mq.driver.Dialect(), step) + return fromU, nil + } + return query +} + +// QueryUser chains the current query on the "user" edge. +func (mq *MemberQuery) QueryUser() *UserQuery { + query := (&UserClient{config: mq.config}).Query() + query.path = func(ctx context.Context) (fromU *sql.Selector, err error) { + if err := mq.prepareQuery(ctx); err != nil { + return nil, err + } + selector := mq.sqlQuery(ctx) + if err := selector.Err(); err != nil { + return nil, err + } + step := sqlgraph.NewStep( + sqlgraph.From(member.Table, member.FieldID, selector), + sqlgraph.To(user.Table, user.FieldID), + sqlgraph.Edge(sqlgraph.M2O, true, member.UserTable, member.UserColumn), + ) + fromU = sqlgraph.SetNeighbors(mq.driver.Dialect(), step) + return fromU, nil + } + return query +} + +// First returns the first Member entity from the query. +// Returns a *NotFoundError when no Member was found. +func (mq *MemberQuery) First(ctx context.Context) (*Member, error) { + nodes, err := mq.Limit(1).All(setContextOp(ctx, mq.ctx, "First")) + if err != nil { + return nil, err + } + if len(nodes) == 0 { + return nil, &NotFoundError{member.Label} + } + return nodes[0], nil +} + +// FirstX is like First, but panics if an error occurs. +func (mq *MemberQuery) FirstX(ctx context.Context) *Member { + node, err := mq.First(ctx) + if err != nil && !IsNotFound(err) { + panic(err) + } + return node +} + +// FirstID returns the first Member ID from the query. +// Returns a *NotFoundError when no Member ID was found. +func (mq *MemberQuery) FirstID(ctx context.Context) (id int, err error) { + var ids []int + if ids, err = mq.Limit(1).IDs(setContextOp(ctx, mq.ctx, "FirstID")); err != nil { + return + } + if len(ids) == 0 { + err = &NotFoundError{member.Label} + return + } + return ids[0], nil +} + +// FirstIDX is like FirstID, but panics if an error occurs. +func (mq *MemberQuery) FirstIDX(ctx context.Context) int { + id, err := mq.FirstID(ctx) + if err != nil && !IsNotFound(err) { + panic(err) + } + return id +} + +// Only returns a single Member entity found by the query, ensuring it only returns one. +// Returns a *NotSingularError when more than one Member entity is found. +// Returns a *NotFoundError when no Member entities are found. +func (mq *MemberQuery) Only(ctx context.Context) (*Member, error) { + nodes, err := mq.Limit(2).All(setContextOp(ctx, mq.ctx, "Only")) + if err != nil { + return nil, err + } + switch len(nodes) { + case 1: + return nodes[0], nil + case 0: + return nil, &NotFoundError{member.Label} + default: + return nil, &NotSingularError{member.Label} + } +} + +// OnlyX is like Only, but panics if an error occurs. +func (mq *MemberQuery) OnlyX(ctx context.Context) *Member { + node, err := mq.Only(ctx) + if err != nil { + panic(err) + } + return node +} + +// OnlyID is like Only, but returns the only Member ID in the query. +// Returns a *NotSingularError when more than one Member ID is found. +// Returns a *NotFoundError when no entities are found. +func (mq *MemberQuery) OnlyID(ctx context.Context) (id int, err error) { + var ids []int + if ids, err = mq.Limit(2).IDs(setContextOp(ctx, mq.ctx, "OnlyID")); err != nil { + return + } + switch len(ids) { + case 1: + id = ids[0] + case 0: + err = &NotFoundError{member.Label} + default: + err = &NotSingularError{member.Label} + } + return +} + +// OnlyIDX is like OnlyID, but panics if an error occurs. +func (mq *MemberQuery) OnlyIDX(ctx context.Context) int { + id, err := mq.OnlyID(ctx) + if err != nil { + panic(err) + } + return id +} + +// All executes the query and returns a list of Members. +func (mq *MemberQuery) All(ctx context.Context) ([]*Member, error) { + ctx = setContextOp(ctx, mq.ctx, "All") + if err := mq.prepareQuery(ctx); err != nil { + return nil, err + } + qr := querierAll[[]*Member, *MemberQuery]() + return withInterceptors[[]*Member](ctx, mq, qr, mq.inters) +} + +// AllX is like All, but panics if an error occurs. +func (mq *MemberQuery) AllX(ctx context.Context) []*Member { + nodes, err := mq.All(ctx) + if err != nil { + panic(err) + } + return nodes +} + +// IDs executes the query and returns a list of Member IDs. +func (mq *MemberQuery) IDs(ctx context.Context) (ids []int, err error) { + if mq.ctx.Unique == nil && mq.path != nil { + mq.Unique(true) + } + ctx = setContextOp(ctx, mq.ctx, "IDs") + if err = mq.Select(member.FieldID).Scan(ctx, &ids); err != nil { + return nil, err + } + return ids, nil +} + +// IDsX is like IDs, but panics if an error occurs. +func (mq *MemberQuery) IDsX(ctx context.Context) []int { + ids, err := mq.IDs(ctx) + if err != nil { + panic(err) + } + return ids +} + +// Count returns the count of the given query. +func (mq *MemberQuery) Count(ctx context.Context) (int, error) { + ctx = setContextOp(ctx, mq.ctx, "Count") + if err := mq.prepareQuery(ctx); err != nil { + return 0, err + } + return withInterceptors[int](ctx, mq, querierCount[*MemberQuery](), mq.inters) +} + +// CountX is like Count, but panics if an error occurs. +func (mq *MemberQuery) CountX(ctx context.Context) int { + count, err := mq.Count(ctx) + if err != nil { + panic(err) + } + return count +} + +// Exist returns true if the query has elements in the graph. +func (mq *MemberQuery) Exist(ctx context.Context) (bool, error) { + ctx = setContextOp(ctx, mq.ctx, "Exist") + switch _, err := mq.FirstID(ctx); { + case IsNotFound(err): + return false, nil + case err != nil: + return false, fmt.Errorf("ent: check existence: %w", err) + default: + return true, nil + } +} + +// ExistX is like Exist, but panics if an error occurs. +func (mq *MemberQuery) ExistX(ctx context.Context) bool { + exist, err := mq.Exist(ctx) + if err != nil { + panic(err) + } + return exist +} + +// Clone returns a duplicate of the MemberQuery builder, including all associated steps. It can be +// used to prepare common query builders and use them differently after the clone is made. +func (mq *MemberQuery) Clone() *MemberQuery { + if mq == nil { + return nil + } + return &MemberQuery{ + config: mq.config, + ctx: mq.ctx.Clone(), + order: append([]member.OrderOption{}, mq.order...), + inters: append([]Interceptor{}, mq.inters...), + predicates: append([]predicate.Member{}, mq.predicates...), + withGuild: mq.withGuild.Clone(), + withUser: mq.withUser.Clone(), + // clone intermediate query. + sql: mq.sql.Clone(), + path: mq.path, + } +} + +// WithGuild tells the query-builder to eager-load the nodes that are connected to +// the "guild" edge. The optional arguments are used to configure the query builder of the edge. +func (mq *MemberQuery) WithGuild(opts ...func(*GuildQuery)) *MemberQuery { + query := (&GuildClient{config: mq.config}).Query() + for _, opt := range opts { + opt(query) + } + mq.withGuild = query + return mq +} + +// WithUser tells the query-builder to eager-load the nodes that are connected to +// the "user" edge. The optional arguments are used to configure the query builder of the edge. +func (mq *MemberQuery) WithUser(opts ...func(*UserQuery)) *MemberQuery { + query := (&UserClient{config: mq.config}).Query() + for _, opt := range opts { + opt(query) + } + mq.withUser = query + return mq +} + +// GroupBy is used to group vertices by one or more fields/columns. +// It is often used with aggregate functions, like: count, max, mean, min, sum. +// +// Example: +// +// var v []struct { +// Permission permissions.Permission `json:"permission,omitempty"` +// Count int `json:"count,omitempty"` +// } +// +// client.Member.Query(). +// GroupBy(member.FieldPermission). +// Aggregate(ent.Count()). +// Scan(ctx, &v) +func (mq *MemberQuery) GroupBy(field string, fields ...string) *MemberGroupBy { + mq.ctx.Fields = append([]string{field}, fields...) + grbuild := &MemberGroupBy{build: mq} + grbuild.flds = &mq.ctx.Fields + grbuild.label = member.Label + grbuild.scan = grbuild.Scan + return grbuild +} + +// Select allows the selection one or more fields/columns for the given query, +// instead of selecting all fields in the entity. +// +// Example: +// +// var v []struct { +// Permission permissions.Permission `json:"permission,omitempty"` +// } +// +// client.Member.Query(). +// Select(member.FieldPermission). +// Scan(ctx, &v) +func (mq *MemberQuery) Select(fields ...string) *MemberSelect { + mq.ctx.Fields = append(mq.ctx.Fields, fields...) + sbuild := &MemberSelect{MemberQuery: mq} + sbuild.label = member.Label + sbuild.flds, sbuild.scan = &mq.ctx.Fields, sbuild.Scan + return sbuild +} + +// Aggregate returns a MemberSelect configured with the given aggregations. +func (mq *MemberQuery) Aggregate(fns ...AggregateFunc) *MemberSelect { + return mq.Select().Aggregate(fns...) +} + +func (mq *MemberQuery) prepareQuery(ctx context.Context) error { + for _, inter := range mq.inters { + if inter == nil { + return fmt.Errorf("ent: uninitialized interceptor (forgotten import ent/runtime?)") + } + if trv, ok := inter.(Traverser); ok { + if err := trv.Traverse(ctx, mq); err != nil { + return err + } + } + } + for _, f := range mq.ctx.Fields { + if !member.ValidColumn(f) { + return &ValidationError{Name: f, err: fmt.Errorf("ent: invalid field %q for query", f)} + } + } + if mq.path != nil { + prev, err := mq.path(ctx) + if err != nil { + return err + } + mq.sql = prev + } + return nil +} + +func (mq *MemberQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*Member, error) { + var ( + nodes = []*Member{} + withFKs = mq.withFKs + _spec = mq.querySpec() + loadedTypes = [2]bool{ + mq.withGuild != nil, + mq.withUser != nil, + } + ) + if mq.withGuild != nil { + withFKs = true + } + if withFKs { + _spec.Node.Columns = append(_spec.Node.Columns, member.ForeignKeys...) + } + _spec.ScanValues = func(columns []string) ([]any, error) { + return (*Member).scanValues(nil, columns) + } + _spec.Assign = func(columns []string, values []any) error { + node := &Member{config: mq.config} + nodes = append(nodes, node) + node.Edges.loadedTypes = loadedTypes + return node.assignValues(columns, values) + } + for i := range hooks { + hooks[i](ctx, _spec) + } + if err := sqlgraph.QueryNodes(ctx, mq.driver, _spec); err != nil { + return nil, err + } + if len(nodes) == 0 { + return nodes, nil + } + if query := mq.withGuild; query != nil { + if err := mq.loadGuild(ctx, query, nodes, nil, + func(n *Member, e *Guild) { n.Edges.Guild = e }); err != nil { + return nil, err + } + } + if query := mq.withUser; query != nil { + if err := mq.loadUser(ctx, query, nodes, nil, + func(n *Member, e *User) { n.Edges.User = e }); err != nil { + return nil, err + } + } + return nodes, nil +} + +func (mq *MemberQuery) loadGuild(ctx context.Context, query *GuildQuery, nodes []*Member, init func(*Member), assign func(*Member, *Guild)) error { + ids := make([]snowflake.ID, 0, len(nodes)) + nodeids := make(map[snowflake.ID][]*Member) + for i := range nodes { + if nodes[i].guild_members == nil { + continue + } + fk := *nodes[i].guild_members + if _, ok := nodeids[fk]; !ok { + ids = append(ids, fk) + } + nodeids[fk] = append(nodeids[fk], nodes[i]) + } + if len(ids) == 0 { + return nil + } + query.Where(guild.IDIn(ids...)) + neighbors, err := query.All(ctx) + if err != nil { + return err + } + for _, n := range neighbors { + nodes, ok := nodeids[n.ID] + if !ok { + return fmt.Errorf(`unexpected foreign-key "guild_members" returned %v`, n.ID) + } + for i := range nodes { + assign(nodes[i], n) + } + } + return nil +} +func (mq *MemberQuery) loadUser(ctx context.Context, query *UserQuery, nodes []*Member, init func(*Member), assign func(*Member, *User)) error { + ids := make([]snowflake.ID, 0, len(nodes)) + nodeids := make(map[snowflake.ID][]*Member) + for i := range nodes { + fk := nodes[i].UserID + if _, ok := nodeids[fk]; !ok { + ids = append(ids, fk) + } + nodeids[fk] = append(nodeids[fk], nodes[i]) + } + if len(ids) == 0 { + return nil + } + query.Where(user.IDIn(ids...)) + neighbors, err := query.All(ctx) + if err != nil { + return err + } + for _, n := range neighbors { + nodes, ok := nodeids[n.ID] + if !ok { + return fmt.Errorf(`unexpected foreign-key "user_id" returned %v`, n.ID) + } + for i := range nodes { + assign(nodes[i], n) + } + } + return nil +} + +func (mq *MemberQuery) sqlCount(ctx context.Context) (int, error) { + _spec := mq.querySpec() + _spec.Node.Columns = mq.ctx.Fields + if len(mq.ctx.Fields) > 0 { + _spec.Unique = mq.ctx.Unique != nil && *mq.ctx.Unique + } + return sqlgraph.CountNodes(ctx, mq.driver, _spec) +} + +func (mq *MemberQuery) querySpec() *sqlgraph.QuerySpec { + _spec := sqlgraph.NewQuerySpec(member.Table, member.Columns, sqlgraph.NewFieldSpec(member.FieldID, field.TypeInt)) + _spec.From = mq.sql + if unique := mq.ctx.Unique; unique != nil { + _spec.Unique = *unique + } else if mq.path != nil { + _spec.Unique = true + } + if fields := mq.ctx.Fields; len(fields) > 0 { + _spec.Node.Columns = make([]string, 0, len(fields)) + _spec.Node.Columns = append(_spec.Node.Columns, member.FieldID) + for i := range fields { + if fields[i] != member.FieldID { + _spec.Node.Columns = append(_spec.Node.Columns, fields[i]) + } + } + if mq.withUser != nil { + _spec.Node.AddColumnOnce(member.FieldUserID) + } + } + if ps := mq.predicates; len(ps) > 0 { + _spec.Predicate = func(selector *sql.Selector) { + for i := range ps { + ps[i](selector) + } + } + } + if limit := mq.ctx.Limit; limit != nil { + _spec.Limit = *limit + } + if offset := mq.ctx.Offset; offset != nil { + _spec.Offset = *offset + } + if ps := mq.order; len(ps) > 0 { + _spec.Order = func(selector *sql.Selector) { + for i := range ps { + ps[i](selector) + } + } + } + return _spec +} + +func (mq *MemberQuery) sqlQuery(ctx context.Context) *sql.Selector { + builder := sql.Dialect(mq.driver.Dialect()) + t1 := builder.Table(member.Table) + columns := mq.ctx.Fields + if len(columns) == 0 { + columns = member.Columns + } + selector := builder.Select(t1.Columns(columns...)...).From(t1) + if mq.sql != nil { + selector = mq.sql + selector.Select(selector.Columns(columns...)...) + } + if mq.ctx.Unique != nil && *mq.ctx.Unique { + selector.Distinct() + } + for _, p := range mq.predicates { + p(selector) + } + for _, p := range mq.order { + p(selector) + } + if offset := mq.ctx.Offset; offset != nil { + // limit is mandatory for offset clause. We start + // with default value, and override it below if needed. + selector.Offset(*offset).Limit(math.MaxInt32) + } + if limit := mq.ctx.Limit; limit != nil { + selector.Limit(*limit) + } + return selector +} + +// MemberGroupBy is the group-by builder for Member entities. +type MemberGroupBy struct { + selector + build *MemberQuery +} + +// Aggregate adds the given aggregation functions to the group-by query. +func (mgb *MemberGroupBy) Aggregate(fns ...AggregateFunc) *MemberGroupBy { + mgb.fns = append(mgb.fns, fns...) + return mgb +} + +// Scan applies the selector query and scans the result into the given value. +func (mgb *MemberGroupBy) Scan(ctx context.Context, v any) error { + ctx = setContextOp(ctx, mgb.build.ctx, "GroupBy") + if err := mgb.build.prepareQuery(ctx); err != nil { + return err + } + return scanWithInterceptors[*MemberQuery, *MemberGroupBy](ctx, mgb.build, mgb, mgb.build.inters, v) +} + +func (mgb *MemberGroupBy) sqlScan(ctx context.Context, root *MemberQuery, v any) error { + selector := root.sqlQuery(ctx).Select() + aggregation := make([]string, 0, len(mgb.fns)) + for _, fn := range mgb.fns { + aggregation = append(aggregation, fn(selector)) + } + if len(selector.SelectedColumns()) == 0 { + columns := make([]string, 0, len(*mgb.flds)+len(mgb.fns)) + for _, f := range *mgb.flds { + columns = append(columns, selector.C(f)) + } + columns = append(columns, aggregation...) + selector.Select(columns...) + } + selector.GroupBy(selector.Columns(*mgb.flds...)...) + if err := selector.Err(); err != nil { + return err + } + rows := &sql.Rows{} + query, args := selector.Query() + if err := mgb.build.driver.Query(ctx, query, args, rows); err != nil { + return err + } + defer rows.Close() + return sql.ScanSlice(rows, v) +} + +// MemberSelect is the builder for selecting fields of Member entities. +type MemberSelect struct { + *MemberQuery + selector +} + +// Aggregate adds the given aggregation functions to the selector query. +func (ms *MemberSelect) Aggregate(fns ...AggregateFunc) *MemberSelect { + ms.fns = append(ms.fns, fns...) + return ms +} + +// Scan applies the selector query and scans the result into the given value. +func (ms *MemberSelect) Scan(ctx context.Context, v any) error { + ctx = setContextOp(ctx, ms.ctx, "Select") + if err := ms.prepareQuery(ctx); err != nil { + return err + } + return scanWithInterceptors[*MemberQuery, *MemberSelect](ctx, ms.MemberQuery, ms, ms.inters, v) +} + +func (ms *MemberSelect) sqlScan(ctx context.Context, root *MemberQuery, v any) error { + selector := root.sqlQuery(ctx) + aggregation := make([]string, 0, len(ms.fns)) + for _, fn := range ms.fns { + aggregation = append(aggregation, fn(selector)) + } + switch n := len(*ms.selector.flds); { + case n == 0 && len(aggregation) > 0: + selector.Select(aggregation...) + case n != 0 && len(aggregation) > 0: + selector.AppendSelect(aggregation...) + } + rows := &sql.Rows{} + query, args := selector.Query() + if err := ms.driver.Query(ctx, query, args, rows); err != nil { + return err + } + defer rows.Close() + return sql.ScanSlice(rows, v) +} diff --git a/ent/member_update.go b/ent/member_update.go new file mode 100644 index 00000000..cc8b3099 --- /dev/null +++ b/ent/member_update.go @@ -0,0 +1,584 @@ +// Code generated by ent, DO NOT EDIT. + +package ent + +import ( + "context" + "errors" + "fmt" + "time" + + "entgo.io/ent/dialect/sql" + "entgo.io/ent/dialect/sql/sqlgraph" + "entgo.io/ent/schema/field" + snowflake "github.com/disgoorg/snowflake/v2" + "github.com/sabafly/gobot/ent/guild" + "github.com/sabafly/gobot/ent/member" + "github.com/sabafly/gobot/ent/predicate" + "github.com/sabafly/gobot/internal/permissions" + "github.com/sabafly/gobot/internal/xppoint" +) + +// MemberUpdate is the builder for updating Member entities. +type MemberUpdate struct { + config + hooks []Hook + mutation *MemberMutation +} + +// Where appends a list predicates to the MemberUpdate builder. +func (mu *MemberUpdate) Where(ps ...predicate.Member) *MemberUpdate { + mu.mutation.Where(ps...) + return mu +} + +// SetPermission sets the "permission" field. +func (mu *MemberUpdate) SetPermission(pe permissions.Permission) *MemberUpdate { + mu.mutation.SetPermission(pe) + return mu +} + +// SetNillablePermission sets the "permission" field if the given value is not nil. +func (mu *MemberUpdate) SetNillablePermission(pe *permissions.Permission) *MemberUpdate { + if pe != nil { + mu.SetPermission(*pe) + } + return mu +} + +// ClearPermission clears the value of the "permission" field. +func (mu *MemberUpdate) ClearPermission() *MemberUpdate { + mu.mutation.ClearPermission() + return mu +} + +// SetXp sets the "xp" field. +func (mu *MemberUpdate) SetXp(x xppoint.XP) *MemberUpdate { + mu.mutation.ResetXp() + mu.mutation.SetXp(x) + return mu +} + +// SetNillableXp sets the "xp" field if the given value is not nil. +func (mu *MemberUpdate) SetNillableXp(x *xppoint.XP) *MemberUpdate { + if x != nil { + mu.SetXp(*x) + } + return mu +} + +// AddXp adds x to the "xp" field. +func (mu *MemberUpdate) AddXp(x xppoint.XP) *MemberUpdate { + mu.mutation.AddXp(x) + return mu +} + +// SetLastXp sets the "last_xp" field. +func (mu *MemberUpdate) SetLastXp(t time.Time) *MemberUpdate { + mu.mutation.SetLastXp(t) + return mu +} + +// SetNillableLastXp sets the "last_xp" field if the given value is not nil. +func (mu *MemberUpdate) SetNillableLastXp(t *time.Time) *MemberUpdate { + if t != nil { + mu.SetLastXp(*t) + } + return mu +} + +// ClearLastXp clears the value of the "last_xp" field. +func (mu *MemberUpdate) ClearLastXp() *MemberUpdate { + mu.mutation.ClearLastXp() + return mu +} + +// SetMessageCount sets the "message_count" field. +func (mu *MemberUpdate) SetMessageCount(u uint64) *MemberUpdate { + mu.mutation.ResetMessageCount() + mu.mutation.SetMessageCount(u) + return mu +} + +// SetNillableMessageCount sets the "message_count" field if the given value is not nil. +func (mu *MemberUpdate) SetNillableMessageCount(u *uint64) *MemberUpdate { + if u != nil { + mu.SetMessageCount(*u) + } + return mu +} + +// AddMessageCount adds u to the "message_count" field. +func (mu *MemberUpdate) AddMessageCount(u int64) *MemberUpdate { + mu.mutation.AddMessageCount(u) + return mu +} + +// SetLastNotifiedLevel sets the "last_notified_level" field. +func (mu *MemberUpdate) SetLastNotifiedLevel(u uint64) *MemberUpdate { + mu.mutation.ResetLastNotifiedLevel() + mu.mutation.SetLastNotifiedLevel(u) + return mu +} + +// SetNillableLastNotifiedLevel sets the "last_notified_level" field if the given value is not nil. +func (mu *MemberUpdate) SetNillableLastNotifiedLevel(u *uint64) *MemberUpdate { + if u != nil { + mu.SetLastNotifiedLevel(*u) + } + return mu +} + +// AddLastNotifiedLevel adds u to the "last_notified_level" field. +func (mu *MemberUpdate) AddLastNotifiedLevel(u int64) *MemberUpdate { + mu.mutation.AddLastNotifiedLevel(u) + return mu +} + +// ClearLastNotifiedLevel clears the value of the "last_notified_level" field. +func (mu *MemberUpdate) ClearLastNotifiedLevel() *MemberUpdate { + mu.mutation.ClearLastNotifiedLevel() + return mu +} + +// SetGuildID sets the "guild" edge to the Guild entity by ID. +func (mu *MemberUpdate) SetGuildID(id snowflake.ID) *MemberUpdate { + mu.mutation.SetGuildID(id) + return mu +} + +// SetGuild sets the "guild" edge to the Guild entity. +func (mu *MemberUpdate) SetGuild(g *Guild) *MemberUpdate { + return mu.SetGuildID(g.ID) +} + +// Mutation returns the MemberMutation object of the builder. +func (mu *MemberUpdate) Mutation() *MemberMutation { + return mu.mutation +} + +// ClearGuild clears the "guild" edge to the Guild entity. +func (mu *MemberUpdate) ClearGuild() *MemberUpdate { + mu.mutation.ClearGuild() + return mu +} + +// Save executes the query and returns the number of nodes affected by the update operation. +func (mu *MemberUpdate) Save(ctx context.Context) (int, error) { + return withHooks(ctx, mu.sqlSave, mu.mutation, mu.hooks) +} + +// SaveX is like Save, but panics if an error occurs. +func (mu *MemberUpdate) SaveX(ctx context.Context) int { + affected, err := mu.Save(ctx) + if err != nil { + panic(err) + } + return affected +} + +// Exec executes the query. +func (mu *MemberUpdate) Exec(ctx context.Context) error { + _, err := mu.Save(ctx) + return err +} + +// ExecX is like Exec, but panics if an error occurs. +func (mu *MemberUpdate) ExecX(ctx context.Context) { + if err := mu.Exec(ctx); err != nil { + panic(err) + } +} + +// check runs all checks and user-defined validators on the builder. +func (mu *MemberUpdate) check() error { + if _, ok := mu.mutation.GuildID(); mu.mutation.GuildCleared() && !ok { + return errors.New(`ent: clearing a required unique edge "Member.guild"`) + } + if _, ok := mu.mutation.UserID(); mu.mutation.UserCleared() && !ok { + return errors.New(`ent: clearing a required unique edge "Member.user"`) + } + return nil +} + +func (mu *MemberUpdate) sqlSave(ctx context.Context) (n int, err error) { + if err := mu.check(); err != nil { + return n, err + } + _spec := sqlgraph.NewUpdateSpec(member.Table, member.Columns, sqlgraph.NewFieldSpec(member.FieldID, field.TypeInt)) + if ps := mu.mutation.predicates; len(ps) > 0 { + _spec.Predicate = func(selector *sql.Selector) { + for i := range ps { + ps[i](selector) + } + } + } + if value, ok := mu.mutation.Permission(); ok { + _spec.SetField(member.FieldPermission, field.TypeJSON, value) + } + if mu.mutation.PermissionCleared() { + _spec.ClearField(member.FieldPermission, field.TypeJSON) + } + if value, ok := mu.mutation.Xp(); ok { + _spec.SetField(member.FieldXp, field.TypeUint64, value) + } + if value, ok := mu.mutation.AddedXp(); ok { + _spec.AddField(member.FieldXp, field.TypeUint64, value) + } + if value, ok := mu.mutation.LastXp(); ok { + _spec.SetField(member.FieldLastXp, field.TypeTime, value) + } + if mu.mutation.LastXpCleared() { + _spec.ClearField(member.FieldLastXp, field.TypeTime) + } + if value, ok := mu.mutation.MessageCount(); ok { + _spec.SetField(member.FieldMessageCount, field.TypeUint64, value) + } + if value, ok := mu.mutation.AddedMessageCount(); ok { + _spec.AddField(member.FieldMessageCount, field.TypeUint64, value) + } + if value, ok := mu.mutation.LastNotifiedLevel(); ok { + _spec.SetField(member.FieldLastNotifiedLevel, field.TypeUint64, value) + } + if value, ok := mu.mutation.AddedLastNotifiedLevel(); ok { + _spec.AddField(member.FieldLastNotifiedLevel, field.TypeUint64, value) + } + if mu.mutation.LastNotifiedLevelCleared() { + _spec.ClearField(member.FieldLastNotifiedLevel, field.TypeUint64) + } + if mu.mutation.GuildCleared() { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.M2O, + Inverse: true, + Table: member.GuildTable, + Columns: []string{member.GuildColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(guild.FieldID, field.TypeUint64), + }, + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := mu.mutation.GuildIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.M2O, + Inverse: true, + Table: member.GuildTable, + Columns: []string{member.GuildColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(guild.FieldID, field.TypeUint64), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Add = append(_spec.Edges.Add, edge) + } + if n, err = sqlgraph.UpdateNodes(ctx, mu.driver, _spec); err != nil { + if _, ok := err.(*sqlgraph.NotFoundError); ok { + err = &NotFoundError{member.Label} + } else if sqlgraph.IsConstraintError(err) { + err = &ConstraintError{msg: err.Error(), wrap: err} + } + return 0, err + } + mu.mutation.done = true + return n, nil +} + +// MemberUpdateOne is the builder for updating a single Member entity. +type MemberUpdateOne struct { + config + fields []string + hooks []Hook + mutation *MemberMutation +} + +// SetPermission sets the "permission" field. +func (muo *MemberUpdateOne) SetPermission(pe permissions.Permission) *MemberUpdateOne { + muo.mutation.SetPermission(pe) + return muo +} + +// SetNillablePermission sets the "permission" field if the given value is not nil. +func (muo *MemberUpdateOne) SetNillablePermission(pe *permissions.Permission) *MemberUpdateOne { + if pe != nil { + muo.SetPermission(*pe) + } + return muo +} + +// ClearPermission clears the value of the "permission" field. +func (muo *MemberUpdateOne) ClearPermission() *MemberUpdateOne { + muo.mutation.ClearPermission() + return muo +} + +// SetXp sets the "xp" field. +func (muo *MemberUpdateOne) SetXp(x xppoint.XP) *MemberUpdateOne { + muo.mutation.ResetXp() + muo.mutation.SetXp(x) + return muo +} + +// SetNillableXp sets the "xp" field if the given value is not nil. +func (muo *MemberUpdateOne) SetNillableXp(x *xppoint.XP) *MemberUpdateOne { + if x != nil { + muo.SetXp(*x) + } + return muo +} + +// AddXp adds x to the "xp" field. +func (muo *MemberUpdateOne) AddXp(x xppoint.XP) *MemberUpdateOne { + muo.mutation.AddXp(x) + return muo +} + +// SetLastXp sets the "last_xp" field. +func (muo *MemberUpdateOne) SetLastXp(t time.Time) *MemberUpdateOne { + muo.mutation.SetLastXp(t) + return muo +} + +// SetNillableLastXp sets the "last_xp" field if the given value is not nil. +func (muo *MemberUpdateOne) SetNillableLastXp(t *time.Time) *MemberUpdateOne { + if t != nil { + muo.SetLastXp(*t) + } + return muo +} + +// ClearLastXp clears the value of the "last_xp" field. +func (muo *MemberUpdateOne) ClearLastXp() *MemberUpdateOne { + muo.mutation.ClearLastXp() + return muo +} + +// SetMessageCount sets the "message_count" field. +func (muo *MemberUpdateOne) SetMessageCount(u uint64) *MemberUpdateOne { + muo.mutation.ResetMessageCount() + muo.mutation.SetMessageCount(u) + return muo +} + +// SetNillableMessageCount sets the "message_count" field if the given value is not nil. +func (muo *MemberUpdateOne) SetNillableMessageCount(u *uint64) *MemberUpdateOne { + if u != nil { + muo.SetMessageCount(*u) + } + return muo +} + +// AddMessageCount adds u to the "message_count" field. +func (muo *MemberUpdateOne) AddMessageCount(u int64) *MemberUpdateOne { + muo.mutation.AddMessageCount(u) + return muo +} + +// SetLastNotifiedLevel sets the "last_notified_level" field. +func (muo *MemberUpdateOne) SetLastNotifiedLevel(u uint64) *MemberUpdateOne { + muo.mutation.ResetLastNotifiedLevel() + muo.mutation.SetLastNotifiedLevel(u) + return muo +} + +// SetNillableLastNotifiedLevel sets the "last_notified_level" field if the given value is not nil. +func (muo *MemberUpdateOne) SetNillableLastNotifiedLevel(u *uint64) *MemberUpdateOne { + if u != nil { + muo.SetLastNotifiedLevel(*u) + } + return muo +} + +// AddLastNotifiedLevel adds u to the "last_notified_level" field. +func (muo *MemberUpdateOne) AddLastNotifiedLevel(u int64) *MemberUpdateOne { + muo.mutation.AddLastNotifiedLevel(u) + return muo +} + +// ClearLastNotifiedLevel clears the value of the "last_notified_level" field. +func (muo *MemberUpdateOne) ClearLastNotifiedLevel() *MemberUpdateOne { + muo.mutation.ClearLastNotifiedLevel() + return muo +} + +// SetGuildID sets the "guild" edge to the Guild entity by ID. +func (muo *MemberUpdateOne) SetGuildID(id snowflake.ID) *MemberUpdateOne { + muo.mutation.SetGuildID(id) + return muo +} + +// SetGuild sets the "guild" edge to the Guild entity. +func (muo *MemberUpdateOne) SetGuild(g *Guild) *MemberUpdateOne { + return muo.SetGuildID(g.ID) +} + +// Mutation returns the MemberMutation object of the builder. +func (muo *MemberUpdateOne) Mutation() *MemberMutation { + return muo.mutation +} + +// ClearGuild clears the "guild" edge to the Guild entity. +func (muo *MemberUpdateOne) ClearGuild() *MemberUpdateOne { + muo.mutation.ClearGuild() + return muo +} + +// Where appends a list predicates to the MemberUpdate builder. +func (muo *MemberUpdateOne) Where(ps ...predicate.Member) *MemberUpdateOne { + muo.mutation.Where(ps...) + return muo +} + +// Select allows selecting one or more fields (columns) of the returned entity. +// The default is selecting all fields defined in the entity schema. +func (muo *MemberUpdateOne) Select(field string, fields ...string) *MemberUpdateOne { + muo.fields = append([]string{field}, fields...) + return muo +} + +// Save executes the query and returns the updated Member entity. +func (muo *MemberUpdateOne) Save(ctx context.Context) (*Member, error) { + return withHooks(ctx, muo.sqlSave, muo.mutation, muo.hooks) +} + +// SaveX is like Save, but panics if an error occurs. +func (muo *MemberUpdateOne) SaveX(ctx context.Context) *Member { + node, err := muo.Save(ctx) + if err != nil { + panic(err) + } + return node +} + +// Exec executes the query on the entity. +func (muo *MemberUpdateOne) Exec(ctx context.Context) error { + _, err := muo.Save(ctx) + return err +} + +// ExecX is like Exec, but panics if an error occurs. +func (muo *MemberUpdateOne) ExecX(ctx context.Context) { + if err := muo.Exec(ctx); err != nil { + panic(err) + } +} + +// check runs all checks and user-defined validators on the builder. +func (muo *MemberUpdateOne) check() error { + if _, ok := muo.mutation.GuildID(); muo.mutation.GuildCleared() && !ok { + return errors.New(`ent: clearing a required unique edge "Member.guild"`) + } + if _, ok := muo.mutation.UserID(); muo.mutation.UserCleared() && !ok { + return errors.New(`ent: clearing a required unique edge "Member.user"`) + } + return nil +} + +func (muo *MemberUpdateOne) sqlSave(ctx context.Context) (_node *Member, err error) { + if err := muo.check(); err != nil { + return _node, err + } + _spec := sqlgraph.NewUpdateSpec(member.Table, member.Columns, sqlgraph.NewFieldSpec(member.FieldID, field.TypeInt)) + id, ok := muo.mutation.ID() + if !ok { + return nil, &ValidationError{Name: "id", err: errors.New(`ent: missing "Member.id" for update`)} + } + _spec.Node.ID.Value = id + if fields := muo.fields; len(fields) > 0 { + _spec.Node.Columns = make([]string, 0, len(fields)) + _spec.Node.Columns = append(_spec.Node.Columns, member.FieldID) + for _, f := range fields { + if !member.ValidColumn(f) { + return nil, &ValidationError{Name: f, err: fmt.Errorf("ent: invalid field %q for query", f)} + } + if f != member.FieldID { + _spec.Node.Columns = append(_spec.Node.Columns, f) + } + } + } + if ps := muo.mutation.predicates; len(ps) > 0 { + _spec.Predicate = func(selector *sql.Selector) { + for i := range ps { + ps[i](selector) + } + } + } + if value, ok := muo.mutation.Permission(); ok { + _spec.SetField(member.FieldPermission, field.TypeJSON, value) + } + if muo.mutation.PermissionCleared() { + _spec.ClearField(member.FieldPermission, field.TypeJSON) + } + if value, ok := muo.mutation.Xp(); ok { + _spec.SetField(member.FieldXp, field.TypeUint64, value) + } + if value, ok := muo.mutation.AddedXp(); ok { + _spec.AddField(member.FieldXp, field.TypeUint64, value) + } + if value, ok := muo.mutation.LastXp(); ok { + _spec.SetField(member.FieldLastXp, field.TypeTime, value) + } + if muo.mutation.LastXpCleared() { + _spec.ClearField(member.FieldLastXp, field.TypeTime) + } + if value, ok := muo.mutation.MessageCount(); ok { + _spec.SetField(member.FieldMessageCount, field.TypeUint64, value) + } + if value, ok := muo.mutation.AddedMessageCount(); ok { + _spec.AddField(member.FieldMessageCount, field.TypeUint64, value) + } + if value, ok := muo.mutation.LastNotifiedLevel(); ok { + _spec.SetField(member.FieldLastNotifiedLevel, field.TypeUint64, value) + } + if value, ok := muo.mutation.AddedLastNotifiedLevel(); ok { + _spec.AddField(member.FieldLastNotifiedLevel, field.TypeUint64, value) + } + if muo.mutation.LastNotifiedLevelCleared() { + _spec.ClearField(member.FieldLastNotifiedLevel, field.TypeUint64) + } + if muo.mutation.GuildCleared() { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.M2O, + Inverse: true, + Table: member.GuildTable, + Columns: []string{member.GuildColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(guild.FieldID, field.TypeUint64), + }, + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := muo.mutation.GuildIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.M2O, + Inverse: true, + Table: member.GuildTable, + Columns: []string{member.GuildColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(guild.FieldID, field.TypeUint64), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Add = append(_spec.Edges.Add, edge) + } + _node = &Member{config: muo.config} + _spec.Assign = _node.assignValues + _spec.ScanValues = _node.scanValues + if err = sqlgraph.UpdateNode(ctx, muo.driver, _spec); err != nil { + if _, ok := err.(*sqlgraph.NotFoundError); ok { + err = &NotFoundError{member.Label} + } else if sqlgraph.IsConstraintError(err) { + err = &ConstraintError{msg: err.Error(), wrap: err} + } + return nil, err + } + muo.mutation.done = true + return _node, nil +} diff --git a/ent/messagepin.go b/ent/messagepin.go new file mode 100644 index 00000000..a9ad5a10 --- /dev/null +++ b/ent/messagepin.go @@ -0,0 +1,202 @@ +// Code generated by ent, DO NOT EDIT. + +package ent + +import ( + "encoding/json" + "fmt" + "strings" + + "entgo.io/ent" + "entgo.io/ent/dialect/sql" + "github.com/disgoorg/disgo/discord" + snowflake "github.com/disgoorg/snowflake/v2" + "github.com/google/uuid" + "github.com/sabafly/gobot/ent/guild" + "github.com/sabafly/gobot/ent/messagepin" + "github.com/sabafly/gobot/ent/schema" +) + +// MessagePin is the model entity for the MessagePin schema. +type MessagePin struct { + config `json:"-"` + // ID of the ent. + ID uuid.UUID `json:"id,omitempty"` + // ChannelID holds the value of the "channel_id" field. + ChannelID snowflake.ID `json:"channel_id,omitempty"` + // Content holds the value of the "content" field. + Content string `json:"content,omitempty"` + // Embeds holds the value of the "embeds" field. + Embeds []discord.Embed `json:"embeds,omitempty"` + // BeforeID holds the value of the "before_id" field. + BeforeID *snowflake.ID `json:"before_id,omitempty"` + // RateLimit holds the value of the "rate_limit" field. + RateLimit schema.RateLimit `json:"rate_limit,omitempty"` + // Edges holds the relations/edges for other nodes in the graph. + // The values are being populated by the MessagePinQuery when eager-loading is set. + Edges MessagePinEdges `json:"edges"` + guild_message_pins *snowflake.ID + selectValues sql.SelectValues +} + +// MessagePinEdges holds the relations/edges for other nodes in the graph. +type MessagePinEdges struct { + // Guild holds the value of the guild edge. + Guild *Guild `json:"guild,omitempty"` + // loadedTypes holds the information for reporting if a + // type was loaded (or requested) in eager-loading or not. + loadedTypes [1]bool +} + +// GuildOrErr returns the Guild value or an error if the edge +// was not loaded in eager-loading, or loaded but was not found. +func (e MessagePinEdges) GuildOrErr() (*Guild, error) { + if e.Guild != nil { + return e.Guild, nil + } else if e.loadedTypes[0] { + return nil, &NotFoundError{label: guild.Label} + } + return nil, &NotLoadedError{edge: "guild"} +} + +// scanValues returns the types for scanning values from sql.Rows. +func (*MessagePin) scanValues(columns []string) ([]any, error) { + values := make([]any, len(columns)) + for i := range columns { + switch columns[i] { + case messagepin.FieldEmbeds, messagepin.FieldRateLimit: + values[i] = new([]byte) + case messagepin.FieldChannelID, messagepin.FieldBeforeID: + values[i] = new(sql.NullInt64) + case messagepin.FieldContent: + values[i] = new(sql.NullString) + case messagepin.FieldID: + values[i] = new(uuid.UUID) + case messagepin.ForeignKeys[0]: // guild_message_pins + values[i] = new(sql.NullInt64) + default: + values[i] = new(sql.UnknownType) + } + } + return values, nil +} + +// assignValues assigns the values that were returned from sql.Rows (after scanning) +// to the MessagePin fields. +func (mp *MessagePin) assignValues(columns []string, values []any) error { + if m, n := len(values), len(columns); m < n { + return fmt.Errorf("mismatch number of scan values: %d != %d", m, n) + } + for i := range columns { + switch columns[i] { + case messagepin.FieldID: + if value, ok := values[i].(*uuid.UUID); !ok { + return fmt.Errorf("unexpected type %T for field id", values[i]) + } else if value != nil { + mp.ID = *value + } + case messagepin.FieldChannelID: + if value, ok := values[i].(*sql.NullInt64); !ok { + return fmt.Errorf("unexpected type %T for field channel_id", values[i]) + } else if value.Valid { + mp.ChannelID = snowflake.ID(value.Int64) + } + case messagepin.FieldContent: + if value, ok := values[i].(*sql.NullString); !ok { + return fmt.Errorf("unexpected type %T for field content", values[i]) + } else if value.Valid { + mp.Content = value.String + } + case messagepin.FieldEmbeds: + if value, ok := values[i].(*[]byte); !ok { + return fmt.Errorf("unexpected type %T for field embeds", values[i]) + } else if value != nil && len(*value) > 0 { + if err := json.Unmarshal(*value, &mp.Embeds); err != nil { + return fmt.Errorf("unmarshal field embeds: %w", err) + } + } + case messagepin.FieldBeforeID: + if value, ok := values[i].(*sql.NullInt64); !ok { + return fmt.Errorf("unexpected type %T for field before_id", values[i]) + } else if value.Valid { + mp.BeforeID = new(snowflake.ID) + *mp.BeforeID = snowflake.ID(value.Int64) + } + case messagepin.FieldRateLimit: + if value, ok := values[i].(*[]byte); !ok { + return fmt.Errorf("unexpected type %T for field rate_limit", values[i]) + } else if value != nil && len(*value) > 0 { + if err := json.Unmarshal(*value, &mp.RateLimit); err != nil { + return fmt.Errorf("unmarshal field rate_limit: %w", err) + } + } + case messagepin.ForeignKeys[0]: + if value, ok := values[i].(*sql.NullInt64); !ok { + return fmt.Errorf("unexpected type %T for field guild_message_pins", values[i]) + } else if value.Valid { + mp.guild_message_pins = new(snowflake.ID) + *mp.guild_message_pins = snowflake.ID(value.Int64) + } + default: + mp.selectValues.Set(columns[i], values[i]) + } + } + return nil +} + +// Value returns the ent.Value that was dynamically selected and assigned to the MessagePin. +// This includes values selected through modifiers, order, etc. +func (mp *MessagePin) Value(name string) (ent.Value, error) { + return mp.selectValues.Get(name) +} + +// QueryGuild queries the "guild" edge of the MessagePin entity. +func (mp *MessagePin) QueryGuild() *GuildQuery { + return NewMessagePinClient(mp.config).QueryGuild(mp) +} + +// Update returns a builder for updating this MessagePin. +// Note that you need to call MessagePin.Unwrap() before calling this method if this MessagePin +// was returned from a transaction, and the transaction was committed or rolled back. +func (mp *MessagePin) Update() *MessagePinUpdateOne { + return NewMessagePinClient(mp.config).UpdateOne(mp) +} + +// Unwrap unwraps the MessagePin entity that was returned from a transaction after it was closed, +// so that all future queries will be executed through the driver which created the transaction. +func (mp *MessagePin) Unwrap() *MessagePin { + _tx, ok := mp.config.driver.(*txDriver) + if !ok { + panic("ent: MessagePin is not a transactional entity") + } + mp.config.driver = _tx.drv + return mp +} + +// String implements the fmt.Stringer. +func (mp *MessagePin) String() string { + var builder strings.Builder + builder.WriteString("MessagePin(") + builder.WriteString(fmt.Sprintf("id=%v, ", mp.ID)) + builder.WriteString("channel_id=") + builder.WriteString(fmt.Sprintf("%v", mp.ChannelID)) + builder.WriteString(", ") + builder.WriteString("content=") + builder.WriteString(mp.Content) + builder.WriteString(", ") + builder.WriteString("embeds=") + builder.WriteString(fmt.Sprintf("%v", mp.Embeds)) + builder.WriteString(", ") + if v := mp.BeforeID; v != nil { + builder.WriteString("before_id=") + builder.WriteString(fmt.Sprintf("%v", *v)) + } + builder.WriteString(", ") + builder.WriteString("rate_limit=") + builder.WriteString(fmt.Sprintf("%v", mp.RateLimit)) + builder.WriteByte(')') + return builder.String() +} + +// MessagePins is a parsable slice of MessagePin. +type MessagePins []*MessagePin diff --git a/ent/messagepin/messagepin.go b/ent/messagepin/messagepin.go new file mode 100644 index 00000000..211d6607 --- /dev/null +++ b/ent/messagepin/messagepin.go @@ -0,0 +1,113 @@ +// Code generated by ent, DO NOT EDIT. + +package messagepin + +import ( + "entgo.io/ent/dialect/sql" + "entgo.io/ent/dialect/sql/sqlgraph" + "github.com/google/uuid" + "github.com/sabafly/gobot/ent/schema" +) + +const ( + // Label holds the string label denoting the messagepin type in the database. + Label = "message_pin" + // FieldID holds the string denoting the id field in the database. + FieldID = "id" + // FieldChannelID holds the string denoting the channel_id field in the database. + FieldChannelID = "channel_id" + // FieldContent holds the string denoting the content field in the database. + FieldContent = "content" + // FieldEmbeds holds the string denoting the embeds field in the database. + FieldEmbeds = "embeds" + // FieldBeforeID holds the string denoting the before_id field in the database. + FieldBeforeID = "before_id" + // FieldRateLimit holds the string denoting the rate_limit field in the database. + FieldRateLimit = "rate_limit" + // EdgeGuild holds the string denoting the guild edge name in mutations. + EdgeGuild = "guild" + // Table holds the table name of the messagepin in the database. + Table = "message_pins" + // GuildTable is the table that holds the guild relation/edge. + GuildTable = "message_pins" + // GuildInverseTable is the table name for the Guild entity. + // It exists in this package in order to avoid circular dependency with the "guild" package. + GuildInverseTable = "guilds" + // GuildColumn is the table column denoting the guild relation/edge. + GuildColumn = "guild_message_pins" +) + +// Columns holds all SQL columns for messagepin fields. +var Columns = []string{ + FieldID, + FieldChannelID, + FieldContent, + FieldEmbeds, + FieldBeforeID, + FieldRateLimit, +} + +// ForeignKeys holds the SQL foreign-keys that are owned by the "message_pins" +// table and are not defined as standalone fields in the schema. +var ForeignKeys = []string{ + "guild_message_pins", +} + +// ValidColumn reports if the column name is valid (part of the table columns). +func ValidColumn(column string) bool { + for i := range Columns { + if column == Columns[i] { + return true + } + } + for i := range ForeignKeys { + if column == ForeignKeys[i] { + return true + } + } + return false +} + +var ( + // DefaultRateLimit holds the default value on creation for the "rate_limit" field. + DefaultRateLimit schema.RateLimit + // DefaultID holds the default value on creation for the "id" field. + DefaultID func() uuid.UUID +) + +// OrderOption defines the ordering options for the MessagePin queries. +type OrderOption func(*sql.Selector) + +// ByID orders the results by the id field. +func ByID(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldID, opts...).ToFunc() +} + +// ByChannelID orders the results by the channel_id field. +func ByChannelID(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldChannelID, opts...).ToFunc() +} + +// ByContent orders the results by the content field. +func ByContent(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldContent, opts...).ToFunc() +} + +// ByBeforeID orders the results by the before_id field. +func ByBeforeID(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldBeforeID, opts...).ToFunc() +} + +// ByGuildField orders the results by guild field. +func ByGuildField(field string, opts ...sql.OrderTermOption) OrderOption { + return func(s *sql.Selector) { + sqlgraph.OrderByNeighborTerms(s, newGuildStep(), sql.OrderByField(field, opts...)) + } +} +func newGuildStep() *sqlgraph.Step { + return sqlgraph.NewStep( + sqlgraph.From(Table, FieldID), + sqlgraph.To(GuildInverseTable, FieldID), + sqlgraph.Edge(sqlgraph.M2O, true, GuildTable, GuildColumn), + ) +} diff --git a/ent/messagepin/where.go b/ent/messagepin/where.go new file mode 100644 index 00000000..87ed385b --- /dev/null +++ b/ent/messagepin/where.go @@ -0,0 +1,314 @@ +// Code generated by ent, DO NOT EDIT. + +package messagepin + +import ( + "entgo.io/ent/dialect/sql" + "entgo.io/ent/dialect/sql/sqlgraph" + snowflake "github.com/disgoorg/snowflake/v2" + "github.com/google/uuid" + "github.com/sabafly/gobot/ent/predicate" +) + +// ID filters vertices based on their ID field. +func ID(id uuid.UUID) predicate.MessagePin { + return predicate.MessagePin(sql.FieldEQ(FieldID, id)) +} + +// IDEQ applies the EQ predicate on the ID field. +func IDEQ(id uuid.UUID) predicate.MessagePin { + return predicate.MessagePin(sql.FieldEQ(FieldID, id)) +} + +// IDNEQ applies the NEQ predicate on the ID field. +func IDNEQ(id uuid.UUID) predicate.MessagePin { + return predicate.MessagePin(sql.FieldNEQ(FieldID, id)) +} + +// IDIn applies the In predicate on the ID field. +func IDIn(ids ...uuid.UUID) predicate.MessagePin { + return predicate.MessagePin(sql.FieldIn(FieldID, ids...)) +} + +// IDNotIn applies the NotIn predicate on the ID field. +func IDNotIn(ids ...uuid.UUID) predicate.MessagePin { + return predicate.MessagePin(sql.FieldNotIn(FieldID, ids...)) +} + +// IDGT applies the GT predicate on the ID field. +func IDGT(id uuid.UUID) predicate.MessagePin { + return predicate.MessagePin(sql.FieldGT(FieldID, id)) +} + +// IDGTE applies the GTE predicate on the ID field. +func IDGTE(id uuid.UUID) predicate.MessagePin { + return predicate.MessagePin(sql.FieldGTE(FieldID, id)) +} + +// IDLT applies the LT predicate on the ID field. +func IDLT(id uuid.UUID) predicate.MessagePin { + return predicate.MessagePin(sql.FieldLT(FieldID, id)) +} + +// IDLTE applies the LTE predicate on the ID field. +func IDLTE(id uuid.UUID) predicate.MessagePin { + return predicate.MessagePin(sql.FieldLTE(FieldID, id)) +} + +// ChannelID applies equality check predicate on the "channel_id" field. It's identical to ChannelIDEQ. +func ChannelID(v snowflake.ID) predicate.MessagePin { + vc := uint64(v) + return predicate.MessagePin(sql.FieldEQ(FieldChannelID, vc)) +} + +// Content applies equality check predicate on the "content" field. It's identical to ContentEQ. +func Content(v string) predicate.MessagePin { + return predicate.MessagePin(sql.FieldEQ(FieldContent, v)) +} + +// BeforeID applies equality check predicate on the "before_id" field. It's identical to BeforeIDEQ. +func BeforeID(v snowflake.ID) predicate.MessagePin { + vc := uint64(v) + return predicate.MessagePin(sql.FieldEQ(FieldBeforeID, vc)) +} + +// ChannelIDEQ applies the EQ predicate on the "channel_id" field. +func ChannelIDEQ(v snowflake.ID) predicate.MessagePin { + vc := uint64(v) + return predicate.MessagePin(sql.FieldEQ(FieldChannelID, vc)) +} + +// ChannelIDNEQ applies the NEQ predicate on the "channel_id" field. +func ChannelIDNEQ(v snowflake.ID) predicate.MessagePin { + vc := uint64(v) + return predicate.MessagePin(sql.FieldNEQ(FieldChannelID, vc)) +} + +// ChannelIDIn applies the In predicate on the "channel_id" field. +func ChannelIDIn(vs ...snowflake.ID) predicate.MessagePin { + v := make([]any, len(vs)) + for i := range v { + v[i] = uint64(vs[i]) + } + return predicate.MessagePin(sql.FieldIn(FieldChannelID, v...)) +} + +// ChannelIDNotIn applies the NotIn predicate on the "channel_id" field. +func ChannelIDNotIn(vs ...snowflake.ID) predicate.MessagePin { + v := make([]any, len(vs)) + for i := range v { + v[i] = uint64(vs[i]) + } + return predicate.MessagePin(sql.FieldNotIn(FieldChannelID, v...)) +} + +// ChannelIDGT applies the GT predicate on the "channel_id" field. +func ChannelIDGT(v snowflake.ID) predicate.MessagePin { + vc := uint64(v) + return predicate.MessagePin(sql.FieldGT(FieldChannelID, vc)) +} + +// ChannelIDGTE applies the GTE predicate on the "channel_id" field. +func ChannelIDGTE(v snowflake.ID) predicate.MessagePin { + vc := uint64(v) + return predicate.MessagePin(sql.FieldGTE(FieldChannelID, vc)) +} + +// ChannelIDLT applies the LT predicate on the "channel_id" field. +func ChannelIDLT(v snowflake.ID) predicate.MessagePin { + vc := uint64(v) + return predicate.MessagePin(sql.FieldLT(FieldChannelID, vc)) +} + +// ChannelIDLTE applies the LTE predicate on the "channel_id" field. +func ChannelIDLTE(v snowflake.ID) predicate.MessagePin { + vc := uint64(v) + return predicate.MessagePin(sql.FieldLTE(FieldChannelID, vc)) +} + +// ContentEQ applies the EQ predicate on the "content" field. +func ContentEQ(v string) predicate.MessagePin { + return predicate.MessagePin(sql.FieldEQ(FieldContent, v)) +} + +// ContentNEQ applies the NEQ predicate on the "content" field. +func ContentNEQ(v string) predicate.MessagePin { + return predicate.MessagePin(sql.FieldNEQ(FieldContent, v)) +} + +// ContentIn applies the In predicate on the "content" field. +func ContentIn(vs ...string) predicate.MessagePin { + return predicate.MessagePin(sql.FieldIn(FieldContent, vs...)) +} + +// ContentNotIn applies the NotIn predicate on the "content" field. +func ContentNotIn(vs ...string) predicate.MessagePin { + return predicate.MessagePin(sql.FieldNotIn(FieldContent, vs...)) +} + +// ContentGT applies the GT predicate on the "content" field. +func ContentGT(v string) predicate.MessagePin { + return predicate.MessagePin(sql.FieldGT(FieldContent, v)) +} + +// ContentGTE applies the GTE predicate on the "content" field. +func ContentGTE(v string) predicate.MessagePin { + return predicate.MessagePin(sql.FieldGTE(FieldContent, v)) +} + +// ContentLT applies the LT predicate on the "content" field. +func ContentLT(v string) predicate.MessagePin { + return predicate.MessagePin(sql.FieldLT(FieldContent, v)) +} + +// ContentLTE applies the LTE predicate on the "content" field. +func ContentLTE(v string) predicate.MessagePin { + return predicate.MessagePin(sql.FieldLTE(FieldContent, v)) +} + +// ContentContains applies the Contains predicate on the "content" field. +func ContentContains(v string) predicate.MessagePin { + return predicate.MessagePin(sql.FieldContains(FieldContent, v)) +} + +// ContentHasPrefix applies the HasPrefix predicate on the "content" field. +func ContentHasPrefix(v string) predicate.MessagePin { + return predicate.MessagePin(sql.FieldHasPrefix(FieldContent, v)) +} + +// ContentHasSuffix applies the HasSuffix predicate on the "content" field. +func ContentHasSuffix(v string) predicate.MessagePin { + return predicate.MessagePin(sql.FieldHasSuffix(FieldContent, v)) +} + +// ContentIsNil applies the IsNil predicate on the "content" field. +func ContentIsNil() predicate.MessagePin { + return predicate.MessagePin(sql.FieldIsNull(FieldContent)) +} + +// ContentNotNil applies the NotNil predicate on the "content" field. +func ContentNotNil() predicate.MessagePin { + return predicate.MessagePin(sql.FieldNotNull(FieldContent)) +} + +// ContentEqualFold applies the EqualFold predicate on the "content" field. +func ContentEqualFold(v string) predicate.MessagePin { + return predicate.MessagePin(sql.FieldEqualFold(FieldContent, v)) +} + +// ContentContainsFold applies the ContainsFold predicate on the "content" field. +func ContentContainsFold(v string) predicate.MessagePin { + return predicate.MessagePin(sql.FieldContainsFold(FieldContent, v)) +} + +// EmbedsIsNil applies the IsNil predicate on the "embeds" field. +func EmbedsIsNil() predicate.MessagePin { + return predicate.MessagePin(sql.FieldIsNull(FieldEmbeds)) +} + +// EmbedsNotNil applies the NotNil predicate on the "embeds" field. +func EmbedsNotNil() predicate.MessagePin { + return predicate.MessagePin(sql.FieldNotNull(FieldEmbeds)) +} + +// BeforeIDEQ applies the EQ predicate on the "before_id" field. +func BeforeIDEQ(v snowflake.ID) predicate.MessagePin { + vc := uint64(v) + return predicate.MessagePin(sql.FieldEQ(FieldBeforeID, vc)) +} + +// BeforeIDNEQ applies the NEQ predicate on the "before_id" field. +func BeforeIDNEQ(v snowflake.ID) predicate.MessagePin { + vc := uint64(v) + return predicate.MessagePin(sql.FieldNEQ(FieldBeforeID, vc)) +} + +// BeforeIDIn applies the In predicate on the "before_id" field. +func BeforeIDIn(vs ...snowflake.ID) predicate.MessagePin { + v := make([]any, len(vs)) + for i := range v { + v[i] = uint64(vs[i]) + } + return predicate.MessagePin(sql.FieldIn(FieldBeforeID, v...)) +} + +// BeforeIDNotIn applies the NotIn predicate on the "before_id" field. +func BeforeIDNotIn(vs ...snowflake.ID) predicate.MessagePin { + v := make([]any, len(vs)) + for i := range v { + v[i] = uint64(vs[i]) + } + return predicate.MessagePin(sql.FieldNotIn(FieldBeforeID, v...)) +} + +// BeforeIDGT applies the GT predicate on the "before_id" field. +func BeforeIDGT(v snowflake.ID) predicate.MessagePin { + vc := uint64(v) + return predicate.MessagePin(sql.FieldGT(FieldBeforeID, vc)) +} + +// BeforeIDGTE applies the GTE predicate on the "before_id" field. +func BeforeIDGTE(v snowflake.ID) predicate.MessagePin { + vc := uint64(v) + return predicate.MessagePin(sql.FieldGTE(FieldBeforeID, vc)) +} + +// BeforeIDLT applies the LT predicate on the "before_id" field. +func BeforeIDLT(v snowflake.ID) predicate.MessagePin { + vc := uint64(v) + return predicate.MessagePin(sql.FieldLT(FieldBeforeID, vc)) +} + +// BeforeIDLTE applies the LTE predicate on the "before_id" field. +func BeforeIDLTE(v snowflake.ID) predicate.MessagePin { + vc := uint64(v) + return predicate.MessagePin(sql.FieldLTE(FieldBeforeID, vc)) +} + +// BeforeIDIsNil applies the IsNil predicate on the "before_id" field. +func BeforeIDIsNil() predicate.MessagePin { + return predicate.MessagePin(sql.FieldIsNull(FieldBeforeID)) +} + +// BeforeIDNotNil applies the NotNil predicate on the "before_id" field. +func BeforeIDNotNil() predicate.MessagePin { + return predicate.MessagePin(sql.FieldNotNull(FieldBeforeID)) +} + +// HasGuild applies the HasEdge predicate on the "guild" edge. +func HasGuild() predicate.MessagePin { + return predicate.MessagePin(func(s *sql.Selector) { + step := sqlgraph.NewStep( + sqlgraph.From(Table, FieldID), + sqlgraph.Edge(sqlgraph.M2O, true, GuildTable, GuildColumn), + ) + sqlgraph.HasNeighbors(s, step) + }) +} + +// HasGuildWith applies the HasEdge predicate on the "guild" edge with a given conditions (other predicates). +func HasGuildWith(preds ...predicate.Guild) predicate.MessagePin { + return predicate.MessagePin(func(s *sql.Selector) { + step := newGuildStep() + sqlgraph.HasNeighborsWith(s, step, func(s *sql.Selector) { + for _, p := range preds { + p(s) + } + }) + }) +} + +// And groups predicates with the AND operator between them. +func And(predicates ...predicate.MessagePin) predicate.MessagePin { + return predicate.MessagePin(sql.AndPredicates(predicates...)) +} + +// Or groups predicates with the OR operator between them. +func Or(predicates ...predicate.MessagePin) predicate.MessagePin { + return predicate.MessagePin(sql.OrPredicates(predicates...)) +} + +// Not applies the not operator on the given predicate. +func Not(p predicate.MessagePin) predicate.MessagePin { + return predicate.MessagePin(sql.NotPredicates(p)) +} diff --git a/ent/messagepin_create.go b/ent/messagepin_create.go new file mode 100644 index 00000000..951987b3 --- /dev/null +++ b/ent/messagepin_create.go @@ -0,0 +1,319 @@ +// Code generated by ent, DO NOT EDIT. + +package ent + +import ( + "context" + "errors" + "fmt" + + "entgo.io/ent/dialect/sql/sqlgraph" + "entgo.io/ent/schema/field" + "github.com/disgoorg/disgo/discord" + snowflake "github.com/disgoorg/snowflake/v2" + "github.com/google/uuid" + "github.com/sabafly/gobot/ent/guild" + "github.com/sabafly/gobot/ent/messagepin" + "github.com/sabafly/gobot/ent/schema" +) + +// MessagePinCreate is the builder for creating a MessagePin entity. +type MessagePinCreate struct { + config + mutation *MessagePinMutation + hooks []Hook +} + +// SetChannelID sets the "channel_id" field. +func (mpc *MessagePinCreate) SetChannelID(s snowflake.ID) *MessagePinCreate { + mpc.mutation.SetChannelID(s) + return mpc +} + +// SetContent sets the "content" field. +func (mpc *MessagePinCreate) SetContent(s string) *MessagePinCreate { + mpc.mutation.SetContent(s) + return mpc +} + +// SetNillableContent sets the "content" field if the given value is not nil. +func (mpc *MessagePinCreate) SetNillableContent(s *string) *MessagePinCreate { + if s != nil { + mpc.SetContent(*s) + } + return mpc +} + +// SetEmbeds sets the "embeds" field. +func (mpc *MessagePinCreate) SetEmbeds(d []discord.Embed) *MessagePinCreate { + mpc.mutation.SetEmbeds(d) + return mpc +} + +// SetBeforeID sets the "before_id" field. +func (mpc *MessagePinCreate) SetBeforeID(s snowflake.ID) *MessagePinCreate { + mpc.mutation.SetBeforeID(s) + return mpc +} + +// SetNillableBeforeID sets the "before_id" field if the given value is not nil. +func (mpc *MessagePinCreate) SetNillableBeforeID(s *snowflake.ID) *MessagePinCreate { + if s != nil { + mpc.SetBeforeID(*s) + } + return mpc +} + +// SetRateLimit sets the "rate_limit" field. +func (mpc *MessagePinCreate) SetRateLimit(sl schema.RateLimit) *MessagePinCreate { + mpc.mutation.SetRateLimit(sl) + return mpc +} + +// SetNillableRateLimit sets the "rate_limit" field if the given value is not nil. +func (mpc *MessagePinCreate) SetNillableRateLimit(sl *schema.RateLimit) *MessagePinCreate { + if sl != nil { + mpc.SetRateLimit(*sl) + } + return mpc +} + +// SetID sets the "id" field. +func (mpc *MessagePinCreate) SetID(u uuid.UUID) *MessagePinCreate { + mpc.mutation.SetID(u) + return mpc +} + +// SetNillableID sets the "id" field if the given value is not nil. +func (mpc *MessagePinCreate) SetNillableID(u *uuid.UUID) *MessagePinCreate { + if u != nil { + mpc.SetID(*u) + } + return mpc +} + +// SetGuildID sets the "guild" edge to the Guild entity by ID. +func (mpc *MessagePinCreate) SetGuildID(id snowflake.ID) *MessagePinCreate { + mpc.mutation.SetGuildID(id) + return mpc +} + +// SetGuild sets the "guild" edge to the Guild entity. +func (mpc *MessagePinCreate) SetGuild(g *Guild) *MessagePinCreate { + return mpc.SetGuildID(g.ID) +} + +// Mutation returns the MessagePinMutation object of the builder. +func (mpc *MessagePinCreate) Mutation() *MessagePinMutation { + return mpc.mutation +} + +// Save creates the MessagePin in the database. +func (mpc *MessagePinCreate) Save(ctx context.Context) (*MessagePin, error) { + mpc.defaults() + return withHooks(ctx, mpc.sqlSave, mpc.mutation, mpc.hooks) +} + +// SaveX calls Save and panics if Save returns an error. +func (mpc *MessagePinCreate) SaveX(ctx context.Context) *MessagePin { + v, err := mpc.Save(ctx) + if err != nil { + panic(err) + } + return v +} + +// Exec executes the query. +func (mpc *MessagePinCreate) Exec(ctx context.Context) error { + _, err := mpc.Save(ctx) + return err +} + +// ExecX is like Exec, but panics if an error occurs. +func (mpc *MessagePinCreate) ExecX(ctx context.Context) { + if err := mpc.Exec(ctx); err != nil { + panic(err) + } +} + +// defaults sets the default values of the builder before save. +func (mpc *MessagePinCreate) defaults() { + if _, ok := mpc.mutation.RateLimit(); !ok { + v := messagepin.DefaultRateLimit + mpc.mutation.SetRateLimit(v) + } + if _, ok := mpc.mutation.ID(); !ok { + v := messagepin.DefaultID() + mpc.mutation.SetID(v) + } +} + +// check runs all checks and user-defined validators on the builder. +func (mpc *MessagePinCreate) check() error { + if _, ok := mpc.mutation.ChannelID(); !ok { + return &ValidationError{Name: "channel_id", err: errors.New(`ent: missing required field "MessagePin.channel_id"`)} + } + if _, ok := mpc.mutation.RateLimit(); !ok { + return &ValidationError{Name: "rate_limit", err: errors.New(`ent: missing required field "MessagePin.rate_limit"`)} + } + if _, ok := mpc.mutation.GuildID(); !ok { + return &ValidationError{Name: "guild", err: errors.New(`ent: missing required edge "MessagePin.guild"`)} + } + return nil +} + +func (mpc *MessagePinCreate) sqlSave(ctx context.Context) (*MessagePin, error) { + if err := mpc.check(); err != nil { + return nil, err + } + _node, _spec := mpc.createSpec() + if err := sqlgraph.CreateNode(ctx, mpc.driver, _spec); err != nil { + if sqlgraph.IsConstraintError(err) { + err = &ConstraintError{msg: err.Error(), wrap: err} + } + return nil, err + } + if _spec.ID.Value != nil { + if id, ok := _spec.ID.Value.(*uuid.UUID); ok { + _node.ID = *id + } else if err := _node.ID.Scan(_spec.ID.Value); err != nil { + return nil, err + } + } + mpc.mutation.id = &_node.ID + mpc.mutation.done = true + return _node, nil +} + +func (mpc *MessagePinCreate) createSpec() (*MessagePin, *sqlgraph.CreateSpec) { + var ( + _node = &MessagePin{config: mpc.config} + _spec = sqlgraph.NewCreateSpec(messagepin.Table, sqlgraph.NewFieldSpec(messagepin.FieldID, field.TypeUUID)) + ) + if id, ok := mpc.mutation.ID(); ok { + _node.ID = id + _spec.ID.Value = &id + } + if value, ok := mpc.mutation.ChannelID(); ok { + _spec.SetField(messagepin.FieldChannelID, field.TypeUint64, value) + _node.ChannelID = value + } + if value, ok := mpc.mutation.Content(); ok { + _spec.SetField(messagepin.FieldContent, field.TypeString, value) + _node.Content = value + } + if value, ok := mpc.mutation.Embeds(); ok { + _spec.SetField(messagepin.FieldEmbeds, field.TypeJSON, value) + _node.Embeds = value + } + if value, ok := mpc.mutation.BeforeID(); ok { + _spec.SetField(messagepin.FieldBeforeID, field.TypeUint64, value) + _node.BeforeID = &value + } + if value, ok := mpc.mutation.RateLimit(); ok { + _spec.SetField(messagepin.FieldRateLimit, field.TypeJSON, value) + _node.RateLimit = value + } + if nodes := mpc.mutation.GuildIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.M2O, + Inverse: true, + Table: messagepin.GuildTable, + Columns: []string{messagepin.GuildColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(guild.FieldID, field.TypeUint64), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _node.guild_message_pins = &nodes[0] + _spec.Edges = append(_spec.Edges, edge) + } + return _node, _spec +} + +// MessagePinCreateBulk is the builder for creating many MessagePin entities in bulk. +type MessagePinCreateBulk struct { + config + err error + builders []*MessagePinCreate +} + +// Save creates the MessagePin entities in the database. +func (mpcb *MessagePinCreateBulk) Save(ctx context.Context) ([]*MessagePin, error) { + if mpcb.err != nil { + return nil, mpcb.err + } + specs := make([]*sqlgraph.CreateSpec, len(mpcb.builders)) + nodes := make([]*MessagePin, len(mpcb.builders)) + mutators := make([]Mutator, len(mpcb.builders)) + for i := range mpcb.builders { + func(i int, root context.Context) { + builder := mpcb.builders[i] + builder.defaults() + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*MessagePinMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + if err := builder.check(); err != nil { + return nil, err + } + builder.mutation = mutation + var err error + nodes[i], specs[i] = builder.createSpec() + if i < len(mutators)-1 { + _, err = mutators[i+1].Mutate(root, mpcb.builders[i+1].mutation) + } else { + spec := &sqlgraph.BatchCreateSpec{Nodes: specs} + // Invoke the actual operation on the latest mutation in the chain. + if err = sqlgraph.BatchCreate(ctx, mpcb.driver, spec); err != nil { + if sqlgraph.IsConstraintError(err) { + err = &ConstraintError{msg: err.Error(), wrap: err} + } + } + } + if err != nil { + return nil, err + } + mutation.id = &nodes[i].ID + mutation.done = true + return nodes[i], nil + }) + for i := len(builder.hooks) - 1; i >= 0; i-- { + mut = builder.hooks[i](mut) + } + mutators[i] = mut + }(i, ctx) + } + if len(mutators) > 0 { + if _, err := mutators[0].Mutate(ctx, mpcb.builders[0].mutation); err != nil { + return nil, err + } + } + return nodes, nil +} + +// SaveX is like Save, but panics if an error occurs. +func (mpcb *MessagePinCreateBulk) SaveX(ctx context.Context) []*MessagePin { + v, err := mpcb.Save(ctx) + if err != nil { + panic(err) + } + return v +} + +// Exec executes the query. +func (mpcb *MessagePinCreateBulk) Exec(ctx context.Context) error { + _, err := mpcb.Save(ctx) + return err +} + +// ExecX is like Exec, but panics if an error occurs. +func (mpcb *MessagePinCreateBulk) ExecX(ctx context.Context) { + if err := mpcb.Exec(ctx); err != nil { + panic(err) + } +} diff --git a/ent/messagepin_delete.go b/ent/messagepin_delete.go new file mode 100644 index 00000000..83e3a61b --- /dev/null +++ b/ent/messagepin_delete.go @@ -0,0 +1,88 @@ +// Code generated by ent, DO NOT EDIT. + +package ent + +import ( + "context" + + "entgo.io/ent/dialect/sql" + "entgo.io/ent/dialect/sql/sqlgraph" + "entgo.io/ent/schema/field" + "github.com/sabafly/gobot/ent/messagepin" + "github.com/sabafly/gobot/ent/predicate" +) + +// MessagePinDelete is the builder for deleting a MessagePin entity. +type MessagePinDelete struct { + config + hooks []Hook + mutation *MessagePinMutation +} + +// Where appends a list predicates to the MessagePinDelete builder. +func (mpd *MessagePinDelete) Where(ps ...predicate.MessagePin) *MessagePinDelete { + mpd.mutation.Where(ps...) + return mpd +} + +// Exec executes the deletion query and returns how many vertices were deleted. +func (mpd *MessagePinDelete) Exec(ctx context.Context) (int, error) { + return withHooks(ctx, mpd.sqlExec, mpd.mutation, mpd.hooks) +} + +// ExecX is like Exec, but panics if an error occurs. +func (mpd *MessagePinDelete) ExecX(ctx context.Context) int { + n, err := mpd.Exec(ctx) + if err != nil { + panic(err) + } + return n +} + +func (mpd *MessagePinDelete) sqlExec(ctx context.Context) (int, error) { + _spec := sqlgraph.NewDeleteSpec(messagepin.Table, sqlgraph.NewFieldSpec(messagepin.FieldID, field.TypeUUID)) + if ps := mpd.mutation.predicates; len(ps) > 0 { + _spec.Predicate = func(selector *sql.Selector) { + for i := range ps { + ps[i](selector) + } + } + } + affected, err := sqlgraph.DeleteNodes(ctx, mpd.driver, _spec) + if err != nil && sqlgraph.IsConstraintError(err) { + err = &ConstraintError{msg: err.Error(), wrap: err} + } + mpd.mutation.done = true + return affected, err +} + +// MessagePinDeleteOne is the builder for deleting a single MessagePin entity. +type MessagePinDeleteOne struct { + mpd *MessagePinDelete +} + +// Where appends a list predicates to the MessagePinDelete builder. +func (mpdo *MessagePinDeleteOne) Where(ps ...predicate.MessagePin) *MessagePinDeleteOne { + mpdo.mpd.mutation.Where(ps...) + return mpdo +} + +// Exec executes the deletion query. +func (mpdo *MessagePinDeleteOne) Exec(ctx context.Context) error { + n, err := mpdo.mpd.Exec(ctx) + switch { + case err != nil: + return err + case n == 0: + return &NotFoundError{messagepin.Label} + default: + return nil + } +} + +// ExecX is like Exec, but panics if an error occurs. +func (mpdo *MessagePinDeleteOne) ExecX(ctx context.Context) { + if err := mpdo.Exec(ctx); err != nil { + panic(err) + } +} diff --git a/ent/messagepin_query.go b/ent/messagepin_query.go new file mode 100644 index 00000000..05111ca7 --- /dev/null +++ b/ent/messagepin_query.go @@ -0,0 +1,615 @@ +// Code generated by ent, DO NOT EDIT. + +package ent + +import ( + "context" + "fmt" + "math" + + "entgo.io/ent/dialect/sql" + "entgo.io/ent/dialect/sql/sqlgraph" + "entgo.io/ent/schema/field" + snowflake "github.com/disgoorg/snowflake/v2" + "github.com/google/uuid" + "github.com/sabafly/gobot/ent/guild" + "github.com/sabafly/gobot/ent/messagepin" + "github.com/sabafly/gobot/ent/predicate" +) + +// MessagePinQuery is the builder for querying MessagePin entities. +type MessagePinQuery struct { + config + ctx *QueryContext + order []messagepin.OrderOption + inters []Interceptor + predicates []predicate.MessagePin + withGuild *GuildQuery + withFKs bool + // intermediate query (i.e. traversal path). + sql *sql.Selector + path func(context.Context) (*sql.Selector, error) +} + +// Where adds a new predicate for the MessagePinQuery builder. +func (mpq *MessagePinQuery) Where(ps ...predicate.MessagePin) *MessagePinQuery { + mpq.predicates = append(mpq.predicates, ps...) + return mpq +} + +// Limit the number of records to be returned by this query. +func (mpq *MessagePinQuery) Limit(limit int) *MessagePinQuery { + mpq.ctx.Limit = &limit + return mpq +} + +// Offset to start from. +func (mpq *MessagePinQuery) Offset(offset int) *MessagePinQuery { + mpq.ctx.Offset = &offset + return mpq +} + +// Unique configures the query builder to filter duplicate records on query. +// By default, unique is set to true, and can be disabled using this method. +func (mpq *MessagePinQuery) Unique(unique bool) *MessagePinQuery { + mpq.ctx.Unique = &unique + return mpq +} + +// Order specifies how the records should be ordered. +func (mpq *MessagePinQuery) Order(o ...messagepin.OrderOption) *MessagePinQuery { + mpq.order = append(mpq.order, o...) + return mpq +} + +// QueryGuild chains the current query on the "guild" edge. +func (mpq *MessagePinQuery) QueryGuild() *GuildQuery { + query := (&GuildClient{config: mpq.config}).Query() + query.path = func(ctx context.Context) (fromU *sql.Selector, err error) { + if err := mpq.prepareQuery(ctx); err != nil { + return nil, err + } + selector := mpq.sqlQuery(ctx) + if err := selector.Err(); err != nil { + return nil, err + } + step := sqlgraph.NewStep( + sqlgraph.From(messagepin.Table, messagepin.FieldID, selector), + sqlgraph.To(guild.Table, guild.FieldID), + sqlgraph.Edge(sqlgraph.M2O, true, messagepin.GuildTable, messagepin.GuildColumn), + ) + fromU = sqlgraph.SetNeighbors(mpq.driver.Dialect(), step) + return fromU, nil + } + return query +} + +// First returns the first MessagePin entity from the query. +// Returns a *NotFoundError when no MessagePin was found. +func (mpq *MessagePinQuery) First(ctx context.Context) (*MessagePin, error) { + nodes, err := mpq.Limit(1).All(setContextOp(ctx, mpq.ctx, "First")) + if err != nil { + return nil, err + } + if len(nodes) == 0 { + return nil, &NotFoundError{messagepin.Label} + } + return nodes[0], nil +} + +// FirstX is like First, but panics if an error occurs. +func (mpq *MessagePinQuery) FirstX(ctx context.Context) *MessagePin { + node, err := mpq.First(ctx) + if err != nil && !IsNotFound(err) { + panic(err) + } + return node +} + +// FirstID returns the first MessagePin ID from the query. +// Returns a *NotFoundError when no MessagePin ID was found. +func (mpq *MessagePinQuery) FirstID(ctx context.Context) (id uuid.UUID, err error) { + var ids []uuid.UUID + if ids, err = mpq.Limit(1).IDs(setContextOp(ctx, mpq.ctx, "FirstID")); err != nil { + return + } + if len(ids) == 0 { + err = &NotFoundError{messagepin.Label} + return + } + return ids[0], nil +} + +// FirstIDX is like FirstID, but panics if an error occurs. +func (mpq *MessagePinQuery) FirstIDX(ctx context.Context) uuid.UUID { + id, err := mpq.FirstID(ctx) + if err != nil && !IsNotFound(err) { + panic(err) + } + return id +} + +// Only returns a single MessagePin entity found by the query, ensuring it only returns one. +// Returns a *NotSingularError when more than one MessagePin entity is found. +// Returns a *NotFoundError when no MessagePin entities are found. +func (mpq *MessagePinQuery) Only(ctx context.Context) (*MessagePin, error) { + nodes, err := mpq.Limit(2).All(setContextOp(ctx, mpq.ctx, "Only")) + if err != nil { + return nil, err + } + switch len(nodes) { + case 1: + return nodes[0], nil + case 0: + return nil, &NotFoundError{messagepin.Label} + default: + return nil, &NotSingularError{messagepin.Label} + } +} + +// OnlyX is like Only, but panics if an error occurs. +func (mpq *MessagePinQuery) OnlyX(ctx context.Context) *MessagePin { + node, err := mpq.Only(ctx) + if err != nil { + panic(err) + } + return node +} + +// OnlyID is like Only, but returns the only MessagePin ID in the query. +// Returns a *NotSingularError when more than one MessagePin ID is found. +// Returns a *NotFoundError when no entities are found. +func (mpq *MessagePinQuery) OnlyID(ctx context.Context) (id uuid.UUID, err error) { + var ids []uuid.UUID + if ids, err = mpq.Limit(2).IDs(setContextOp(ctx, mpq.ctx, "OnlyID")); err != nil { + return + } + switch len(ids) { + case 1: + id = ids[0] + case 0: + err = &NotFoundError{messagepin.Label} + default: + err = &NotSingularError{messagepin.Label} + } + return +} + +// OnlyIDX is like OnlyID, but panics if an error occurs. +func (mpq *MessagePinQuery) OnlyIDX(ctx context.Context) uuid.UUID { + id, err := mpq.OnlyID(ctx) + if err != nil { + panic(err) + } + return id +} + +// All executes the query and returns a list of MessagePins. +func (mpq *MessagePinQuery) All(ctx context.Context) ([]*MessagePin, error) { + ctx = setContextOp(ctx, mpq.ctx, "All") + if err := mpq.prepareQuery(ctx); err != nil { + return nil, err + } + qr := querierAll[[]*MessagePin, *MessagePinQuery]() + return withInterceptors[[]*MessagePin](ctx, mpq, qr, mpq.inters) +} + +// AllX is like All, but panics if an error occurs. +func (mpq *MessagePinQuery) AllX(ctx context.Context) []*MessagePin { + nodes, err := mpq.All(ctx) + if err != nil { + panic(err) + } + return nodes +} + +// IDs executes the query and returns a list of MessagePin IDs. +func (mpq *MessagePinQuery) IDs(ctx context.Context) (ids []uuid.UUID, err error) { + if mpq.ctx.Unique == nil && mpq.path != nil { + mpq.Unique(true) + } + ctx = setContextOp(ctx, mpq.ctx, "IDs") + if err = mpq.Select(messagepin.FieldID).Scan(ctx, &ids); err != nil { + return nil, err + } + return ids, nil +} + +// IDsX is like IDs, but panics if an error occurs. +func (mpq *MessagePinQuery) IDsX(ctx context.Context) []uuid.UUID { + ids, err := mpq.IDs(ctx) + if err != nil { + panic(err) + } + return ids +} + +// Count returns the count of the given query. +func (mpq *MessagePinQuery) Count(ctx context.Context) (int, error) { + ctx = setContextOp(ctx, mpq.ctx, "Count") + if err := mpq.prepareQuery(ctx); err != nil { + return 0, err + } + return withInterceptors[int](ctx, mpq, querierCount[*MessagePinQuery](), mpq.inters) +} + +// CountX is like Count, but panics if an error occurs. +func (mpq *MessagePinQuery) CountX(ctx context.Context) int { + count, err := mpq.Count(ctx) + if err != nil { + panic(err) + } + return count +} + +// Exist returns true if the query has elements in the graph. +func (mpq *MessagePinQuery) Exist(ctx context.Context) (bool, error) { + ctx = setContextOp(ctx, mpq.ctx, "Exist") + switch _, err := mpq.FirstID(ctx); { + case IsNotFound(err): + return false, nil + case err != nil: + return false, fmt.Errorf("ent: check existence: %w", err) + default: + return true, nil + } +} + +// ExistX is like Exist, but panics if an error occurs. +func (mpq *MessagePinQuery) ExistX(ctx context.Context) bool { + exist, err := mpq.Exist(ctx) + if err != nil { + panic(err) + } + return exist +} + +// Clone returns a duplicate of the MessagePinQuery builder, including all associated steps. It can be +// used to prepare common query builders and use them differently after the clone is made. +func (mpq *MessagePinQuery) Clone() *MessagePinQuery { + if mpq == nil { + return nil + } + return &MessagePinQuery{ + config: mpq.config, + ctx: mpq.ctx.Clone(), + order: append([]messagepin.OrderOption{}, mpq.order...), + inters: append([]Interceptor{}, mpq.inters...), + predicates: append([]predicate.MessagePin{}, mpq.predicates...), + withGuild: mpq.withGuild.Clone(), + // clone intermediate query. + sql: mpq.sql.Clone(), + path: mpq.path, + } +} + +// WithGuild tells the query-builder to eager-load the nodes that are connected to +// the "guild" edge. The optional arguments are used to configure the query builder of the edge. +func (mpq *MessagePinQuery) WithGuild(opts ...func(*GuildQuery)) *MessagePinQuery { + query := (&GuildClient{config: mpq.config}).Query() + for _, opt := range opts { + opt(query) + } + mpq.withGuild = query + return mpq +} + +// GroupBy is used to group vertices by one or more fields/columns. +// It is often used with aggregate functions, like: count, max, mean, min, sum. +// +// Example: +// +// var v []struct { +// ChannelID snowflake.ID `json:"channel_id,omitempty"` +// Count int `json:"count,omitempty"` +// } +// +// client.MessagePin.Query(). +// GroupBy(messagepin.FieldChannelID). +// Aggregate(ent.Count()). +// Scan(ctx, &v) +func (mpq *MessagePinQuery) GroupBy(field string, fields ...string) *MessagePinGroupBy { + mpq.ctx.Fields = append([]string{field}, fields...) + grbuild := &MessagePinGroupBy{build: mpq} + grbuild.flds = &mpq.ctx.Fields + grbuild.label = messagepin.Label + grbuild.scan = grbuild.Scan + return grbuild +} + +// Select allows the selection one or more fields/columns for the given query, +// instead of selecting all fields in the entity. +// +// Example: +// +// var v []struct { +// ChannelID snowflake.ID `json:"channel_id,omitempty"` +// } +// +// client.MessagePin.Query(). +// Select(messagepin.FieldChannelID). +// Scan(ctx, &v) +func (mpq *MessagePinQuery) Select(fields ...string) *MessagePinSelect { + mpq.ctx.Fields = append(mpq.ctx.Fields, fields...) + sbuild := &MessagePinSelect{MessagePinQuery: mpq} + sbuild.label = messagepin.Label + sbuild.flds, sbuild.scan = &mpq.ctx.Fields, sbuild.Scan + return sbuild +} + +// Aggregate returns a MessagePinSelect configured with the given aggregations. +func (mpq *MessagePinQuery) Aggregate(fns ...AggregateFunc) *MessagePinSelect { + return mpq.Select().Aggregate(fns...) +} + +func (mpq *MessagePinQuery) prepareQuery(ctx context.Context) error { + for _, inter := range mpq.inters { + if inter == nil { + return fmt.Errorf("ent: uninitialized interceptor (forgotten import ent/runtime?)") + } + if trv, ok := inter.(Traverser); ok { + if err := trv.Traverse(ctx, mpq); err != nil { + return err + } + } + } + for _, f := range mpq.ctx.Fields { + if !messagepin.ValidColumn(f) { + return &ValidationError{Name: f, err: fmt.Errorf("ent: invalid field %q for query", f)} + } + } + if mpq.path != nil { + prev, err := mpq.path(ctx) + if err != nil { + return err + } + mpq.sql = prev + } + return nil +} + +func (mpq *MessagePinQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*MessagePin, error) { + var ( + nodes = []*MessagePin{} + withFKs = mpq.withFKs + _spec = mpq.querySpec() + loadedTypes = [1]bool{ + mpq.withGuild != nil, + } + ) + if mpq.withGuild != nil { + withFKs = true + } + if withFKs { + _spec.Node.Columns = append(_spec.Node.Columns, messagepin.ForeignKeys...) + } + _spec.ScanValues = func(columns []string) ([]any, error) { + return (*MessagePin).scanValues(nil, columns) + } + _spec.Assign = func(columns []string, values []any) error { + node := &MessagePin{config: mpq.config} + nodes = append(nodes, node) + node.Edges.loadedTypes = loadedTypes + return node.assignValues(columns, values) + } + for i := range hooks { + hooks[i](ctx, _spec) + } + if err := sqlgraph.QueryNodes(ctx, mpq.driver, _spec); err != nil { + return nil, err + } + if len(nodes) == 0 { + return nodes, nil + } + if query := mpq.withGuild; query != nil { + if err := mpq.loadGuild(ctx, query, nodes, nil, + func(n *MessagePin, e *Guild) { n.Edges.Guild = e }); err != nil { + return nil, err + } + } + return nodes, nil +} + +func (mpq *MessagePinQuery) loadGuild(ctx context.Context, query *GuildQuery, nodes []*MessagePin, init func(*MessagePin), assign func(*MessagePin, *Guild)) error { + ids := make([]snowflake.ID, 0, len(nodes)) + nodeids := make(map[snowflake.ID][]*MessagePin) + for i := range nodes { + if nodes[i].guild_message_pins == nil { + continue + } + fk := *nodes[i].guild_message_pins + if _, ok := nodeids[fk]; !ok { + ids = append(ids, fk) + } + nodeids[fk] = append(nodeids[fk], nodes[i]) + } + if len(ids) == 0 { + return nil + } + query.Where(guild.IDIn(ids...)) + neighbors, err := query.All(ctx) + if err != nil { + return err + } + for _, n := range neighbors { + nodes, ok := nodeids[n.ID] + if !ok { + return fmt.Errorf(`unexpected foreign-key "guild_message_pins" returned %v`, n.ID) + } + for i := range nodes { + assign(nodes[i], n) + } + } + return nil +} + +func (mpq *MessagePinQuery) sqlCount(ctx context.Context) (int, error) { + _spec := mpq.querySpec() + _spec.Node.Columns = mpq.ctx.Fields + if len(mpq.ctx.Fields) > 0 { + _spec.Unique = mpq.ctx.Unique != nil && *mpq.ctx.Unique + } + return sqlgraph.CountNodes(ctx, mpq.driver, _spec) +} + +func (mpq *MessagePinQuery) querySpec() *sqlgraph.QuerySpec { + _spec := sqlgraph.NewQuerySpec(messagepin.Table, messagepin.Columns, sqlgraph.NewFieldSpec(messagepin.FieldID, field.TypeUUID)) + _spec.From = mpq.sql + if unique := mpq.ctx.Unique; unique != nil { + _spec.Unique = *unique + } else if mpq.path != nil { + _spec.Unique = true + } + if fields := mpq.ctx.Fields; len(fields) > 0 { + _spec.Node.Columns = make([]string, 0, len(fields)) + _spec.Node.Columns = append(_spec.Node.Columns, messagepin.FieldID) + for i := range fields { + if fields[i] != messagepin.FieldID { + _spec.Node.Columns = append(_spec.Node.Columns, fields[i]) + } + } + } + if ps := mpq.predicates; len(ps) > 0 { + _spec.Predicate = func(selector *sql.Selector) { + for i := range ps { + ps[i](selector) + } + } + } + if limit := mpq.ctx.Limit; limit != nil { + _spec.Limit = *limit + } + if offset := mpq.ctx.Offset; offset != nil { + _spec.Offset = *offset + } + if ps := mpq.order; len(ps) > 0 { + _spec.Order = func(selector *sql.Selector) { + for i := range ps { + ps[i](selector) + } + } + } + return _spec +} + +func (mpq *MessagePinQuery) sqlQuery(ctx context.Context) *sql.Selector { + builder := sql.Dialect(mpq.driver.Dialect()) + t1 := builder.Table(messagepin.Table) + columns := mpq.ctx.Fields + if len(columns) == 0 { + columns = messagepin.Columns + } + selector := builder.Select(t1.Columns(columns...)...).From(t1) + if mpq.sql != nil { + selector = mpq.sql + selector.Select(selector.Columns(columns...)...) + } + if mpq.ctx.Unique != nil && *mpq.ctx.Unique { + selector.Distinct() + } + for _, p := range mpq.predicates { + p(selector) + } + for _, p := range mpq.order { + p(selector) + } + if offset := mpq.ctx.Offset; offset != nil { + // limit is mandatory for offset clause. We start + // with default value, and override it below if needed. + selector.Offset(*offset).Limit(math.MaxInt32) + } + if limit := mpq.ctx.Limit; limit != nil { + selector.Limit(*limit) + } + return selector +} + +// MessagePinGroupBy is the group-by builder for MessagePin entities. +type MessagePinGroupBy struct { + selector + build *MessagePinQuery +} + +// Aggregate adds the given aggregation functions to the group-by query. +func (mpgb *MessagePinGroupBy) Aggregate(fns ...AggregateFunc) *MessagePinGroupBy { + mpgb.fns = append(mpgb.fns, fns...) + return mpgb +} + +// Scan applies the selector query and scans the result into the given value. +func (mpgb *MessagePinGroupBy) Scan(ctx context.Context, v any) error { + ctx = setContextOp(ctx, mpgb.build.ctx, "GroupBy") + if err := mpgb.build.prepareQuery(ctx); err != nil { + return err + } + return scanWithInterceptors[*MessagePinQuery, *MessagePinGroupBy](ctx, mpgb.build, mpgb, mpgb.build.inters, v) +} + +func (mpgb *MessagePinGroupBy) sqlScan(ctx context.Context, root *MessagePinQuery, v any) error { + selector := root.sqlQuery(ctx).Select() + aggregation := make([]string, 0, len(mpgb.fns)) + for _, fn := range mpgb.fns { + aggregation = append(aggregation, fn(selector)) + } + if len(selector.SelectedColumns()) == 0 { + columns := make([]string, 0, len(*mpgb.flds)+len(mpgb.fns)) + for _, f := range *mpgb.flds { + columns = append(columns, selector.C(f)) + } + columns = append(columns, aggregation...) + selector.Select(columns...) + } + selector.GroupBy(selector.Columns(*mpgb.flds...)...) + if err := selector.Err(); err != nil { + return err + } + rows := &sql.Rows{} + query, args := selector.Query() + if err := mpgb.build.driver.Query(ctx, query, args, rows); err != nil { + return err + } + defer rows.Close() + return sql.ScanSlice(rows, v) +} + +// MessagePinSelect is the builder for selecting fields of MessagePin entities. +type MessagePinSelect struct { + *MessagePinQuery + selector +} + +// Aggregate adds the given aggregation functions to the selector query. +func (mps *MessagePinSelect) Aggregate(fns ...AggregateFunc) *MessagePinSelect { + mps.fns = append(mps.fns, fns...) + return mps +} + +// Scan applies the selector query and scans the result into the given value. +func (mps *MessagePinSelect) Scan(ctx context.Context, v any) error { + ctx = setContextOp(ctx, mps.ctx, "Select") + if err := mps.prepareQuery(ctx); err != nil { + return err + } + return scanWithInterceptors[*MessagePinQuery, *MessagePinSelect](ctx, mps.MessagePinQuery, mps, mps.inters, v) +} + +func (mps *MessagePinSelect) sqlScan(ctx context.Context, root *MessagePinQuery, v any) error { + selector := root.sqlQuery(ctx) + aggregation := make([]string, 0, len(mps.fns)) + for _, fn := range mps.fns { + aggregation = append(aggregation, fn(selector)) + } + switch n := len(*mps.selector.flds); { + case n == 0 && len(aggregation) > 0: + selector.Select(aggregation...) + case n != 0 && len(aggregation) > 0: + selector.AppendSelect(aggregation...) + } + rows := &sql.Rows{} + query, args := selector.Query() + if err := mps.driver.Query(ctx, query, args, rows); err != nil { + return err + } + defer rows.Close() + return sql.ScanSlice(rows, v) +} diff --git a/ent/messagepin_update.go b/ent/messagepin_update.go new file mode 100644 index 00000000..bcceb8cf --- /dev/null +++ b/ent/messagepin_update.go @@ -0,0 +1,564 @@ +// Code generated by ent, DO NOT EDIT. + +package ent + +import ( + "context" + "errors" + "fmt" + + "entgo.io/ent/dialect/sql" + "entgo.io/ent/dialect/sql/sqlgraph" + "entgo.io/ent/dialect/sql/sqljson" + "entgo.io/ent/schema/field" + "github.com/disgoorg/disgo/discord" + snowflake "github.com/disgoorg/snowflake/v2" + "github.com/sabafly/gobot/ent/guild" + "github.com/sabafly/gobot/ent/messagepin" + "github.com/sabafly/gobot/ent/predicate" + "github.com/sabafly/gobot/ent/schema" +) + +// MessagePinUpdate is the builder for updating MessagePin entities. +type MessagePinUpdate struct { + config + hooks []Hook + mutation *MessagePinMutation +} + +// Where appends a list predicates to the MessagePinUpdate builder. +func (mpu *MessagePinUpdate) Where(ps ...predicate.MessagePin) *MessagePinUpdate { + mpu.mutation.Where(ps...) + return mpu +} + +// SetChannelID sets the "channel_id" field. +func (mpu *MessagePinUpdate) SetChannelID(s snowflake.ID) *MessagePinUpdate { + mpu.mutation.ResetChannelID() + mpu.mutation.SetChannelID(s) + return mpu +} + +// SetNillableChannelID sets the "channel_id" field if the given value is not nil. +func (mpu *MessagePinUpdate) SetNillableChannelID(s *snowflake.ID) *MessagePinUpdate { + if s != nil { + mpu.SetChannelID(*s) + } + return mpu +} + +// AddChannelID adds s to the "channel_id" field. +func (mpu *MessagePinUpdate) AddChannelID(s snowflake.ID) *MessagePinUpdate { + mpu.mutation.AddChannelID(s) + return mpu +} + +// SetContent sets the "content" field. +func (mpu *MessagePinUpdate) SetContent(s string) *MessagePinUpdate { + mpu.mutation.SetContent(s) + return mpu +} + +// SetNillableContent sets the "content" field if the given value is not nil. +func (mpu *MessagePinUpdate) SetNillableContent(s *string) *MessagePinUpdate { + if s != nil { + mpu.SetContent(*s) + } + return mpu +} + +// ClearContent clears the value of the "content" field. +func (mpu *MessagePinUpdate) ClearContent() *MessagePinUpdate { + mpu.mutation.ClearContent() + return mpu +} + +// SetEmbeds sets the "embeds" field. +func (mpu *MessagePinUpdate) SetEmbeds(d []discord.Embed) *MessagePinUpdate { + mpu.mutation.SetEmbeds(d) + return mpu +} + +// AppendEmbeds appends d to the "embeds" field. +func (mpu *MessagePinUpdate) AppendEmbeds(d []discord.Embed) *MessagePinUpdate { + mpu.mutation.AppendEmbeds(d) + return mpu +} + +// ClearEmbeds clears the value of the "embeds" field. +func (mpu *MessagePinUpdate) ClearEmbeds() *MessagePinUpdate { + mpu.mutation.ClearEmbeds() + return mpu +} + +// SetBeforeID sets the "before_id" field. +func (mpu *MessagePinUpdate) SetBeforeID(s snowflake.ID) *MessagePinUpdate { + mpu.mutation.ResetBeforeID() + mpu.mutation.SetBeforeID(s) + return mpu +} + +// SetNillableBeforeID sets the "before_id" field if the given value is not nil. +func (mpu *MessagePinUpdate) SetNillableBeforeID(s *snowflake.ID) *MessagePinUpdate { + if s != nil { + mpu.SetBeforeID(*s) + } + return mpu +} + +// AddBeforeID adds s to the "before_id" field. +func (mpu *MessagePinUpdate) AddBeforeID(s snowflake.ID) *MessagePinUpdate { + mpu.mutation.AddBeforeID(s) + return mpu +} + +// ClearBeforeID clears the value of the "before_id" field. +func (mpu *MessagePinUpdate) ClearBeforeID() *MessagePinUpdate { + mpu.mutation.ClearBeforeID() + return mpu +} + +// SetRateLimit sets the "rate_limit" field. +func (mpu *MessagePinUpdate) SetRateLimit(sl schema.RateLimit) *MessagePinUpdate { + mpu.mutation.SetRateLimit(sl) + return mpu +} + +// SetNillableRateLimit sets the "rate_limit" field if the given value is not nil. +func (mpu *MessagePinUpdate) SetNillableRateLimit(sl *schema.RateLimit) *MessagePinUpdate { + if sl != nil { + mpu.SetRateLimit(*sl) + } + return mpu +} + +// SetGuildID sets the "guild" edge to the Guild entity by ID. +func (mpu *MessagePinUpdate) SetGuildID(id snowflake.ID) *MessagePinUpdate { + mpu.mutation.SetGuildID(id) + return mpu +} + +// SetGuild sets the "guild" edge to the Guild entity. +func (mpu *MessagePinUpdate) SetGuild(g *Guild) *MessagePinUpdate { + return mpu.SetGuildID(g.ID) +} + +// Mutation returns the MessagePinMutation object of the builder. +func (mpu *MessagePinUpdate) Mutation() *MessagePinMutation { + return mpu.mutation +} + +// ClearGuild clears the "guild" edge to the Guild entity. +func (mpu *MessagePinUpdate) ClearGuild() *MessagePinUpdate { + mpu.mutation.ClearGuild() + return mpu +} + +// Save executes the query and returns the number of nodes affected by the update operation. +func (mpu *MessagePinUpdate) Save(ctx context.Context) (int, error) { + return withHooks(ctx, mpu.sqlSave, mpu.mutation, mpu.hooks) +} + +// SaveX is like Save, but panics if an error occurs. +func (mpu *MessagePinUpdate) SaveX(ctx context.Context) int { + affected, err := mpu.Save(ctx) + if err != nil { + panic(err) + } + return affected +} + +// Exec executes the query. +func (mpu *MessagePinUpdate) Exec(ctx context.Context) error { + _, err := mpu.Save(ctx) + return err +} + +// ExecX is like Exec, but panics if an error occurs. +func (mpu *MessagePinUpdate) ExecX(ctx context.Context) { + if err := mpu.Exec(ctx); err != nil { + panic(err) + } +} + +// check runs all checks and user-defined validators on the builder. +func (mpu *MessagePinUpdate) check() error { + if _, ok := mpu.mutation.GuildID(); mpu.mutation.GuildCleared() && !ok { + return errors.New(`ent: clearing a required unique edge "MessagePin.guild"`) + } + return nil +} + +func (mpu *MessagePinUpdate) sqlSave(ctx context.Context) (n int, err error) { + if err := mpu.check(); err != nil { + return n, err + } + _spec := sqlgraph.NewUpdateSpec(messagepin.Table, messagepin.Columns, sqlgraph.NewFieldSpec(messagepin.FieldID, field.TypeUUID)) + if ps := mpu.mutation.predicates; len(ps) > 0 { + _spec.Predicate = func(selector *sql.Selector) { + for i := range ps { + ps[i](selector) + } + } + } + if value, ok := mpu.mutation.ChannelID(); ok { + _spec.SetField(messagepin.FieldChannelID, field.TypeUint64, value) + } + if value, ok := mpu.mutation.AddedChannelID(); ok { + _spec.AddField(messagepin.FieldChannelID, field.TypeUint64, value) + } + if value, ok := mpu.mutation.Content(); ok { + _spec.SetField(messagepin.FieldContent, field.TypeString, value) + } + if mpu.mutation.ContentCleared() { + _spec.ClearField(messagepin.FieldContent, field.TypeString) + } + if value, ok := mpu.mutation.Embeds(); ok { + _spec.SetField(messagepin.FieldEmbeds, field.TypeJSON, value) + } + if value, ok := mpu.mutation.AppendedEmbeds(); ok { + _spec.AddModifier(func(u *sql.UpdateBuilder) { + sqljson.Append(u, messagepin.FieldEmbeds, value) + }) + } + if mpu.mutation.EmbedsCleared() { + _spec.ClearField(messagepin.FieldEmbeds, field.TypeJSON) + } + if value, ok := mpu.mutation.BeforeID(); ok { + _spec.SetField(messagepin.FieldBeforeID, field.TypeUint64, value) + } + if value, ok := mpu.mutation.AddedBeforeID(); ok { + _spec.AddField(messagepin.FieldBeforeID, field.TypeUint64, value) + } + if mpu.mutation.BeforeIDCleared() { + _spec.ClearField(messagepin.FieldBeforeID, field.TypeUint64) + } + if value, ok := mpu.mutation.RateLimit(); ok { + _spec.SetField(messagepin.FieldRateLimit, field.TypeJSON, value) + } + if mpu.mutation.GuildCleared() { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.M2O, + Inverse: true, + Table: messagepin.GuildTable, + Columns: []string{messagepin.GuildColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(guild.FieldID, field.TypeUint64), + }, + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := mpu.mutation.GuildIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.M2O, + Inverse: true, + Table: messagepin.GuildTable, + Columns: []string{messagepin.GuildColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(guild.FieldID, field.TypeUint64), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Add = append(_spec.Edges.Add, edge) + } + if n, err = sqlgraph.UpdateNodes(ctx, mpu.driver, _spec); err != nil { + if _, ok := err.(*sqlgraph.NotFoundError); ok { + err = &NotFoundError{messagepin.Label} + } else if sqlgraph.IsConstraintError(err) { + err = &ConstraintError{msg: err.Error(), wrap: err} + } + return 0, err + } + mpu.mutation.done = true + return n, nil +} + +// MessagePinUpdateOne is the builder for updating a single MessagePin entity. +type MessagePinUpdateOne struct { + config + fields []string + hooks []Hook + mutation *MessagePinMutation +} + +// SetChannelID sets the "channel_id" field. +func (mpuo *MessagePinUpdateOne) SetChannelID(s snowflake.ID) *MessagePinUpdateOne { + mpuo.mutation.ResetChannelID() + mpuo.mutation.SetChannelID(s) + return mpuo +} + +// SetNillableChannelID sets the "channel_id" field if the given value is not nil. +func (mpuo *MessagePinUpdateOne) SetNillableChannelID(s *snowflake.ID) *MessagePinUpdateOne { + if s != nil { + mpuo.SetChannelID(*s) + } + return mpuo +} + +// AddChannelID adds s to the "channel_id" field. +func (mpuo *MessagePinUpdateOne) AddChannelID(s snowflake.ID) *MessagePinUpdateOne { + mpuo.mutation.AddChannelID(s) + return mpuo +} + +// SetContent sets the "content" field. +func (mpuo *MessagePinUpdateOne) SetContent(s string) *MessagePinUpdateOne { + mpuo.mutation.SetContent(s) + return mpuo +} + +// SetNillableContent sets the "content" field if the given value is not nil. +func (mpuo *MessagePinUpdateOne) SetNillableContent(s *string) *MessagePinUpdateOne { + if s != nil { + mpuo.SetContent(*s) + } + return mpuo +} + +// ClearContent clears the value of the "content" field. +func (mpuo *MessagePinUpdateOne) ClearContent() *MessagePinUpdateOne { + mpuo.mutation.ClearContent() + return mpuo +} + +// SetEmbeds sets the "embeds" field. +func (mpuo *MessagePinUpdateOne) SetEmbeds(d []discord.Embed) *MessagePinUpdateOne { + mpuo.mutation.SetEmbeds(d) + return mpuo +} + +// AppendEmbeds appends d to the "embeds" field. +func (mpuo *MessagePinUpdateOne) AppendEmbeds(d []discord.Embed) *MessagePinUpdateOne { + mpuo.mutation.AppendEmbeds(d) + return mpuo +} + +// ClearEmbeds clears the value of the "embeds" field. +func (mpuo *MessagePinUpdateOne) ClearEmbeds() *MessagePinUpdateOne { + mpuo.mutation.ClearEmbeds() + return mpuo +} + +// SetBeforeID sets the "before_id" field. +func (mpuo *MessagePinUpdateOne) SetBeforeID(s snowflake.ID) *MessagePinUpdateOne { + mpuo.mutation.ResetBeforeID() + mpuo.mutation.SetBeforeID(s) + return mpuo +} + +// SetNillableBeforeID sets the "before_id" field if the given value is not nil. +func (mpuo *MessagePinUpdateOne) SetNillableBeforeID(s *snowflake.ID) *MessagePinUpdateOne { + if s != nil { + mpuo.SetBeforeID(*s) + } + return mpuo +} + +// AddBeforeID adds s to the "before_id" field. +func (mpuo *MessagePinUpdateOne) AddBeforeID(s snowflake.ID) *MessagePinUpdateOne { + mpuo.mutation.AddBeforeID(s) + return mpuo +} + +// ClearBeforeID clears the value of the "before_id" field. +func (mpuo *MessagePinUpdateOne) ClearBeforeID() *MessagePinUpdateOne { + mpuo.mutation.ClearBeforeID() + return mpuo +} + +// SetRateLimit sets the "rate_limit" field. +func (mpuo *MessagePinUpdateOne) SetRateLimit(sl schema.RateLimit) *MessagePinUpdateOne { + mpuo.mutation.SetRateLimit(sl) + return mpuo +} + +// SetNillableRateLimit sets the "rate_limit" field if the given value is not nil. +func (mpuo *MessagePinUpdateOne) SetNillableRateLimit(sl *schema.RateLimit) *MessagePinUpdateOne { + if sl != nil { + mpuo.SetRateLimit(*sl) + } + return mpuo +} + +// SetGuildID sets the "guild" edge to the Guild entity by ID. +func (mpuo *MessagePinUpdateOne) SetGuildID(id snowflake.ID) *MessagePinUpdateOne { + mpuo.mutation.SetGuildID(id) + return mpuo +} + +// SetGuild sets the "guild" edge to the Guild entity. +func (mpuo *MessagePinUpdateOne) SetGuild(g *Guild) *MessagePinUpdateOne { + return mpuo.SetGuildID(g.ID) +} + +// Mutation returns the MessagePinMutation object of the builder. +func (mpuo *MessagePinUpdateOne) Mutation() *MessagePinMutation { + return mpuo.mutation +} + +// ClearGuild clears the "guild" edge to the Guild entity. +func (mpuo *MessagePinUpdateOne) ClearGuild() *MessagePinUpdateOne { + mpuo.mutation.ClearGuild() + return mpuo +} + +// Where appends a list predicates to the MessagePinUpdate builder. +func (mpuo *MessagePinUpdateOne) Where(ps ...predicate.MessagePin) *MessagePinUpdateOne { + mpuo.mutation.Where(ps...) + return mpuo +} + +// Select allows selecting one or more fields (columns) of the returned entity. +// The default is selecting all fields defined in the entity schema. +func (mpuo *MessagePinUpdateOne) Select(field string, fields ...string) *MessagePinUpdateOne { + mpuo.fields = append([]string{field}, fields...) + return mpuo +} + +// Save executes the query and returns the updated MessagePin entity. +func (mpuo *MessagePinUpdateOne) Save(ctx context.Context) (*MessagePin, error) { + return withHooks(ctx, mpuo.sqlSave, mpuo.mutation, mpuo.hooks) +} + +// SaveX is like Save, but panics if an error occurs. +func (mpuo *MessagePinUpdateOne) SaveX(ctx context.Context) *MessagePin { + node, err := mpuo.Save(ctx) + if err != nil { + panic(err) + } + return node +} + +// Exec executes the query on the entity. +func (mpuo *MessagePinUpdateOne) Exec(ctx context.Context) error { + _, err := mpuo.Save(ctx) + return err +} + +// ExecX is like Exec, but panics if an error occurs. +func (mpuo *MessagePinUpdateOne) ExecX(ctx context.Context) { + if err := mpuo.Exec(ctx); err != nil { + panic(err) + } +} + +// check runs all checks and user-defined validators on the builder. +func (mpuo *MessagePinUpdateOne) check() error { + if _, ok := mpuo.mutation.GuildID(); mpuo.mutation.GuildCleared() && !ok { + return errors.New(`ent: clearing a required unique edge "MessagePin.guild"`) + } + return nil +} + +func (mpuo *MessagePinUpdateOne) sqlSave(ctx context.Context) (_node *MessagePin, err error) { + if err := mpuo.check(); err != nil { + return _node, err + } + _spec := sqlgraph.NewUpdateSpec(messagepin.Table, messagepin.Columns, sqlgraph.NewFieldSpec(messagepin.FieldID, field.TypeUUID)) + id, ok := mpuo.mutation.ID() + if !ok { + return nil, &ValidationError{Name: "id", err: errors.New(`ent: missing "MessagePin.id" for update`)} + } + _spec.Node.ID.Value = id + if fields := mpuo.fields; len(fields) > 0 { + _spec.Node.Columns = make([]string, 0, len(fields)) + _spec.Node.Columns = append(_spec.Node.Columns, messagepin.FieldID) + for _, f := range fields { + if !messagepin.ValidColumn(f) { + return nil, &ValidationError{Name: f, err: fmt.Errorf("ent: invalid field %q for query", f)} + } + if f != messagepin.FieldID { + _spec.Node.Columns = append(_spec.Node.Columns, f) + } + } + } + if ps := mpuo.mutation.predicates; len(ps) > 0 { + _spec.Predicate = func(selector *sql.Selector) { + for i := range ps { + ps[i](selector) + } + } + } + if value, ok := mpuo.mutation.ChannelID(); ok { + _spec.SetField(messagepin.FieldChannelID, field.TypeUint64, value) + } + if value, ok := mpuo.mutation.AddedChannelID(); ok { + _spec.AddField(messagepin.FieldChannelID, field.TypeUint64, value) + } + if value, ok := mpuo.mutation.Content(); ok { + _spec.SetField(messagepin.FieldContent, field.TypeString, value) + } + if mpuo.mutation.ContentCleared() { + _spec.ClearField(messagepin.FieldContent, field.TypeString) + } + if value, ok := mpuo.mutation.Embeds(); ok { + _spec.SetField(messagepin.FieldEmbeds, field.TypeJSON, value) + } + if value, ok := mpuo.mutation.AppendedEmbeds(); ok { + _spec.AddModifier(func(u *sql.UpdateBuilder) { + sqljson.Append(u, messagepin.FieldEmbeds, value) + }) + } + if mpuo.mutation.EmbedsCleared() { + _spec.ClearField(messagepin.FieldEmbeds, field.TypeJSON) + } + if value, ok := mpuo.mutation.BeforeID(); ok { + _spec.SetField(messagepin.FieldBeforeID, field.TypeUint64, value) + } + if value, ok := mpuo.mutation.AddedBeforeID(); ok { + _spec.AddField(messagepin.FieldBeforeID, field.TypeUint64, value) + } + if mpuo.mutation.BeforeIDCleared() { + _spec.ClearField(messagepin.FieldBeforeID, field.TypeUint64) + } + if value, ok := mpuo.mutation.RateLimit(); ok { + _spec.SetField(messagepin.FieldRateLimit, field.TypeJSON, value) + } + if mpuo.mutation.GuildCleared() { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.M2O, + Inverse: true, + Table: messagepin.GuildTable, + Columns: []string{messagepin.GuildColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(guild.FieldID, field.TypeUint64), + }, + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := mpuo.mutation.GuildIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.M2O, + Inverse: true, + Table: messagepin.GuildTable, + Columns: []string{messagepin.GuildColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(guild.FieldID, field.TypeUint64), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Add = append(_spec.Edges.Add, edge) + } + _node = &MessagePin{config: mpuo.config} + _spec.Assign = _node.assignValues + _spec.ScanValues = _node.scanValues + if err = sqlgraph.UpdateNode(ctx, mpuo.driver, _spec); err != nil { + if _, ok := err.(*sqlgraph.NotFoundError); ok { + err = &NotFoundError{messagepin.Label} + } else if sqlgraph.IsConstraintError(err) { + err = &ConstraintError{msg: err.Error(), wrap: err} + } + return nil, err + } + mpuo.mutation.done = true + return _node, nil +} diff --git a/ent/messageremind.go b/ent/messageremind.go new file mode 100644 index 00000000..17783d81 --- /dev/null +++ b/ent/messageremind.go @@ -0,0 +1,193 @@ +// Code generated by ent, DO NOT EDIT. + +package ent + +import ( + "fmt" + "strings" + "time" + + "entgo.io/ent" + "entgo.io/ent/dialect/sql" + snowflake "github.com/disgoorg/snowflake/v2" + "github.com/google/uuid" + "github.com/sabafly/gobot/ent/guild" + "github.com/sabafly/gobot/ent/messageremind" +) + +// MessageRemind is the model entity for the MessageRemind schema. +type MessageRemind struct { + config `json:"-"` + // ID of the ent. + ID uuid.UUID `json:"id,omitempty"` + // ChannelID holds the value of the "channel_id" field. + ChannelID snowflake.ID `json:"channel_id,omitempty"` + // AuthorID holds the value of the "author_id" field. + AuthorID snowflake.ID `json:"author_id,omitempty"` + // Time holds the value of the "time" field. + Time time.Time `json:"time,omitempty"` + // Content holds the value of the "content" field. + Content string `json:"content,omitempty"` + // Name holds the value of the "name" field. + Name string `json:"name,omitempty"` + // Edges holds the relations/edges for other nodes in the graph. + // The values are being populated by the MessageRemindQuery when eager-loading is set. + Edges MessageRemindEdges `json:"edges"` + guild_reminds *snowflake.ID + selectValues sql.SelectValues +} + +// MessageRemindEdges holds the relations/edges for other nodes in the graph. +type MessageRemindEdges struct { + // Guild holds the value of the guild edge. + Guild *Guild `json:"guild,omitempty"` + // loadedTypes holds the information for reporting if a + // type was loaded (or requested) in eager-loading or not. + loadedTypes [1]bool +} + +// GuildOrErr returns the Guild value or an error if the edge +// was not loaded in eager-loading, or loaded but was not found. +func (e MessageRemindEdges) GuildOrErr() (*Guild, error) { + if e.Guild != nil { + return e.Guild, nil + } else if e.loadedTypes[0] { + return nil, &NotFoundError{label: guild.Label} + } + return nil, &NotLoadedError{edge: "guild"} +} + +// scanValues returns the types for scanning values from sql.Rows. +func (*MessageRemind) scanValues(columns []string) ([]any, error) { + values := make([]any, len(columns)) + for i := range columns { + switch columns[i] { + case messageremind.FieldChannelID, messageremind.FieldAuthorID: + values[i] = new(sql.NullInt64) + case messageremind.FieldContent, messageremind.FieldName: + values[i] = new(sql.NullString) + case messageremind.FieldTime: + values[i] = new(sql.NullTime) + case messageremind.FieldID: + values[i] = new(uuid.UUID) + case messageremind.ForeignKeys[0]: // guild_reminds + values[i] = new(sql.NullInt64) + default: + values[i] = new(sql.UnknownType) + } + } + return values, nil +} + +// assignValues assigns the values that were returned from sql.Rows (after scanning) +// to the MessageRemind fields. +func (mr *MessageRemind) assignValues(columns []string, values []any) error { + if m, n := len(values), len(columns); m < n { + return fmt.Errorf("mismatch number of scan values: %d != %d", m, n) + } + for i := range columns { + switch columns[i] { + case messageremind.FieldID: + if value, ok := values[i].(*uuid.UUID); !ok { + return fmt.Errorf("unexpected type %T for field id", values[i]) + } else if value != nil { + mr.ID = *value + } + case messageremind.FieldChannelID: + if value, ok := values[i].(*sql.NullInt64); !ok { + return fmt.Errorf("unexpected type %T for field channel_id", values[i]) + } else if value.Valid { + mr.ChannelID = snowflake.ID(value.Int64) + } + case messageremind.FieldAuthorID: + if value, ok := values[i].(*sql.NullInt64); !ok { + return fmt.Errorf("unexpected type %T for field author_id", values[i]) + } else if value.Valid { + mr.AuthorID = snowflake.ID(value.Int64) + } + case messageremind.FieldTime: + if value, ok := values[i].(*sql.NullTime); !ok { + return fmt.Errorf("unexpected type %T for field time", values[i]) + } else if value.Valid { + mr.Time = value.Time + } + case messageremind.FieldContent: + if value, ok := values[i].(*sql.NullString); !ok { + return fmt.Errorf("unexpected type %T for field content", values[i]) + } else if value.Valid { + mr.Content = value.String + } + case messageremind.FieldName: + if value, ok := values[i].(*sql.NullString); !ok { + return fmt.Errorf("unexpected type %T for field name", values[i]) + } else if value.Valid { + mr.Name = value.String + } + case messageremind.ForeignKeys[0]: + if value, ok := values[i].(*sql.NullInt64); !ok { + return fmt.Errorf("unexpected type %T for field guild_reminds", values[i]) + } else if value.Valid { + mr.guild_reminds = new(snowflake.ID) + *mr.guild_reminds = snowflake.ID(value.Int64) + } + default: + mr.selectValues.Set(columns[i], values[i]) + } + } + return nil +} + +// Value returns the ent.Value that was dynamically selected and assigned to the MessageRemind. +// This includes values selected through modifiers, order, etc. +func (mr *MessageRemind) Value(name string) (ent.Value, error) { + return mr.selectValues.Get(name) +} + +// QueryGuild queries the "guild" edge of the MessageRemind entity. +func (mr *MessageRemind) QueryGuild() *GuildQuery { + return NewMessageRemindClient(mr.config).QueryGuild(mr) +} + +// Update returns a builder for updating this MessageRemind. +// Note that you need to call MessageRemind.Unwrap() before calling this method if this MessageRemind +// was returned from a transaction, and the transaction was committed or rolled back. +func (mr *MessageRemind) Update() *MessageRemindUpdateOne { + return NewMessageRemindClient(mr.config).UpdateOne(mr) +} + +// Unwrap unwraps the MessageRemind entity that was returned from a transaction after it was closed, +// so that all future queries will be executed through the driver which created the transaction. +func (mr *MessageRemind) Unwrap() *MessageRemind { + _tx, ok := mr.config.driver.(*txDriver) + if !ok { + panic("ent: MessageRemind is not a transactional entity") + } + mr.config.driver = _tx.drv + return mr +} + +// String implements the fmt.Stringer. +func (mr *MessageRemind) String() string { + var builder strings.Builder + builder.WriteString("MessageRemind(") + builder.WriteString(fmt.Sprintf("id=%v, ", mr.ID)) + builder.WriteString("channel_id=") + builder.WriteString(fmt.Sprintf("%v", mr.ChannelID)) + builder.WriteString(", ") + builder.WriteString("author_id=") + builder.WriteString(fmt.Sprintf("%v", mr.AuthorID)) + builder.WriteString(", ") + builder.WriteString("time=") + builder.WriteString(mr.Time.Format(time.ANSIC)) + builder.WriteString(", ") + builder.WriteString("content=") + builder.WriteString(mr.Content) + builder.WriteString(", ") + builder.WriteString("name=") + builder.WriteString(mr.Name) + builder.WriteByte(')') + return builder.String() +} + +// MessageReminds is a parsable slice of MessageRemind. +type MessageReminds []*MessageRemind diff --git a/ent/messageremind/messageremind.go b/ent/messageremind/messageremind.go new file mode 100644 index 00000000..3a4d0ff3 --- /dev/null +++ b/ent/messageremind/messageremind.go @@ -0,0 +1,124 @@ +// Code generated by ent, DO NOT EDIT. + +package messageremind + +import ( + "entgo.io/ent/dialect/sql" + "entgo.io/ent/dialect/sql/sqlgraph" + "github.com/google/uuid" +) + +const ( + // Label holds the string label denoting the messageremind type in the database. + Label = "message_remind" + // FieldID holds the string denoting the id field in the database. + FieldID = "id" + // FieldChannelID holds the string denoting the channel_id field in the database. + FieldChannelID = "channel_id" + // FieldAuthorID holds the string denoting the author_id field in the database. + FieldAuthorID = "author_id" + // FieldTime holds the string denoting the time field in the database. + FieldTime = "time" + // FieldContent holds the string denoting the content field in the database. + FieldContent = "content" + // FieldName holds the string denoting the name field in the database. + FieldName = "name" + // EdgeGuild holds the string denoting the guild edge name in mutations. + EdgeGuild = "guild" + // Table holds the table name of the messageremind in the database. + Table = "message_reminds" + // GuildTable is the table that holds the guild relation/edge. + GuildTable = "message_reminds" + // GuildInverseTable is the table name for the Guild entity. + // It exists in this package in order to avoid circular dependency with the "guild" package. + GuildInverseTable = "guilds" + // GuildColumn is the table column denoting the guild relation/edge. + GuildColumn = "guild_reminds" +) + +// Columns holds all SQL columns for messageremind fields. +var Columns = []string{ + FieldID, + FieldChannelID, + FieldAuthorID, + FieldTime, + FieldContent, + FieldName, +} + +// ForeignKeys holds the SQL foreign-keys that are owned by the "message_reminds" +// table and are not defined as standalone fields in the schema. +var ForeignKeys = []string{ + "guild_reminds", +} + +// ValidColumn reports if the column name is valid (part of the table columns). +func ValidColumn(column string) bool { + for i := range Columns { + if column == Columns[i] { + return true + } + } + for i := range ForeignKeys { + if column == ForeignKeys[i] { + return true + } + } + return false +} + +var ( + // ContentValidator is a validator for the "content" field. It is called by the builders before save. + ContentValidator func(string) error + // NameValidator is a validator for the "name" field. It is called by the builders before save. + NameValidator func(string) error + // DefaultID holds the default value on creation for the "id" field. + DefaultID func() uuid.UUID +) + +// OrderOption defines the ordering options for the MessageRemind queries. +type OrderOption func(*sql.Selector) + +// ByID orders the results by the id field. +func ByID(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldID, opts...).ToFunc() +} + +// ByChannelID orders the results by the channel_id field. +func ByChannelID(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldChannelID, opts...).ToFunc() +} + +// ByAuthorID orders the results by the author_id field. +func ByAuthorID(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldAuthorID, opts...).ToFunc() +} + +// ByTime orders the results by the time field. +func ByTime(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldTime, opts...).ToFunc() +} + +// ByContent orders the results by the content field. +func ByContent(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldContent, opts...).ToFunc() +} + +// ByName orders the results by the name field. +func ByName(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldName, opts...).ToFunc() +} + +// ByGuildField orders the results by guild field. +func ByGuildField(field string, opts ...sql.OrderTermOption) OrderOption { + return func(s *sql.Selector) { + sqlgraph.OrderByNeighborTerms(s, newGuildStep(), sql.OrderByField(field, opts...)) + } +} +func newGuildStep() *sqlgraph.Step { + return sqlgraph.NewStep( + sqlgraph.From(Table, FieldID), + sqlgraph.To(GuildInverseTable, FieldID), + sqlgraph.Edge(sqlgraph.M2O, true, GuildTable, GuildColumn), + ) +} diff --git a/ent/messageremind/where.go b/ent/messageremind/where.go new file mode 100644 index 00000000..4313266f --- /dev/null +++ b/ent/messageremind/where.go @@ -0,0 +1,401 @@ +// Code generated by ent, DO NOT EDIT. + +package messageremind + +import ( + "time" + + "entgo.io/ent/dialect/sql" + "entgo.io/ent/dialect/sql/sqlgraph" + snowflake "github.com/disgoorg/snowflake/v2" + "github.com/google/uuid" + "github.com/sabafly/gobot/ent/predicate" +) + +// ID filters vertices based on their ID field. +func ID(id uuid.UUID) predicate.MessageRemind { + return predicate.MessageRemind(sql.FieldEQ(FieldID, id)) +} + +// IDEQ applies the EQ predicate on the ID field. +func IDEQ(id uuid.UUID) predicate.MessageRemind { + return predicate.MessageRemind(sql.FieldEQ(FieldID, id)) +} + +// IDNEQ applies the NEQ predicate on the ID field. +func IDNEQ(id uuid.UUID) predicate.MessageRemind { + return predicate.MessageRemind(sql.FieldNEQ(FieldID, id)) +} + +// IDIn applies the In predicate on the ID field. +func IDIn(ids ...uuid.UUID) predicate.MessageRemind { + return predicate.MessageRemind(sql.FieldIn(FieldID, ids...)) +} + +// IDNotIn applies the NotIn predicate on the ID field. +func IDNotIn(ids ...uuid.UUID) predicate.MessageRemind { + return predicate.MessageRemind(sql.FieldNotIn(FieldID, ids...)) +} + +// IDGT applies the GT predicate on the ID field. +func IDGT(id uuid.UUID) predicate.MessageRemind { + return predicate.MessageRemind(sql.FieldGT(FieldID, id)) +} + +// IDGTE applies the GTE predicate on the ID field. +func IDGTE(id uuid.UUID) predicate.MessageRemind { + return predicate.MessageRemind(sql.FieldGTE(FieldID, id)) +} + +// IDLT applies the LT predicate on the ID field. +func IDLT(id uuid.UUID) predicate.MessageRemind { + return predicate.MessageRemind(sql.FieldLT(FieldID, id)) +} + +// IDLTE applies the LTE predicate on the ID field. +func IDLTE(id uuid.UUID) predicate.MessageRemind { + return predicate.MessageRemind(sql.FieldLTE(FieldID, id)) +} + +// ChannelID applies equality check predicate on the "channel_id" field. It's identical to ChannelIDEQ. +func ChannelID(v snowflake.ID) predicate.MessageRemind { + vc := uint64(v) + return predicate.MessageRemind(sql.FieldEQ(FieldChannelID, vc)) +} + +// AuthorID applies equality check predicate on the "author_id" field. It's identical to AuthorIDEQ. +func AuthorID(v snowflake.ID) predicate.MessageRemind { + vc := uint64(v) + return predicate.MessageRemind(sql.FieldEQ(FieldAuthorID, vc)) +} + +// Time applies equality check predicate on the "time" field. It's identical to TimeEQ. +func Time(v time.Time) predicate.MessageRemind { + return predicate.MessageRemind(sql.FieldEQ(FieldTime, v)) +} + +// Content applies equality check predicate on the "content" field. It's identical to ContentEQ. +func Content(v string) predicate.MessageRemind { + return predicate.MessageRemind(sql.FieldEQ(FieldContent, v)) +} + +// Name applies equality check predicate on the "name" field. It's identical to NameEQ. +func Name(v string) predicate.MessageRemind { + return predicate.MessageRemind(sql.FieldEQ(FieldName, v)) +} + +// ChannelIDEQ applies the EQ predicate on the "channel_id" field. +func ChannelIDEQ(v snowflake.ID) predicate.MessageRemind { + vc := uint64(v) + return predicate.MessageRemind(sql.FieldEQ(FieldChannelID, vc)) +} + +// ChannelIDNEQ applies the NEQ predicate on the "channel_id" field. +func ChannelIDNEQ(v snowflake.ID) predicate.MessageRemind { + vc := uint64(v) + return predicate.MessageRemind(sql.FieldNEQ(FieldChannelID, vc)) +} + +// ChannelIDIn applies the In predicate on the "channel_id" field. +func ChannelIDIn(vs ...snowflake.ID) predicate.MessageRemind { + v := make([]any, len(vs)) + for i := range v { + v[i] = uint64(vs[i]) + } + return predicate.MessageRemind(sql.FieldIn(FieldChannelID, v...)) +} + +// ChannelIDNotIn applies the NotIn predicate on the "channel_id" field. +func ChannelIDNotIn(vs ...snowflake.ID) predicate.MessageRemind { + v := make([]any, len(vs)) + for i := range v { + v[i] = uint64(vs[i]) + } + return predicate.MessageRemind(sql.FieldNotIn(FieldChannelID, v...)) +} + +// ChannelIDGT applies the GT predicate on the "channel_id" field. +func ChannelIDGT(v snowflake.ID) predicate.MessageRemind { + vc := uint64(v) + return predicate.MessageRemind(sql.FieldGT(FieldChannelID, vc)) +} + +// ChannelIDGTE applies the GTE predicate on the "channel_id" field. +func ChannelIDGTE(v snowflake.ID) predicate.MessageRemind { + vc := uint64(v) + return predicate.MessageRemind(sql.FieldGTE(FieldChannelID, vc)) +} + +// ChannelIDLT applies the LT predicate on the "channel_id" field. +func ChannelIDLT(v snowflake.ID) predicate.MessageRemind { + vc := uint64(v) + return predicate.MessageRemind(sql.FieldLT(FieldChannelID, vc)) +} + +// ChannelIDLTE applies the LTE predicate on the "channel_id" field. +func ChannelIDLTE(v snowflake.ID) predicate.MessageRemind { + vc := uint64(v) + return predicate.MessageRemind(sql.FieldLTE(FieldChannelID, vc)) +} + +// AuthorIDEQ applies the EQ predicate on the "author_id" field. +func AuthorIDEQ(v snowflake.ID) predicate.MessageRemind { + vc := uint64(v) + return predicate.MessageRemind(sql.FieldEQ(FieldAuthorID, vc)) +} + +// AuthorIDNEQ applies the NEQ predicate on the "author_id" field. +func AuthorIDNEQ(v snowflake.ID) predicate.MessageRemind { + vc := uint64(v) + return predicate.MessageRemind(sql.FieldNEQ(FieldAuthorID, vc)) +} + +// AuthorIDIn applies the In predicate on the "author_id" field. +func AuthorIDIn(vs ...snowflake.ID) predicate.MessageRemind { + v := make([]any, len(vs)) + for i := range v { + v[i] = uint64(vs[i]) + } + return predicate.MessageRemind(sql.FieldIn(FieldAuthorID, v...)) +} + +// AuthorIDNotIn applies the NotIn predicate on the "author_id" field. +func AuthorIDNotIn(vs ...snowflake.ID) predicate.MessageRemind { + v := make([]any, len(vs)) + for i := range v { + v[i] = uint64(vs[i]) + } + return predicate.MessageRemind(sql.FieldNotIn(FieldAuthorID, v...)) +} + +// AuthorIDGT applies the GT predicate on the "author_id" field. +func AuthorIDGT(v snowflake.ID) predicate.MessageRemind { + vc := uint64(v) + return predicate.MessageRemind(sql.FieldGT(FieldAuthorID, vc)) +} + +// AuthorIDGTE applies the GTE predicate on the "author_id" field. +func AuthorIDGTE(v snowflake.ID) predicate.MessageRemind { + vc := uint64(v) + return predicate.MessageRemind(sql.FieldGTE(FieldAuthorID, vc)) +} + +// AuthorIDLT applies the LT predicate on the "author_id" field. +func AuthorIDLT(v snowflake.ID) predicate.MessageRemind { + vc := uint64(v) + return predicate.MessageRemind(sql.FieldLT(FieldAuthorID, vc)) +} + +// AuthorIDLTE applies the LTE predicate on the "author_id" field. +func AuthorIDLTE(v snowflake.ID) predicate.MessageRemind { + vc := uint64(v) + return predicate.MessageRemind(sql.FieldLTE(FieldAuthorID, vc)) +} + +// TimeEQ applies the EQ predicate on the "time" field. +func TimeEQ(v time.Time) predicate.MessageRemind { + return predicate.MessageRemind(sql.FieldEQ(FieldTime, v)) +} + +// TimeNEQ applies the NEQ predicate on the "time" field. +func TimeNEQ(v time.Time) predicate.MessageRemind { + return predicate.MessageRemind(sql.FieldNEQ(FieldTime, v)) +} + +// TimeIn applies the In predicate on the "time" field. +func TimeIn(vs ...time.Time) predicate.MessageRemind { + return predicate.MessageRemind(sql.FieldIn(FieldTime, vs...)) +} + +// TimeNotIn applies the NotIn predicate on the "time" field. +func TimeNotIn(vs ...time.Time) predicate.MessageRemind { + return predicate.MessageRemind(sql.FieldNotIn(FieldTime, vs...)) +} + +// TimeGT applies the GT predicate on the "time" field. +func TimeGT(v time.Time) predicate.MessageRemind { + return predicate.MessageRemind(sql.FieldGT(FieldTime, v)) +} + +// TimeGTE applies the GTE predicate on the "time" field. +func TimeGTE(v time.Time) predicate.MessageRemind { + return predicate.MessageRemind(sql.FieldGTE(FieldTime, v)) +} + +// TimeLT applies the LT predicate on the "time" field. +func TimeLT(v time.Time) predicate.MessageRemind { + return predicate.MessageRemind(sql.FieldLT(FieldTime, v)) +} + +// TimeLTE applies the LTE predicate on the "time" field. +func TimeLTE(v time.Time) predicate.MessageRemind { + return predicate.MessageRemind(sql.FieldLTE(FieldTime, v)) +} + +// ContentEQ applies the EQ predicate on the "content" field. +func ContentEQ(v string) predicate.MessageRemind { + return predicate.MessageRemind(sql.FieldEQ(FieldContent, v)) +} + +// ContentNEQ applies the NEQ predicate on the "content" field. +func ContentNEQ(v string) predicate.MessageRemind { + return predicate.MessageRemind(sql.FieldNEQ(FieldContent, v)) +} + +// ContentIn applies the In predicate on the "content" field. +func ContentIn(vs ...string) predicate.MessageRemind { + return predicate.MessageRemind(sql.FieldIn(FieldContent, vs...)) +} + +// ContentNotIn applies the NotIn predicate on the "content" field. +func ContentNotIn(vs ...string) predicate.MessageRemind { + return predicate.MessageRemind(sql.FieldNotIn(FieldContent, vs...)) +} + +// ContentGT applies the GT predicate on the "content" field. +func ContentGT(v string) predicate.MessageRemind { + return predicate.MessageRemind(sql.FieldGT(FieldContent, v)) +} + +// ContentGTE applies the GTE predicate on the "content" field. +func ContentGTE(v string) predicate.MessageRemind { + return predicate.MessageRemind(sql.FieldGTE(FieldContent, v)) +} + +// ContentLT applies the LT predicate on the "content" field. +func ContentLT(v string) predicate.MessageRemind { + return predicate.MessageRemind(sql.FieldLT(FieldContent, v)) +} + +// ContentLTE applies the LTE predicate on the "content" field. +func ContentLTE(v string) predicate.MessageRemind { + return predicate.MessageRemind(sql.FieldLTE(FieldContent, v)) +} + +// ContentContains applies the Contains predicate on the "content" field. +func ContentContains(v string) predicate.MessageRemind { + return predicate.MessageRemind(sql.FieldContains(FieldContent, v)) +} + +// ContentHasPrefix applies the HasPrefix predicate on the "content" field. +func ContentHasPrefix(v string) predicate.MessageRemind { + return predicate.MessageRemind(sql.FieldHasPrefix(FieldContent, v)) +} + +// ContentHasSuffix applies the HasSuffix predicate on the "content" field. +func ContentHasSuffix(v string) predicate.MessageRemind { + return predicate.MessageRemind(sql.FieldHasSuffix(FieldContent, v)) +} + +// ContentEqualFold applies the EqualFold predicate on the "content" field. +func ContentEqualFold(v string) predicate.MessageRemind { + return predicate.MessageRemind(sql.FieldEqualFold(FieldContent, v)) +} + +// ContentContainsFold applies the ContainsFold predicate on the "content" field. +func ContentContainsFold(v string) predicate.MessageRemind { + return predicate.MessageRemind(sql.FieldContainsFold(FieldContent, v)) +} + +// NameEQ applies the EQ predicate on the "name" field. +func NameEQ(v string) predicate.MessageRemind { + return predicate.MessageRemind(sql.FieldEQ(FieldName, v)) +} + +// NameNEQ applies the NEQ predicate on the "name" field. +func NameNEQ(v string) predicate.MessageRemind { + return predicate.MessageRemind(sql.FieldNEQ(FieldName, v)) +} + +// NameIn applies the In predicate on the "name" field. +func NameIn(vs ...string) predicate.MessageRemind { + return predicate.MessageRemind(sql.FieldIn(FieldName, vs...)) +} + +// NameNotIn applies the NotIn predicate on the "name" field. +func NameNotIn(vs ...string) predicate.MessageRemind { + return predicate.MessageRemind(sql.FieldNotIn(FieldName, vs...)) +} + +// NameGT applies the GT predicate on the "name" field. +func NameGT(v string) predicate.MessageRemind { + return predicate.MessageRemind(sql.FieldGT(FieldName, v)) +} + +// NameGTE applies the GTE predicate on the "name" field. +func NameGTE(v string) predicate.MessageRemind { + return predicate.MessageRemind(sql.FieldGTE(FieldName, v)) +} + +// NameLT applies the LT predicate on the "name" field. +func NameLT(v string) predicate.MessageRemind { + return predicate.MessageRemind(sql.FieldLT(FieldName, v)) +} + +// NameLTE applies the LTE predicate on the "name" field. +func NameLTE(v string) predicate.MessageRemind { + return predicate.MessageRemind(sql.FieldLTE(FieldName, v)) +} + +// NameContains applies the Contains predicate on the "name" field. +func NameContains(v string) predicate.MessageRemind { + return predicate.MessageRemind(sql.FieldContains(FieldName, v)) +} + +// NameHasPrefix applies the HasPrefix predicate on the "name" field. +func NameHasPrefix(v string) predicate.MessageRemind { + return predicate.MessageRemind(sql.FieldHasPrefix(FieldName, v)) +} + +// NameHasSuffix applies the HasSuffix predicate on the "name" field. +func NameHasSuffix(v string) predicate.MessageRemind { + return predicate.MessageRemind(sql.FieldHasSuffix(FieldName, v)) +} + +// NameEqualFold applies the EqualFold predicate on the "name" field. +func NameEqualFold(v string) predicate.MessageRemind { + return predicate.MessageRemind(sql.FieldEqualFold(FieldName, v)) +} + +// NameContainsFold applies the ContainsFold predicate on the "name" field. +func NameContainsFold(v string) predicate.MessageRemind { + return predicate.MessageRemind(sql.FieldContainsFold(FieldName, v)) +} + +// HasGuild applies the HasEdge predicate on the "guild" edge. +func HasGuild() predicate.MessageRemind { + return predicate.MessageRemind(func(s *sql.Selector) { + step := sqlgraph.NewStep( + sqlgraph.From(Table, FieldID), + sqlgraph.Edge(sqlgraph.M2O, true, GuildTable, GuildColumn), + ) + sqlgraph.HasNeighbors(s, step) + }) +} + +// HasGuildWith applies the HasEdge predicate on the "guild" edge with a given conditions (other predicates). +func HasGuildWith(preds ...predicate.Guild) predicate.MessageRemind { + return predicate.MessageRemind(func(s *sql.Selector) { + step := newGuildStep() + sqlgraph.HasNeighborsWith(s, step, func(s *sql.Selector) { + for _, p := range preds { + p(s) + } + }) + }) +} + +// And groups predicates with the AND operator between them. +func And(predicates ...predicate.MessageRemind) predicate.MessageRemind { + return predicate.MessageRemind(sql.AndPredicates(predicates...)) +} + +// Or groups predicates with the OR operator between them. +func Or(predicates ...predicate.MessageRemind) predicate.MessageRemind { + return predicate.MessageRemind(sql.OrPredicates(predicates...)) +} + +// Not applies the not operator on the given predicate. +func Not(p predicate.MessageRemind) predicate.MessageRemind { + return predicate.MessageRemind(sql.NotPredicates(p)) +} diff --git a/ent/messageremind_create.go b/ent/messageremind_create.go new file mode 100644 index 00000000..7e8423ff --- /dev/null +++ b/ent/messageremind_create.go @@ -0,0 +1,309 @@ +// Code generated by ent, DO NOT EDIT. + +package ent + +import ( + "context" + "errors" + "fmt" + "time" + + "entgo.io/ent/dialect/sql/sqlgraph" + "entgo.io/ent/schema/field" + snowflake "github.com/disgoorg/snowflake/v2" + "github.com/google/uuid" + "github.com/sabafly/gobot/ent/guild" + "github.com/sabafly/gobot/ent/messageremind" +) + +// MessageRemindCreate is the builder for creating a MessageRemind entity. +type MessageRemindCreate struct { + config + mutation *MessageRemindMutation + hooks []Hook +} + +// SetChannelID sets the "channel_id" field. +func (mrc *MessageRemindCreate) SetChannelID(s snowflake.ID) *MessageRemindCreate { + mrc.mutation.SetChannelID(s) + return mrc +} + +// SetAuthorID sets the "author_id" field. +func (mrc *MessageRemindCreate) SetAuthorID(s snowflake.ID) *MessageRemindCreate { + mrc.mutation.SetAuthorID(s) + return mrc +} + +// SetTime sets the "time" field. +func (mrc *MessageRemindCreate) SetTime(t time.Time) *MessageRemindCreate { + mrc.mutation.SetTime(t) + return mrc +} + +// SetContent sets the "content" field. +func (mrc *MessageRemindCreate) SetContent(s string) *MessageRemindCreate { + mrc.mutation.SetContent(s) + return mrc +} + +// SetName sets the "name" field. +func (mrc *MessageRemindCreate) SetName(s string) *MessageRemindCreate { + mrc.mutation.SetName(s) + return mrc +} + +// SetID sets the "id" field. +func (mrc *MessageRemindCreate) SetID(u uuid.UUID) *MessageRemindCreate { + mrc.mutation.SetID(u) + return mrc +} + +// SetNillableID sets the "id" field if the given value is not nil. +func (mrc *MessageRemindCreate) SetNillableID(u *uuid.UUID) *MessageRemindCreate { + if u != nil { + mrc.SetID(*u) + } + return mrc +} + +// SetGuildID sets the "guild" edge to the Guild entity by ID. +func (mrc *MessageRemindCreate) SetGuildID(id snowflake.ID) *MessageRemindCreate { + mrc.mutation.SetGuildID(id) + return mrc +} + +// SetGuild sets the "guild" edge to the Guild entity. +func (mrc *MessageRemindCreate) SetGuild(g *Guild) *MessageRemindCreate { + return mrc.SetGuildID(g.ID) +} + +// Mutation returns the MessageRemindMutation object of the builder. +func (mrc *MessageRemindCreate) Mutation() *MessageRemindMutation { + return mrc.mutation +} + +// Save creates the MessageRemind in the database. +func (mrc *MessageRemindCreate) Save(ctx context.Context) (*MessageRemind, error) { + mrc.defaults() + return withHooks(ctx, mrc.sqlSave, mrc.mutation, mrc.hooks) +} + +// SaveX calls Save and panics if Save returns an error. +func (mrc *MessageRemindCreate) SaveX(ctx context.Context) *MessageRemind { + v, err := mrc.Save(ctx) + if err != nil { + panic(err) + } + return v +} + +// Exec executes the query. +func (mrc *MessageRemindCreate) Exec(ctx context.Context) error { + _, err := mrc.Save(ctx) + return err +} + +// ExecX is like Exec, but panics if an error occurs. +func (mrc *MessageRemindCreate) ExecX(ctx context.Context) { + if err := mrc.Exec(ctx); err != nil { + panic(err) + } +} + +// defaults sets the default values of the builder before save. +func (mrc *MessageRemindCreate) defaults() { + if _, ok := mrc.mutation.ID(); !ok { + v := messageremind.DefaultID() + mrc.mutation.SetID(v) + } +} + +// check runs all checks and user-defined validators on the builder. +func (mrc *MessageRemindCreate) check() error { + if _, ok := mrc.mutation.ChannelID(); !ok { + return &ValidationError{Name: "channel_id", err: errors.New(`ent: missing required field "MessageRemind.channel_id"`)} + } + if _, ok := mrc.mutation.AuthorID(); !ok { + return &ValidationError{Name: "author_id", err: errors.New(`ent: missing required field "MessageRemind.author_id"`)} + } + if _, ok := mrc.mutation.Time(); !ok { + return &ValidationError{Name: "time", err: errors.New(`ent: missing required field "MessageRemind.time"`)} + } + if _, ok := mrc.mutation.Content(); !ok { + return &ValidationError{Name: "content", err: errors.New(`ent: missing required field "MessageRemind.content"`)} + } + if v, ok := mrc.mutation.Content(); ok { + if err := messageremind.ContentValidator(v); err != nil { + return &ValidationError{Name: "content", err: fmt.Errorf(`ent: validator failed for field "MessageRemind.content": %w`, err)} + } + } + if _, ok := mrc.mutation.Name(); !ok { + return &ValidationError{Name: "name", err: errors.New(`ent: missing required field "MessageRemind.name"`)} + } + if v, ok := mrc.mutation.Name(); ok { + if err := messageremind.NameValidator(v); err != nil { + return &ValidationError{Name: "name", err: fmt.Errorf(`ent: validator failed for field "MessageRemind.name": %w`, err)} + } + } + if _, ok := mrc.mutation.GuildID(); !ok { + return &ValidationError{Name: "guild", err: errors.New(`ent: missing required edge "MessageRemind.guild"`)} + } + return nil +} + +func (mrc *MessageRemindCreate) sqlSave(ctx context.Context) (*MessageRemind, error) { + if err := mrc.check(); err != nil { + return nil, err + } + _node, _spec := mrc.createSpec() + if err := sqlgraph.CreateNode(ctx, mrc.driver, _spec); err != nil { + if sqlgraph.IsConstraintError(err) { + err = &ConstraintError{msg: err.Error(), wrap: err} + } + return nil, err + } + if _spec.ID.Value != nil { + if id, ok := _spec.ID.Value.(*uuid.UUID); ok { + _node.ID = *id + } else if err := _node.ID.Scan(_spec.ID.Value); err != nil { + return nil, err + } + } + mrc.mutation.id = &_node.ID + mrc.mutation.done = true + return _node, nil +} + +func (mrc *MessageRemindCreate) createSpec() (*MessageRemind, *sqlgraph.CreateSpec) { + var ( + _node = &MessageRemind{config: mrc.config} + _spec = sqlgraph.NewCreateSpec(messageremind.Table, sqlgraph.NewFieldSpec(messageremind.FieldID, field.TypeUUID)) + ) + if id, ok := mrc.mutation.ID(); ok { + _node.ID = id + _spec.ID.Value = &id + } + if value, ok := mrc.mutation.ChannelID(); ok { + _spec.SetField(messageremind.FieldChannelID, field.TypeUint64, value) + _node.ChannelID = value + } + if value, ok := mrc.mutation.AuthorID(); ok { + _spec.SetField(messageremind.FieldAuthorID, field.TypeUint64, value) + _node.AuthorID = value + } + if value, ok := mrc.mutation.Time(); ok { + _spec.SetField(messageremind.FieldTime, field.TypeTime, value) + _node.Time = value + } + if value, ok := mrc.mutation.Content(); ok { + _spec.SetField(messageremind.FieldContent, field.TypeString, value) + _node.Content = value + } + if value, ok := mrc.mutation.Name(); ok { + _spec.SetField(messageremind.FieldName, field.TypeString, value) + _node.Name = value + } + if nodes := mrc.mutation.GuildIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.M2O, + Inverse: true, + Table: messageremind.GuildTable, + Columns: []string{messageremind.GuildColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(guild.FieldID, field.TypeUint64), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _node.guild_reminds = &nodes[0] + _spec.Edges = append(_spec.Edges, edge) + } + return _node, _spec +} + +// MessageRemindCreateBulk is the builder for creating many MessageRemind entities in bulk. +type MessageRemindCreateBulk struct { + config + err error + builders []*MessageRemindCreate +} + +// Save creates the MessageRemind entities in the database. +func (mrcb *MessageRemindCreateBulk) Save(ctx context.Context) ([]*MessageRemind, error) { + if mrcb.err != nil { + return nil, mrcb.err + } + specs := make([]*sqlgraph.CreateSpec, len(mrcb.builders)) + nodes := make([]*MessageRemind, len(mrcb.builders)) + mutators := make([]Mutator, len(mrcb.builders)) + for i := range mrcb.builders { + func(i int, root context.Context) { + builder := mrcb.builders[i] + builder.defaults() + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*MessageRemindMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + if err := builder.check(); err != nil { + return nil, err + } + builder.mutation = mutation + var err error + nodes[i], specs[i] = builder.createSpec() + if i < len(mutators)-1 { + _, err = mutators[i+1].Mutate(root, mrcb.builders[i+1].mutation) + } else { + spec := &sqlgraph.BatchCreateSpec{Nodes: specs} + // Invoke the actual operation on the latest mutation in the chain. + if err = sqlgraph.BatchCreate(ctx, mrcb.driver, spec); err != nil { + if sqlgraph.IsConstraintError(err) { + err = &ConstraintError{msg: err.Error(), wrap: err} + } + } + } + if err != nil { + return nil, err + } + mutation.id = &nodes[i].ID + mutation.done = true + return nodes[i], nil + }) + for i := len(builder.hooks) - 1; i >= 0; i-- { + mut = builder.hooks[i](mut) + } + mutators[i] = mut + }(i, ctx) + } + if len(mutators) > 0 { + if _, err := mutators[0].Mutate(ctx, mrcb.builders[0].mutation); err != nil { + return nil, err + } + } + return nodes, nil +} + +// SaveX is like Save, but panics if an error occurs. +func (mrcb *MessageRemindCreateBulk) SaveX(ctx context.Context) []*MessageRemind { + v, err := mrcb.Save(ctx) + if err != nil { + panic(err) + } + return v +} + +// Exec executes the query. +func (mrcb *MessageRemindCreateBulk) Exec(ctx context.Context) error { + _, err := mrcb.Save(ctx) + return err +} + +// ExecX is like Exec, but panics if an error occurs. +func (mrcb *MessageRemindCreateBulk) ExecX(ctx context.Context) { + if err := mrcb.Exec(ctx); err != nil { + panic(err) + } +} diff --git a/ent/messageremind_delete.go b/ent/messageremind_delete.go new file mode 100644 index 00000000..74f43224 --- /dev/null +++ b/ent/messageremind_delete.go @@ -0,0 +1,88 @@ +// Code generated by ent, DO NOT EDIT. + +package ent + +import ( + "context" + + "entgo.io/ent/dialect/sql" + "entgo.io/ent/dialect/sql/sqlgraph" + "entgo.io/ent/schema/field" + "github.com/sabafly/gobot/ent/messageremind" + "github.com/sabafly/gobot/ent/predicate" +) + +// MessageRemindDelete is the builder for deleting a MessageRemind entity. +type MessageRemindDelete struct { + config + hooks []Hook + mutation *MessageRemindMutation +} + +// Where appends a list predicates to the MessageRemindDelete builder. +func (mrd *MessageRemindDelete) Where(ps ...predicate.MessageRemind) *MessageRemindDelete { + mrd.mutation.Where(ps...) + return mrd +} + +// Exec executes the deletion query and returns how many vertices were deleted. +func (mrd *MessageRemindDelete) Exec(ctx context.Context) (int, error) { + return withHooks(ctx, mrd.sqlExec, mrd.mutation, mrd.hooks) +} + +// ExecX is like Exec, but panics if an error occurs. +func (mrd *MessageRemindDelete) ExecX(ctx context.Context) int { + n, err := mrd.Exec(ctx) + if err != nil { + panic(err) + } + return n +} + +func (mrd *MessageRemindDelete) sqlExec(ctx context.Context) (int, error) { + _spec := sqlgraph.NewDeleteSpec(messageremind.Table, sqlgraph.NewFieldSpec(messageremind.FieldID, field.TypeUUID)) + if ps := mrd.mutation.predicates; len(ps) > 0 { + _spec.Predicate = func(selector *sql.Selector) { + for i := range ps { + ps[i](selector) + } + } + } + affected, err := sqlgraph.DeleteNodes(ctx, mrd.driver, _spec) + if err != nil && sqlgraph.IsConstraintError(err) { + err = &ConstraintError{msg: err.Error(), wrap: err} + } + mrd.mutation.done = true + return affected, err +} + +// MessageRemindDeleteOne is the builder for deleting a single MessageRemind entity. +type MessageRemindDeleteOne struct { + mrd *MessageRemindDelete +} + +// Where appends a list predicates to the MessageRemindDelete builder. +func (mrdo *MessageRemindDeleteOne) Where(ps ...predicate.MessageRemind) *MessageRemindDeleteOne { + mrdo.mrd.mutation.Where(ps...) + return mrdo +} + +// Exec executes the deletion query. +func (mrdo *MessageRemindDeleteOne) Exec(ctx context.Context) error { + n, err := mrdo.mrd.Exec(ctx) + switch { + case err != nil: + return err + case n == 0: + return &NotFoundError{messageremind.Label} + default: + return nil + } +} + +// ExecX is like Exec, but panics if an error occurs. +func (mrdo *MessageRemindDeleteOne) ExecX(ctx context.Context) { + if err := mrdo.Exec(ctx); err != nil { + panic(err) + } +} diff --git a/ent/messageremind_query.go b/ent/messageremind_query.go new file mode 100644 index 00000000..355f9ff3 --- /dev/null +++ b/ent/messageremind_query.go @@ -0,0 +1,615 @@ +// Code generated by ent, DO NOT EDIT. + +package ent + +import ( + "context" + "fmt" + "math" + + "entgo.io/ent/dialect/sql" + "entgo.io/ent/dialect/sql/sqlgraph" + "entgo.io/ent/schema/field" + snowflake "github.com/disgoorg/snowflake/v2" + "github.com/google/uuid" + "github.com/sabafly/gobot/ent/guild" + "github.com/sabafly/gobot/ent/messageremind" + "github.com/sabafly/gobot/ent/predicate" +) + +// MessageRemindQuery is the builder for querying MessageRemind entities. +type MessageRemindQuery struct { + config + ctx *QueryContext + order []messageremind.OrderOption + inters []Interceptor + predicates []predicate.MessageRemind + withGuild *GuildQuery + withFKs bool + // intermediate query (i.e. traversal path). + sql *sql.Selector + path func(context.Context) (*sql.Selector, error) +} + +// Where adds a new predicate for the MessageRemindQuery builder. +func (mrq *MessageRemindQuery) Where(ps ...predicate.MessageRemind) *MessageRemindQuery { + mrq.predicates = append(mrq.predicates, ps...) + return mrq +} + +// Limit the number of records to be returned by this query. +func (mrq *MessageRemindQuery) Limit(limit int) *MessageRemindQuery { + mrq.ctx.Limit = &limit + return mrq +} + +// Offset to start from. +func (mrq *MessageRemindQuery) Offset(offset int) *MessageRemindQuery { + mrq.ctx.Offset = &offset + return mrq +} + +// Unique configures the query builder to filter duplicate records on query. +// By default, unique is set to true, and can be disabled using this method. +func (mrq *MessageRemindQuery) Unique(unique bool) *MessageRemindQuery { + mrq.ctx.Unique = &unique + return mrq +} + +// Order specifies how the records should be ordered. +func (mrq *MessageRemindQuery) Order(o ...messageremind.OrderOption) *MessageRemindQuery { + mrq.order = append(mrq.order, o...) + return mrq +} + +// QueryGuild chains the current query on the "guild" edge. +func (mrq *MessageRemindQuery) QueryGuild() *GuildQuery { + query := (&GuildClient{config: mrq.config}).Query() + query.path = func(ctx context.Context) (fromU *sql.Selector, err error) { + if err := mrq.prepareQuery(ctx); err != nil { + return nil, err + } + selector := mrq.sqlQuery(ctx) + if err := selector.Err(); err != nil { + return nil, err + } + step := sqlgraph.NewStep( + sqlgraph.From(messageremind.Table, messageremind.FieldID, selector), + sqlgraph.To(guild.Table, guild.FieldID), + sqlgraph.Edge(sqlgraph.M2O, true, messageremind.GuildTable, messageremind.GuildColumn), + ) + fromU = sqlgraph.SetNeighbors(mrq.driver.Dialect(), step) + return fromU, nil + } + return query +} + +// First returns the first MessageRemind entity from the query. +// Returns a *NotFoundError when no MessageRemind was found. +func (mrq *MessageRemindQuery) First(ctx context.Context) (*MessageRemind, error) { + nodes, err := mrq.Limit(1).All(setContextOp(ctx, mrq.ctx, "First")) + if err != nil { + return nil, err + } + if len(nodes) == 0 { + return nil, &NotFoundError{messageremind.Label} + } + return nodes[0], nil +} + +// FirstX is like First, but panics if an error occurs. +func (mrq *MessageRemindQuery) FirstX(ctx context.Context) *MessageRemind { + node, err := mrq.First(ctx) + if err != nil && !IsNotFound(err) { + panic(err) + } + return node +} + +// FirstID returns the first MessageRemind ID from the query. +// Returns a *NotFoundError when no MessageRemind ID was found. +func (mrq *MessageRemindQuery) FirstID(ctx context.Context) (id uuid.UUID, err error) { + var ids []uuid.UUID + if ids, err = mrq.Limit(1).IDs(setContextOp(ctx, mrq.ctx, "FirstID")); err != nil { + return + } + if len(ids) == 0 { + err = &NotFoundError{messageremind.Label} + return + } + return ids[0], nil +} + +// FirstIDX is like FirstID, but panics if an error occurs. +func (mrq *MessageRemindQuery) FirstIDX(ctx context.Context) uuid.UUID { + id, err := mrq.FirstID(ctx) + if err != nil && !IsNotFound(err) { + panic(err) + } + return id +} + +// Only returns a single MessageRemind entity found by the query, ensuring it only returns one. +// Returns a *NotSingularError when more than one MessageRemind entity is found. +// Returns a *NotFoundError when no MessageRemind entities are found. +func (mrq *MessageRemindQuery) Only(ctx context.Context) (*MessageRemind, error) { + nodes, err := mrq.Limit(2).All(setContextOp(ctx, mrq.ctx, "Only")) + if err != nil { + return nil, err + } + switch len(nodes) { + case 1: + return nodes[0], nil + case 0: + return nil, &NotFoundError{messageremind.Label} + default: + return nil, &NotSingularError{messageremind.Label} + } +} + +// OnlyX is like Only, but panics if an error occurs. +func (mrq *MessageRemindQuery) OnlyX(ctx context.Context) *MessageRemind { + node, err := mrq.Only(ctx) + if err != nil { + panic(err) + } + return node +} + +// OnlyID is like Only, but returns the only MessageRemind ID in the query. +// Returns a *NotSingularError when more than one MessageRemind ID is found. +// Returns a *NotFoundError when no entities are found. +func (mrq *MessageRemindQuery) OnlyID(ctx context.Context) (id uuid.UUID, err error) { + var ids []uuid.UUID + if ids, err = mrq.Limit(2).IDs(setContextOp(ctx, mrq.ctx, "OnlyID")); err != nil { + return + } + switch len(ids) { + case 1: + id = ids[0] + case 0: + err = &NotFoundError{messageremind.Label} + default: + err = &NotSingularError{messageremind.Label} + } + return +} + +// OnlyIDX is like OnlyID, but panics if an error occurs. +func (mrq *MessageRemindQuery) OnlyIDX(ctx context.Context) uuid.UUID { + id, err := mrq.OnlyID(ctx) + if err != nil { + panic(err) + } + return id +} + +// All executes the query and returns a list of MessageReminds. +func (mrq *MessageRemindQuery) All(ctx context.Context) ([]*MessageRemind, error) { + ctx = setContextOp(ctx, mrq.ctx, "All") + if err := mrq.prepareQuery(ctx); err != nil { + return nil, err + } + qr := querierAll[[]*MessageRemind, *MessageRemindQuery]() + return withInterceptors[[]*MessageRemind](ctx, mrq, qr, mrq.inters) +} + +// AllX is like All, but panics if an error occurs. +func (mrq *MessageRemindQuery) AllX(ctx context.Context) []*MessageRemind { + nodes, err := mrq.All(ctx) + if err != nil { + panic(err) + } + return nodes +} + +// IDs executes the query and returns a list of MessageRemind IDs. +func (mrq *MessageRemindQuery) IDs(ctx context.Context) (ids []uuid.UUID, err error) { + if mrq.ctx.Unique == nil && mrq.path != nil { + mrq.Unique(true) + } + ctx = setContextOp(ctx, mrq.ctx, "IDs") + if err = mrq.Select(messageremind.FieldID).Scan(ctx, &ids); err != nil { + return nil, err + } + return ids, nil +} + +// IDsX is like IDs, but panics if an error occurs. +func (mrq *MessageRemindQuery) IDsX(ctx context.Context) []uuid.UUID { + ids, err := mrq.IDs(ctx) + if err != nil { + panic(err) + } + return ids +} + +// Count returns the count of the given query. +func (mrq *MessageRemindQuery) Count(ctx context.Context) (int, error) { + ctx = setContextOp(ctx, mrq.ctx, "Count") + if err := mrq.prepareQuery(ctx); err != nil { + return 0, err + } + return withInterceptors[int](ctx, mrq, querierCount[*MessageRemindQuery](), mrq.inters) +} + +// CountX is like Count, but panics if an error occurs. +func (mrq *MessageRemindQuery) CountX(ctx context.Context) int { + count, err := mrq.Count(ctx) + if err != nil { + panic(err) + } + return count +} + +// Exist returns true if the query has elements in the graph. +func (mrq *MessageRemindQuery) Exist(ctx context.Context) (bool, error) { + ctx = setContextOp(ctx, mrq.ctx, "Exist") + switch _, err := mrq.FirstID(ctx); { + case IsNotFound(err): + return false, nil + case err != nil: + return false, fmt.Errorf("ent: check existence: %w", err) + default: + return true, nil + } +} + +// ExistX is like Exist, but panics if an error occurs. +func (mrq *MessageRemindQuery) ExistX(ctx context.Context) bool { + exist, err := mrq.Exist(ctx) + if err != nil { + panic(err) + } + return exist +} + +// Clone returns a duplicate of the MessageRemindQuery builder, including all associated steps. It can be +// used to prepare common query builders and use them differently after the clone is made. +func (mrq *MessageRemindQuery) Clone() *MessageRemindQuery { + if mrq == nil { + return nil + } + return &MessageRemindQuery{ + config: mrq.config, + ctx: mrq.ctx.Clone(), + order: append([]messageremind.OrderOption{}, mrq.order...), + inters: append([]Interceptor{}, mrq.inters...), + predicates: append([]predicate.MessageRemind{}, mrq.predicates...), + withGuild: mrq.withGuild.Clone(), + // clone intermediate query. + sql: mrq.sql.Clone(), + path: mrq.path, + } +} + +// WithGuild tells the query-builder to eager-load the nodes that are connected to +// the "guild" edge. The optional arguments are used to configure the query builder of the edge. +func (mrq *MessageRemindQuery) WithGuild(opts ...func(*GuildQuery)) *MessageRemindQuery { + query := (&GuildClient{config: mrq.config}).Query() + for _, opt := range opts { + opt(query) + } + mrq.withGuild = query + return mrq +} + +// GroupBy is used to group vertices by one or more fields/columns. +// It is often used with aggregate functions, like: count, max, mean, min, sum. +// +// Example: +// +// var v []struct { +// ChannelID snowflake.ID `json:"channel_id,omitempty"` +// Count int `json:"count,omitempty"` +// } +// +// client.MessageRemind.Query(). +// GroupBy(messageremind.FieldChannelID). +// Aggregate(ent.Count()). +// Scan(ctx, &v) +func (mrq *MessageRemindQuery) GroupBy(field string, fields ...string) *MessageRemindGroupBy { + mrq.ctx.Fields = append([]string{field}, fields...) + grbuild := &MessageRemindGroupBy{build: mrq} + grbuild.flds = &mrq.ctx.Fields + grbuild.label = messageremind.Label + grbuild.scan = grbuild.Scan + return grbuild +} + +// Select allows the selection one or more fields/columns for the given query, +// instead of selecting all fields in the entity. +// +// Example: +// +// var v []struct { +// ChannelID snowflake.ID `json:"channel_id,omitempty"` +// } +// +// client.MessageRemind.Query(). +// Select(messageremind.FieldChannelID). +// Scan(ctx, &v) +func (mrq *MessageRemindQuery) Select(fields ...string) *MessageRemindSelect { + mrq.ctx.Fields = append(mrq.ctx.Fields, fields...) + sbuild := &MessageRemindSelect{MessageRemindQuery: mrq} + sbuild.label = messageremind.Label + sbuild.flds, sbuild.scan = &mrq.ctx.Fields, sbuild.Scan + return sbuild +} + +// Aggregate returns a MessageRemindSelect configured with the given aggregations. +func (mrq *MessageRemindQuery) Aggregate(fns ...AggregateFunc) *MessageRemindSelect { + return mrq.Select().Aggregate(fns...) +} + +func (mrq *MessageRemindQuery) prepareQuery(ctx context.Context) error { + for _, inter := range mrq.inters { + if inter == nil { + return fmt.Errorf("ent: uninitialized interceptor (forgotten import ent/runtime?)") + } + if trv, ok := inter.(Traverser); ok { + if err := trv.Traverse(ctx, mrq); err != nil { + return err + } + } + } + for _, f := range mrq.ctx.Fields { + if !messageremind.ValidColumn(f) { + return &ValidationError{Name: f, err: fmt.Errorf("ent: invalid field %q for query", f)} + } + } + if mrq.path != nil { + prev, err := mrq.path(ctx) + if err != nil { + return err + } + mrq.sql = prev + } + return nil +} + +func (mrq *MessageRemindQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*MessageRemind, error) { + var ( + nodes = []*MessageRemind{} + withFKs = mrq.withFKs + _spec = mrq.querySpec() + loadedTypes = [1]bool{ + mrq.withGuild != nil, + } + ) + if mrq.withGuild != nil { + withFKs = true + } + if withFKs { + _spec.Node.Columns = append(_spec.Node.Columns, messageremind.ForeignKeys...) + } + _spec.ScanValues = func(columns []string) ([]any, error) { + return (*MessageRemind).scanValues(nil, columns) + } + _spec.Assign = func(columns []string, values []any) error { + node := &MessageRemind{config: mrq.config} + nodes = append(nodes, node) + node.Edges.loadedTypes = loadedTypes + return node.assignValues(columns, values) + } + for i := range hooks { + hooks[i](ctx, _spec) + } + if err := sqlgraph.QueryNodes(ctx, mrq.driver, _spec); err != nil { + return nil, err + } + if len(nodes) == 0 { + return nodes, nil + } + if query := mrq.withGuild; query != nil { + if err := mrq.loadGuild(ctx, query, nodes, nil, + func(n *MessageRemind, e *Guild) { n.Edges.Guild = e }); err != nil { + return nil, err + } + } + return nodes, nil +} + +func (mrq *MessageRemindQuery) loadGuild(ctx context.Context, query *GuildQuery, nodes []*MessageRemind, init func(*MessageRemind), assign func(*MessageRemind, *Guild)) error { + ids := make([]snowflake.ID, 0, len(nodes)) + nodeids := make(map[snowflake.ID][]*MessageRemind) + for i := range nodes { + if nodes[i].guild_reminds == nil { + continue + } + fk := *nodes[i].guild_reminds + if _, ok := nodeids[fk]; !ok { + ids = append(ids, fk) + } + nodeids[fk] = append(nodeids[fk], nodes[i]) + } + if len(ids) == 0 { + return nil + } + query.Where(guild.IDIn(ids...)) + neighbors, err := query.All(ctx) + if err != nil { + return err + } + for _, n := range neighbors { + nodes, ok := nodeids[n.ID] + if !ok { + return fmt.Errorf(`unexpected foreign-key "guild_reminds" returned %v`, n.ID) + } + for i := range nodes { + assign(nodes[i], n) + } + } + return nil +} + +func (mrq *MessageRemindQuery) sqlCount(ctx context.Context) (int, error) { + _spec := mrq.querySpec() + _spec.Node.Columns = mrq.ctx.Fields + if len(mrq.ctx.Fields) > 0 { + _spec.Unique = mrq.ctx.Unique != nil && *mrq.ctx.Unique + } + return sqlgraph.CountNodes(ctx, mrq.driver, _spec) +} + +func (mrq *MessageRemindQuery) querySpec() *sqlgraph.QuerySpec { + _spec := sqlgraph.NewQuerySpec(messageremind.Table, messageremind.Columns, sqlgraph.NewFieldSpec(messageremind.FieldID, field.TypeUUID)) + _spec.From = mrq.sql + if unique := mrq.ctx.Unique; unique != nil { + _spec.Unique = *unique + } else if mrq.path != nil { + _spec.Unique = true + } + if fields := mrq.ctx.Fields; len(fields) > 0 { + _spec.Node.Columns = make([]string, 0, len(fields)) + _spec.Node.Columns = append(_spec.Node.Columns, messageremind.FieldID) + for i := range fields { + if fields[i] != messageremind.FieldID { + _spec.Node.Columns = append(_spec.Node.Columns, fields[i]) + } + } + } + if ps := mrq.predicates; len(ps) > 0 { + _spec.Predicate = func(selector *sql.Selector) { + for i := range ps { + ps[i](selector) + } + } + } + if limit := mrq.ctx.Limit; limit != nil { + _spec.Limit = *limit + } + if offset := mrq.ctx.Offset; offset != nil { + _spec.Offset = *offset + } + if ps := mrq.order; len(ps) > 0 { + _spec.Order = func(selector *sql.Selector) { + for i := range ps { + ps[i](selector) + } + } + } + return _spec +} + +func (mrq *MessageRemindQuery) sqlQuery(ctx context.Context) *sql.Selector { + builder := sql.Dialect(mrq.driver.Dialect()) + t1 := builder.Table(messageremind.Table) + columns := mrq.ctx.Fields + if len(columns) == 0 { + columns = messageremind.Columns + } + selector := builder.Select(t1.Columns(columns...)...).From(t1) + if mrq.sql != nil { + selector = mrq.sql + selector.Select(selector.Columns(columns...)...) + } + if mrq.ctx.Unique != nil && *mrq.ctx.Unique { + selector.Distinct() + } + for _, p := range mrq.predicates { + p(selector) + } + for _, p := range mrq.order { + p(selector) + } + if offset := mrq.ctx.Offset; offset != nil { + // limit is mandatory for offset clause. We start + // with default value, and override it below if needed. + selector.Offset(*offset).Limit(math.MaxInt32) + } + if limit := mrq.ctx.Limit; limit != nil { + selector.Limit(*limit) + } + return selector +} + +// MessageRemindGroupBy is the group-by builder for MessageRemind entities. +type MessageRemindGroupBy struct { + selector + build *MessageRemindQuery +} + +// Aggregate adds the given aggregation functions to the group-by query. +func (mrgb *MessageRemindGroupBy) Aggregate(fns ...AggregateFunc) *MessageRemindGroupBy { + mrgb.fns = append(mrgb.fns, fns...) + return mrgb +} + +// Scan applies the selector query and scans the result into the given value. +func (mrgb *MessageRemindGroupBy) Scan(ctx context.Context, v any) error { + ctx = setContextOp(ctx, mrgb.build.ctx, "GroupBy") + if err := mrgb.build.prepareQuery(ctx); err != nil { + return err + } + return scanWithInterceptors[*MessageRemindQuery, *MessageRemindGroupBy](ctx, mrgb.build, mrgb, mrgb.build.inters, v) +} + +func (mrgb *MessageRemindGroupBy) sqlScan(ctx context.Context, root *MessageRemindQuery, v any) error { + selector := root.sqlQuery(ctx).Select() + aggregation := make([]string, 0, len(mrgb.fns)) + for _, fn := range mrgb.fns { + aggregation = append(aggregation, fn(selector)) + } + if len(selector.SelectedColumns()) == 0 { + columns := make([]string, 0, len(*mrgb.flds)+len(mrgb.fns)) + for _, f := range *mrgb.flds { + columns = append(columns, selector.C(f)) + } + columns = append(columns, aggregation...) + selector.Select(columns...) + } + selector.GroupBy(selector.Columns(*mrgb.flds...)...) + if err := selector.Err(); err != nil { + return err + } + rows := &sql.Rows{} + query, args := selector.Query() + if err := mrgb.build.driver.Query(ctx, query, args, rows); err != nil { + return err + } + defer rows.Close() + return sql.ScanSlice(rows, v) +} + +// MessageRemindSelect is the builder for selecting fields of MessageRemind entities. +type MessageRemindSelect struct { + *MessageRemindQuery + selector +} + +// Aggregate adds the given aggregation functions to the selector query. +func (mrs *MessageRemindSelect) Aggregate(fns ...AggregateFunc) *MessageRemindSelect { + mrs.fns = append(mrs.fns, fns...) + return mrs +} + +// Scan applies the selector query and scans the result into the given value. +func (mrs *MessageRemindSelect) Scan(ctx context.Context, v any) error { + ctx = setContextOp(ctx, mrs.ctx, "Select") + if err := mrs.prepareQuery(ctx); err != nil { + return err + } + return scanWithInterceptors[*MessageRemindQuery, *MessageRemindSelect](ctx, mrs.MessageRemindQuery, mrs, mrs.inters, v) +} + +func (mrs *MessageRemindSelect) sqlScan(ctx context.Context, root *MessageRemindQuery, v any) error { + selector := root.sqlQuery(ctx) + aggregation := make([]string, 0, len(mrs.fns)) + for _, fn := range mrs.fns { + aggregation = append(aggregation, fn(selector)) + } + switch n := len(*mrs.selector.flds); { + case n == 0 && len(aggregation) > 0: + selector.Select(aggregation...) + case n != 0 && len(aggregation) > 0: + selector.AppendSelect(aggregation...) + } + rows := &sql.Rows{} + query, args := selector.Query() + if err := mrs.driver.Query(ctx, query, args, rows); err != nil { + return err + } + defer rows.Close() + return sql.ScanSlice(rows, v) +} diff --git a/ent/messageremind_update.go b/ent/messageremind_update.go new file mode 100644 index 00000000..301a8212 --- /dev/null +++ b/ent/messageremind_update.go @@ -0,0 +1,522 @@ +// Code generated by ent, DO NOT EDIT. + +package ent + +import ( + "context" + "errors" + "fmt" + "time" + + "entgo.io/ent/dialect/sql" + "entgo.io/ent/dialect/sql/sqlgraph" + "entgo.io/ent/schema/field" + snowflake "github.com/disgoorg/snowflake/v2" + "github.com/sabafly/gobot/ent/guild" + "github.com/sabafly/gobot/ent/messageremind" + "github.com/sabafly/gobot/ent/predicate" +) + +// MessageRemindUpdate is the builder for updating MessageRemind entities. +type MessageRemindUpdate struct { + config + hooks []Hook + mutation *MessageRemindMutation +} + +// Where appends a list predicates to the MessageRemindUpdate builder. +func (mru *MessageRemindUpdate) Where(ps ...predicate.MessageRemind) *MessageRemindUpdate { + mru.mutation.Where(ps...) + return mru +} + +// SetChannelID sets the "channel_id" field. +func (mru *MessageRemindUpdate) SetChannelID(s snowflake.ID) *MessageRemindUpdate { + mru.mutation.ResetChannelID() + mru.mutation.SetChannelID(s) + return mru +} + +// SetNillableChannelID sets the "channel_id" field if the given value is not nil. +func (mru *MessageRemindUpdate) SetNillableChannelID(s *snowflake.ID) *MessageRemindUpdate { + if s != nil { + mru.SetChannelID(*s) + } + return mru +} + +// AddChannelID adds s to the "channel_id" field. +func (mru *MessageRemindUpdate) AddChannelID(s snowflake.ID) *MessageRemindUpdate { + mru.mutation.AddChannelID(s) + return mru +} + +// SetAuthorID sets the "author_id" field. +func (mru *MessageRemindUpdate) SetAuthorID(s snowflake.ID) *MessageRemindUpdate { + mru.mutation.ResetAuthorID() + mru.mutation.SetAuthorID(s) + return mru +} + +// SetNillableAuthorID sets the "author_id" field if the given value is not nil. +func (mru *MessageRemindUpdate) SetNillableAuthorID(s *snowflake.ID) *MessageRemindUpdate { + if s != nil { + mru.SetAuthorID(*s) + } + return mru +} + +// AddAuthorID adds s to the "author_id" field. +func (mru *MessageRemindUpdate) AddAuthorID(s snowflake.ID) *MessageRemindUpdate { + mru.mutation.AddAuthorID(s) + return mru +} + +// SetTime sets the "time" field. +func (mru *MessageRemindUpdate) SetTime(t time.Time) *MessageRemindUpdate { + mru.mutation.SetTime(t) + return mru +} + +// SetNillableTime sets the "time" field if the given value is not nil. +func (mru *MessageRemindUpdate) SetNillableTime(t *time.Time) *MessageRemindUpdate { + if t != nil { + mru.SetTime(*t) + } + return mru +} + +// SetContent sets the "content" field. +func (mru *MessageRemindUpdate) SetContent(s string) *MessageRemindUpdate { + mru.mutation.SetContent(s) + return mru +} + +// SetNillableContent sets the "content" field if the given value is not nil. +func (mru *MessageRemindUpdate) SetNillableContent(s *string) *MessageRemindUpdate { + if s != nil { + mru.SetContent(*s) + } + return mru +} + +// SetName sets the "name" field. +func (mru *MessageRemindUpdate) SetName(s string) *MessageRemindUpdate { + mru.mutation.SetName(s) + return mru +} + +// SetNillableName sets the "name" field if the given value is not nil. +func (mru *MessageRemindUpdate) SetNillableName(s *string) *MessageRemindUpdate { + if s != nil { + mru.SetName(*s) + } + return mru +} + +// SetGuildID sets the "guild" edge to the Guild entity by ID. +func (mru *MessageRemindUpdate) SetGuildID(id snowflake.ID) *MessageRemindUpdate { + mru.mutation.SetGuildID(id) + return mru +} + +// SetGuild sets the "guild" edge to the Guild entity. +func (mru *MessageRemindUpdate) SetGuild(g *Guild) *MessageRemindUpdate { + return mru.SetGuildID(g.ID) +} + +// Mutation returns the MessageRemindMutation object of the builder. +func (mru *MessageRemindUpdate) Mutation() *MessageRemindMutation { + return mru.mutation +} + +// ClearGuild clears the "guild" edge to the Guild entity. +func (mru *MessageRemindUpdate) ClearGuild() *MessageRemindUpdate { + mru.mutation.ClearGuild() + return mru +} + +// Save executes the query and returns the number of nodes affected by the update operation. +func (mru *MessageRemindUpdate) Save(ctx context.Context) (int, error) { + return withHooks(ctx, mru.sqlSave, mru.mutation, mru.hooks) +} + +// SaveX is like Save, but panics if an error occurs. +func (mru *MessageRemindUpdate) SaveX(ctx context.Context) int { + affected, err := mru.Save(ctx) + if err != nil { + panic(err) + } + return affected +} + +// Exec executes the query. +func (mru *MessageRemindUpdate) Exec(ctx context.Context) error { + _, err := mru.Save(ctx) + return err +} + +// ExecX is like Exec, but panics if an error occurs. +func (mru *MessageRemindUpdate) ExecX(ctx context.Context) { + if err := mru.Exec(ctx); err != nil { + panic(err) + } +} + +// check runs all checks and user-defined validators on the builder. +func (mru *MessageRemindUpdate) check() error { + if v, ok := mru.mutation.Content(); ok { + if err := messageremind.ContentValidator(v); err != nil { + return &ValidationError{Name: "content", err: fmt.Errorf(`ent: validator failed for field "MessageRemind.content": %w`, err)} + } + } + if v, ok := mru.mutation.Name(); ok { + if err := messageremind.NameValidator(v); err != nil { + return &ValidationError{Name: "name", err: fmt.Errorf(`ent: validator failed for field "MessageRemind.name": %w`, err)} + } + } + if _, ok := mru.mutation.GuildID(); mru.mutation.GuildCleared() && !ok { + return errors.New(`ent: clearing a required unique edge "MessageRemind.guild"`) + } + return nil +} + +func (mru *MessageRemindUpdate) sqlSave(ctx context.Context) (n int, err error) { + if err := mru.check(); err != nil { + return n, err + } + _spec := sqlgraph.NewUpdateSpec(messageremind.Table, messageremind.Columns, sqlgraph.NewFieldSpec(messageremind.FieldID, field.TypeUUID)) + if ps := mru.mutation.predicates; len(ps) > 0 { + _spec.Predicate = func(selector *sql.Selector) { + for i := range ps { + ps[i](selector) + } + } + } + if value, ok := mru.mutation.ChannelID(); ok { + _spec.SetField(messageremind.FieldChannelID, field.TypeUint64, value) + } + if value, ok := mru.mutation.AddedChannelID(); ok { + _spec.AddField(messageremind.FieldChannelID, field.TypeUint64, value) + } + if value, ok := mru.mutation.AuthorID(); ok { + _spec.SetField(messageremind.FieldAuthorID, field.TypeUint64, value) + } + if value, ok := mru.mutation.AddedAuthorID(); ok { + _spec.AddField(messageremind.FieldAuthorID, field.TypeUint64, value) + } + if value, ok := mru.mutation.Time(); ok { + _spec.SetField(messageremind.FieldTime, field.TypeTime, value) + } + if value, ok := mru.mutation.Content(); ok { + _spec.SetField(messageremind.FieldContent, field.TypeString, value) + } + if value, ok := mru.mutation.Name(); ok { + _spec.SetField(messageremind.FieldName, field.TypeString, value) + } + if mru.mutation.GuildCleared() { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.M2O, + Inverse: true, + Table: messageremind.GuildTable, + Columns: []string{messageremind.GuildColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(guild.FieldID, field.TypeUint64), + }, + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := mru.mutation.GuildIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.M2O, + Inverse: true, + Table: messageremind.GuildTable, + Columns: []string{messageremind.GuildColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(guild.FieldID, field.TypeUint64), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Add = append(_spec.Edges.Add, edge) + } + if n, err = sqlgraph.UpdateNodes(ctx, mru.driver, _spec); err != nil { + if _, ok := err.(*sqlgraph.NotFoundError); ok { + err = &NotFoundError{messageremind.Label} + } else if sqlgraph.IsConstraintError(err) { + err = &ConstraintError{msg: err.Error(), wrap: err} + } + return 0, err + } + mru.mutation.done = true + return n, nil +} + +// MessageRemindUpdateOne is the builder for updating a single MessageRemind entity. +type MessageRemindUpdateOne struct { + config + fields []string + hooks []Hook + mutation *MessageRemindMutation +} + +// SetChannelID sets the "channel_id" field. +func (mruo *MessageRemindUpdateOne) SetChannelID(s snowflake.ID) *MessageRemindUpdateOne { + mruo.mutation.ResetChannelID() + mruo.mutation.SetChannelID(s) + return mruo +} + +// SetNillableChannelID sets the "channel_id" field if the given value is not nil. +func (mruo *MessageRemindUpdateOne) SetNillableChannelID(s *snowflake.ID) *MessageRemindUpdateOne { + if s != nil { + mruo.SetChannelID(*s) + } + return mruo +} + +// AddChannelID adds s to the "channel_id" field. +func (mruo *MessageRemindUpdateOne) AddChannelID(s snowflake.ID) *MessageRemindUpdateOne { + mruo.mutation.AddChannelID(s) + return mruo +} + +// SetAuthorID sets the "author_id" field. +func (mruo *MessageRemindUpdateOne) SetAuthorID(s snowflake.ID) *MessageRemindUpdateOne { + mruo.mutation.ResetAuthorID() + mruo.mutation.SetAuthorID(s) + return mruo +} + +// SetNillableAuthorID sets the "author_id" field if the given value is not nil. +func (mruo *MessageRemindUpdateOne) SetNillableAuthorID(s *snowflake.ID) *MessageRemindUpdateOne { + if s != nil { + mruo.SetAuthorID(*s) + } + return mruo +} + +// AddAuthorID adds s to the "author_id" field. +func (mruo *MessageRemindUpdateOne) AddAuthorID(s snowflake.ID) *MessageRemindUpdateOne { + mruo.mutation.AddAuthorID(s) + return mruo +} + +// SetTime sets the "time" field. +func (mruo *MessageRemindUpdateOne) SetTime(t time.Time) *MessageRemindUpdateOne { + mruo.mutation.SetTime(t) + return mruo +} + +// SetNillableTime sets the "time" field if the given value is not nil. +func (mruo *MessageRemindUpdateOne) SetNillableTime(t *time.Time) *MessageRemindUpdateOne { + if t != nil { + mruo.SetTime(*t) + } + return mruo +} + +// SetContent sets the "content" field. +func (mruo *MessageRemindUpdateOne) SetContent(s string) *MessageRemindUpdateOne { + mruo.mutation.SetContent(s) + return mruo +} + +// SetNillableContent sets the "content" field if the given value is not nil. +func (mruo *MessageRemindUpdateOne) SetNillableContent(s *string) *MessageRemindUpdateOne { + if s != nil { + mruo.SetContent(*s) + } + return mruo +} + +// SetName sets the "name" field. +func (mruo *MessageRemindUpdateOne) SetName(s string) *MessageRemindUpdateOne { + mruo.mutation.SetName(s) + return mruo +} + +// SetNillableName sets the "name" field if the given value is not nil. +func (mruo *MessageRemindUpdateOne) SetNillableName(s *string) *MessageRemindUpdateOne { + if s != nil { + mruo.SetName(*s) + } + return mruo +} + +// SetGuildID sets the "guild" edge to the Guild entity by ID. +func (mruo *MessageRemindUpdateOne) SetGuildID(id snowflake.ID) *MessageRemindUpdateOne { + mruo.mutation.SetGuildID(id) + return mruo +} + +// SetGuild sets the "guild" edge to the Guild entity. +func (mruo *MessageRemindUpdateOne) SetGuild(g *Guild) *MessageRemindUpdateOne { + return mruo.SetGuildID(g.ID) +} + +// Mutation returns the MessageRemindMutation object of the builder. +func (mruo *MessageRemindUpdateOne) Mutation() *MessageRemindMutation { + return mruo.mutation +} + +// ClearGuild clears the "guild" edge to the Guild entity. +func (mruo *MessageRemindUpdateOne) ClearGuild() *MessageRemindUpdateOne { + mruo.mutation.ClearGuild() + return mruo +} + +// Where appends a list predicates to the MessageRemindUpdate builder. +func (mruo *MessageRemindUpdateOne) Where(ps ...predicate.MessageRemind) *MessageRemindUpdateOne { + mruo.mutation.Where(ps...) + return mruo +} + +// Select allows selecting one or more fields (columns) of the returned entity. +// The default is selecting all fields defined in the entity schema. +func (mruo *MessageRemindUpdateOne) Select(field string, fields ...string) *MessageRemindUpdateOne { + mruo.fields = append([]string{field}, fields...) + return mruo +} + +// Save executes the query and returns the updated MessageRemind entity. +func (mruo *MessageRemindUpdateOne) Save(ctx context.Context) (*MessageRemind, error) { + return withHooks(ctx, mruo.sqlSave, mruo.mutation, mruo.hooks) +} + +// SaveX is like Save, but panics if an error occurs. +func (mruo *MessageRemindUpdateOne) SaveX(ctx context.Context) *MessageRemind { + node, err := mruo.Save(ctx) + if err != nil { + panic(err) + } + return node +} + +// Exec executes the query on the entity. +func (mruo *MessageRemindUpdateOne) Exec(ctx context.Context) error { + _, err := mruo.Save(ctx) + return err +} + +// ExecX is like Exec, but panics if an error occurs. +func (mruo *MessageRemindUpdateOne) ExecX(ctx context.Context) { + if err := mruo.Exec(ctx); err != nil { + panic(err) + } +} + +// check runs all checks and user-defined validators on the builder. +func (mruo *MessageRemindUpdateOne) check() error { + if v, ok := mruo.mutation.Content(); ok { + if err := messageremind.ContentValidator(v); err != nil { + return &ValidationError{Name: "content", err: fmt.Errorf(`ent: validator failed for field "MessageRemind.content": %w`, err)} + } + } + if v, ok := mruo.mutation.Name(); ok { + if err := messageremind.NameValidator(v); err != nil { + return &ValidationError{Name: "name", err: fmt.Errorf(`ent: validator failed for field "MessageRemind.name": %w`, err)} + } + } + if _, ok := mruo.mutation.GuildID(); mruo.mutation.GuildCleared() && !ok { + return errors.New(`ent: clearing a required unique edge "MessageRemind.guild"`) + } + return nil +} + +func (mruo *MessageRemindUpdateOne) sqlSave(ctx context.Context) (_node *MessageRemind, err error) { + if err := mruo.check(); err != nil { + return _node, err + } + _spec := sqlgraph.NewUpdateSpec(messageremind.Table, messageremind.Columns, sqlgraph.NewFieldSpec(messageremind.FieldID, field.TypeUUID)) + id, ok := mruo.mutation.ID() + if !ok { + return nil, &ValidationError{Name: "id", err: errors.New(`ent: missing "MessageRemind.id" for update`)} + } + _spec.Node.ID.Value = id + if fields := mruo.fields; len(fields) > 0 { + _spec.Node.Columns = make([]string, 0, len(fields)) + _spec.Node.Columns = append(_spec.Node.Columns, messageremind.FieldID) + for _, f := range fields { + if !messageremind.ValidColumn(f) { + return nil, &ValidationError{Name: f, err: fmt.Errorf("ent: invalid field %q for query", f)} + } + if f != messageremind.FieldID { + _spec.Node.Columns = append(_spec.Node.Columns, f) + } + } + } + if ps := mruo.mutation.predicates; len(ps) > 0 { + _spec.Predicate = func(selector *sql.Selector) { + for i := range ps { + ps[i](selector) + } + } + } + if value, ok := mruo.mutation.ChannelID(); ok { + _spec.SetField(messageremind.FieldChannelID, field.TypeUint64, value) + } + if value, ok := mruo.mutation.AddedChannelID(); ok { + _spec.AddField(messageremind.FieldChannelID, field.TypeUint64, value) + } + if value, ok := mruo.mutation.AuthorID(); ok { + _spec.SetField(messageremind.FieldAuthorID, field.TypeUint64, value) + } + if value, ok := mruo.mutation.AddedAuthorID(); ok { + _spec.AddField(messageremind.FieldAuthorID, field.TypeUint64, value) + } + if value, ok := mruo.mutation.Time(); ok { + _spec.SetField(messageremind.FieldTime, field.TypeTime, value) + } + if value, ok := mruo.mutation.Content(); ok { + _spec.SetField(messageremind.FieldContent, field.TypeString, value) + } + if value, ok := mruo.mutation.Name(); ok { + _spec.SetField(messageremind.FieldName, field.TypeString, value) + } + if mruo.mutation.GuildCleared() { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.M2O, + Inverse: true, + Table: messageremind.GuildTable, + Columns: []string{messageremind.GuildColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(guild.FieldID, field.TypeUint64), + }, + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := mruo.mutation.GuildIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.M2O, + Inverse: true, + Table: messageremind.GuildTable, + Columns: []string{messageremind.GuildColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(guild.FieldID, field.TypeUint64), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Add = append(_spec.Edges.Add, edge) + } + _node = &MessageRemind{config: mruo.config} + _spec.Assign = _node.assignValues + _spec.ScanValues = _node.scanValues + if err = sqlgraph.UpdateNode(ctx, mruo.driver, _spec); err != nil { + if _, ok := err.(*sqlgraph.NotFoundError); ok { + err = &NotFoundError{messageremind.Label} + } else if sqlgraph.IsConstraintError(err) { + err = &ConstraintError{msg: err.Error(), wrap: err} + } + return nil, err + } + mruo.mutation.done = true + return _node, nil +} diff --git a/ent/migrate/migrate.go b/ent/migrate/migrate.go new file mode 100644 index 00000000..1956a6bf --- /dev/null +++ b/ent/migrate/migrate.go @@ -0,0 +1,64 @@ +// Code generated by ent, DO NOT EDIT. + +package migrate + +import ( + "context" + "fmt" + "io" + + "entgo.io/ent/dialect" + "entgo.io/ent/dialect/sql/schema" +) + +var ( + // WithGlobalUniqueID sets the universal ids options to the migration. + // If this option is enabled, ent migration will allocate a 1<<32 range + // for the ids of each entity (table). + // Note that this option cannot be applied on tables that already exist. + WithGlobalUniqueID = schema.WithGlobalUniqueID + // WithDropColumn sets the drop column option to the migration. + // If this option is enabled, ent migration will drop old columns + // that were used for both fields and edges. This defaults to false. + WithDropColumn = schema.WithDropColumn + // WithDropIndex sets the drop index option to the migration. + // If this option is enabled, ent migration will drop old indexes + // that were defined in the schema. This defaults to false. + // Note that unique constraints are defined using `UNIQUE INDEX`, + // and therefore, it's recommended to enable this option to get more + // flexibility in the schema changes. + WithDropIndex = schema.WithDropIndex + // WithForeignKeys enables creating foreign-key in schema DDL. This defaults to true. + WithForeignKeys = schema.WithForeignKeys +) + +// Schema is the API for creating, migrating and dropping a schema. +type Schema struct { + drv dialect.Driver +} + +// NewSchema creates a new schema client. +func NewSchema(drv dialect.Driver) *Schema { return &Schema{drv: drv} } + +// Create creates all schema resources. +func (s *Schema) Create(ctx context.Context, opts ...schema.MigrateOption) error { + return Create(ctx, s, Tables, opts...) +} + +// Create creates all table resources using the given schema driver. +func Create(ctx context.Context, s *Schema, tables []*schema.Table, opts ...schema.MigrateOption) error { + migrate, err := schema.NewMigrate(s.drv, opts...) + if err != nil { + return fmt.Errorf("ent/migrate: %w", err) + } + return migrate.Create(ctx, tables...) +} + +// WriteTo writes the schema changes to w instead of running them against the database. +// +// if err := client.Schema.WriteTo(context.Background(), os.Stdout); err != nil { +// log.Fatal(err) +// } +func (s *Schema) WriteTo(ctx context.Context, w io.Writer, opts ...schema.MigrateOption) error { + return Create(ctx, &Schema{drv: &schema.WriteDriver{Writer: w, Driver: s.drv}}, Tables, opts...) +} diff --git a/ent/migrate/schema.go b/ent/migrate/schema.go new file mode 100644 index 00000000..57cb62c9 --- /dev/null +++ b/ent/migrate/schema.go @@ -0,0 +1,299 @@ +// Code generated by ent, DO NOT EDIT. + +package migrate + +import ( + "entgo.io/ent/dialect/sql/schema" + "entgo.io/ent/schema/field" +) + +var ( + // GuildsColumns holds the columns for the "guilds" table. + GuildsColumns = []*schema.Column{ + {Name: "id", Type: field.TypeUint64, Increment: true}, + {Name: "name", Type: field.TypeString}, + {Name: "locale", Type: field.TypeString, Default: "ja"}, + {Name: "level_up_message", Type: field.TypeString, Default: "{user}がレベルアップしたよ🥳\n**{before_level} レベル → {after_level} レベル**"}, + {Name: "level_up_channel", Type: field.TypeUint64, Nullable: true}, + {Name: "level_up_exclude_channel", Type: field.TypeJSON, Nullable: true}, + {Name: "level_mee6_imported", Type: field.TypeBool, Default: false}, + {Name: "level_role", Type: field.TypeJSON, Nullable: true}, + {Name: "permissions", Type: field.TypeJSON}, + {Name: "remind_count", Type: field.TypeInt, Default: 0}, + {Name: "role_panel_edit_times", Type: field.TypeJSON, Default: "[]"}, + {Name: "bump_enabled", Type: field.TypeBool, Default: true}, + {Name: "bump_message_title", Type: field.TypeString, Default: "Bumpを怜知したした"}, + {Name: "bump_message", Type: field.TypeString, Default: "時間埌に通知したす"}, + {Name: "bump_remind_message_title", Type: field.TypeString, Default: "Bumpの時間です"}, + {Name: "bump_remind_message", Type: field.TypeString, Default: "でBumpしたしょう"}, + {Name: "up_enabled", Type: field.TypeBool, Default: true}, + {Name: "up_message_title", Type: field.TypeString, Default: "UPを怜知したした"}, + {Name: "up_message", Type: field.TypeString, Default: "時間埌に通知したす"}, + {Name: "up_remind_message_title", Type: field.TypeString, Default: "UPの時間です"}, + {Name: "up_remind_message", Type: field.TypeString, Default: "でUPしたしょう"}, + {Name: "bump_mention", Type: field.TypeUint64, Nullable: true}, + {Name: "up_mention", Type: field.TypeUint64, Nullable: true}, + {Name: "user_own_guilds", Type: field.TypeUint64}, + } + // GuildsTable holds the schema information for the "guilds" table. + GuildsTable = &schema.Table{ + Name: "guilds", + Columns: GuildsColumns, + PrimaryKey: []*schema.Column{GuildsColumns[0]}, + ForeignKeys: []*schema.ForeignKey{ + { + Symbol: "guilds_users_own_guilds", + Columns: []*schema.Column{GuildsColumns[23]}, + RefColumns: []*schema.Column{UsersColumns[0]}, + OnDelete: schema.NoAction, + }, + }, + } + // MembersColumns holds the columns for the "members" table. + MembersColumns = []*schema.Column{ + {Name: "id", Type: field.TypeInt, Increment: true}, + {Name: "permission", Type: field.TypeJSON, Nullable: true}, + {Name: "xp", Type: field.TypeUint64, Default: 0}, + {Name: "last_xp", Type: field.TypeTime, Nullable: true}, + {Name: "message_count", Type: field.TypeUint64, Default: 0}, + {Name: "last_notified_level", Type: field.TypeUint64, Nullable: true}, + {Name: "guild_members", Type: field.TypeUint64}, + {Name: "user_id", Type: field.TypeUint64}, + } + // MembersTable holds the schema information for the "members" table. + MembersTable = &schema.Table{ + Name: "members", + Columns: MembersColumns, + PrimaryKey: []*schema.Column{MembersColumns[0]}, + ForeignKeys: []*schema.ForeignKey{ + { + Symbol: "members_guilds_members", + Columns: []*schema.Column{MembersColumns[6]}, + RefColumns: []*schema.Column{GuildsColumns[0]}, + OnDelete: schema.NoAction, + }, + { + Symbol: "members_users_guilds", + Columns: []*schema.Column{MembersColumns[7]}, + RefColumns: []*schema.Column{UsersColumns[0]}, + OnDelete: schema.NoAction, + }, + }, + } + // MessagePinsColumns holds the columns for the "message_pins" table. + MessagePinsColumns = []*schema.Column{ + {Name: "id", Type: field.TypeUUID, Unique: true}, + {Name: "channel_id", Type: field.TypeUint64, Unique: true}, + {Name: "content", Type: field.TypeString, Nullable: true}, + {Name: "embeds", Type: field.TypeJSON, Nullable: true}, + {Name: "before_id", Type: field.TypeUint64, Nullable: true}, + {Name: "rate_limit", Type: field.TypeJSON}, + {Name: "guild_message_pins", Type: field.TypeUint64}, + } + // MessagePinsTable holds the schema information for the "message_pins" table. + MessagePinsTable = &schema.Table{ + Name: "message_pins", + Columns: MessagePinsColumns, + PrimaryKey: []*schema.Column{MessagePinsColumns[0]}, + ForeignKeys: []*schema.ForeignKey{ + { + Symbol: "message_pins_guilds_message_pins", + Columns: []*schema.Column{MessagePinsColumns[6]}, + RefColumns: []*schema.Column{GuildsColumns[0]}, + OnDelete: schema.NoAction, + }, + }, + } + // MessageRemindsColumns holds the columns for the "message_reminds" table. + MessageRemindsColumns = []*schema.Column{ + {Name: "id", Type: field.TypeUUID, Unique: true}, + {Name: "channel_id", Type: field.TypeUint64}, + {Name: "author_id", Type: field.TypeUint64}, + {Name: "time", Type: field.TypeTime}, + {Name: "content", Type: field.TypeString}, + {Name: "name", Type: field.TypeString}, + {Name: "guild_reminds", Type: field.TypeUint64}, + } + // MessageRemindsTable holds the schema information for the "message_reminds" table. + MessageRemindsTable = &schema.Table{ + Name: "message_reminds", + Columns: MessageRemindsColumns, + PrimaryKey: []*schema.Column{MessageRemindsColumns[0]}, + ForeignKeys: []*schema.ForeignKey{ + { + Symbol: "message_reminds_guilds_reminds", + Columns: []*schema.Column{MessageRemindsColumns[6]}, + RefColumns: []*schema.Column{GuildsColumns[0]}, + OnDelete: schema.NoAction, + }, + }, + } + // RolePanelsColumns holds the columns for the "role_panels" table. + RolePanelsColumns = []*schema.Column{ + {Name: "id", Type: field.TypeUUID, Unique: true}, + {Name: "name", Type: field.TypeString}, + {Name: "description", Type: field.TypeString}, + {Name: "roles", Type: field.TypeJSON, Nullable: true}, + {Name: "updated_at", Type: field.TypeTime, Nullable: true}, + {Name: "applied_at", Type: field.TypeTime, Nullable: true}, + {Name: "guild_role_panels", Type: field.TypeUint64}, + } + // RolePanelsTable holds the schema information for the "role_panels" table. + RolePanelsTable = &schema.Table{ + Name: "role_panels", + Columns: RolePanelsColumns, + PrimaryKey: []*schema.Column{RolePanelsColumns[0]}, + ForeignKeys: []*schema.ForeignKey{ + { + Symbol: "role_panels_guilds_role_panels", + Columns: []*schema.Column{RolePanelsColumns[6]}, + RefColumns: []*schema.Column{GuildsColumns[0]}, + OnDelete: schema.NoAction, + }, + }, + } + // RolePanelEditsColumns holds the columns for the "role_panel_edits" table. + RolePanelEditsColumns = []*schema.Column{ + {Name: "id", Type: field.TypeUUID, Unique: true}, + {Name: "channel_id", Type: field.TypeUint64}, + {Name: "emoji_author", Type: field.TypeUint64, Nullable: true}, + {Name: "token", Type: field.TypeString, Nullable: true}, + {Name: "selected_role", Type: field.TypeUint64, Nullable: true}, + {Name: "modified", Type: field.TypeBool, Default: false}, + {Name: "name", Type: field.TypeString, Nullable: true}, + {Name: "description", Type: field.TypeString, Nullable: true}, + {Name: "roles", Type: field.TypeJSON, Nullable: true}, + {Name: "guild_role_panel_edits", Type: field.TypeUint64}, + {Name: "role_panel_edit", Type: field.TypeUUID, Unique: true}, + } + // RolePanelEditsTable holds the schema information for the "role_panel_edits" table. + RolePanelEditsTable = &schema.Table{ + Name: "role_panel_edits", + Columns: RolePanelEditsColumns, + PrimaryKey: []*schema.Column{RolePanelEditsColumns[0]}, + ForeignKeys: []*schema.ForeignKey{ + { + Symbol: "role_panel_edits_guilds_role_panel_edits", + Columns: []*schema.Column{RolePanelEditsColumns[9]}, + RefColumns: []*schema.Column{GuildsColumns[0]}, + OnDelete: schema.NoAction, + }, + { + Symbol: "role_panel_edits_role_panels_edit", + Columns: []*schema.Column{RolePanelEditsColumns[10]}, + RefColumns: []*schema.Column{RolePanelsColumns[0]}, + OnDelete: schema.NoAction, + }, + }, + } + // RolePanelPlacedsColumns holds the columns for the "role_panel_placeds" table. + RolePanelPlacedsColumns = []*schema.Column{ + {Name: "id", Type: field.TypeUUID, Unique: true}, + {Name: "message_id", Type: field.TypeUint64, Nullable: true}, + {Name: "channel_id", Type: field.TypeUint64}, + {Name: "type", Type: field.TypeEnum, Nullable: true, Enums: []string{"button", "reaction", "select_menu"}}, + {Name: "button_type", Type: field.TypeInt, Default: 1}, + {Name: "show_name", Type: field.TypeBool, Default: false}, + {Name: "folding_select_menu", Type: field.TypeBool, Default: true}, + {Name: "hide_notice", Type: field.TypeBool, Default: false}, + {Name: "use_display_name", Type: field.TypeBool, Default: false}, + {Name: "created_at", Type: field.TypeTime}, + {Name: "uses", Type: field.TypeInt, Default: 0}, + {Name: "name", Type: field.TypeString}, + {Name: "description", Type: field.TypeString}, + {Name: "roles", Type: field.TypeJSON, Nullable: true}, + {Name: "updated_at", Type: field.TypeTime, Nullable: true}, + {Name: "guild_role_panel_placements", Type: field.TypeUint64}, + {Name: "role_panel_placements", Type: field.TypeUUID}, + } + // RolePanelPlacedsTable holds the schema information for the "role_panel_placeds" table. + RolePanelPlacedsTable = &schema.Table{ + Name: "role_panel_placeds", + Columns: RolePanelPlacedsColumns, + PrimaryKey: []*schema.Column{RolePanelPlacedsColumns[0]}, + ForeignKeys: []*schema.ForeignKey{ + { + Symbol: "role_panel_placeds_guilds_role_panel_placements", + Columns: []*schema.Column{RolePanelPlacedsColumns[15]}, + RefColumns: []*schema.Column{GuildsColumns[0]}, + OnDelete: schema.NoAction, + }, + { + Symbol: "role_panel_placeds_role_panels_placements", + Columns: []*schema.Column{RolePanelPlacedsColumns[16]}, + RefColumns: []*schema.Column{RolePanelsColumns[0]}, + OnDelete: schema.NoAction, + }, + }, + } + // UsersColumns holds the columns for the "users" table. + UsersColumns = []*schema.Column{ + {Name: "id", Type: field.TypeUint64, Increment: true}, + {Name: "name", Type: field.TypeString}, + {Name: "created_at", Type: field.TypeTime}, + {Name: "locale", Type: field.TypeString, Default: "ja"}, + {Name: "xp", Type: field.TypeUint64, Default: 0}, + } + // UsersTable holds the schema information for the "users" table. + UsersTable = &schema.Table{ + Name: "users", + Columns: UsersColumns, + PrimaryKey: []*schema.Column{UsersColumns[0]}, + } + // WordSuffixesColumns holds the columns for the "word_suffixes" table. + WordSuffixesColumns = []*schema.Column{ + {Name: "id", Type: field.TypeUUID}, + {Name: "suffix", Type: field.TypeString}, + {Name: "expired", Type: field.TypeTime, Nullable: true}, + {Name: "rule", Type: field.TypeEnum, Enums: []string{"webhook", "warn", "delete"}, Default: "webhook"}, + {Name: "user_word_suffix", Type: field.TypeUint64}, + {Name: "guild_id", Type: field.TypeUint64, Nullable: true}, + } + // WordSuffixesTable holds the schema information for the "word_suffixes" table. + WordSuffixesTable = &schema.Table{ + Name: "word_suffixes", + Columns: WordSuffixesColumns, + PrimaryKey: []*schema.Column{WordSuffixesColumns[0]}, + ForeignKeys: []*schema.ForeignKey{ + { + Symbol: "word_suffixes_users_word_suffix", + Columns: []*schema.Column{WordSuffixesColumns[4]}, + RefColumns: []*schema.Column{UsersColumns[0]}, + OnDelete: schema.NoAction, + }, + { + Symbol: "word_suffixes_guilds_guild", + Columns: []*schema.Column{WordSuffixesColumns[5]}, + RefColumns: []*schema.Column{GuildsColumns[0]}, + OnDelete: schema.SetNull, + }, + }, + } + // Tables holds all the tables in the schema. + Tables = []*schema.Table{ + GuildsTable, + MembersTable, + MessagePinsTable, + MessageRemindsTable, + RolePanelsTable, + RolePanelEditsTable, + RolePanelPlacedsTable, + UsersTable, + WordSuffixesTable, + } +) + +func init() { + GuildsTable.ForeignKeys[0].RefTable = UsersTable + MembersTable.ForeignKeys[0].RefTable = GuildsTable + MembersTable.ForeignKeys[1].RefTable = UsersTable + MessagePinsTable.ForeignKeys[0].RefTable = GuildsTable + MessageRemindsTable.ForeignKeys[0].RefTable = GuildsTable + RolePanelsTable.ForeignKeys[0].RefTable = GuildsTable + RolePanelEditsTable.ForeignKeys[0].RefTable = GuildsTable + RolePanelEditsTable.ForeignKeys[1].RefTable = RolePanelsTable + RolePanelPlacedsTable.ForeignKeys[0].RefTable = GuildsTable + RolePanelPlacedsTable.ForeignKeys[1].RefTable = RolePanelsTable + WordSuffixesTable.ForeignKeys[0].RefTable = UsersTable + WordSuffixesTable.ForeignKeys[1].RefTable = GuildsTable +} diff --git a/ent/mutation.go b/ent/mutation.go new file mode 100644 index 00000000..421928ec --- /dev/null +++ b/ent/mutation.go @@ -0,0 +1,9412 @@ +// Code generated by ent, DO NOT EDIT. + +package ent + +import ( + "context" + "errors" + "fmt" + "sync" + "time" + + "entgo.io/ent" + "entgo.io/ent/dialect/sql" + "github.com/disgoorg/disgo/discord" + snowflake "github.com/disgoorg/snowflake/v2" + "github.com/google/uuid" + "github.com/sabafly/gobot/ent/guild" + "github.com/sabafly/gobot/ent/member" + "github.com/sabafly/gobot/ent/messagepin" + "github.com/sabafly/gobot/ent/messageremind" + "github.com/sabafly/gobot/ent/predicate" + "github.com/sabafly/gobot/ent/rolepanel" + "github.com/sabafly/gobot/ent/rolepaneledit" + "github.com/sabafly/gobot/ent/rolepanelplaced" + "github.com/sabafly/gobot/ent/schema" + "github.com/sabafly/gobot/ent/user" + "github.com/sabafly/gobot/ent/wordsuffix" + "github.com/sabafly/gobot/internal/permissions" + "github.com/sabafly/gobot/internal/xppoint" +) + +const ( + // Operation types. + OpCreate = ent.OpCreate + OpDelete = ent.OpDelete + OpDeleteOne = ent.OpDeleteOne + OpUpdate = ent.OpUpdate + OpUpdateOne = ent.OpUpdateOne + + // Node types. + TypeGuild = "Guild" + TypeMember = "Member" + TypeMessagePin = "MessagePin" + TypeMessageRemind = "MessageRemind" + TypeRolePanel = "RolePanel" + TypeRolePanelEdit = "RolePanelEdit" + TypeRolePanelPlaced = "RolePanelPlaced" + TypeUser = "User" + TypeWordSuffix = "WordSuffix" +) + +// GuildMutation represents an operation that mutates the Guild nodes in the graph. +type GuildMutation struct { + config + op Op + typ string + id *snowflake.ID + name *string + locale *discord.Locale + level_up_message *string + level_up_channel *snowflake.ID + addlevel_up_channel *snowflake.ID + level_up_exclude_channel *[]snowflake.ID + appendlevel_up_exclude_channel []snowflake.ID + level_mee6_imported *bool + level_role *map[int]snowflake.ID + permissions *map[snowflake.ID]permissions.Permission + remind_count *int + addremind_count *int + role_panel_edit_times *[]time.Time + appendrole_panel_edit_times []time.Time + bump_enabled *bool + bump_message_title *string + bump_message *string + bump_remind_message_title *string + bump_remind_message *string + up_enabled *bool + up_message_title *string + up_message *string + up_remind_message_title *string + up_remind_message *string + bump_mention *snowflake.ID + addbump_mention *snowflake.ID + up_mention *snowflake.ID + addup_mention *snowflake.ID + clearedFields map[string]struct{} + owner *snowflake.ID + clearedowner bool + members map[int]struct{} + removedmembers map[int]struct{} + clearedmembers bool + message_pins map[uuid.UUID]struct{} + removedmessage_pins map[uuid.UUID]struct{} + clearedmessage_pins bool + reminds map[uuid.UUID]struct{} + removedreminds map[uuid.UUID]struct{} + clearedreminds bool + role_panels map[uuid.UUID]struct{} + removedrole_panels map[uuid.UUID]struct{} + clearedrole_panels bool + role_panel_placements map[uuid.UUID]struct{} + removedrole_panel_placements map[uuid.UUID]struct{} + clearedrole_panel_placements bool + role_panel_edits map[uuid.UUID]struct{} + removedrole_panel_edits map[uuid.UUID]struct{} + clearedrole_panel_edits bool + done bool + oldValue func(context.Context) (*Guild, error) + predicates []predicate.Guild +} + +var _ ent.Mutation = (*GuildMutation)(nil) + +// guildOption allows management of the mutation configuration using functional options. +type guildOption func(*GuildMutation) + +// newGuildMutation creates new mutation for the Guild entity. +func newGuildMutation(c config, op Op, opts ...guildOption) *GuildMutation { + m := &GuildMutation{ + config: c, + op: op, + typ: TypeGuild, + clearedFields: make(map[string]struct{}), + } + for _, opt := range opts { + opt(m) + } + return m +} + +// withGuildID sets the ID field of the mutation. +func withGuildID(id snowflake.ID) guildOption { + return func(m *GuildMutation) { + var ( + err error + once sync.Once + value *Guild + ) + m.oldValue = func(ctx context.Context) (*Guild, error) { + once.Do(func() { + if m.done { + err = errors.New("querying old values post mutation is not allowed") + } else { + value, err = m.Client().Guild.Get(ctx, id) + } + }) + return value, err + } + m.id = &id + } +} + +// withGuild sets the old Guild of the mutation. +func withGuild(node *Guild) guildOption { + return func(m *GuildMutation) { + m.oldValue = func(context.Context) (*Guild, error) { + return node, nil + } + m.id = &node.ID + } +} + +// Client returns a new `ent.Client` from the mutation. If the mutation was +// executed in a transaction (ent.Tx), a transactional client is returned. +func (m GuildMutation) Client() *Client { + client := &Client{config: m.config} + client.init() + return client +} + +// Tx returns an `ent.Tx` for mutations that were executed in transactions; +// it returns an error otherwise. +func (m GuildMutation) Tx() (*Tx, error) { + if _, ok := m.driver.(*txDriver); !ok { + return nil, errors.New("ent: mutation is not running in a transaction") + } + tx := &Tx{config: m.config} + tx.init() + return tx, nil +} + +// SetID sets the value of the id field. Note that this +// operation is only accepted on creation of Guild entities. +func (m *GuildMutation) SetID(id snowflake.ID) { + m.id = &id +} + +// ID returns the ID value in the mutation. Note that the ID is only available +// if it was provided to the builder or after it was returned from the database. +func (m *GuildMutation) ID() (id snowflake.ID, exists bool) { + if m.id == nil { + return + } + return *m.id, true +} + +// IDs queries the database and returns the entity ids that match the mutation's predicate. +// That means, if the mutation is applied within a transaction with an isolation level such +// as sql.LevelSerializable, the returned ids match the ids of the rows that will be updated +// or updated by the mutation. +func (m *GuildMutation) IDs(ctx context.Context) ([]snowflake.ID, error) { + switch { + case m.op.Is(OpUpdateOne | OpDeleteOne): + id, exists := m.ID() + if exists { + return []snowflake.ID{id}, nil + } + fallthrough + case m.op.Is(OpUpdate | OpDelete): + return m.Client().Guild.Query().Where(m.predicates...).IDs(ctx) + default: + return nil, fmt.Errorf("IDs is not allowed on %s operations", m.op) + } +} + +// SetName sets the "name" field. +func (m *GuildMutation) SetName(s string) { + m.name = &s +} + +// Name returns the value of the "name" field in the mutation. +func (m *GuildMutation) Name() (r string, exists bool) { + v := m.name + if v == nil { + return + } + return *v, true +} + +// OldName returns the old "name" field's value of the Guild entity. +// If the Guild object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *GuildMutation) OldName(ctx context.Context) (v string, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldName is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldName requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldName: %w", err) + } + return oldValue.Name, nil +} + +// ResetName resets all changes to the "name" field. +func (m *GuildMutation) ResetName() { + m.name = nil +} + +// SetLocale sets the "locale" field. +func (m *GuildMutation) SetLocale(d discord.Locale) { + m.locale = &d +} + +// Locale returns the value of the "locale" field in the mutation. +func (m *GuildMutation) Locale() (r discord.Locale, exists bool) { + v := m.locale + if v == nil { + return + } + return *v, true +} + +// OldLocale returns the old "locale" field's value of the Guild entity. +// If the Guild object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *GuildMutation) OldLocale(ctx context.Context) (v discord.Locale, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldLocale is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldLocale requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldLocale: %w", err) + } + return oldValue.Locale, nil +} + +// ResetLocale resets all changes to the "locale" field. +func (m *GuildMutation) ResetLocale() { + m.locale = nil +} + +// SetLevelUpMessage sets the "level_up_message" field. +func (m *GuildMutation) SetLevelUpMessage(s string) { + m.level_up_message = &s +} + +// LevelUpMessage returns the value of the "level_up_message" field in the mutation. +func (m *GuildMutation) LevelUpMessage() (r string, exists bool) { + v := m.level_up_message + if v == nil { + return + } + return *v, true +} + +// OldLevelUpMessage returns the old "level_up_message" field's value of the Guild entity. +// If the Guild object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *GuildMutation) OldLevelUpMessage(ctx context.Context) (v string, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldLevelUpMessage is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldLevelUpMessage requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldLevelUpMessage: %w", err) + } + return oldValue.LevelUpMessage, nil +} + +// ResetLevelUpMessage resets all changes to the "level_up_message" field. +func (m *GuildMutation) ResetLevelUpMessage() { + m.level_up_message = nil +} + +// SetLevelUpChannel sets the "level_up_channel" field. +func (m *GuildMutation) SetLevelUpChannel(s snowflake.ID) { + m.level_up_channel = &s + m.addlevel_up_channel = nil +} + +// LevelUpChannel returns the value of the "level_up_channel" field in the mutation. +func (m *GuildMutation) LevelUpChannel() (r snowflake.ID, exists bool) { + v := m.level_up_channel + if v == nil { + return + } + return *v, true +} + +// OldLevelUpChannel returns the old "level_up_channel" field's value of the Guild entity. +// If the Guild object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *GuildMutation) OldLevelUpChannel(ctx context.Context) (v *snowflake.ID, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldLevelUpChannel is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldLevelUpChannel requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldLevelUpChannel: %w", err) + } + return oldValue.LevelUpChannel, nil +} + +// AddLevelUpChannel adds s to the "level_up_channel" field. +func (m *GuildMutation) AddLevelUpChannel(s snowflake.ID) { + if m.addlevel_up_channel != nil { + *m.addlevel_up_channel += s + } else { + m.addlevel_up_channel = &s + } +} + +// AddedLevelUpChannel returns the value that was added to the "level_up_channel" field in this mutation. +func (m *GuildMutation) AddedLevelUpChannel() (r snowflake.ID, exists bool) { + v := m.addlevel_up_channel + if v == nil { + return + } + return *v, true +} + +// ClearLevelUpChannel clears the value of the "level_up_channel" field. +func (m *GuildMutation) ClearLevelUpChannel() { + m.level_up_channel = nil + m.addlevel_up_channel = nil + m.clearedFields[guild.FieldLevelUpChannel] = struct{}{} +} + +// LevelUpChannelCleared returns if the "level_up_channel" field was cleared in this mutation. +func (m *GuildMutation) LevelUpChannelCleared() bool { + _, ok := m.clearedFields[guild.FieldLevelUpChannel] + return ok +} + +// ResetLevelUpChannel resets all changes to the "level_up_channel" field. +func (m *GuildMutation) ResetLevelUpChannel() { + m.level_up_channel = nil + m.addlevel_up_channel = nil + delete(m.clearedFields, guild.FieldLevelUpChannel) +} + +// SetLevelUpExcludeChannel sets the "level_up_exclude_channel" field. +func (m *GuildMutation) SetLevelUpExcludeChannel(s []snowflake.ID) { + m.level_up_exclude_channel = &s + m.appendlevel_up_exclude_channel = nil +} + +// LevelUpExcludeChannel returns the value of the "level_up_exclude_channel" field in the mutation. +func (m *GuildMutation) LevelUpExcludeChannel() (r []snowflake.ID, exists bool) { + v := m.level_up_exclude_channel + if v == nil { + return + } + return *v, true +} + +// OldLevelUpExcludeChannel returns the old "level_up_exclude_channel" field's value of the Guild entity. +// If the Guild object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *GuildMutation) OldLevelUpExcludeChannel(ctx context.Context) (v []snowflake.ID, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldLevelUpExcludeChannel is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldLevelUpExcludeChannel requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldLevelUpExcludeChannel: %w", err) + } + return oldValue.LevelUpExcludeChannel, nil +} + +// AppendLevelUpExcludeChannel adds s to the "level_up_exclude_channel" field. +func (m *GuildMutation) AppendLevelUpExcludeChannel(s []snowflake.ID) { + m.appendlevel_up_exclude_channel = append(m.appendlevel_up_exclude_channel, s...) +} + +// AppendedLevelUpExcludeChannel returns the list of values that were appended to the "level_up_exclude_channel" field in this mutation. +func (m *GuildMutation) AppendedLevelUpExcludeChannel() ([]snowflake.ID, bool) { + if len(m.appendlevel_up_exclude_channel) == 0 { + return nil, false + } + return m.appendlevel_up_exclude_channel, true +} + +// ClearLevelUpExcludeChannel clears the value of the "level_up_exclude_channel" field. +func (m *GuildMutation) ClearLevelUpExcludeChannel() { + m.level_up_exclude_channel = nil + m.appendlevel_up_exclude_channel = nil + m.clearedFields[guild.FieldLevelUpExcludeChannel] = struct{}{} +} + +// LevelUpExcludeChannelCleared returns if the "level_up_exclude_channel" field was cleared in this mutation. +func (m *GuildMutation) LevelUpExcludeChannelCleared() bool { + _, ok := m.clearedFields[guild.FieldLevelUpExcludeChannel] + return ok +} + +// ResetLevelUpExcludeChannel resets all changes to the "level_up_exclude_channel" field. +func (m *GuildMutation) ResetLevelUpExcludeChannel() { + m.level_up_exclude_channel = nil + m.appendlevel_up_exclude_channel = nil + delete(m.clearedFields, guild.FieldLevelUpExcludeChannel) +} + +// SetLevelMee6Imported sets the "level_mee6_imported" field. +func (m *GuildMutation) SetLevelMee6Imported(b bool) { + m.level_mee6_imported = &b +} + +// LevelMee6Imported returns the value of the "level_mee6_imported" field in the mutation. +func (m *GuildMutation) LevelMee6Imported() (r bool, exists bool) { + v := m.level_mee6_imported + if v == nil { + return + } + return *v, true +} + +// OldLevelMee6Imported returns the old "level_mee6_imported" field's value of the Guild entity. +// If the Guild object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *GuildMutation) OldLevelMee6Imported(ctx context.Context) (v bool, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldLevelMee6Imported is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldLevelMee6Imported requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldLevelMee6Imported: %w", err) + } + return oldValue.LevelMee6Imported, nil +} + +// ResetLevelMee6Imported resets all changes to the "level_mee6_imported" field. +func (m *GuildMutation) ResetLevelMee6Imported() { + m.level_mee6_imported = nil +} + +// SetLevelRole sets the "level_role" field. +func (m *GuildMutation) SetLevelRole(value map[int]snowflake.ID) { + m.level_role = &value +} + +// LevelRole returns the value of the "level_role" field in the mutation. +func (m *GuildMutation) LevelRole() (r map[int]snowflake.ID, exists bool) { + v := m.level_role + if v == nil { + return + } + return *v, true +} + +// OldLevelRole returns the old "level_role" field's value of the Guild entity. +// If the Guild object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *GuildMutation) OldLevelRole(ctx context.Context) (v map[int]snowflake.ID, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldLevelRole is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldLevelRole requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldLevelRole: %w", err) + } + return oldValue.LevelRole, nil +} + +// ClearLevelRole clears the value of the "level_role" field. +func (m *GuildMutation) ClearLevelRole() { + m.level_role = nil + m.clearedFields[guild.FieldLevelRole] = struct{}{} +} + +// LevelRoleCleared returns if the "level_role" field was cleared in this mutation. +func (m *GuildMutation) LevelRoleCleared() bool { + _, ok := m.clearedFields[guild.FieldLevelRole] + return ok +} + +// ResetLevelRole resets all changes to the "level_role" field. +func (m *GuildMutation) ResetLevelRole() { + m.level_role = nil + delete(m.clearedFields, guild.FieldLevelRole) +} + +// SetPermissions sets the "permissions" field. +func (m *GuildMutation) SetPermissions(value map[snowflake.ID]permissions.Permission) { + m.permissions = &value +} + +// Permissions returns the value of the "permissions" field in the mutation. +func (m *GuildMutation) Permissions() (r map[snowflake.ID]permissions.Permission, exists bool) { + v := m.permissions + if v == nil { + return + } + return *v, true +} + +// OldPermissions returns the old "permissions" field's value of the Guild entity. +// If the Guild object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *GuildMutation) OldPermissions(ctx context.Context) (v map[snowflake.ID]permissions.Permission, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldPermissions is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldPermissions requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldPermissions: %w", err) + } + return oldValue.Permissions, nil +} + +// ResetPermissions resets all changes to the "permissions" field. +func (m *GuildMutation) ResetPermissions() { + m.permissions = nil +} + +// SetRemindCount sets the "remind_count" field. +func (m *GuildMutation) SetRemindCount(i int) { + m.remind_count = &i + m.addremind_count = nil +} + +// RemindCount returns the value of the "remind_count" field in the mutation. +func (m *GuildMutation) RemindCount() (r int, exists bool) { + v := m.remind_count + if v == nil { + return + } + return *v, true +} + +// OldRemindCount returns the old "remind_count" field's value of the Guild entity. +// If the Guild object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *GuildMutation) OldRemindCount(ctx context.Context) (v int, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldRemindCount is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldRemindCount requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldRemindCount: %w", err) + } + return oldValue.RemindCount, nil +} + +// AddRemindCount adds i to the "remind_count" field. +func (m *GuildMutation) AddRemindCount(i int) { + if m.addremind_count != nil { + *m.addremind_count += i + } else { + m.addremind_count = &i + } +} + +// AddedRemindCount returns the value that was added to the "remind_count" field in this mutation. +func (m *GuildMutation) AddedRemindCount() (r int, exists bool) { + v := m.addremind_count + if v == nil { + return + } + return *v, true +} + +// ResetRemindCount resets all changes to the "remind_count" field. +func (m *GuildMutation) ResetRemindCount() { + m.remind_count = nil + m.addremind_count = nil +} + +// SetRolePanelEditTimes sets the "role_panel_edit_times" field. +func (m *GuildMutation) SetRolePanelEditTimes(t []time.Time) { + m.role_panel_edit_times = &t + m.appendrole_panel_edit_times = nil +} + +// RolePanelEditTimes returns the value of the "role_panel_edit_times" field in the mutation. +func (m *GuildMutation) RolePanelEditTimes() (r []time.Time, exists bool) { + v := m.role_panel_edit_times + if v == nil { + return + } + return *v, true +} + +// OldRolePanelEditTimes returns the old "role_panel_edit_times" field's value of the Guild entity. +// If the Guild object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *GuildMutation) OldRolePanelEditTimes(ctx context.Context) (v []time.Time, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldRolePanelEditTimes is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldRolePanelEditTimes requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldRolePanelEditTimes: %w", err) + } + return oldValue.RolePanelEditTimes, nil +} + +// AppendRolePanelEditTimes adds t to the "role_panel_edit_times" field. +func (m *GuildMutation) AppendRolePanelEditTimes(t []time.Time) { + m.appendrole_panel_edit_times = append(m.appendrole_panel_edit_times, t...) +} + +// AppendedRolePanelEditTimes returns the list of values that were appended to the "role_panel_edit_times" field in this mutation. +func (m *GuildMutation) AppendedRolePanelEditTimes() ([]time.Time, bool) { + if len(m.appendrole_panel_edit_times) == 0 { + return nil, false + } + return m.appendrole_panel_edit_times, true +} + +// ResetRolePanelEditTimes resets all changes to the "role_panel_edit_times" field. +func (m *GuildMutation) ResetRolePanelEditTimes() { + m.role_panel_edit_times = nil + m.appendrole_panel_edit_times = nil +} + +// SetBumpEnabled sets the "bump_enabled" field. +func (m *GuildMutation) SetBumpEnabled(b bool) { + m.bump_enabled = &b +} + +// BumpEnabled returns the value of the "bump_enabled" field in the mutation. +func (m *GuildMutation) BumpEnabled() (r bool, exists bool) { + v := m.bump_enabled + if v == nil { + return + } + return *v, true +} + +// OldBumpEnabled returns the old "bump_enabled" field's value of the Guild entity. +// If the Guild object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *GuildMutation) OldBumpEnabled(ctx context.Context) (v bool, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldBumpEnabled is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldBumpEnabled requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldBumpEnabled: %w", err) + } + return oldValue.BumpEnabled, nil +} + +// ResetBumpEnabled resets all changes to the "bump_enabled" field. +func (m *GuildMutation) ResetBumpEnabled() { + m.bump_enabled = nil +} + +// SetBumpMessageTitle sets the "bump_message_title" field. +func (m *GuildMutation) SetBumpMessageTitle(s string) { + m.bump_message_title = &s +} + +// BumpMessageTitle returns the value of the "bump_message_title" field in the mutation. +func (m *GuildMutation) BumpMessageTitle() (r string, exists bool) { + v := m.bump_message_title + if v == nil { + return + } + return *v, true +} + +// OldBumpMessageTitle returns the old "bump_message_title" field's value of the Guild entity. +// If the Guild object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *GuildMutation) OldBumpMessageTitle(ctx context.Context) (v string, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldBumpMessageTitle is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldBumpMessageTitle requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldBumpMessageTitle: %w", err) + } + return oldValue.BumpMessageTitle, nil +} + +// ResetBumpMessageTitle resets all changes to the "bump_message_title" field. +func (m *GuildMutation) ResetBumpMessageTitle() { + m.bump_message_title = nil +} + +// SetBumpMessage sets the "bump_message" field. +func (m *GuildMutation) SetBumpMessage(s string) { + m.bump_message = &s +} + +// BumpMessage returns the value of the "bump_message" field in the mutation. +func (m *GuildMutation) BumpMessage() (r string, exists bool) { + v := m.bump_message + if v == nil { + return + } + return *v, true +} + +// OldBumpMessage returns the old "bump_message" field's value of the Guild entity. +// If the Guild object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *GuildMutation) OldBumpMessage(ctx context.Context) (v string, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldBumpMessage is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldBumpMessage requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldBumpMessage: %w", err) + } + return oldValue.BumpMessage, nil +} + +// ResetBumpMessage resets all changes to the "bump_message" field. +func (m *GuildMutation) ResetBumpMessage() { + m.bump_message = nil +} + +// SetBumpRemindMessageTitle sets the "bump_remind_message_title" field. +func (m *GuildMutation) SetBumpRemindMessageTitle(s string) { + m.bump_remind_message_title = &s +} + +// BumpRemindMessageTitle returns the value of the "bump_remind_message_title" field in the mutation. +func (m *GuildMutation) BumpRemindMessageTitle() (r string, exists bool) { + v := m.bump_remind_message_title + if v == nil { + return + } + return *v, true +} + +// OldBumpRemindMessageTitle returns the old "bump_remind_message_title" field's value of the Guild entity. +// If the Guild object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *GuildMutation) OldBumpRemindMessageTitle(ctx context.Context) (v string, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldBumpRemindMessageTitle is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldBumpRemindMessageTitle requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldBumpRemindMessageTitle: %w", err) + } + return oldValue.BumpRemindMessageTitle, nil +} + +// ResetBumpRemindMessageTitle resets all changes to the "bump_remind_message_title" field. +func (m *GuildMutation) ResetBumpRemindMessageTitle() { + m.bump_remind_message_title = nil +} + +// SetBumpRemindMessage sets the "bump_remind_message" field. +func (m *GuildMutation) SetBumpRemindMessage(s string) { + m.bump_remind_message = &s +} + +// BumpRemindMessage returns the value of the "bump_remind_message" field in the mutation. +func (m *GuildMutation) BumpRemindMessage() (r string, exists bool) { + v := m.bump_remind_message + if v == nil { + return + } + return *v, true +} + +// OldBumpRemindMessage returns the old "bump_remind_message" field's value of the Guild entity. +// If the Guild object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *GuildMutation) OldBumpRemindMessage(ctx context.Context) (v string, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldBumpRemindMessage is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldBumpRemindMessage requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldBumpRemindMessage: %w", err) + } + return oldValue.BumpRemindMessage, nil +} + +// ResetBumpRemindMessage resets all changes to the "bump_remind_message" field. +func (m *GuildMutation) ResetBumpRemindMessage() { + m.bump_remind_message = nil +} + +// SetUpEnabled sets the "up_enabled" field. +func (m *GuildMutation) SetUpEnabled(b bool) { + m.up_enabled = &b +} + +// UpEnabled returns the value of the "up_enabled" field in the mutation. +func (m *GuildMutation) UpEnabled() (r bool, exists bool) { + v := m.up_enabled + if v == nil { + return + } + return *v, true +} + +// OldUpEnabled returns the old "up_enabled" field's value of the Guild entity. +// If the Guild object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *GuildMutation) OldUpEnabled(ctx context.Context) (v bool, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldUpEnabled is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldUpEnabled requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldUpEnabled: %w", err) + } + return oldValue.UpEnabled, nil +} + +// ResetUpEnabled resets all changes to the "up_enabled" field. +func (m *GuildMutation) ResetUpEnabled() { + m.up_enabled = nil +} + +// SetUpMessageTitle sets the "up_message_title" field. +func (m *GuildMutation) SetUpMessageTitle(s string) { + m.up_message_title = &s +} + +// UpMessageTitle returns the value of the "up_message_title" field in the mutation. +func (m *GuildMutation) UpMessageTitle() (r string, exists bool) { + v := m.up_message_title + if v == nil { + return + } + return *v, true +} + +// OldUpMessageTitle returns the old "up_message_title" field's value of the Guild entity. +// If the Guild object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *GuildMutation) OldUpMessageTitle(ctx context.Context) (v string, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldUpMessageTitle is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldUpMessageTitle requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldUpMessageTitle: %w", err) + } + return oldValue.UpMessageTitle, nil +} + +// ResetUpMessageTitle resets all changes to the "up_message_title" field. +func (m *GuildMutation) ResetUpMessageTitle() { + m.up_message_title = nil +} + +// SetUpMessage sets the "up_message" field. +func (m *GuildMutation) SetUpMessage(s string) { + m.up_message = &s +} + +// UpMessage returns the value of the "up_message" field in the mutation. +func (m *GuildMutation) UpMessage() (r string, exists bool) { + v := m.up_message + if v == nil { + return + } + return *v, true +} + +// OldUpMessage returns the old "up_message" field's value of the Guild entity. +// If the Guild object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *GuildMutation) OldUpMessage(ctx context.Context) (v string, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldUpMessage is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldUpMessage requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldUpMessage: %w", err) + } + return oldValue.UpMessage, nil +} + +// ResetUpMessage resets all changes to the "up_message" field. +func (m *GuildMutation) ResetUpMessage() { + m.up_message = nil +} + +// SetUpRemindMessageTitle sets the "up_remind_message_title" field. +func (m *GuildMutation) SetUpRemindMessageTitle(s string) { + m.up_remind_message_title = &s +} + +// UpRemindMessageTitle returns the value of the "up_remind_message_title" field in the mutation. +func (m *GuildMutation) UpRemindMessageTitle() (r string, exists bool) { + v := m.up_remind_message_title + if v == nil { + return + } + return *v, true +} + +// OldUpRemindMessageTitle returns the old "up_remind_message_title" field's value of the Guild entity. +// If the Guild object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *GuildMutation) OldUpRemindMessageTitle(ctx context.Context) (v string, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldUpRemindMessageTitle is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldUpRemindMessageTitle requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldUpRemindMessageTitle: %w", err) + } + return oldValue.UpRemindMessageTitle, nil +} + +// ResetUpRemindMessageTitle resets all changes to the "up_remind_message_title" field. +func (m *GuildMutation) ResetUpRemindMessageTitle() { + m.up_remind_message_title = nil +} + +// SetUpRemindMessage sets the "up_remind_message" field. +func (m *GuildMutation) SetUpRemindMessage(s string) { + m.up_remind_message = &s +} + +// UpRemindMessage returns the value of the "up_remind_message" field in the mutation. +func (m *GuildMutation) UpRemindMessage() (r string, exists bool) { + v := m.up_remind_message + if v == nil { + return + } + return *v, true +} + +// OldUpRemindMessage returns the old "up_remind_message" field's value of the Guild entity. +// If the Guild object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *GuildMutation) OldUpRemindMessage(ctx context.Context) (v string, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldUpRemindMessage is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldUpRemindMessage requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldUpRemindMessage: %w", err) + } + return oldValue.UpRemindMessage, nil +} + +// ResetUpRemindMessage resets all changes to the "up_remind_message" field. +func (m *GuildMutation) ResetUpRemindMessage() { + m.up_remind_message = nil +} + +// SetBumpMention sets the "bump_mention" field. +func (m *GuildMutation) SetBumpMention(s snowflake.ID) { + m.bump_mention = &s + m.addbump_mention = nil +} + +// BumpMention returns the value of the "bump_mention" field in the mutation. +func (m *GuildMutation) BumpMention() (r snowflake.ID, exists bool) { + v := m.bump_mention + if v == nil { + return + } + return *v, true +} + +// OldBumpMention returns the old "bump_mention" field's value of the Guild entity. +// If the Guild object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *GuildMutation) OldBumpMention(ctx context.Context) (v *snowflake.ID, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldBumpMention is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldBumpMention requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldBumpMention: %w", err) + } + return oldValue.BumpMention, nil +} + +// AddBumpMention adds s to the "bump_mention" field. +func (m *GuildMutation) AddBumpMention(s snowflake.ID) { + if m.addbump_mention != nil { + *m.addbump_mention += s + } else { + m.addbump_mention = &s + } +} + +// AddedBumpMention returns the value that was added to the "bump_mention" field in this mutation. +func (m *GuildMutation) AddedBumpMention() (r snowflake.ID, exists bool) { + v := m.addbump_mention + if v == nil { + return + } + return *v, true +} + +// ClearBumpMention clears the value of the "bump_mention" field. +func (m *GuildMutation) ClearBumpMention() { + m.bump_mention = nil + m.addbump_mention = nil + m.clearedFields[guild.FieldBumpMention] = struct{}{} +} + +// BumpMentionCleared returns if the "bump_mention" field was cleared in this mutation. +func (m *GuildMutation) BumpMentionCleared() bool { + _, ok := m.clearedFields[guild.FieldBumpMention] + return ok +} + +// ResetBumpMention resets all changes to the "bump_mention" field. +func (m *GuildMutation) ResetBumpMention() { + m.bump_mention = nil + m.addbump_mention = nil + delete(m.clearedFields, guild.FieldBumpMention) +} + +// SetUpMention sets the "up_mention" field. +func (m *GuildMutation) SetUpMention(s snowflake.ID) { + m.up_mention = &s + m.addup_mention = nil +} + +// UpMention returns the value of the "up_mention" field in the mutation. +func (m *GuildMutation) UpMention() (r snowflake.ID, exists bool) { + v := m.up_mention + if v == nil { + return + } + return *v, true +} + +// OldUpMention returns the old "up_mention" field's value of the Guild entity. +// If the Guild object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *GuildMutation) OldUpMention(ctx context.Context) (v *snowflake.ID, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldUpMention is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldUpMention requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldUpMention: %w", err) + } + return oldValue.UpMention, nil +} + +// AddUpMention adds s to the "up_mention" field. +func (m *GuildMutation) AddUpMention(s snowflake.ID) { + if m.addup_mention != nil { + *m.addup_mention += s + } else { + m.addup_mention = &s + } +} + +// AddedUpMention returns the value that was added to the "up_mention" field in this mutation. +func (m *GuildMutation) AddedUpMention() (r snowflake.ID, exists bool) { + v := m.addup_mention + if v == nil { + return + } + return *v, true +} + +// ClearUpMention clears the value of the "up_mention" field. +func (m *GuildMutation) ClearUpMention() { + m.up_mention = nil + m.addup_mention = nil + m.clearedFields[guild.FieldUpMention] = struct{}{} +} + +// UpMentionCleared returns if the "up_mention" field was cleared in this mutation. +func (m *GuildMutation) UpMentionCleared() bool { + _, ok := m.clearedFields[guild.FieldUpMention] + return ok +} + +// ResetUpMention resets all changes to the "up_mention" field. +func (m *GuildMutation) ResetUpMention() { + m.up_mention = nil + m.addup_mention = nil + delete(m.clearedFields, guild.FieldUpMention) +} + +// SetOwnerID sets the "owner" edge to the User entity by id. +func (m *GuildMutation) SetOwnerID(id snowflake.ID) { + m.owner = &id +} + +// ClearOwner clears the "owner" edge to the User entity. +func (m *GuildMutation) ClearOwner() { + m.clearedowner = true +} + +// OwnerCleared reports if the "owner" edge to the User entity was cleared. +func (m *GuildMutation) OwnerCleared() bool { + return m.clearedowner +} + +// OwnerID returns the "owner" edge ID in the mutation. +func (m *GuildMutation) OwnerID() (id snowflake.ID, exists bool) { + if m.owner != nil { + return *m.owner, true + } + return +} + +// OwnerIDs returns the "owner" edge IDs in the mutation. +// Note that IDs always returns len(IDs) <= 1 for unique edges, and you should use +// OwnerID instead. It exists only for internal usage by the builders. +func (m *GuildMutation) OwnerIDs() (ids []snowflake.ID) { + if id := m.owner; id != nil { + ids = append(ids, *id) + } + return +} + +// ResetOwner resets all changes to the "owner" edge. +func (m *GuildMutation) ResetOwner() { + m.owner = nil + m.clearedowner = false +} + +// AddMemberIDs adds the "members" edge to the Member entity by ids. +func (m *GuildMutation) AddMemberIDs(ids ...int) { + if m.members == nil { + m.members = make(map[int]struct{}) + } + for i := range ids { + m.members[ids[i]] = struct{}{} + } +} + +// ClearMembers clears the "members" edge to the Member entity. +func (m *GuildMutation) ClearMembers() { + m.clearedmembers = true +} + +// MembersCleared reports if the "members" edge to the Member entity was cleared. +func (m *GuildMutation) MembersCleared() bool { + return m.clearedmembers +} + +// RemoveMemberIDs removes the "members" edge to the Member entity by IDs. +func (m *GuildMutation) RemoveMemberIDs(ids ...int) { + if m.removedmembers == nil { + m.removedmembers = make(map[int]struct{}) + } + for i := range ids { + delete(m.members, ids[i]) + m.removedmembers[ids[i]] = struct{}{} + } +} + +// RemovedMembers returns the removed IDs of the "members" edge to the Member entity. +func (m *GuildMutation) RemovedMembersIDs() (ids []int) { + for id := range m.removedmembers { + ids = append(ids, id) + } + return +} + +// MembersIDs returns the "members" edge IDs in the mutation. +func (m *GuildMutation) MembersIDs() (ids []int) { + for id := range m.members { + ids = append(ids, id) + } + return +} + +// ResetMembers resets all changes to the "members" edge. +func (m *GuildMutation) ResetMembers() { + m.members = nil + m.clearedmembers = false + m.removedmembers = nil +} + +// AddMessagePinIDs adds the "message_pins" edge to the MessagePin entity by ids. +func (m *GuildMutation) AddMessagePinIDs(ids ...uuid.UUID) { + if m.message_pins == nil { + m.message_pins = make(map[uuid.UUID]struct{}) + } + for i := range ids { + m.message_pins[ids[i]] = struct{}{} + } +} + +// ClearMessagePins clears the "message_pins" edge to the MessagePin entity. +func (m *GuildMutation) ClearMessagePins() { + m.clearedmessage_pins = true +} + +// MessagePinsCleared reports if the "message_pins" edge to the MessagePin entity was cleared. +func (m *GuildMutation) MessagePinsCleared() bool { + return m.clearedmessage_pins +} + +// RemoveMessagePinIDs removes the "message_pins" edge to the MessagePin entity by IDs. +func (m *GuildMutation) RemoveMessagePinIDs(ids ...uuid.UUID) { + if m.removedmessage_pins == nil { + m.removedmessage_pins = make(map[uuid.UUID]struct{}) + } + for i := range ids { + delete(m.message_pins, ids[i]) + m.removedmessage_pins[ids[i]] = struct{}{} + } +} + +// RemovedMessagePins returns the removed IDs of the "message_pins" edge to the MessagePin entity. +func (m *GuildMutation) RemovedMessagePinsIDs() (ids []uuid.UUID) { + for id := range m.removedmessage_pins { + ids = append(ids, id) + } + return +} + +// MessagePinsIDs returns the "message_pins" edge IDs in the mutation. +func (m *GuildMutation) MessagePinsIDs() (ids []uuid.UUID) { + for id := range m.message_pins { + ids = append(ids, id) + } + return +} + +// ResetMessagePins resets all changes to the "message_pins" edge. +func (m *GuildMutation) ResetMessagePins() { + m.message_pins = nil + m.clearedmessage_pins = false + m.removedmessage_pins = nil +} + +// AddRemindIDs adds the "reminds" edge to the MessageRemind entity by ids. +func (m *GuildMutation) AddRemindIDs(ids ...uuid.UUID) { + if m.reminds == nil { + m.reminds = make(map[uuid.UUID]struct{}) + } + for i := range ids { + m.reminds[ids[i]] = struct{}{} + } +} + +// ClearReminds clears the "reminds" edge to the MessageRemind entity. +func (m *GuildMutation) ClearReminds() { + m.clearedreminds = true +} + +// RemindsCleared reports if the "reminds" edge to the MessageRemind entity was cleared. +func (m *GuildMutation) RemindsCleared() bool { + return m.clearedreminds +} + +// RemoveRemindIDs removes the "reminds" edge to the MessageRemind entity by IDs. +func (m *GuildMutation) RemoveRemindIDs(ids ...uuid.UUID) { + if m.removedreminds == nil { + m.removedreminds = make(map[uuid.UUID]struct{}) + } + for i := range ids { + delete(m.reminds, ids[i]) + m.removedreminds[ids[i]] = struct{}{} + } +} + +// RemovedReminds returns the removed IDs of the "reminds" edge to the MessageRemind entity. +func (m *GuildMutation) RemovedRemindsIDs() (ids []uuid.UUID) { + for id := range m.removedreminds { + ids = append(ids, id) + } + return +} + +// RemindsIDs returns the "reminds" edge IDs in the mutation. +func (m *GuildMutation) RemindsIDs() (ids []uuid.UUID) { + for id := range m.reminds { + ids = append(ids, id) + } + return +} + +// ResetReminds resets all changes to the "reminds" edge. +func (m *GuildMutation) ResetReminds() { + m.reminds = nil + m.clearedreminds = false + m.removedreminds = nil +} + +// AddRolePanelIDs adds the "role_panels" edge to the RolePanel entity by ids. +func (m *GuildMutation) AddRolePanelIDs(ids ...uuid.UUID) { + if m.role_panels == nil { + m.role_panels = make(map[uuid.UUID]struct{}) + } + for i := range ids { + m.role_panels[ids[i]] = struct{}{} + } +} + +// ClearRolePanels clears the "role_panels" edge to the RolePanel entity. +func (m *GuildMutation) ClearRolePanels() { + m.clearedrole_panels = true +} + +// RolePanelsCleared reports if the "role_panels" edge to the RolePanel entity was cleared. +func (m *GuildMutation) RolePanelsCleared() bool { + return m.clearedrole_panels +} + +// RemoveRolePanelIDs removes the "role_panels" edge to the RolePanel entity by IDs. +func (m *GuildMutation) RemoveRolePanelIDs(ids ...uuid.UUID) { + if m.removedrole_panels == nil { + m.removedrole_panels = make(map[uuid.UUID]struct{}) + } + for i := range ids { + delete(m.role_panels, ids[i]) + m.removedrole_panels[ids[i]] = struct{}{} + } +} + +// RemovedRolePanels returns the removed IDs of the "role_panels" edge to the RolePanel entity. +func (m *GuildMutation) RemovedRolePanelsIDs() (ids []uuid.UUID) { + for id := range m.removedrole_panels { + ids = append(ids, id) + } + return +} + +// RolePanelsIDs returns the "role_panels" edge IDs in the mutation. +func (m *GuildMutation) RolePanelsIDs() (ids []uuid.UUID) { + for id := range m.role_panels { + ids = append(ids, id) + } + return +} + +// ResetRolePanels resets all changes to the "role_panels" edge. +func (m *GuildMutation) ResetRolePanels() { + m.role_panels = nil + m.clearedrole_panels = false + m.removedrole_panels = nil +} + +// AddRolePanelPlacementIDs adds the "role_panel_placements" edge to the RolePanelPlaced entity by ids. +func (m *GuildMutation) AddRolePanelPlacementIDs(ids ...uuid.UUID) { + if m.role_panel_placements == nil { + m.role_panel_placements = make(map[uuid.UUID]struct{}) + } + for i := range ids { + m.role_panel_placements[ids[i]] = struct{}{} + } +} + +// ClearRolePanelPlacements clears the "role_panel_placements" edge to the RolePanelPlaced entity. +func (m *GuildMutation) ClearRolePanelPlacements() { + m.clearedrole_panel_placements = true +} + +// RolePanelPlacementsCleared reports if the "role_panel_placements" edge to the RolePanelPlaced entity was cleared. +func (m *GuildMutation) RolePanelPlacementsCleared() bool { + return m.clearedrole_panel_placements +} + +// RemoveRolePanelPlacementIDs removes the "role_panel_placements" edge to the RolePanelPlaced entity by IDs. +func (m *GuildMutation) RemoveRolePanelPlacementIDs(ids ...uuid.UUID) { + if m.removedrole_panel_placements == nil { + m.removedrole_panel_placements = make(map[uuid.UUID]struct{}) + } + for i := range ids { + delete(m.role_panel_placements, ids[i]) + m.removedrole_panel_placements[ids[i]] = struct{}{} + } +} + +// RemovedRolePanelPlacements returns the removed IDs of the "role_panel_placements" edge to the RolePanelPlaced entity. +func (m *GuildMutation) RemovedRolePanelPlacementsIDs() (ids []uuid.UUID) { + for id := range m.removedrole_panel_placements { + ids = append(ids, id) + } + return +} + +// RolePanelPlacementsIDs returns the "role_panel_placements" edge IDs in the mutation. +func (m *GuildMutation) RolePanelPlacementsIDs() (ids []uuid.UUID) { + for id := range m.role_panel_placements { + ids = append(ids, id) + } + return +} + +// ResetRolePanelPlacements resets all changes to the "role_panel_placements" edge. +func (m *GuildMutation) ResetRolePanelPlacements() { + m.role_panel_placements = nil + m.clearedrole_panel_placements = false + m.removedrole_panel_placements = nil +} + +// AddRolePanelEditIDs adds the "role_panel_edits" edge to the RolePanelEdit entity by ids. +func (m *GuildMutation) AddRolePanelEditIDs(ids ...uuid.UUID) { + if m.role_panel_edits == nil { + m.role_panel_edits = make(map[uuid.UUID]struct{}) + } + for i := range ids { + m.role_panel_edits[ids[i]] = struct{}{} + } +} + +// ClearRolePanelEdits clears the "role_panel_edits" edge to the RolePanelEdit entity. +func (m *GuildMutation) ClearRolePanelEdits() { + m.clearedrole_panel_edits = true +} + +// RolePanelEditsCleared reports if the "role_panel_edits" edge to the RolePanelEdit entity was cleared. +func (m *GuildMutation) RolePanelEditsCleared() bool { + return m.clearedrole_panel_edits +} + +// RemoveRolePanelEditIDs removes the "role_panel_edits" edge to the RolePanelEdit entity by IDs. +func (m *GuildMutation) RemoveRolePanelEditIDs(ids ...uuid.UUID) { + if m.removedrole_panel_edits == nil { + m.removedrole_panel_edits = make(map[uuid.UUID]struct{}) + } + for i := range ids { + delete(m.role_panel_edits, ids[i]) + m.removedrole_panel_edits[ids[i]] = struct{}{} + } +} + +// RemovedRolePanelEdits returns the removed IDs of the "role_panel_edits" edge to the RolePanelEdit entity. +func (m *GuildMutation) RemovedRolePanelEditsIDs() (ids []uuid.UUID) { + for id := range m.removedrole_panel_edits { + ids = append(ids, id) + } + return +} + +// RolePanelEditsIDs returns the "role_panel_edits" edge IDs in the mutation. +func (m *GuildMutation) RolePanelEditsIDs() (ids []uuid.UUID) { + for id := range m.role_panel_edits { + ids = append(ids, id) + } + return +} + +// ResetRolePanelEdits resets all changes to the "role_panel_edits" edge. +func (m *GuildMutation) ResetRolePanelEdits() { + m.role_panel_edits = nil + m.clearedrole_panel_edits = false + m.removedrole_panel_edits = nil +} + +// Where appends a list predicates to the GuildMutation builder. +func (m *GuildMutation) Where(ps ...predicate.Guild) { + m.predicates = append(m.predicates, ps...) +} + +// WhereP appends storage-level predicates to the GuildMutation builder. Using this method, +// users can use type-assertion to append predicates that do not depend on any generated package. +func (m *GuildMutation) WhereP(ps ...func(*sql.Selector)) { + p := make([]predicate.Guild, len(ps)) + for i := range ps { + p[i] = ps[i] + } + m.Where(p...) +} + +// Op returns the operation name. +func (m *GuildMutation) Op() Op { + return m.op +} + +// SetOp allows setting the mutation operation. +func (m *GuildMutation) SetOp(op Op) { + m.op = op +} + +// Type returns the node type of this mutation (Guild). +func (m *GuildMutation) Type() string { + return m.typ +} + +// Fields returns all fields that were changed during this mutation. Note that in +// order to get all numeric fields that were incremented/decremented, call +// AddedFields(). +func (m *GuildMutation) Fields() []string { + fields := make([]string, 0, 22) + if m.name != nil { + fields = append(fields, guild.FieldName) + } + if m.locale != nil { + fields = append(fields, guild.FieldLocale) + } + if m.level_up_message != nil { + fields = append(fields, guild.FieldLevelUpMessage) + } + if m.level_up_channel != nil { + fields = append(fields, guild.FieldLevelUpChannel) + } + if m.level_up_exclude_channel != nil { + fields = append(fields, guild.FieldLevelUpExcludeChannel) + } + if m.level_mee6_imported != nil { + fields = append(fields, guild.FieldLevelMee6Imported) + } + if m.level_role != nil { + fields = append(fields, guild.FieldLevelRole) + } + if m.permissions != nil { + fields = append(fields, guild.FieldPermissions) + } + if m.remind_count != nil { + fields = append(fields, guild.FieldRemindCount) + } + if m.role_panel_edit_times != nil { + fields = append(fields, guild.FieldRolePanelEditTimes) + } + if m.bump_enabled != nil { + fields = append(fields, guild.FieldBumpEnabled) + } + if m.bump_message_title != nil { + fields = append(fields, guild.FieldBumpMessageTitle) + } + if m.bump_message != nil { + fields = append(fields, guild.FieldBumpMessage) + } + if m.bump_remind_message_title != nil { + fields = append(fields, guild.FieldBumpRemindMessageTitle) + } + if m.bump_remind_message != nil { + fields = append(fields, guild.FieldBumpRemindMessage) + } + if m.up_enabled != nil { + fields = append(fields, guild.FieldUpEnabled) + } + if m.up_message_title != nil { + fields = append(fields, guild.FieldUpMessageTitle) + } + if m.up_message != nil { + fields = append(fields, guild.FieldUpMessage) + } + if m.up_remind_message_title != nil { + fields = append(fields, guild.FieldUpRemindMessageTitle) + } + if m.up_remind_message != nil { + fields = append(fields, guild.FieldUpRemindMessage) + } + if m.bump_mention != nil { + fields = append(fields, guild.FieldBumpMention) + } + if m.up_mention != nil { + fields = append(fields, guild.FieldUpMention) + } + return fields +} + +// Field returns the value of a field with the given name. The second boolean +// return value indicates that this field was not set, or was not defined in the +// schema. +func (m *GuildMutation) Field(name string) (ent.Value, bool) { + switch name { + case guild.FieldName: + return m.Name() + case guild.FieldLocale: + return m.Locale() + case guild.FieldLevelUpMessage: + return m.LevelUpMessage() + case guild.FieldLevelUpChannel: + return m.LevelUpChannel() + case guild.FieldLevelUpExcludeChannel: + return m.LevelUpExcludeChannel() + case guild.FieldLevelMee6Imported: + return m.LevelMee6Imported() + case guild.FieldLevelRole: + return m.LevelRole() + case guild.FieldPermissions: + return m.Permissions() + case guild.FieldRemindCount: + return m.RemindCount() + case guild.FieldRolePanelEditTimes: + return m.RolePanelEditTimes() + case guild.FieldBumpEnabled: + return m.BumpEnabled() + case guild.FieldBumpMessageTitle: + return m.BumpMessageTitle() + case guild.FieldBumpMessage: + return m.BumpMessage() + case guild.FieldBumpRemindMessageTitle: + return m.BumpRemindMessageTitle() + case guild.FieldBumpRemindMessage: + return m.BumpRemindMessage() + case guild.FieldUpEnabled: + return m.UpEnabled() + case guild.FieldUpMessageTitle: + return m.UpMessageTitle() + case guild.FieldUpMessage: + return m.UpMessage() + case guild.FieldUpRemindMessageTitle: + return m.UpRemindMessageTitle() + case guild.FieldUpRemindMessage: + return m.UpRemindMessage() + case guild.FieldBumpMention: + return m.BumpMention() + case guild.FieldUpMention: + return m.UpMention() + } + return nil, false +} + +// OldField returns the old value of the field from the database. An error is +// returned if the mutation operation is not UpdateOne, or the query to the +// database failed. +func (m *GuildMutation) OldField(ctx context.Context, name string) (ent.Value, error) { + switch name { + case guild.FieldName: + return m.OldName(ctx) + case guild.FieldLocale: + return m.OldLocale(ctx) + case guild.FieldLevelUpMessage: + return m.OldLevelUpMessage(ctx) + case guild.FieldLevelUpChannel: + return m.OldLevelUpChannel(ctx) + case guild.FieldLevelUpExcludeChannel: + return m.OldLevelUpExcludeChannel(ctx) + case guild.FieldLevelMee6Imported: + return m.OldLevelMee6Imported(ctx) + case guild.FieldLevelRole: + return m.OldLevelRole(ctx) + case guild.FieldPermissions: + return m.OldPermissions(ctx) + case guild.FieldRemindCount: + return m.OldRemindCount(ctx) + case guild.FieldRolePanelEditTimes: + return m.OldRolePanelEditTimes(ctx) + case guild.FieldBumpEnabled: + return m.OldBumpEnabled(ctx) + case guild.FieldBumpMessageTitle: + return m.OldBumpMessageTitle(ctx) + case guild.FieldBumpMessage: + return m.OldBumpMessage(ctx) + case guild.FieldBumpRemindMessageTitle: + return m.OldBumpRemindMessageTitle(ctx) + case guild.FieldBumpRemindMessage: + return m.OldBumpRemindMessage(ctx) + case guild.FieldUpEnabled: + return m.OldUpEnabled(ctx) + case guild.FieldUpMessageTitle: + return m.OldUpMessageTitle(ctx) + case guild.FieldUpMessage: + return m.OldUpMessage(ctx) + case guild.FieldUpRemindMessageTitle: + return m.OldUpRemindMessageTitle(ctx) + case guild.FieldUpRemindMessage: + return m.OldUpRemindMessage(ctx) + case guild.FieldBumpMention: + return m.OldBumpMention(ctx) + case guild.FieldUpMention: + return m.OldUpMention(ctx) + } + return nil, fmt.Errorf("unknown Guild field %s", name) +} + +// SetField sets the value of a field with the given name. It returns an error if +// the field is not defined in the schema, or if the type mismatched the field +// type. +func (m *GuildMutation) SetField(name string, value ent.Value) error { + switch name { + case guild.FieldName: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetName(v) + return nil + case guild.FieldLocale: + v, ok := value.(discord.Locale) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetLocale(v) + return nil + case guild.FieldLevelUpMessage: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetLevelUpMessage(v) + return nil + case guild.FieldLevelUpChannel: + v, ok := value.(snowflake.ID) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetLevelUpChannel(v) + return nil + case guild.FieldLevelUpExcludeChannel: + v, ok := value.([]snowflake.ID) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetLevelUpExcludeChannel(v) + return nil + case guild.FieldLevelMee6Imported: + v, ok := value.(bool) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetLevelMee6Imported(v) + return nil + case guild.FieldLevelRole: + v, ok := value.(map[int]snowflake.ID) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetLevelRole(v) + return nil + case guild.FieldPermissions: + v, ok := value.(map[snowflake.ID]permissions.Permission) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetPermissions(v) + return nil + case guild.FieldRemindCount: + v, ok := value.(int) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetRemindCount(v) + return nil + case guild.FieldRolePanelEditTimes: + v, ok := value.([]time.Time) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetRolePanelEditTimes(v) + return nil + case guild.FieldBumpEnabled: + v, ok := value.(bool) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetBumpEnabled(v) + return nil + case guild.FieldBumpMessageTitle: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetBumpMessageTitle(v) + return nil + case guild.FieldBumpMessage: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetBumpMessage(v) + return nil + case guild.FieldBumpRemindMessageTitle: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetBumpRemindMessageTitle(v) + return nil + case guild.FieldBumpRemindMessage: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetBumpRemindMessage(v) + return nil + case guild.FieldUpEnabled: + v, ok := value.(bool) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetUpEnabled(v) + return nil + case guild.FieldUpMessageTitle: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetUpMessageTitle(v) + return nil + case guild.FieldUpMessage: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetUpMessage(v) + return nil + case guild.FieldUpRemindMessageTitle: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetUpRemindMessageTitle(v) + return nil + case guild.FieldUpRemindMessage: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetUpRemindMessage(v) + return nil + case guild.FieldBumpMention: + v, ok := value.(snowflake.ID) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetBumpMention(v) + return nil + case guild.FieldUpMention: + v, ok := value.(snowflake.ID) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetUpMention(v) + return nil + } + return fmt.Errorf("unknown Guild field %s", name) +} + +// AddedFields returns all numeric fields that were incremented/decremented during +// this mutation. +func (m *GuildMutation) AddedFields() []string { + var fields []string + if m.addlevel_up_channel != nil { + fields = append(fields, guild.FieldLevelUpChannel) + } + if m.addremind_count != nil { + fields = append(fields, guild.FieldRemindCount) + } + if m.addbump_mention != nil { + fields = append(fields, guild.FieldBumpMention) + } + if m.addup_mention != nil { + fields = append(fields, guild.FieldUpMention) + } + return fields +} + +// AddedField returns the numeric value that was incremented/decremented on a field +// with the given name. The second boolean return value indicates that this field +// was not set, or was not defined in the schema. +func (m *GuildMutation) AddedField(name string) (ent.Value, bool) { + switch name { + case guild.FieldLevelUpChannel: + return m.AddedLevelUpChannel() + case guild.FieldRemindCount: + return m.AddedRemindCount() + case guild.FieldBumpMention: + return m.AddedBumpMention() + case guild.FieldUpMention: + return m.AddedUpMention() + } + return nil, false +} + +// AddField adds the value to the field with the given name. It returns an error if +// the field is not defined in the schema, or if the type mismatched the field +// type. +func (m *GuildMutation) AddField(name string, value ent.Value) error { + switch name { + case guild.FieldLevelUpChannel: + v, ok := value.(snowflake.ID) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.AddLevelUpChannel(v) + return nil + case guild.FieldRemindCount: + v, ok := value.(int) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.AddRemindCount(v) + return nil + case guild.FieldBumpMention: + v, ok := value.(snowflake.ID) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.AddBumpMention(v) + return nil + case guild.FieldUpMention: + v, ok := value.(snowflake.ID) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.AddUpMention(v) + return nil + } + return fmt.Errorf("unknown Guild numeric field %s", name) +} + +// ClearedFields returns all nullable fields that were cleared during this +// mutation. +func (m *GuildMutation) ClearedFields() []string { + var fields []string + if m.FieldCleared(guild.FieldLevelUpChannel) { + fields = append(fields, guild.FieldLevelUpChannel) + } + if m.FieldCleared(guild.FieldLevelUpExcludeChannel) { + fields = append(fields, guild.FieldLevelUpExcludeChannel) + } + if m.FieldCleared(guild.FieldLevelRole) { + fields = append(fields, guild.FieldLevelRole) + } + if m.FieldCleared(guild.FieldBumpMention) { + fields = append(fields, guild.FieldBumpMention) + } + if m.FieldCleared(guild.FieldUpMention) { + fields = append(fields, guild.FieldUpMention) + } + return fields +} + +// FieldCleared returns a boolean indicating if a field with the given name was +// cleared in this mutation. +func (m *GuildMutation) FieldCleared(name string) bool { + _, ok := m.clearedFields[name] + return ok +} + +// ClearField clears the value of the field with the given name. It returns an +// error if the field is not defined in the schema. +func (m *GuildMutation) ClearField(name string) error { + switch name { + case guild.FieldLevelUpChannel: + m.ClearLevelUpChannel() + return nil + case guild.FieldLevelUpExcludeChannel: + m.ClearLevelUpExcludeChannel() + return nil + case guild.FieldLevelRole: + m.ClearLevelRole() + return nil + case guild.FieldBumpMention: + m.ClearBumpMention() + return nil + case guild.FieldUpMention: + m.ClearUpMention() + return nil + } + return fmt.Errorf("unknown Guild nullable field %s", name) +} + +// ResetField resets all changes in the mutation for the field with the given name. +// It returns an error if the field is not defined in the schema. +func (m *GuildMutation) ResetField(name string) error { + switch name { + case guild.FieldName: + m.ResetName() + return nil + case guild.FieldLocale: + m.ResetLocale() + return nil + case guild.FieldLevelUpMessage: + m.ResetLevelUpMessage() + return nil + case guild.FieldLevelUpChannel: + m.ResetLevelUpChannel() + return nil + case guild.FieldLevelUpExcludeChannel: + m.ResetLevelUpExcludeChannel() + return nil + case guild.FieldLevelMee6Imported: + m.ResetLevelMee6Imported() + return nil + case guild.FieldLevelRole: + m.ResetLevelRole() + return nil + case guild.FieldPermissions: + m.ResetPermissions() + return nil + case guild.FieldRemindCount: + m.ResetRemindCount() + return nil + case guild.FieldRolePanelEditTimes: + m.ResetRolePanelEditTimes() + return nil + case guild.FieldBumpEnabled: + m.ResetBumpEnabled() + return nil + case guild.FieldBumpMessageTitle: + m.ResetBumpMessageTitle() + return nil + case guild.FieldBumpMessage: + m.ResetBumpMessage() + return nil + case guild.FieldBumpRemindMessageTitle: + m.ResetBumpRemindMessageTitle() + return nil + case guild.FieldBumpRemindMessage: + m.ResetBumpRemindMessage() + return nil + case guild.FieldUpEnabled: + m.ResetUpEnabled() + return nil + case guild.FieldUpMessageTitle: + m.ResetUpMessageTitle() + return nil + case guild.FieldUpMessage: + m.ResetUpMessage() + return nil + case guild.FieldUpRemindMessageTitle: + m.ResetUpRemindMessageTitle() + return nil + case guild.FieldUpRemindMessage: + m.ResetUpRemindMessage() + return nil + case guild.FieldBumpMention: + m.ResetBumpMention() + return nil + case guild.FieldUpMention: + m.ResetUpMention() + return nil + } + return fmt.Errorf("unknown Guild field %s", name) +} + +// AddedEdges returns all edge names that were set/added in this mutation. +func (m *GuildMutation) AddedEdges() []string { + edges := make([]string, 0, 7) + if m.owner != nil { + edges = append(edges, guild.EdgeOwner) + } + if m.members != nil { + edges = append(edges, guild.EdgeMembers) + } + if m.message_pins != nil { + edges = append(edges, guild.EdgeMessagePins) + } + if m.reminds != nil { + edges = append(edges, guild.EdgeReminds) + } + if m.role_panels != nil { + edges = append(edges, guild.EdgeRolePanels) + } + if m.role_panel_placements != nil { + edges = append(edges, guild.EdgeRolePanelPlacements) + } + if m.role_panel_edits != nil { + edges = append(edges, guild.EdgeRolePanelEdits) + } + return edges +} + +// AddedIDs returns all IDs (to other nodes) that were added for the given edge +// name in this mutation. +func (m *GuildMutation) AddedIDs(name string) []ent.Value { + switch name { + case guild.EdgeOwner: + if id := m.owner; id != nil { + return []ent.Value{*id} + } + case guild.EdgeMembers: + ids := make([]ent.Value, 0, len(m.members)) + for id := range m.members { + ids = append(ids, id) + } + return ids + case guild.EdgeMessagePins: + ids := make([]ent.Value, 0, len(m.message_pins)) + for id := range m.message_pins { + ids = append(ids, id) + } + return ids + case guild.EdgeReminds: + ids := make([]ent.Value, 0, len(m.reminds)) + for id := range m.reminds { + ids = append(ids, id) + } + return ids + case guild.EdgeRolePanels: + ids := make([]ent.Value, 0, len(m.role_panels)) + for id := range m.role_panels { + ids = append(ids, id) + } + return ids + case guild.EdgeRolePanelPlacements: + ids := make([]ent.Value, 0, len(m.role_panel_placements)) + for id := range m.role_panel_placements { + ids = append(ids, id) + } + return ids + case guild.EdgeRolePanelEdits: + ids := make([]ent.Value, 0, len(m.role_panel_edits)) + for id := range m.role_panel_edits { + ids = append(ids, id) + } + return ids + } + return nil +} + +// RemovedEdges returns all edge names that were removed in this mutation. +func (m *GuildMutation) RemovedEdges() []string { + edges := make([]string, 0, 7) + if m.removedmembers != nil { + edges = append(edges, guild.EdgeMembers) + } + if m.removedmessage_pins != nil { + edges = append(edges, guild.EdgeMessagePins) + } + if m.removedreminds != nil { + edges = append(edges, guild.EdgeReminds) + } + if m.removedrole_panels != nil { + edges = append(edges, guild.EdgeRolePanels) + } + if m.removedrole_panel_placements != nil { + edges = append(edges, guild.EdgeRolePanelPlacements) + } + if m.removedrole_panel_edits != nil { + edges = append(edges, guild.EdgeRolePanelEdits) + } + return edges +} + +// RemovedIDs returns all IDs (to other nodes) that were removed for the edge with +// the given name in this mutation. +func (m *GuildMutation) RemovedIDs(name string) []ent.Value { + switch name { + case guild.EdgeMembers: + ids := make([]ent.Value, 0, len(m.removedmembers)) + for id := range m.removedmembers { + ids = append(ids, id) + } + return ids + case guild.EdgeMessagePins: + ids := make([]ent.Value, 0, len(m.removedmessage_pins)) + for id := range m.removedmessage_pins { + ids = append(ids, id) + } + return ids + case guild.EdgeReminds: + ids := make([]ent.Value, 0, len(m.removedreminds)) + for id := range m.removedreminds { + ids = append(ids, id) + } + return ids + case guild.EdgeRolePanels: + ids := make([]ent.Value, 0, len(m.removedrole_panels)) + for id := range m.removedrole_panels { + ids = append(ids, id) + } + return ids + case guild.EdgeRolePanelPlacements: + ids := make([]ent.Value, 0, len(m.removedrole_panel_placements)) + for id := range m.removedrole_panel_placements { + ids = append(ids, id) + } + return ids + case guild.EdgeRolePanelEdits: + ids := make([]ent.Value, 0, len(m.removedrole_panel_edits)) + for id := range m.removedrole_panel_edits { + ids = append(ids, id) + } + return ids + } + return nil +} + +// ClearedEdges returns all edge names that were cleared in this mutation. +func (m *GuildMutation) ClearedEdges() []string { + edges := make([]string, 0, 7) + if m.clearedowner { + edges = append(edges, guild.EdgeOwner) + } + if m.clearedmembers { + edges = append(edges, guild.EdgeMembers) + } + if m.clearedmessage_pins { + edges = append(edges, guild.EdgeMessagePins) + } + if m.clearedreminds { + edges = append(edges, guild.EdgeReminds) + } + if m.clearedrole_panels { + edges = append(edges, guild.EdgeRolePanels) + } + if m.clearedrole_panel_placements { + edges = append(edges, guild.EdgeRolePanelPlacements) + } + if m.clearedrole_panel_edits { + edges = append(edges, guild.EdgeRolePanelEdits) + } + return edges +} + +// EdgeCleared returns a boolean which indicates if the edge with the given name +// was cleared in this mutation. +func (m *GuildMutation) EdgeCleared(name string) bool { + switch name { + case guild.EdgeOwner: + return m.clearedowner + case guild.EdgeMembers: + return m.clearedmembers + case guild.EdgeMessagePins: + return m.clearedmessage_pins + case guild.EdgeReminds: + return m.clearedreminds + case guild.EdgeRolePanels: + return m.clearedrole_panels + case guild.EdgeRolePanelPlacements: + return m.clearedrole_panel_placements + case guild.EdgeRolePanelEdits: + return m.clearedrole_panel_edits + } + return false +} + +// ClearEdge clears the value of the edge with the given name. It returns an error +// if that edge is not defined in the schema. +func (m *GuildMutation) ClearEdge(name string) error { + switch name { + case guild.EdgeOwner: + m.ClearOwner() + return nil + } + return fmt.Errorf("unknown Guild unique edge %s", name) +} + +// ResetEdge resets all changes to the edge with the given name in this mutation. +// It returns an error if the edge is not defined in the schema. +func (m *GuildMutation) ResetEdge(name string) error { + switch name { + case guild.EdgeOwner: + m.ResetOwner() + return nil + case guild.EdgeMembers: + m.ResetMembers() + return nil + case guild.EdgeMessagePins: + m.ResetMessagePins() + return nil + case guild.EdgeReminds: + m.ResetReminds() + return nil + case guild.EdgeRolePanels: + m.ResetRolePanels() + return nil + case guild.EdgeRolePanelPlacements: + m.ResetRolePanelPlacements() + return nil + case guild.EdgeRolePanelEdits: + m.ResetRolePanelEdits() + return nil + } + return fmt.Errorf("unknown Guild edge %s", name) +} + +// MemberMutation represents an operation that mutates the Member nodes in the graph. +type MemberMutation struct { + config + op Op + typ string + id *int + permission *permissions.Permission + xp *xppoint.XP + addxp *xppoint.XP + last_xp *time.Time + message_count *uint64 + addmessage_count *int64 + last_notified_level *uint64 + addlast_notified_level *int64 + clearedFields map[string]struct{} + guild *snowflake.ID + clearedguild bool + user *snowflake.ID + cleareduser bool + done bool + oldValue func(context.Context) (*Member, error) + predicates []predicate.Member +} + +var _ ent.Mutation = (*MemberMutation)(nil) + +// memberOption allows management of the mutation configuration using functional options. +type memberOption func(*MemberMutation) + +// newMemberMutation creates new mutation for the Member entity. +func newMemberMutation(c config, op Op, opts ...memberOption) *MemberMutation { + m := &MemberMutation{ + config: c, + op: op, + typ: TypeMember, + clearedFields: make(map[string]struct{}), + } + for _, opt := range opts { + opt(m) + } + return m +} + +// withMemberID sets the ID field of the mutation. +func withMemberID(id int) memberOption { + return func(m *MemberMutation) { + var ( + err error + once sync.Once + value *Member + ) + m.oldValue = func(ctx context.Context) (*Member, error) { + once.Do(func() { + if m.done { + err = errors.New("querying old values post mutation is not allowed") + } else { + value, err = m.Client().Member.Get(ctx, id) + } + }) + return value, err + } + m.id = &id + } +} + +// withMember sets the old Member of the mutation. +func withMember(node *Member) memberOption { + return func(m *MemberMutation) { + m.oldValue = func(context.Context) (*Member, error) { + return node, nil + } + m.id = &node.ID + } +} + +// Client returns a new `ent.Client` from the mutation. If the mutation was +// executed in a transaction (ent.Tx), a transactional client is returned. +func (m MemberMutation) Client() *Client { + client := &Client{config: m.config} + client.init() + return client +} + +// Tx returns an `ent.Tx` for mutations that were executed in transactions; +// it returns an error otherwise. +func (m MemberMutation) Tx() (*Tx, error) { + if _, ok := m.driver.(*txDriver); !ok { + return nil, errors.New("ent: mutation is not running in a transaction") + } + tx := &Tx{config: m.config} + tx.init() + return tx, nil +} + +// ID returns the ID value in the mutation. Note that the ID is only available +// if it was provided to the builder or after it was returned from the database. +func (m *MemberMutation) ID() (id int, exists bool) { + if m.id == nil { + return + } + return *m.id, true +} + +// IDs queries the database and returns the entity ids that match the mutation's predicate. +// That means, if the mutation is applied within a transaction with an isolation level such +// as sql.LevelSerializable, the returned ids match the ids of the rows that will be updated +// or updated by the mutation. +func (m *MemberMutation) IDs(ctx context.Context) ([]int, error) { + switch { + case m.op.Is(OpUpdateOne | OpDeleteOne): + id, exists := m.ID() + if exists { + return []int{id}, nil + } + fallthrough + case m.op.Is(OpUpdate | OpDelete): + return m.Client().Member.Query().Where(m.predicates...).IDs(ctx) + default: + return nil, fmt.Errorf("IDs is not allowed on %s operations", m.op) + } +} + +// SetPermission sets the "permission" field. +func (m *MemberMutation) SetPermission(pe permissions.Permission) { + m.permission = &pe +} + +// Permission returns the value of the "permission" field in the mutation. +func (m *MemberMutation) Permission() (r permissions.Permission, exists bool) { + v := m.permission + if v == nil { + return + } + return *v, true +} + +// OldPermission returns the old "permission" field's value of the Member entity. +// If the Member object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *MemberMutation) OldPermission(ctx context.Context) (v permissions.Permission, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldPermission is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldPermission requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldPermission: %w", err) + } + return oldValue.Permission, nil +} + +// ClearPermission clears the value of the "permission" field. +func (m *MemberMutation) ClearPermission() { + m.permission = nil + m.clearedFields[member.FieldPermission] = struct{}{} +} + +// PermissionCleared returns if the "permission" field was cleared in this mutation. +func (m *MemberMutation) PermissionCleared() bool { + _, ok := m.clearedFields[member.FieldPermission] + return ok +} + +// ResetPermission resets all changes to the "permission" field. +func (m *MemberMutation) ResetPermission() { + m.permission = nil + delete(m.clearedFields, member.FieldPermission) +} + +// SetXp sets the "xp" field. +func (m *MemberMutation) SetXp(x xppoint.XP) { + m.xp = &x + m.addxp = nil +} + +// Xp returns the value of the "xp" field in the mutation. +func (m *MemberMutation) Xp() (r xppoint.XP, exists bool) { + v := m.xp + if v == nil { + return + } + return *v, true +} + +// OldXp returns the old "xp" field's value of the Member entity. +// If the Member object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *MemberMutation) OldXp(ctx context.Context) (v xppoint.XP, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldXp is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldXp requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldXp: %w", err) + } + return oldValue.Xp, nil +} + +// AddXp adds x to the "xp" field. +func (m *MemberMutation) AddXp(x xppoint.XP) { + if m.addxp != nil { + *m.addxp += x + } else { + m.addxp = &x + } +} + +// AddedXp returns the value that was added to the "xp" field in this mutation. +func (m *MemberMutation) AddedXp() (r xppoint.XP, exists bool) { + v := m.addxp + if v == nil { + return + } + return *v, true +} + +// ResetXp resets all changes to the "xp" field. +func (m *MemberMutation) ResetXp() { + m.xp = nil + m.addxp = nil +} + +// SetUserID sets the "user_id" field. +func (m *MemberMutation) SetUserID(s snowflake.ID) { + m.user = &s +} + +// UserID returns the value of the "user_id" field in the mutation. +func (m *MemberMutation) UserID() (r snowflake.ID, exists bool) { + v := m.user + if v == nil { + return + } + return *v, true +} + +// OldUserID returns the old "user_id" field's value of the Member entity. +// If the Member object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *MemberMutation) OldUserID(ctx context.Context) (v snowflake.ID, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldUserID is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldUserID requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldUserID: %w", err) + } + return oldValue.UserID, nil +} + +// ResetUserID resets all changes to the "user_id" field. +func (m *MemberMutation) ResetUserID() { + m.user = nil +} + +// SetLastXp sets the "last_xp" field. +func (m *MemberMutation) SetLastXp(t time.Time) { + m.last_xp = &t +} + +// LastXp returns the value of the "last_xp" field in the mutation. +func (m *MemberMutation) LastXp() (r time.Time, exists bool) { + v := m.last_xp + if v == nil { + return + } + return *v, true +} + +// OldLastXp returns the old "last_xp" field's value of the Member entity. +// If the Member object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *MemberMutation) OldLastXp(ctx context.Context) (v time.Time, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldLastXp is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldLastXp requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldLastXp: %w", err) + } + return oldValue.LastXp, nil +} + +// ClearLastXp clears the value of the "last_xp" field. +func (m *MemberMutation) ClearLastXp() { + m.last_xp = nil + m.clearedFields[member.FieldLastXp] = struct{}{} +} + +// LastXpCleared returns if the "last_xp" field was cleared in this mutation. +func (m *MemberMutation) LastXpCleared() bool { + _, ok := m.clearedFields[member.FieldLastXp] + return ok +} + +// ResetLastXp resets all changes to the "last_xp" field. +func (m *MemberMutation) ResetLastXp() { + m.last_xp = nil + delete(m.clearedFields, member.FieldLastXp) +} + +// SetMessageCount sets the "message_count" field. +func (m *MemberMutation) SetMessageCount(u uint64) { + m.message_count = &u + m.addmessage_count = nil +} + +// MessageCount returns the value of the "message_count" field in the mutation. +func (m *MemberMutation) MessageCount() (r uint64, exists bool) { + v := m.message_count + if v == nil { + return + } + return *v, true +} + +// OldMessageCount returns the old "message_count" field's value of the Member entity. +// If the Member object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *MemberMutation) OldMessageCount(ctx context.Context) (v uint64, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldMessageCount is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldMessageCount requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldMessageCount: %w", err) + } + return oldValue.MessageCount, nil +} + +// AddMessageCount adds u to the "message_count" field. +func (m *MemberMutation) AddMessageCount(u int64) { + if m.addmessage_count != nil { + *m.addmessage_count += u + } else { + m.addmessage_count = &u + } +} + +// AddedMessageCount returns the value that was added to the "message_count" field in this mutation. +func (m *MemberMutation) AddedMessageCount() (r int64, exists bool) { + v := m.addmessage_count + if v == nil { + return + } + return *v, true +} + +// ResetMessageCount resets all changes to the "message_count" field. +func (m *MemberMutation) ResetMessageCount() { + m.message_count = nil + m.addmessage_count = nil +} + +// SetLastNotifiedLevel sets the "last_notified_level" field. +func (m *MemberMutation) SetLastNotifiedLevel(u uint64) { + m.last_notified_level = &u + m.addlast_notified_level = nil +} + +// LastNotifiedLevel returns the value of the "last_notified_level" field in the mutation. +func (m *MemberMutation) LastNotifiedLevel() (r uint64, exists bool) { + v := m.last_notified_level + if v == nil { + return + } + return *v, true +} + +// OldLastNotifiedLevel returns the old "last_notified_level" field's value of the Member entity. +// If the Member object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *MemberMutation) OldLastNotifiedLevel(ctx context.Context) (v *uint64, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldLastNotifiedLevel is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldLastNotifiedLevel requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldLastNotifiedLevel: %w", err) + } + return oldValue.LastNotifiedLevel, nil +} + +// AddLastNotifiedLevel adds u to the "last_notified_level" field. +func (m *MemberMutation) AddLastNotifiedLevel(u int64) { + if m.addlast_notified_level != nil { + *m.addlast_notified_level += u + } else { + m.addlast_notified_level = &u + } +} + +// AddedLastNotifiedLevel returns the value that was added to the "last_notified_level" field in this mutation. +func (m *MemberMutation) AddedLastNotifiedLevel() (r int64, exists bool) { + v := m.addlast_notified_level + if v == nil { + return + } + return *v, true +} + +// ClearLastNotifiedLevel clears the value of the "last_notified_level" field. +func (m *MemberMutation) ClearLastNotifiedLevel() { + m.last_notified_level = nil + m.addlast_notified_level = nil + m.clearedFields[member.FieldLastNotifiedLevel] = struct{}{} +} + +// LastNotifiedLevelCleared returns if the "last_notified_level" field was cleared in this mutation. +func (m *MemberMutation) LastNotifiedLevelCleared() bool { + _, ok := m.clearedFields[member.FieldLastNotifiedLevel] + return ok +} + +// ResetLastNotifiedLevel resets all changes to the "last_notified_level" field. +func (m *MemberMutation) ResetLastNotifiedLevel() { + m.last_notified_level = nil + m.addlast_notified_level = nil + delete(m.clearedFields, member.FieldLastNotifiedLevel) +} + +// SetGuildID sets the "guild" edge to the Guild entity by id. +func (m *MemberMutation) SetGuildID(id snowflake.ID) { + m.guild = &id +} + +// ClearGuild clears the "guild" edge to the Guild entity. +func (m *MemberMutation) ClearGuild() { + m.clearedguild = true +} + +// GuildCleared reports if the "guild" edge to the Guild entity was cleared. +func (m *MemberMutation) GuildCleared() bool { + return m.clearedguild +} + +// GuildID returns the "guild" edge ID in the mutation. +func (m *MemberMutation) GuildID() (id snowflake.ID, exists bool) { + if m.guild != nil { + return *m.guild, true + } + return +} + +// GuildIDs returns the "guild" edge IDs in the mutation. +// Note that IDs always returns len(IDs) <= 1 for unique edges, and you should use +// GuildID instead. It exists only for internal usage by the builders. +func (m *MemberMutation) GuildIDs() (ids []snowflake.ID) { + if id := m.guild; id != nil { + ids = append(ids, *id) + } + return +} + +// ResetGuild resets all changes to the "guild" edge. +func (m *MemberMutation) ResetGuild() { + m.guild = nil + m.clearedguild = false +} + +// ClearUser clears the "user" edge to the User entity. +func (m *MemberMutation) ClearUser() { + m.cleareduser = true + m.clearedFields[member.FieldUserID] = struct{}{} +} + +// UserCleared reports if the "user" edge to the User entity was cleared. +func (m *MemberMutation) UserCleared() bool { + return m.cleareduser +} + +// UserIDs returns the "user" edge IDs in the mutation. +// Note that IDs always returns len(IDs) <= 1 for unique edges, and you should use +// UserID instead. It exists only for internal usage by the builders. +func (m *MemberMutation) UserIDs() (ids []snowflake.ID) { + if id := m.user; id != nil { + ids = append(ids, *id) + } + return +} + +// ResetUser resets all changes to the "user" edge. +func (m *MemberMutation) ResetUser() { + m.user = nil + m.cleareduser = false +} + +// Where appends a list predicates to the MemberMutation builder. +func (m *MemberMutation) Where(ps ...predicate.Member) { + m.predicates = append(m.predicates, ps...) +} + +// WhereP appends storage-level predicates to the MemberMutation builder. Using this method, +// users can use type-assertion to append predicates that do not depend on any generated package. +func (m *MemberMutation) WhereP(ps ...func(*sql.Selector)) { + p := make([]predicate.Member, len(ps)) + for i := range ps { + p[i] = ps[i] + } + m.Where(p...) +} + +// Op returns the operation name. +func (m *MemberMutation) Op() Op { + return m.op +} + +// SetOp allows setting the mutation operation. +func (m *MemberMutation) SetOp(op Op) { + m.op = op +} + +// Type returns the node type of this mutation (Member). +func (m *MemberMutation) Type() string { + return m.typ +} + +// Fields returns all fields that were changed during this mutation. Note that in +// order to get all numeric fields that were incremented/decremented, call +// AddedFields(). +func (m *MemberMutation) Fields() []string { + fields := make([]string, 0, 6) + if m.permission != nil { + fields = append(fields, member.FieldPermission) + } + if m.xp != nil { + fields = append(fields, member.FieldXp) + } + if m.user != nil { + fields = append(fields, member.FieldUserID) + } + if m.last_xp != nil { + fields = append(fields, member.FieldLastXp) + } + if m.message_count != nil { + fields = append(fields, member.FieldMessageCount) + } + if m.last_notified_level != nil { + fields = append(fields, member.FieldLastNotifiedLevel) + } + return fields +} + +// Field returns the value of a field with the given name. The second boolean +// return value indicates that this field was not set, or was not defined in the +// schema. +func (m *MemberMutation) Field(name string) (ent.Value, bool) { + switch name { + case member.FieldPermission: + return m.Permission() + case member.FieldXp: + return m.Xp() + case member.FieldUserID: + return m.UserID() + case member.FieldLastXp: + return m.LastXp() + case member.FieldMessageCount: + return m.MessageCount() + case member.FieldLastNotifiedLevel: + return m.LastNotifiedLevel() + } + return nil, false +} + +// OldField returns the old value of the field from the database. An error is +// returned if the mutation operation is not UpdateOne, or the query to the +// database failed. +func (m *MemberMutation) OldField(ctx context.Context, name string) (ent.Value, error) { + switch name { + case member.FieldPermission: + return m.OldPermission(ctx) + case member.FieldXp: + return m.OldXp(ctx) + case member.FieldUserID: + return m.OldUserID(ctx) + case member.FieldLastXp: + return m.OldLastXp(ctx) + case member.FieldMessageCount: + return m.OldMessageCount(ctx) + case member.FieldLastNotifiedLevel: + return m.OldLastNotifiedLevel(ctx) + } + return nil, fmt.Errorf("unknown Member field %s", name) +} + +// SetField sets the value of a field with the given name. It returns an error if +// the field is not defined in the schema, or if the type mismatched the field +// type. +func (m *MemberMutation) SetField(name string, value ent.Value) error { + switch name { + case member.FieldPermission: + v, ok := value.(permissions.Permission) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetPermission(v) + return nil + case member.FieldXp: + v, ok := value.(xppoint.XP) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetXp(v) + return nil + case member.FieldUserID: + v, ok := value.(snowflake.ID) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetUserID(v) + return nil + case member.FieldLastXp: + v, ok := value.(time.Time) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetLastXp(v) + return nil + case member.FieldMessageCount: + v, ok := value.(uint64) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetMessageCount(v) + return nil + case member.FieldLastNotifiedLevel: + v, ok := value.(uint64) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetLastNotifiedLevel(v) + return nil + } + return fmt.Errorf("unknown Member field %s", name) +} + +// AddedFields returns all numeric fields that were incremented/decremented during +// this mutation. +func (m *MemberMutation) AddedFields() []string { + var fields []string + if m.addxp != nil { + fields = append(fields, member.FieldXp) + } + if m.addmessage_count != nil { + fields = append(fields, member.FieldMessageCount) + } + if m.addlast_notified_level != nil { + fields = append(fields, member.FieldLastNotifiedLevel) + } + return fields +} + +// AddedField returns the numeric value that was incremented/decremented on a field +// with the given name. The second boolean return value indicates that this field +// was not set, or was not defined in the schema. +func (m *MemberMutation) AddedField(name string) (ent.Value, bool) { + switch name { + case member.FieldXp: + return m.AddedXp() + case member.FieldMessageCount: + return m.AddedMessageCount() + case member.FieldLastNotifiedLevel: + return m.AddedLastNotifiedLevel() + } + return nil, false +} + +// AddField adds the value to the field with the given name. It returns an error if +// the field is not defined in the schema, or if the type mismatched the field +// type. +func (m *MemberMutation) AddField(name string, value ent.Value) error { + switch name { + case member.FieldXp: + v, ok := value.(xppoint.XP) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.AddXp(v) + return nil + case member.FieldMessageCount: + v, ok := value.(int64) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.AddMessageCount(v) + return nil + case member.FieldLastNotifiedLevel: + v, ok := value.(int64) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.AddLastNotifiedLevel(v) + return nil + } + return fmt.Errorf("unknown Member numeric field %s", name) +} + +// ClearedFields returns all nullable fields that were cleared during this +// mutation. +func (m *MemberMutation) ClearedFields() []string { + var fields []string + if m.FieldCleared(member.FieldPermission) { + fields = append(fields, member.FieldPermission) + } + if m.FieldCleared(member.FieldLastXp) { + fields = append(fields, member.FieldLastXp) + } + if m.FieldCleared(member.FieldLastNotifiedLevel) { + fields = append(fields, member.FieldLastNotifiedLevel) + } + return fields +} + +// FieldCleared returns a boolean indicating if a field with the given name was +// cleared in this mutation. +func (m *MemberMutation) FieldCleared(name string) bool { + _, ok := m.clearedFields[name] + return ok +} + +// ClearField clears the value of the field with the given name. It returns an +// error if the field is not defined in the schema. +func (m *MemberMutation) ClearField(name string) error { + switch name { + case member.FieldPermission: + m.ClearPermission() + return nil + case member.FieldLastXp: + m.ClearLastXp() + return nil + case member.FieldLastNotifiedLevel: + m.ClearLastNotifiedLevel() + return nil + } + return fmt.Errorf("unknown Member nullable field %s", name) +} + +// ResetField resets all changes in the mutation for the field with the given name. +// It returns an error if the field is not defined in the schema. +func (m *MemberMutation) ResetField(name string) error { + switch name { + case member.FieldPermission: + m.ResetPermission() + return nil + case member.FieldXp: + m.ResetXp() + return nil + case member.FieldUserID: + m.ResetUserID() + return nil + case member.FieldLastXp: + m.ResetLastXp() + return nil + case member.FieldMessageCount: + m.ResetMessageCount() + return nil + case member.FieldLastNotifiedLevel: + m.ResetLastNotifiedLevel() + return nil + } + return fmt.Errorf("unknown Member field %s", name) +} + +// AddedEdges returns all edge names that were set/added in this mutation. +func (m *MemberMutation) AddedEdges() []string { + edges := make([]string, 0, 2) + if m.guild != nil { + edges = append(edges, member.EdgeGuild) + } + if m.user != nil { + edges = append(edges, member.EdgeUser) + } + return edges +} + +// AddedIDs returns all IDs (to other nodes) that were added for the given edge +// name in this mutation. +func (m *MemberMutation) AddedIDs(name string) []ent.Value { + switch name { + case member.EdgeGuild: + if id := m.guild; id != nil { + return []ent.Value{*id} + } + case member.EdgeUser: + if id := m.user; id != nil { + return []ent.Value{*id} + } + } + return nil +} + +// RemovedEdges returns all edge names that were removed in this mutation. +func (m *MemberMutation) RemovedEdges() []string { + edges := make([]string, 0, 2) + return edges +} + +// RemovedIDs returns all IDs (to other nodes) that were removed for the edge with +// the given name in this mutation. +func (m *MemberMutation) RemovedIDs(name string) []ent.Value { + return nil +} + +// ClearedEdges returns all edge names that were cleared in this mutation. +func (m *MemberMutation) ClearedEdges() []string { + edges := make([]string, 0, 2) + if m.clearedguild { + edges = append(edges, member.EdgeGuild) + } + if m.cleareduser { + edges = append(edges, member.EdgeUser) + } + return edges +} + +// EdgeCleared returns a boolean which indicates if the edge with the given name +// was cleared in this mutation. +func (m *MemberMutation) EdgeCleared(name string) bool { + switch name { + case member.EdgeGuild: + return m.clearedguild + case member.EdgeUser: + return m.cleareduser + } + return false +} + +// ClearEdge clears the value of the edge with the given name. It returns an error +// if that edge is not defined in the schema. +func (m *MemberMutation) ClearEdge(name string) error { + switch name { + case member.EdgeGuild: + m.ClearGuild() + return nil + case member.EdgeUser: + m.ClearUser() + return nil + } + return fmt.Errorf("unknown Member unique edge %s", name) +} + +// ResetEdge resets all changes to the edge with the given name in this mutation. +// It returns an error if the edge is not defined in the schema. +func (m *MemberMutation) ResetEdge(name string) error { + switch name { + case member.EdgeGuild: + m.ResetGuild() + return nil + case member.EdgeUser: + m.ResetUser() + return nil + } + return fmt.Errorf("unknown Member edge %s", name) +} + +// MessagePinMutation represents an operation that mutates the MessagePin nodes in the graph. +type MessagePinMutation struct { + config + op Op + typ string + id *uuid.UUID + channel_id *snowflake.ID + addchannel_id *snowflake.ID + content *string + embeds *[]discord.Embed + appendembeds []discord.Embed + before_id *snowflake.ID + addbefore_id *snowflake.ID + rate_limit *schema.RateLimit + clearedFields map[string]struct{} + guild *snowflake.ID + clearedguild bool + done bool + oldValue func(context.Context) (*MessagePin, error) + predicates []predicate.MessagePin +} + +var _ ent.Mutation = (*MessagePinMutation)(nil) + +// messagepinOption allows management of the mutation configuration using functional options. +type messagepinOption func(*MessagePinMutation) + +// newMessagePinMutation creates new mutation for the MessagePin entity. +func newMessagePinMutation(c config, op Op, opts ...messagepinOption) *MessagePinMutation { + m := &MessagePinMutation{ + config: c, + op: op, + typ: TypeMessagePin, + clearedFields: make(map[string]struct{}), + } + for _, opt := range opts { + opt(m) + } + return m +} + +// withMessagePinID sets the ID field of the mutation. +func withMessagePinID(id uuid.UUID) messagepinOption { + return func(m *MessagePinMutation) { + var ( + err error + once sync.Once + value *MessagePin + ) + m.oldValue = func(ctx context.Context) (*MessagePin, error) { + once.Do(func() { + if m.done { + err = errors.New("querying old values post mutation is not allowed") + } else { + value, err = m.Client().MessagePin.Get(ctx, id) + } + }) + return value, err + } + m.id = &id + } +} + +// withMessagePin sets the old MessagePin of the mutation. +func withMessagePin(node *MessagePin) messagepinOption { + return func(m *MessagePinMutation) { + m.oldValue = func(context.Context) (*MessagePin, error) { + return node, nil + } + m.id = &node.ID + } +} + +// Client returns a new `ent.Client` from the mutation. If the mutation was +// executed in a transaction (ent.Tx), a transactional client is returned. +func (m MessagePinMutation) Client() *Client { + client := &Client{config: m.config} + client.init() + return client +} + +// Tx returns an `ent.Tx` for mutations that were executed in transactions; +// it returns an error otherwise. +func (m MessagePinMutation) Tx() (*Tx, error) { + if _, ok := m.driver.(*txDriver); !ok { + return nil, errors.New("ent: mutation is not running in a transaction") + } + tx := &Tx{config: m.config} + tx.init() + return tx, nil +} + +// SetID sets the value of the id field. Note that this +// operation is only accepted on creation of MessagePin entities. +func (m *MessagePinMutation) SetID(id uuid.UUID) { + m.id = &id +} + +// ID returns the ID value in the mutation. Note that the ID is only available +// if it was provided to the builder or after it was returned from the database. +func (m *MessagePinMutation) ID() (id uuid.UUID, exists bool) { + if m.id == nil { + return + } + return *m.id, true +} + +// IDs queries the database and returns the entity ids that match the mutation's predicate. +// That means, if the mutation is applied within a transaction with an isolation level such +// as sql.LevelSerializable, the returned ids match the ids of the rows that will be updated +// or updated by the mutation. +func (m *MessagePinMutation) IDs(ctx context.Context) ([]uuid.UUID, error) { + switch { + case m.op.Is(OpUpdateOne | OpDeleteOne): + id, exists := m.ID() + if exists { + return []uuid.UUID{id}, nil + } + fallthrough + case m.op.Is(OpUpdate | OpDelete): + return m.Client().MessagePin.Query().Where(m.predicates...).IDs(ctx) + default: + return nil, fmt.Errorf("IDs is not allowed on %s operations", m.op) + } +} + +// SetChannelID sets the "channel_id" field. +func (m *MessagePinMutation) SetChannelID(s snowflake.ID) { + m.channel_id = &s + m.addchannel_id = nil +} + +// ChannelID returns the value of the "channel_id" field in the mutation. +func (m *MessagePinMutation) ChannelID() (r snowflake.ID, exists bool) { + v := m.channel_id + if v == nil { + return + } + return *v, true +} + +// OldChannelID returns the old "channel_id" field's value of the MessagePin entity. +// If the MessagePin object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *MessagePinMutation) OldChannelID(ctx context.Context) (v snowflake.ID, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldChannelID is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldChannelID requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldChannelID: %w", err) + } + return oldValue.ChannelID, nil +} + +// AddChannelID adds s to the "channel_id" field. +func (m *MessagePinMutation) AddChannelID(s snowflake.ID) { + if m.addchannel_id != nil { + *m.addchannel_id += s + } else { + m.addchannel_id = &s + } +} + +// AddedChannelID returns the value that was added to the "channel_id" field in this mutation. +func (m *MessagePinMutation) AddedChannelID() (r snowflake.ID, exists bool) { + v := m.addchannel_id + if v == nil { + return + } + return *v, true +} + +// ResetChannelID resets all changes to the "channel_id" field. +func (m *MessagePinMutation) ResetChannelID() { + m.channel_id = nil + m.addchannel_id = nil +} + +// SetContent sets the "content" field. +func (m *MessagePinMutation) SetContent(s string) { + m.content = &s +} + +// Content returns the value of the "content" field in the mutation. +func (m *MessagePinMutation) Content() (r string, exists bool) { + v := m.content + if v == nil { + return + } + return *v, true +} + +// OldContent returns the old "content" field's value of the MessagePin entity. +// If the MessagePin object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *MessagePinMutation) OldContent(ctx context.Context) (v string, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldContent is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldContent requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldContent: %w", err) + } + return oldValue.Content, nil +} + +// ClearContent clears the value of the "content" field. +func (m *MessagePinMutation) ClearContent() { + m.content = nil + m.clearedFields[messagepin.FieldContent] = struct{}{} +} + +// ContentCleared returns if the "content" field was cleared in this mutation. +func (m *MessagePinMutation) ContentCleared() bool { + _, ok := m.clearedFields[messagepin.FieldContent] + return ok +} + +// ResetContent resets all changes to the "content" field. +func (m *MessagePinMutation) ResetContent() { + m.content = nil + delete(m.clearedFields, messagepin.FieldContent) +} + +// SetEmbeds sets the "embeds" field. +func (m *MessagePinMutation) SetEmbeds(d []discord.Embed) { + m.embeds = &d + m.appendembeds = nil +} + +// Embeds returns the value of the "embeds" field in the mutation. +func (m *MessagePinMutation) Embeds() (r []discord.Embed, exists bool) { + v := m.embeds + if v == nil { + return + } + return *v, true +} + +// OldEmbeds returns the old "embeds" field's value of the MessagePin entity. +// If the MessagePin object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *MessagePinMutation) OldEmbeds(ctx context.Context) (v []discord.Embed, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldEmbeds is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldEmbeds requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldEmbeds: %w", err) + } + return oldValue.Embeds, nil +} + +// AppendEmbeds adds d to the "embeds" field. +func (m *MessagePinMutation) AppendEmbeds(d []discord.Embed) { + m.appendembeds = append(m.appendembeds, d...) +} + +// AppendedEmbeds returns the list of values that were appended to the "embeds" field in this mutation. +func (m *MessagePinMutation) AppendedEmbeds() ([]discord.Embed, bool) { + if len(m.appendembeds) == 0 { + return nil, false + } + return m.appendembeds, true +} + +// ClearEmbeds clears the value of the "embeds" field. +func (m *MessagePinMutation) ClearEmbeds() { + m.embeds = nil + m.appendembeds = nil + m.clearedFields[messagepin.FieldEmbeds] = struct{}{} +} + +// EmbedsCleared returns if the "embeds" field was cleared in this mutation. +func (m *MessagePinMutation) EmbedsCleared() bool { + _, ok := m.clearedFields[messagepin.FieldEmbeds] + return ok +} + +// ResetEmbeds resets all changes to the "embeds" field. +func (m *MessagePinMutation) ResetEmbeds() { + m.embeds = nil + m.appendembeds = nil + delete(m.clearedFields, messagepin.FieldEmbeds) +} + +// SetBeforeID sets the "before_id" field. +func (m *MessagePinMutation) SetBeforeID(s snowflake.ID) { + m.before_id = &s + m.addbefore_id = nil +} + +// BeforeID returns the value of the "before_id" field in the mutation. +func (m *MessagePinMutation) BeforeID() (r snowflake.ID, exists bool) { + v := m.before_id + if v == nil { + return + } + return *v, true +} + +// OldBeforeID returns the old "before_id" field's value of the MessagePin entity. +// If the MessagePin object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *MessagePinMutation) OldBeforeID(ctx context.Context) (v *snowflake.ID, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldBeforeID is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldBeforeID requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldBeforeID: %w", err) + } + return oldValue.BeforeID, nil +} + +// AddBeforeID adds s to the "before_id" field. +func (m *MessagePinMutation) AddBeforeID(s snowflake.ID) { + if m.addbefore_id != nil { + *m.addbefore_id += s + } else { + m.addbefore_id = &s + } +} + +// AddedBeforeID returns the value that was added to the "before_id" field in this mutation. +func (m *MessagePinMutation) AddedBeforeID() (r snowflake.ID, exists bool) { + v := m.addbefore_id + if v == nil { + return + } + return *v, true +} + +// ClearBeforeID clears the value of the "before_id" field. +func (m *MessagePinMutation) ClearBeforeID() { + m.before_id = nil + m.addbefore_id = nil + m.clearedFields[messagepin.FieldBeforeID] = struct{}{} +} + +// BeforeIDCleared returns if the "before_id" field was cleared in this mutation. +func (m *MessagePinMutation) BeforeIDCleared() bool { + _, ok := m.clearedFields[messagepin.FieldBeforeID] + return ok +} + +// ResetBeforeID resets all changes to the "before_id" field. +func (m *MessagePinMutation) ResetBeforeID() { + m.before_id = nil + m.addbefore_id = nil + delete(m.clearedFields, messagepin.FieldBeforeID) +} + +// SetRateLimit sets the "rate_limit" field. +func (m *MessagePinMutation) SetRateLimit(sl schema.RateLimit) { + m.rate_limit = &sl +} + +// RateLimit returns the value of the "rate_limit" field in the mutation. +func (m *MessagePinMutation) RateLimit() (r schema.RateLimit, exists bool) { + v := m.rate_limit + if v == nil { + return + } + return *v, true +} + +// OldRateLimit returns the old "rate_limit" field's value of the MessagePin entity. +// If the MessagePin object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *MessagePinMutation) OldRateLimit(ctx context.Context) (v schema.RateLimit, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldRateLimit is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldRateLimit requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldRateLimit: %w", err) + } + return oldValue.RateLimit, nil +} + +// ResetRateLimit resets all changes to the "rate_limit" field. +func (m *MessagePinMutation) ResetRateLimit() { + m.rate_limit = nil +} + +// SetGuildID sets the "guild" edge to the Guild entity by id. +func (m *MessagePinMutation) SetGuildID(id snowflake.ID) { + m.guild = &id +} + +// ClearGuild clears the "guild" edge to the Guild entity. +func (m *MessagePinMutation) ClearGuild() { + m.clearedguild = true +} + +// GuildCleared reports if the "guild" edge to the Guild entity was cleared. +func (m *MessagePinMutation) GuildCleared() bool { + return m.clearedguild +} + +// GuildID returns the "guild" edge ID in the mutation. +func (m *MessagePinMutation) GuildID() (id snowflake.ID, exists bool) { + if m.guild != nil { + return *m.guild, true + } + return +} + +// GuildIDs returns the "guild" edge IDs in the mutation. +// Note that IDs always returns len(IDs) <= 1 for unique edges, and you should use +// GuildID instead. It exists only for internal usage by the builders. +func (m *MessagePinMutation) GuildIDs() (ids []snowflake.ID) { + if id := m.guild; id != nil { + ids = append(ids, *id) + } + return +} + +// ResetGuild resets all changes to the "guild" edge. +func (m *MessagePinMutation) ResetGuild() { + m.guild = nil + m.clearedguild = false +} + +// Where appends a list predicates to the MessagePinMutation builder. +func (m *MessagePinMutation) Where(ps ...predicate.MessagePin) { + m.predicates = append(m.predicates, ps...) +} + +// WhereP appends storage-level predicates to the MessagePinMutation builder. Using this method, +// users can use type-assertion to append predicates that do not depend on any generated package. +func (m *MessagePinMutation) WhereP(ps ...func(*sql.Selector)) { + p := make([]predicate.MessagePin, len(ps)) + for i := range ps { + p[i] = ps[i] + } + m.Where(p...) +} + +// Op returns the operation name. +func (m *MessagePinMutation) Op() Op { + return m.op +} + +// SetOp allows setting the mutation operation. +func (m *MessagePinMutation) SetOp(op Op) { + m.op = op +} + +// Type returns the node type of this mutation (MessagePin). +func (m *MessagePinMutation) Type() string { + return m.typ +} + +// Fields returns all fields that were changed during this mutation. Note that in +// order to get all numeric fields that were incremented/decremented, call +// AddedFields(). +func (m *MessagePinMutation) Fields() []string { + fields := make([]string, 0, 5) + if m.channel_id != nil { + fields = append(fields, messagepin.FieldChannelID) + } + if m.content != nil { + fields = append(fields, messagepin.FieldContent) + } + if m.embeds != nil { + fields = append(fields, messagepin.FieldEmbeds) + } + if m.before_id != nil { + fields = append(fields, messagepin.FieldBeforeID) + } + if m.rate_limit != nil { + fields = append(fields, messagepin.FieldRateLimit) + } + return fields +} + +// Field returns the value of a field with the given name. The second boolean +// return value indicates that this field was not set, or was not defined in the +// schema. +func (m *MessagePinMutation) Field(name string) (ent.Value, bool) { + switch name { + case messagepin.FieldChannelID: + return m.ChannelID() + case messagepin.FieldContent: + return m.Content() + case messagepin.FieldEmbeds: + return m.Embeds() + case messagepin.FieldBeforeID: + return m.BeforeID() + case messagepin.FieldRateLimit: + return m.RateLimit() + } + return nil, false +} + +// OldField returns the old value of the field from the database. An error is +// returned if the mutation operation is not UpdateOne, or the query to the +// database failed. +func (m *MessagePinMutation) OldField(ctx context.Context, name string) (ent.Value, error) { + switch name { + case messagepin.FieldChannelID: + return m.OldChannelID(ctx) + case messagepin.FieldContent: + return m.OldContent(ctx) + case messagepin.FieldEmbeds: + return m.OldEmbeds(ctx) + case messagepin.FieldBeforeID: + return m.OldBeforeID(ctx) + case messagepin.FieldRateLimit: + return m.OldRateLimit(ctx) + } + return nil, fmt.Errorf("unknown MessagePin field %s", name) +} + +// SetField sets the value of a field with the given name. It returns an error if +// the field is not defined in the schema, or if the type mismatched the field +// type. +func (m *MessagePinMutation) SetField(name string, value ent.Value) error { + switch name { + case messagepin.FieldChannelID: + v, ok := value.(snowflake.ID) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetChannelID(v) + return nil + case messagepin.FieldContent: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetContent(v) + return nil + case messagepin.FieldEmbeds: + v, ok := value.([]discord.Embed) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetEmbeds(v) + return nil + case messagepin.FieldBeforeID: + v, ok := value.(snowflake.ID) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetBeforeID(v) + return nil + case messagepin.FieldRateLimit: + v, ok := value.(schema.RateLimit) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetRateLimit(v) + return nil + } + return fmt.Errorf("unknown MessagePin field %s", name) +} + +// AddedFields returns all numeric fields that were incremented/decremented during +// this mutation. +func (m *MessagePinMutation) AddedFields() []string { + var fields []string + if m.addchannel_id != nil { + fields = append(fields, messagepin.FieldChannelID) + } + if m.addbefore_id != nil { + fields = append(fields, messagepin.FieldBeforeID) + } + return fields +} + +// AddedField returns the numeric value that was incremented/decremented on a field +// with the given name. The second boolean return value indicates that this field +// was not set, or was not defined in the schema. +func (m *MessagePinMutation) AddedField(name string) (ent.Value, bool) { + switch name { + case messagepin.FieldChannelID: + return m.AddedChannelID() + case messagepin.FieldBeforeID: + return m.AddedBeforeID() + } + return nil, false +} + +// AddField adds the value to the field with the given name. It returns an error if +// the field is not defined in the schema, or if the type mismatched the field +// type. +func (m *MessagePinMutation) AddField(name string, value ent.Value) error { + switch name { + case messagepin.FieldChannelID: + v, ok := value.(snowflake.ID) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.AddChannelID(v) + return nil + case messagepin.FieldBeforeID: + v, ok := value.(snowflake.ID) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.AddBeforeID(v) + return nil + } + return fmt.Errorf("unknown MessagePin numeric field %s", name) +} + +// ClearedFields returns all nullable fields that were cleared during this +// mutation. +func (m *MessagePinMutation) ClearedFields() []string { + var fields []string + if m.FieldCleared(messagepin.FieldContent) { + fields = append(fields, messagepin.FieldContent) + } + if m.FieldCleared(messagepin.FieldEmbeds) { + fields = append(fields, messagepin.FieldEmbeds) + } + if m.FieldCleared(messagepin.FieldBeforeID) { + fields = append(fields, messagepin.FieldBeforeID) + } + return fields +} + +// FieldCleared returns a boolean indicating if a field with the given name was +// cleared in this mutation. +func (m *MessagePinMutation) FieldCleared(name string) bool { + _, ok := m.clearedFields[name] + return ok +} + +// ClearField clears the value of the field with the given name. It returns an +// error if the field is not defined in the schema. +func (m *MessagePinMutation) ClearField(name string) error { + switch name { + case messagepin.FieldContent: + m.ClearContent() + return nil + case messagepin.FieldEmbeds: + m.ClearEmbeds() + return nil + case messagepin.FieldBeforeID: + m.ClearBeforeID() + return nil + } + return fmt.Errorf("unknown MessagePin nullable field %s", name) +} + +// ResetField resets all changes in the mutation for the field with the given name. +// It returns an error if the field is not defined in the schema. +func (m *MessagePinMutation) ResetField(name string) error { + switch name { + case messagepin.FieldChannelID: + m.ResetChannelID() + return nil + case messagepin.FieldContent: + m.ResetContent() + return nil + case messagepin.FieldEmbeds: + m.ResetEmbeds() + return nil + case messagepin.FieldBeforeID: + m.ResetBeforeID() + return nil + case messagepin.FieldRateLimit: + m.ResetRateLimit() + return nil + } + return fmt.Errorf("unknown MessagePin field %s", name) +} + +// AddedEdges returns all edge names that were set/added in this mutation. +func (m *MessagePinMutation) AddedEdges() []string { + edges := make([]string, 0, 1) + if m.guild != nil { + edges = append(edges, messagepin.EdgeGuild) + } + return edges +} + +// AddedIDs returns all IDs (to other nodes) that were added for the given edge +// name in this mutation. +func (m *MessagePinMutation) AddedIDs(name string) []ent.Value { + switch name { + case messagepin.EdgeGuild: + if id := m.guild; id != nil { + return []ent.Value{*id} + } + } + return nil +} + +// RemovedEdges returns all edge names that were removed in this mutation. +func (m *MessagePinMutation) RemovedEdges() []string { + edges := make([]string, 0, 1) + return edges +} + +// RemovedIDs returns all IDs (to other nodes) that were removed for the edge with +// the given name in this mutation. +func (m *MessagePinMutation) RemovedIDs(name string) []ent.Value { + return nil +} + +// ClearedEdges returns all edge names that were cleared in this mutation. +func (m *MessagePinMutation) ClearedEdges() []string { + edges := make([]string, 0, 1) + if m.clearedguild { + edges = append(edges, messagepin.EdgeGuild) + } + return edges +} + +// EdgeCleared returns a boolean which indicates if the edge with the given name +// was cleared in this mutation. +func (m *MessagePinMutation) EdgeCleared(name string) bool { + switch name { + case messagepin.EdgeGuild: + return m.clearedguild + } + return false +} + +// ClearEdge clears the value of the edge with the given name. It returns an error +// if that edge is not defined in the schema. +func (m *MessagePinMutation) ClearEdge(name string) error { + switch name { + case messagepin.EdgeGuild: + m.ClearGuild() + return nil + } + return fmt.Errorf("unknown MessagePin unique edge %s", name) +} + +// ResetEdge resets all changes to the edge with the given name in this mutation. +// It returns an error if the edge is not defined in the schema. +func (m *MessagePinMutation) ResetEdge(name string) error { + switch name { + case messagepin.EdgeGuild: + m.ResetGuild() + return nil + } + return fmt.Errorf("unknown MessagePin edge %s", name) +} + +// MessageRemindMutation represents an operation that mutates the MessageRemind nodes in the graph. +type MessageRemindMutation struct { + config + op Op + typ string + id *uuid.UUID + channel_id *snowflake.ID + addchannel_id *snowflake.ID + author_id *snowflake.ID + addauthor_id *snowflake.ID + time *time.Time + content *string + name *string + clearedFields map[string]struct{} + guild *snowflake.ID + clearedguild bool + done bool + oldValue func(context.Context) (*MessageRemind, error) + predicates []predicate.MessageRemind +} + +var _ ent.Mutation = (*MessageRemindMutation)(nil) + +// messageremindOption allows management of the mutation configuration using functional options. +type messageremindOption func(*MessageRemindMutation) + +// newMessageRemindMutation creates new mutation for the MessageRemind entity. +func newMessageRemindMutation(c config, op Op, opts ...messageremindOption) *MessageRemindMutation { + m := &MessageRemindMutation{ + config: c, + op: op, + typ: TypeMessageRemind, + clearedFields: make(map[string]struct{}), + } + for _, opt := range opts { + opt(m) + } + return m +} + +// withMessageRemindID sets the ID field of the mutation. +func withMessageRemindID(id uuid.UUID) messageremindOption { + return func(m *MessageRemindMutation) { + var ( + err error + once sync.Once + value *MessageRemind + ) + m.oldValue = func(ctx context.Context) (*MessageRemind, error) { + once.Do(func() { + if m.done { + err = errors.New("querying old values post mutation is not allowed") + } else { + value, err = m.Client().MessageRemind.Get(ctx, id) + } + }) + return value, err + } + m.id = &id + } +} + +// withMessageRemind sets the old MessageRemind of the mutation. +func withMessageRemind(node *MessageRemind) messageremindOption { + return func(m *MessageRemindMutation) { + m.oldValue = func(context.Context) (*MessageRemind, error) { + return node, nil + } + m.id = &node.ID + } +} + +// Client returns a new `ent.Client` from the mutation. If the mutation was +// executed in a transaction (ent.Tx), a transactional client is returned. +func (m MessageRemindMutation) Client() *Client { + client := &Client{config: m.config} + client.init() + return client +} + +// Tx returns an `ent.Tx` for mutations that were executed in transactions; +// it returns an error otherwise. +func (m MessageRemindMutation) Tx() (*Tx, error) { + if _, ok := m.driver.(*txDriver); !ok { + return nil, errors.New("ent: mutation is not running in a transaction") + } + tx := &Tx{config: m.config} + tx.init() + return tx, nil +} + +// SetID sets the value of the id field. Note that this +// operation is only accepted on creation of MessageRemind entities. +func (m *MessageRemindMutation) SetID(id uuid.UUID) { + m.id = &id +} + +// ID returns the ID value in the mutation. Note that the ID is only available +// if it was provided to the builder or after it was returned from the database. +func (m *MessageRemindMutation) ID() (id uuid.UUID, exists bool) { + if m.id == nil { + return + } + return *m.id, true +} + +// IDs queries the database and returns the entity ids that match the mutation's predicate. +// That means, if the mutation is applied within a transaction with an isolation level such +// as sql.LevelSerializable, the returned ids match the ids of the rows that will be updated +// or updated by the mutation. +func (m *MessageRemindMutation) IDs(ctx context.Context) ([]uuid.UUID, error) { + switch { + case m.op.Is(OpUpdateOne | OpDeleteOne): + id, exists := m.ID() + if exists { + return []uuid.UUID{id}, nil + } + fallthrough + case m.op.Is(OpUpdate | OpDelete): + return m.Client().MessageRemind.Query().Where(m.predicates...).IDs(ctx) + default: + return nil, fmt.Errorf("IDs is not allowed on %s operations", m.op) + } +} + +// SetChannelID sets the "channel_id" field. +func (m *MessageRemindMutation) SetChannelID(s snowflake.ID) { + m.channel_id = &s + m.addchannel_id = nil +} + +// ChannelID returns the value of the "channel_id" field in the mutation. +func (m *MessageRemindMutation) ChannelID() (r snowflake.ID, exists bool) { + v := m.channel_id + if v == nil { + return + } + return *v, true +} + +// OldChannelID returns the old "channel_id" field's value of the MessageRemind entity. +// If the MessageRemind object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *MessageRemindMutation) OldChannelID(ctx context.Context) (v snowflake.ID, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldChannelID is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldChannelID requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldChannelID: %w", err) + } + return oldValue.ChannelID, nil +} + +// AddChannelID adds s to the "channel_id" field. +func (m *MessageRemindMutation) AddChannelID(s snowflake.ID) { + if m.addchannel_id != nil { + *m.addchannel_id += s + } else { + m.addchannel_id = &s + } +} + +// AddedChannelID returns the value that was added to the "channel_id" field in this mutation. +func (m *MessageRemindMutation) AddedChannelID() (r snowflake.ID, exists bool) { + v := m.addchannel_id + if v == nil { + return + } + return *v, true +} + +// ResetChannelID resets all changes to the "channel_id" field. +func (m *MessageRemindMutation) ResetChannelID() { + m.channel_id = nil + m.addchannel_id = nil +} + +// SetAuthorID sets the "author_id" field. +func (m *MessageRemindMutation) SetAuthorID(s snowflake.ID) { + m.author_id = &s + m.addauthor_id = nil +} + +// AuthorID returns the value of the "author_id" field in the mutation. +func (m *MessageRemindMutation) AuthorID() (r snowflake.ID, exists bool) { + v := m.author_id + if v == nil { + return + } + return *v, true +} + +// OldAuthorID returns the old "author_id" field's value of the MessageRemind entity. +// If the MessageRemind object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *MessageRemindMutation) OldAuthorID(ctx context.Context) (v snowflake.ID, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldAuthorID is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldAuthorID requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldAuthorID: %w", err) + } + return oldValue.AuthorID, nil +} + +// AddAuthorID adds s to the "author_id" field. +func (m *MessageRemindMutation) AddAuthorID(s snowflake.ID) { + if m.addauthor_id != nil { + *m.addauthor_id += s + } else { + m.addauthor_id = &s + } +} + +// AddedAuthorID returns the value that was added to the "author_id" field in this mutation. +func (m *MessageRemindMutation) AddedAuthorID() (r snowflake.ID, exists bool) { + v := m.addauthor_id + if v == nil { + return + } + return *v, true +} + +// ResetAuthorID resets all changes to the "author_id" field. +func (m *MessageRemindMutation) ResetAuthorID() { + m.author_id = nil + m.addauthor_id = nil +} + +// SetTime sets the "time" field. +func (m *MessageRemindMutation) SetTime(t time.Time) { + m.time = &t +} + +// Time returns the value of the "time" field in the mutation. +func (m *MessageRemindMutation) Time() (r time.Time, exists bool) { + v := m.time + if v == nil { + return + } + return *v, true +} + +// OldTime returns the old "time" field's value of the MessageRemind entity. +// If the MessageRemind object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *MessageRemindMutation) OldTime(ctx context.Context) (v time.Time, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldTime is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldTime requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldTime: %w", err) + } + return oldValue.Time, nil +} + +// ResetTime resets all changes to the "time" field. +func (m *MessageRemindMutation) ResetTime() { + m.time = nil +} + +// SetContent sets the "content" field. +func (m *MessageRemindMutation) SetContent(s string) { + m.content = &s +} + +// Content returns the value of the "content" field in the mutation. +func (m *MessageRemindMutation) Content() (r string, exists bool) { + v := m.content + if v == nil { + return + } + return *v, true +} + +// OldContent returns the old "content" field's value of the MessageRemind entity. +// If the MessageRemind object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *MessageRemindMutation) OldContent(ctx context.Context) (v string, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldContent is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldContent requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldContent: %w", err) + } + return oldValue.Content, nil +} + +// ResetContent resets all changes to the "content" field. +func (m *MessageRemindMutation) ResetContent() { + m.content = nil +} + +// SetName sets the "name" field. +func (m *MessageRemindMutation) SetName(s string) { + m.name = &s +} + +// Name returns the value of the "name" field in the mutation. +func (m *MessageRemindMutation) Name() (r string, exists bool) { + v := m.name + if v == nil { + return + } + return *v, true +} + +// OldName returns the old "name" field's value of the MessageRemind entity. +// If the MessageRemind object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *MessageRemindMutation) OldName(ctx context.Context) (v string, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldName is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldName requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldName: %w", err) + } + return oldValue.Name, nil +} + +// ResetName resets all changes to the "name" field. +func (m *MessageRemindMutation) ResetName() { + m.name = nil +} + +// SetGuildID sets the "guild" edge to the Guild entity by id. +func (m *MessageRemindMutation) SetGuildID(id snowflake.ID) { + m.guild = &id +} + +// ClearGuild clears the "guild" edge to the Guild entity. +func (m *MessageRemindMutation) ClearGuild() { + m.clearedguild = true +} + +// GuildCleared reports if the "guild" edge to the Guild entity was cleared. +func (m *MessageRemindMutation) GuildCleared() bool { + return m.clearedguild +} + +// GuildID returns the "guild" edge ID in the mutation. +func (m *MessageRemindMutation) GuildID() (id snowflake.ID, exists bool) { + if m.guild != nil { + return *m.guild, true + } + return +} + +// GuildIDs returns the "guild" edge IDs in the mutation. +// Note that IDs always returns len(IDs) <= 1 for unique edges, and you should use +// GuildID instead. It exists only for internal usage by the builders. +func (m *MessageRemindMutation) GuildIDs() (ids []snowflake.ID) { + if id := m.guild; id != nil { + ids = append(ids, *id) + } + return +} + +// ResetGuild resets all changes to the "guild" edge. +func (m *MessageRemindMutation) ResetGuild() { + m.guild = nil + m.clearedguild = false +} + +// Where appends a list predicates to the MessageRemindMutation builder. +func (m *MessageRemindMutation) Where(ps ...predicate.MessageRemind) { + m.predicates = append(m.predicates, ps...) +} + +// WhereP appends storage-level predicates to the MessageRemindMutation builder. Using this method, +// users can use type-assertion to append predicates that do not depend on any generated package. +func (m *MessageRemindMutation) WhereP(ps ...func(*sql.Selector)) { + p := make([]predicate.MessageRemind, len(ps)) + for i := range ps { + p[i] = ps[i] + } + m.Where(p...) +} + +// Op returns the operation name. +func (m *MessageRemindMutation) Op() Op { + return m.op +} + +// SetOp allows setting the mutation operation. +func (m *MessageRemindMutation) SetOp(op Op) { + m.op = op +} + +// Type returns the node type of this mutation (MessageRemind). +func (m *MessageRemindMutation) Type() string { + return m.typ +} + +// Fields returns all fields that were changed during this mutation. Note that in +// order to get all numeric fields that were incremented/decremented, call +// AddedFields(). +func (m *MessageRemindMutation) Fields() []string { + fields := make([]string, 0, 5) + if m.channel_id != nil { + fields = append(fields, messageremind.FieldChannelID) + } + if m.author_id != nil { + fields = append(fields, messageremind.FieldAuthorID) + } + if m.time != nil { + fields = append(fields, messageremind.FieldTime) + } + if m.content != nil { + fields = append(fields, messageremind.FieldContent) + } + if m.name != nil { + fields = append(fields, messageremind.FieldName) + } + return fields +} + +// Field returns the value of a field with the given name. The second boolean +// return value indicates that this field was not set, or was not defined in the +// schema. +func (m *MessageRemindMutation) Field(name string) (ent.Value, bool) { + switch name { + case messageremind.FieldChannelID: + return m.ChannelID() + case messageremind.FieldAuthorID: + return m.AuthorID() + case messageremind.FieldTime: + return m.Time() + case messageremind.FieldContent: + return m.Content() + case messageremind.FieldName: + return m.Name() + } + return nil, false +} + +// OldField returns the old value of the field from the database. An error is +// returned if the mutation operation is not UpdateOne, or the query to the +// database failed. +func (m *MessageRemindMutation) OldField(ctx context.Context, name string) (ent.Value, error) { + switch name { + case messageremind.FieldChannelID: + return m.OldChannelID(ctx) + case messageremind.FieldAuthorID: + return m.OldAuthorID(ctx) + case messageremind.FieldTime: + return m.OldTime(ctx) + case messageremind.FieldContent: + return m.OldContent(ctx) + case messageremind.FieldName: + return m.OldName(ctx) + } + return nil, fmt.Errorf("unknown MessageRemind field %s", name) +} + +// SetField sets the value of a field with the given name. It returns an error if +// the field is not defined in the schema, or if the type mismatched the field +// type. +func (m *MessageRemindMutation) SetField(name string, value ent.Value) error { + switch name { + case messageremind.FieldChannelID: + v, ok := value.(snowflake.ID) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetChannelID(v) + return nil + case messageremind.FieldAuthorID: + v, ok := value.(snowflake.ID) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetAuthorID(v) + return nil + case messageremind.FieldTime: + v, ok := value.(time.Time) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetTime(v) + return nil + case messageremind.FieldContent: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetContent(v) + return nil + case messageremind.FieldName: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetName(v) + return nil + } + return fmt.Errorf("unknown MessageRemind field %s", name) +} + +// AddedFields returns all numeric fields that were incremented/decremented during +// this mutation. +func (m *MessageRemindMutation) AddedFields() []string { + var fields []string + if m.addchannel_id != nil { + fields = append(fields, messageremind.FieldChannelID) + } + if m.addauthor_id != nil { + fields = append(fields, messageremind.FieldAuthorID) + } + return fields +} + +// AddedField returns the numeric value that was incremented/decremented on a field +// with the given name. The second boolean return value indicates that this field +// was not set, or was not defined in the schema. +func (m *MessageRemindMutation) AddedField(name string) (ent.Value, bool) { + switch name { + case messageremind.FieldChannelID: + return m.AddedChannelID() + case messageremind.FieldAuthorID: + return m.AddedAuthorID() + } + return nil, false +} + +// AddField adds the value to the field with the given name. It returns an error if +// the field is not defined in the schema, or if the type mismatched the field +// type. +func (m *MessageRemindMutation) AddField(name string, value ent.Value) error { + switch name { + case messageremind.FieldChannelID: + v, ok := value.(snowflake.ID) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.AddChannelID(v) + return nil + case messageremind.FieldAuthorID: + v, ok := value.(snowflake.ID) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.AddAuthorID(v) + return nil + } + return fmt.Errorf("unknown MessageRemind numeric field %s", name) +} + +// ClearedFields returns all nullable fields that were cleared during this +// mutation. +func (m *MessageRemindMutation) ClearedFields() []string { + return nil +} + +// FieldCleared returns a boolean indicating if a field with the given name was +// cleared in this mutation. +func (m *MessageRemindMutation) FieldCleared(name string) bool { + _, ok := m.clearedFields[name] + return ok +} + +// ClearField clears the value of the field with the given name. It returns an +// error if the field is not defined in the schema. +func (m *MessageRemindMutation) ClearField(name string) error { + return fmt.Errorf("unknown MessageRemind nullable field %s", name) +} + +// ResetField resets all changes in the mutation for the field with the given name. +// It returns an error if the field is not defined in the schema. +func (m *MessageRemindMutation) ResetField(name string) error { + switch name { + case messageremind.FieldChannelID: + m.ResetChannelID() + return nil + case messageremind.FieldAuthorID: + m.ResetAuthorID() + return nil + case messageremind.FieldTime: + m.ResetTime() + return nil + case messageremind.FieldContent: + m.ResetContent() + return nil + case messageremind.FieldName: + m.ResetName() + return nil + } + return fmt.Errorf("unknown MessageRemind field %s", name) +} + +// AddedEdges returns all edge names that were set/added in this mutation. +func (m *MessageRemindMutation) AddedEdges() []string { + edges := make([]string, 0, 1) + if m.guild != nil { + edges = append(edges, messageremind.EdgeGuild) + } + return edges +} + +// AddedIDs returns all IDs (to other nodes) that were added for the given edge +// name in this mutation. +func (m *MessageRemindMutation) AddedIDs(name string) []ent.Value { + switch name { + case messageremind.EdgeGuild: + if id := m.guild; id != nil { + return []ent.Value{*id} + } + } + return nil +} + +// RemovedEdges returns all edge names that were removed in this mutation. +func (m *MessageRemindMutation) RemovedEdges() []string { + edges := make([]string, 0, 1) + return edges +} + +// RemovedIDs returns all IDs (to other nodes) that were removed for the edge with +// the given name in this mutation. +func (m *MessageRemindMutation) RemovedIDs(name string) []ent.Value { + return nil +} + +// ClearedEdges returns all edge names that were cleared in this mutation. +func (m *MessageRemindMutation) ClearedEdges() []string { + edges := make([]string, 0, 1) + if m.clearedguild { + edges = append(edges, messageremind.EdgeGuild) + } + return edges +} + +// EdgeCleared returns a boolean which indicates if the edge with the given name +// was cleared in this mutation. +func (m *MessageRemindMutation) EdgeCleared(name string) bool { + switch name { + case messageremind.EdgeGuild: + return m.clearedguild + } + return false +} + +// ClearEdge clears the value of the edge with the given name. It returns an error +// if that edge is not defined in the schema. +func (m *MessageRemindMutation) ClearEdge(name string) error { + switch name { + case messageremind.EdgeGuild: + m.ClearGuild() + return nil + } + return fmt.Errorf("unknown MessageRemind unique edge %s", name) +} + +// ResetEdge resets all changes to the edge with the given name in this mutation. +// It returns an error if the edge is not defined in the schema. +func (m *MessageRemindMutation) ResetEdge(name string) error { + switch name { + case messageremind.EdgeGuild: + m.ResetGuild() + return nil + } + return fmt.Errorf("unknown MessageRemind edge %s", name) +} + +// RolePanelMutation represents an operation that mutates the RolePanel nodes in the graph. +type RolePanelMutation struct { + config + op Op + typ string + id *uuid.UUID + name *string + description *string + roles *[]schema.Role + appendroles []schema.Role + updated_at *time.Time + applied_at *time.Time + clearedFields map[string]struct{} + guild *snowflake.ID + clearedguild bool + placements map[uuid.UUID]struct{} + removedplacements map[uuid.UUID]struct{} + clearedplacements bool + edit *uuid.UUID + clearededit bool + done bool + oldValue func(context.Context) (*RolePanel, error) + predicates []predicate.RolePanel +} + +var _ ent.Mutation = (*RolePanelMutation)(nil) + +// rolepanelOption allows management of the mutation configuration using functional options. +type rolepanelOption func(*RolePanelMutation) + +// newRolePanelMutation creates new mutation for the RolePanel entity. +func newRolePanelMutation(c config, op Op, opts ...rolepanelOption) *RolePanelMutation { + m := &RolePanelMutation{ + config: c, + op: op, + typ: TypeRolePanel, + clearedFields: make(map[string]struct{}), + } + for _, opt := range opts { + opt(m) + } + return m +} + +// withRolePanelID sets the ID field of the mutation. +func withRolePanelID(id uuid.UUID) rolepanelOption { + return func(m *RolePanelMutation) { + var ( + err error + once sync.Once + value *RolePanel + ) + m.oldValue = func(ctx context.Context) (*RolePanel, error) { + once.Do(func() { + if m.done { + err = errors.New("querying old values post mutation is not allowed") + } else { + value, err = m.Client().RolePanel.Get(ctx, id) + } + }) + return value, err + } + m.id = &id + } +} + +// withRolePanel sets the old RolePanel of the mutation. +func withRolePanel(node *RolePanel) rolepanelOption { + return func(m *RolePanelMutation) { + m.oldValue = func(context.Context) (*RolePanel, error) { + return node, nil + } + m.id = &node.ID + } +} + +// Client returns a new `ent.Client` from the mutation. If the mutation was +// executed in a transaction (ent.Tx), a transactional client is returned. +func (m RolePanelMutation) Client() *Client { + client := &Client{config: m.config} + client.init() + return client +} + +// Tx returns an `ent.Tx` for mutations that were executed in transactions; +// it returns an error otherwise. +func (m RolePanelMutation) Tx() (*Tx, error) { + if _, ok := m.driver.(*txDriver); !ok { + return nil, errors.New("ent: mutation is not running in a transaction") + } + tx := &Tx{config: m.config} + tx.init() + return tx, nil +} + +// SetID sets the value of the id field. Note that this +// operation is only accepted on creation of RolePanel entities. +func (m *RolePanelMutation) SetID(id uuid.UUID) { + m.id = &id +} + +// ID returns the ID value in the mutation. Note that the ID is only available +// if it was provided to the builder or after it was returned from the database. +func (m *RolePanelMutation) ID() (id uuid.UUID, exists bool) { + if m.id == nil { + return + } + return *m.id, true +} + +// IDs queries the database and returns the entity ids that match the mutation's predicate. +// That means, if the mutation is applied within a transaction with an isolation level such +// as sql.LevelSerializable, the returned ids match the ids of the rows that will be updated +// or updated by the mutation. +func (m *RolePanelMutation) IDs(ctx context.Context) ([]uuid.UUID, error) { + switch { + case m.op.Is(OpUpdateOne | OpDeleteOne): + id, exists := m.ID() + if exists { + return []uuid.UUID{id}, nil + } + fallthrough + case m.op.Is(OpUpdate | OpDelete): + return m.Client().RolePanel.Query().Where(m.predicates...).IDs(ctx) + default: + return nil, fmt.Errorf("IDs is not allowed on %s operations", m.op) + } +} + +// SetName sets the "name" field. +func (m *RolePanelMutation) SetName(s string) { + m.name = &s +} + +// Name returns the value of the "name" field in the mutation. +func (m *RolePanelMutation) Name() (r string, exists bool) { + v := m.name + if v == nil { + return + } + return *v, true +} + +// OldName returns the old "name" field's value of the RolePanel entity. +// If the RolePanel object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *RolePanelMutation) OldName(ctx context.Context) (v string, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldName is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldName requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldName: %w", err) + } + return oldValue.Name, nil +} + +// ResetName resets all changes to the "name" field. +func (m *RolePanelMutation) ResetName() { + m.name = nil +} + +// SetDescription sets the "description" field. +func (m *RolePanelMutation) SetDescription(s string) { + m.description = &s +} + +// Description returns the value of the "description" field in the mutation. +func (m *RolePanelMutation) Description() (r string, exists bool) { + v := m.description + if v == nil { + return + } + return *v, true +} + +// OldDescription returns the old "description" field's value of the RolePanel entity. +// If the RolePanel object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *RolePanelMutation) OldDescription(ctx context.Context) (v string, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldDescription is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldDescription requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldDescription: %w", err) + } + return oldValue.Description, nil +} + +// ResetDescription resets all changes to the "description" field. +func (m *RolePanelMutation) ResetDescription() { + m.description = nil +} + +// SetRoles sets the "roles" field. +func (m *RolePanelMutation) SetRoles(s []schema.Role) { + m.roles = &s + m.appendroles = nil +} + +// Roles returns the value of the "roles" field in the mutation. +func (m *RolePanelMutation) Roles() (r []schema.Role, exists bool) { + v := m.roles + if v == nil { + return + } + return *v, true +} + +// OldRoles returns the old "roles" field's value of the RolePanel entity. +// If the RolePanel object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *RolePanelMutation) OldRoles(ctx context.Context) (v []schema.Role, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldRoles is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldRoles requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldRoles: %w", err) + } + return oldValue.Roles, nil +} + +// AppendRoles adds s to the "roles" field. +func (m *RolePanelMutation) AppendRoles(s []schema.Role) { + m.appendroles = append(m.appendroles, s...) +} + +// AppendedRoles returns the list of values that were appended to the "roles" field in this mutation. +func (m *RolePanelMutation) AppendedRoles() ([]schema.Role, bool) { + if len(m.appendroles) == 0 { + return nil, false + } + return m.appendroles, true +} + +// ClearRoles clears the value of the "roles" field. +func (m *RolePanelMutation) ClearRoles() { + m.roles = nil + m.appendroles = nil + m.clearedFields[rolepanel.FieldRoles] = struct{}{} +} + +// RolesCleared returns if the "roles" field was cleared in this mutation. +func (m *RolePanelMutation) RolesCleared() bool { + _, ok := m.clearedFields[rolepanel.FieldRoles] + return ok +} + +// ResetRoles resets all changes to the "roles" field. +func (m *RolePanelMutation) ResetRoles() { + m.roles = nil + m.appendroles = nil + delete(m.clearedFields, rolepanel.FieldRoles) +} + +// SetUpdatedAt sets the "updated_at" field. +func (m *RolePanelMutation) SetUpdatedAt(t time.Time) { + m.updated_at = &t +} + +// UpdatedAt returns the value of the "updated_at" field in the mutation. +func (m *RolePanelMutation) UpdatedAt() (r time.Time, exists bool) { + v := m.updated_at + if v == nil { + return + } + return *v, true +} + +// OldUpdatedAt returns the old "updated_at" field's value of the RolePanel entity. +// If the RolePanel object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *RolePanelMutation) OldUpdatedAt(ctx context.Context) (v time.Time, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldUpdatedAt is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldUpdatedAt requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldUpdatedAt: %w", err) + } + return oldValue.UpdatedAt, nil +} + +// ClearUpdatedAt clears the value of the "updated_at" field. +func (m *RolePanelMutation) ClearUpdatedAt() { + m.updated_at = nil + m.clearedFields[rolepanel.FieldUpdatedAt] = struct{}{} +} + +// UpdatedAtCleared returns if the "updated_at" field was cleared in this mutation. +func (m *RolePanelMutation) UpdatedAtCleared() bool { + _, ok := m.clearedFields[rolepanel.FieldUpdatedAt] + return ok +} + +// ResetUpdatedAt resets all changes to the "updated_at" field. +func (m *RolePanelMutation) ResetUpdatedAt() { + m.updated_at = nil + delete(m.clearedFields, rolepanel.FieldUpdatedAt) +} + +// SetAppliedAt sets the "applied_at" field. +func (m *RolePanelMutation) SetAppliedAt(t time.Time) { + m.applied_at = &t +} + +// AppliedAt returns the value of the "applied_at" field in the mutation. +func (m *RolePanelMutation) AppliedAt() (r time.Time, exists bool) { + v := m.applied_at + if v == nil { + return + } + return *v, true +} + +// OldAppliedAt returns the old "applied_at" field's value of the RolePanel entity. +// If the RolePanel object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *RolePanelMutation) OldAppliedAt(ctx context.Context) (v time.Time, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldAppliedAt is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldAppliedAt requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldAppliedAt: %w", err) + } + return oldValue.AppliedAt, nil +} + +// ClearAppliedAt clears the value of the "applied_at" field. +func (m *RolePanelMutation) ClearAppliedAt() { + m.applied_at = nil + m.clearedFields[rolepanel.FieldAppliedAt] = struct{}{} +} + +// AppliedAtCleared returns if the "applied_at" field was cleared in this mutation. +func (m *RolePanelMutation) AppliedAtCleared() bool { + _, ok := m.clearedFields[rolepanel.FieldAppliedAt] + return ok +} + +// ResetAppliedAt resets all changes to the "applied_at" field. +func (m *RolePanelMutation) ResetAppliedAt() { + m.applied_at = nil + delete(m.clearedFields, rolepanel.FieldAppliedAt) +} + +// SetGuildID sets the "guild" edge to the Guild entity by id. +func (m *RolePanelMutation) SetGuildID(id snowflake.ID) { + m.guild = &id +} + +// ClearGuild clears the "guild" edge to the Guild entity. +func (m *RolePanelMutation) ClearGuild() { + m.clearedguild = true +} + +// GuildCleared reports if the "guild" edge to the Guild entity was cleared. +func (m *RolePanelMutation) GuildCleared() bool { + return m.clearedguild +} + +// GuildID returns the "guild" edge ID in the mutation. +func (m *RolePanelMutation) GuildID() (id snowflake.ID, exists bool) { + if m.guild != nil { + return *m.guild, true + } + return +} + +// GuildIDs returns the "guild" edge IDs in the mutation. +// Note that IDs always returns len(IDs) <= 1 for unique edges, and you should use +// GuildID instead. It exists only for internal usage by the builders. +func (m *RolePanelMutation) GuildIDs() (ids []snowflake.ID) { + if id := m.guild; id != nil { + ids = append(ids, *id) + } + return +} + +// ResetGuild resets all changes to the "guild" edge. +func (m *RolePanelMutation) ResetGuild() { + m.guild = nil + m.clearedguild = false +} + +// AddPlacementIDs adds the "placements" edge to the RolePanelPlaced entity by ids. +func (m *RolePanelMutation) AddPlacementIDs(ids ...uuid.UUID) { + if m.placements == nil { + m.placements = make(map[uuid.UUID]struct{}) + } + for i := range ids { + m.placements[ids[i]] = struct{}{} + } +} + +// ClearPlacements clears the "placements" edge to the RolePanelPlaced entity. +func (m *RolePanelMutation) ClearPlacements() { + m.clearedplacements = true +} + +// PlacementsCleared reports if the "placements" edge to the RolePanelPlaced entity was cleared. +func (m *RolePanelMutation) PlacementsCleared() bool { + return m.clearedplacements +} + +// RemovePlacementIDs removes the "placements" edge to the RolePanelPlaced entity by IDs. +func (m *RolePanelMutation) RemovePlacementIDs(ids ...uuid.UUID) { + if m.removedplacements == nil { + m.removedplacements = make(map[uuid.UUID]struct{}) + } + for i := range ids { + delete(m.placements, ids[i]) + m.removedplacements[ids[i]] = struct{}{} + } +} + +// RemovedPlacements returns the removed IDs of the "placements" edge to the RolePanelPlaced entity. +func (m *RolePanelMutation) RemovedPlacementsIDs() (ids []uuid.UUID) { + for id := range m.removedplacements { + ids = append(ids, id) + } + return +} + +// PlacementsIDs returns the "placements" edge IDs in the mutation. +func (m *RolePanelMutation) PlacementsIDs() (ids []uuid.UUID) { + for id := range m.placements { + ids = append(ids, id) + } + return +} + +// ResetPlacements resets all changes to the "placements" edge. +func (m *RolePanelMutation) ResetPlacements() { + m.placements = nil + m.clearedplacements = false + m.removedplacements = nil +} + +// SetEditID sets the "edit" edge to the RolePanelEdit entity by id. +func (m *RolePanelMutation) SetEditID(id uuid.UUID) { + m.edit = &id +} + +// ClearEdit clears the "edit" edge to the RolePanelEdit entity. +func (m *RolePanelMutation) ClearEdit() { + m.clearededit = true +} + +// EditCleared reports if the "edit" edge to the RolePanelEdit entity was cleared. +func (m *RolePanelMutation) EditCleared() bool { + return m.clearededit +} + +// EditID returns the "edit" edge ID in the mutation. +func (m *RolePanelMutation) EditID() (id uuid.UUID, exists bool) { + if m.edit != nil { + return *m.edit, true + } + return +} + +// EditIDs returns the "edit" edge IDs in the mutation. +// Note that IDs always returns len(IDs) <= 1 for unique edges, and you should use +// EditID instead. It exists only for internal usage by the builders. +func (m *RolePanelMutation) EditIDs() (ids []uuid.UUID) { + if id := m.edit; id != nil { + ids = append(ids, *id) + } + return +} + +// ResetEdit resets all changes to the "edit" edge. +func (m *RolePanelMutation) ResetEdit() { + m.edit = nil + m.clearededit = false +} + +// Where appends a list predicates to the RolePanelMutation builder. +func (m *RolePanelMutation) Where(ps ...predicate.RolePanel) { + m.predicates = append(m.predicates, ps...) +} + +// WhereP appends storage-level predicates to the RolePanelMutation builder. Using this method, +// users can use type-assertion to append predicates that do not depend on any generated package. +func (m *RolePanelMutation) WhereP(ps ...func(*sql.Selector)) { + p := make([]predicate.RolePanel, len(ps)) + for i := range ps { + p[i] = ps[i] + } + m.Where(p...) +} + +// Op returns the operation name. +func (m *RolePanelMutation) Op() Op { + return m.op +} + +// SetOp allows setting the mutation operation. +func (m *RolePanelMutation) SetOp(op Op) { + m.op = op +} + +// Type returns the node type of this mutation (RolePanel). +func (m *RolePanelMutation) Type() string { + return m.typ +} + +// Fields returns all fields that were changed during this mutation. Note that in +// order to get all numeric fields that were incremented/decremented, call +// AddedFields(). +func (m *RolePanelMutation) Fields() []string { + fields := make([]string, 0, 5) + if m.name != nil { + fields = append(fields, rolepanel.FieldName) + } + if m.description != nil { + fields = append(fields, rolepanel.FieldDescription) + } + if m.roles != nil { + fields = append(fields, rolepanel.FieldRoles) + } + if m.updated_at != nil { + fields = append(fields, rolepanel.FieldUpdatedAt) + } + if m.applied_at != nil { + fields = append(fields, rolepanel.FieldAppliedAt) + } + return fields +} + +// Field returns the value of a field with the given name. The second boolean +// return value indicates that this field was not set, or was not defined in the +// schema. +func (m *RolePanelMutation) Field(name string) (ent.Value, bool) { + switch name { + case rolepanel.FieldName: + return m.Name() + case rolepanel.FieldDescription: + return m.Description() + case rolepanel.FieldRoles: + return m.Roles() + case rolepanel.FieldUpdatedAt: + return m.UpdatedAt() + case rolepanel.FieldAppliedAt: + return m.AppliedAt() + } + return nil, false +} + +// OldField returns the old value of the field from the database. An error is +// returned if the mutation operation is not UpdateOne, or the query to the +// database failed. +func (m *RolePanelMutation) OldField(ctx context.Context, name string) (ent.Value, error) { + switch name { + case rolepanel.FieldName: + return m.OldName(ctx) + case rolepanel.FieldDescription: + return m.OldDescription(ctx) + case rolepanel.FieldRoles: + return m.OldRoles(ctx) + case rolepanel.FieldUpdatedAt: + return m.OldUpdatedAt(ctx) + case rolepanel.FieldAppliedAt: + return m.OldAppliedAt(ctx) + } + return nil, fmt.Errorf("unknown RolePanel field %s", name) +} + +// SetField sets the value of a field with the given name. It returns an error if +// the field is not defined in the schema, or if the type mismatched the field +// type. +func (m *RolePanelMutation) SetField(name string, value ent.Value) error { + switch name { + case rolepanel.FieldName: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetName(v) + return nil + case rolepanel.FieldDescription: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetDescription(v) + return nil + case rolepanel.FieldRoles: + v, ok := value.([]schema.Role) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetRoles(v) + return nil + case rolepanel.FieldUpdatedAt: + v, ok := value.(time.Time) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetUpdatedAt(v) + return nil + case rolepanel.FieldAppliedAt: + v, ok := value.(time.Time) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetAppliedAt(v) + return nil + } + return fmt.Errorf("unknown RolePanel field %s", name) +} + +// AddedFields returns all numeric fields that were incremented/decremented during +// this mutation. +func (m *RolePanelMutation) AddedFields() []string { + return nil +} + +// AddedField returns the numeric value that was incremented/decremented on a field +// with the given name. The second boolean return value indicates that this field +// was not set, or was not defined in the schema. +func (m *RolePanelMutation) AddedField(name string) (ent.Value, bool) { + return nil, false +} + +// AddField adds the value to the field with the given name. It returns an error if +// the field is not defined in the schema, or if the type mismatched the field +// type. +func (m *RolePanelMutation) AddField(name string, value ent.Value) error { + switch name { + } + return fmt.Errorf("unknown RolePanel numeric field %s", name) +} + +// ClearedFields returns all nullable fields that were cleared during this +// mutation. +func (m *RolePanelMutation) ClearedFields() []string { + var fields []string + if m.FieldCleared(rolepanel.FieldRoles) { + fields = append(fields, rolepanel.FieldRoles) + } + if m.FieldCleared(rolepanel.FieldUpdatedAt) { + fields = append(fields, rolepanel.FieldUpdatedAt) + } + if m.FieldCleared(rolepanel.FieldAppliedAt) { + fields = append(fields, rolepanel.FieldAppliedAt) + } + return fields +} + +// FieldCleared returns a boolean indicating if a field with the given name was +// cleared in this mutation. +func (m *RolePanelMutation) FieldCleared(name string) bool { + _, ok := m.clearedFields[name] + return ok +} + +// ClearField clears the value of the field with the given name. It returns an +// error if the field is not defined in the schema. +func (m *RolePanelMutation) ClearField(name string) error { + switch name { + case rolepanel.FieldRoles: + m.ClearRoles() + return nil + case rolepanel.FieldUpdatedAt: + m.ClearUpdatedAt() + return nil + case rolepanel.FieldAppliedAt: + m.ClearAppliedAt() + return nil + } + return fmt.Errorf("unknown RolePanel nullable field %s", name) +} + +// ResetField resets all changes in the mutation for the field with the given name. +// It returns an error if the field is not defined in the schema. +func (m *RolePanelMutation) ResetField(name string) error { + switch name { + case rolepanel.FieldName: + m.ResetName() + return nil + case rolepanel.FieldDescription: + m.ResetDescription() + return nil + case rolepanel.FieldRoles: + m.ResetRoles() + return nil + case rolepanel.FieldUpdatedAt: + m.ResetUpdatedAt() + return nil + case rolepanel.FieldAppliedAt: + m.ResetAppliedAt() + return nil + } + return fmt.Errorf("unknown RolePanel field %s", name) +} + +// AddedEdges returns all edge names that were set/added in this mutation. +func (m *RolePanelMutation) AddedEdges() []string { + edges := make([]string, 0, 3) + if m.guild != nil { + edges = append(edges, rolepanel.EdgeGuild) + } + if m.placements != nil { + edges = append(edges, rolepanel.EdgePlacements) + } + if m.edit != nil { + edges = append(edges, rolepanel.EdgeEdit) + } + return edges +} + +// AddedIDs returns all IDs (to other nodes) that were added for the given edge +// name in this mutation. +func (m *RolePanelMutation) AddedIDs(name string) []ent.Value { + switch name { + case rolepanel.EdgeGuild: + if id := m.guild; id != nil { + return []ent.Value{*id} + } + case rolepanel.EdgePlacements: + ids := make([]ent.Value, 0, len(m.placements)) + for id := range m.placements { + ids = append(ids, id) + } + return ids + case rolepanel.EdgeEdit: + if id := m.edit; id != nil { + return []ent.Value{*id} + } + } + return nil +} + +// RemovedEdges returns all edge names that were removed in this mutation. +func (m *RolePanelMutation) RemovedEdges() []string { + edges := make([]string, 0, 3) + if m.removedplacements != nil { + edges = append(edges, rolepanel.EdgePlacements) + } + return edges +} + +// RemovedIDs returns all IDs (to other nodes) that were removed for the edge with +// the given name in this mutation. +func (m *RolePanelMutation) RemovedIDs(name string) []ent.Value { + switch name { + case rolepanel.EdgePlacements: + ids := make([]ent.Value, 0, len(m.removedplacements)) + for id := range m.removedplacements { + ids = append(ids, id) + } + return ids + } + return nil +} + +// ClearedEdges returns all edge names that were cleared in this mutation. +func (m *RolePanelMutation) ClearedEdges() []string { + edges := make([]string, 0, 3) + if m.clearedguild { + edges = append(edges, rolepanel.EdgeGuild) + } + if m.clearedplacements { + edges = append(edges, rolepanel.EdgePlacements) + } + if m.clearededit { + edges = append(edges, rolepanel.EdgeEdit) + } + return edges +} + +// EdgeCleared returns a boolean which indicates if the edge with the given name +// was cleared in this mutation. +func (m *RolePanelMutation) EdgeCleared(name string) bool { + switch name { + case rolepanel.EdgeGuild: + return m.clearedguild + case rolepanel.EdgePlacements: + return m.clearedplacements + case rolepanel.EdgeEdit: + return m.clearededit + } + return false +} + +// ClearEdge clears the value of the edge with the given name. It returns an error +// if that edge is not defined in the schema. +func (m *RolePanelMutation) ClearEdge(name string) error { + switch name { + case rolepanel.EdgeGuild: + m.ClearGuild() + return nil + case rolepanel.EdgeEdit: + m.ClearEdit() + return nil + } + return fmt.Errorf("unknown RolePanel unique edge %s", name) +} + +// ResetEdge resets all changes to the edge with the given name in this mutation. +// It returns an error if the edge is not defined in the schema. +func (m *RolePanelMutation) ResetEdge(name string) error { + switch name { + case rolepanel.EdgeGuild: + m.ResetGuild() + return nil + case rolepanel.EdgePlacements: + m.ResetPlacements() + return nil + case rolepanel.EdgeEdit: + m.ResetEdit() + return nil + } + return fmt.Errorf("unknown RolePanel edge %s", name) +} + +// RolePanelEditMutation represents an operation that mutates the RolePanelEdit nodes in the graph. +type RolePanelEditMutation struct { + config + op Op + typ string + id *uuid.UUID + channel_id *snowflake.ID + addchannel_id *snowflake.ID + emoji_author *snowflake.ID + addemoji_author *snowflake.ID + token *string + selected_role *snowflake.ID + addselected_role *snowflake.ID + modified *bool + name *string + description *string + roles *[]schema.Role + appendroles []schema.Role + clearedFields map[string]struct{} + guild *snowflake.ID + clearedguild bool + parent *uuid.UUID + clearedparent bool + done bool + oldValue func(context.Context) (*RolePanelEdit, error) + predicates []predicate.RolePanelEdit +} + +var _ ent.Mutation = (*RolePanelEditMutation)(nil) + +// rolepaneleditOption allows management of the mutation configuration using functional options. +type rolepaneleditOption func(*RolePanelEditMutation) + +// newRolePanelEditMutation creates new mutation for the RolePanelEdit entity. +func newRolePanelEditMutation(c config, op Op, opts ...rolepaneleditOption) *RolePanelEditMutation { + m := &RolePanelEditMutation{ + config: c, + op: op, + typ: TypeRolePanelEdit, + clearedFields: make(map[string]struct{}), + } + for _, opt := range opts { + opt(m) + } + return m +} + +// withRolePanelEditID sets the ID field of the mutation. +func withRolePanelEditID(id uuid.UUID) rolepaneleditOption { + return func(m *RolePanelEditMutation) { + var ( + err error + once sync.Once + value *RolePanelEdit + ) + m.oldValue = func(ctx context.Context) (*RolePanelEdit, error) { + once.Do(func() { + if m.done { + err = errors.New("querying old values post mutation is not allowed") + } else { + value, err = m.Client().RolePanelEdit.Get(ctx, id) + } + }) + return value, err + } + m.id = &id + } +} + +// withRolePanelEdit sets the old RolePanelEdit of the mutation. +func withRolePanelEdit(node *RolePanelEdit) rolepaneleditOption { + return func(m *RolePanelEditMutation) { + m.oldValue = func(context.Context) (*RolePanelEdit, error) { + return node, nil + } + m.id = &node.ID + } +} + +// Client returns a new `ent.Client` from the mutation. If the mutation was +// executed in a transaction (ent.Tx), a transactional client is returned. +func (m RolePanelEditMutation) Client() *Client { + client := &Client{config: m.config} + client.init() + return client +} + +// Tx returns an `ent.Tx` for mutations that were executed in transactions; +// it returns an error otherwise. +func (m RolePanelEditMutation) Tx() (*Tx, error) { + if _, ok := m.driver.(*txDriver); !ok { + return nil, errors.New("ent: mutation is not running in a transaction") + } + tx := &Tx{config: m.config} + tx.init() + return tx, nil +} + +// SetID sets the value of the id field. Note that this +// operation is only accepted on creation of RolePanelEdit entities. +func (m *RolePanelEditMutation) SetID(id uuid.UUID) { + m.id = &id +} + +// ID returns the ID value in the mutation. Note that the ID is only available +// if it was provided to the builder or after it was returned from the database. +func (m *RolePanelEditMutation) ID() (id uuid.UUID, exists bool) { + if m.id == nil { + return + } + return *m.id, true +} + +// IDs queries the database and returns the entity ids that match the mutation's predicate. +// That means, if the mutation is applied within a transaction with an isolation level such +// as sql.LevelSerializable, the returned ids match the ids of the rows that will be updated +// or updated by the mutation. +func (m *RolePanelEditMutation) IDs(ctx context.Context) ([]uuid.UUID, error) { + switch { + case m.op.Is(OpUpdateOne | OpDeleteOne): + id, exists := m.ID() + if exists { + return []uuid.UUID{id}, nil + } + fallthrough + case m.op.Is(OpUpdate | OpDelete): + return m.Client().RolePanelEdit.Query().Where(m.predicates...).IDs(ctx) + default: + return nil, fmt.Errorf("IDs is not allowed on %s operations", m.op) + } +} + +// SetChannelID sets the "channel_id" field. +func (m *RolePanelEditMutation) SetChannelID(s snowflake.ID) { + m.channel_id = &s + m.addchannel_id = nil +} + +// ChannelID returns the value of the "channel_id" field in the mutation. +func (m *RolePanelEditMutation) ChannelID() (r snowflake.ID, exists bool) { + v := m.channel_id + if v == nil { + return + } + return *v, true +} + +// OldChannelID returns the old "channel_id" field's value of the RolePanelEdit entity. +// If the RolePanelEdit object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *RolePanelEditMutation) OldChannelID(ctx context.Context) (v snowflake.ID, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldChannelID is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldChannelID requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldChannelID: %w", err) + } + return oldValue.ChannelID, nil +} + +// AddChannelID adds s to the "channel_id" field. +func (m *RolePanelEditMutation) AddChannelID(s snowflake.ID) { + if m.addchannel_id != nil { + *m.addchannel_id += s + } else { + m.addchannel_id = &s + } +} + +// AddedChannelID returns the value that was added to the "channel_id" field in this mutation. +func (m *RolePanelEditMutation) AddedChannelID() (r snowflake.ID, exists bool) { + v := m.addchannel_id + if v == nil { + return + } + return *v, true +} + +// ResetChannelID resets all changes to the "channel_id" field. +func (m *RolePanelEditMutation) ResetChannelID() { + m.channel_id = nil + m.addchannel_id = nil +} + +// SetEmojiAuthor sets the "emoji_author" field. +func (m *RolePanelEditMutation) SetEmojiAuthor(s snowflake.ID) { + m.emoji_author = &s + m.addemoji_author = nil +} + +// EmojiAuthor returns the value of the "emoji_author" field in the mutation. +func (m *RolePanelEditMutation) EmojiAuthor() (r snowflake.ID, exists bool) { + v := m.emoji_author + if v == nil { + return + } + return *v, true +} + +// OldEmojiAuthor returns the old "emoji_author" field's value of the RolePanelEdit entity. +// If the RolePanelEdit object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *RolePanelEditMutation) OldEmojiAuthor(ctx context.Context) (v *snowflake.ID, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldEmojiAuthor is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldEmojiAuthor requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldEmojiAuthor: %w", err) + } + return oldValue.EmojiAuthor, nil +} + +// AddEmojiAuthor adds s to the "emoji_author" field. +func (m *RolePanelEditMutation) AddEmojiAuthor(s snowflake.ID) { + if m.addemoji_author != nil { + *m.addemoji_author += s + } else { + m.addemoji_author = &s + } +} + +// AddedEmojiAuthor returns the value that was added to the "emoji_author" field in this mutation. +func (m *RolePanelEditMutation) AddedEmojiAuthor() (r snowflake.ID, exists bool) { + v := m.addemoji_author + if v == nil { + return + } + return *v, true +} + +// ClearEmojiAuthor clears the value of the "emoji_author" field. +func (m *RolePanelEditMutation) ClearEmojiAuthor() { + m.emoji_author = nil + m.addemoji_author = nil + m.clearedFields[rolepaneledit.FieldEmojiAuthor] = struct{}{} +} + +// EmojiAuthorCleared returns if the "emoji_author" field was cleared in this mutation. +func (m *RolePanelEditMutation) EmojiAuthorCleared() bool { + _, ok := m.clearedFields[rolepaneledit.FieldEmojiAuthor] + return ok +} + +// ResetEmojiAuthor resets all changes to the "emoji_author" field. +func (m *RolePanelEditMutation) ResetEmojiAuthor() { + m.emoji_author = nil + m.addemoji_author = nil + delete(m.clearedFields, rolepaneledit.FieldEmojiAuthor) +} + +// SetToken sets the "token" field. +func (m *RolePanelEditMutation) SetToken(s string) { + m.token = &s +} + +// Token returns the value of the "token" field in the mutation. +func (m *RolePanelEditMutation) Token() (r string, exists bool) { + v := m.token + if v == nil { + return + } + return *v, true +} + +// OldToken returns the old "token" field's value of the RolePanelEdit entity. +// If the RolePanelEdit object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *RolePanelEditMutation) OldToken(ctx context.Context) (v *string, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldToken is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldToken requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldToken: %w", err) + } + return oldValue.Token, nil +} + +// ClearToken clears the value of the "token" field. +func (m *RolePanelEditMutation) ClearToken() { + m.token = nil + m.clearedFields[rolepaneledit.FieldToken] = struct{}{} +} + +// TokenCleared returns if the "token" field was cleared in this mutation. +func (m *RolePanelEditMutation) TokenCleared() bool { + _, ok := m.clearedFields[rolepaneledit.FieldToken] + return ok +} + +// ResetToken resets all changes to the "token" field. +func (m *RolePanelEditMutation) ResetToken() { + m.token = nil + delete(m.clearedFields, rolepaneledit.FieldToken) +} + +// SetSelectedRole sets the "selected_role" field. +func (m *RolePanelEditMutation) SetSelectedRole(s snowflake.ID) { + m.selected_role = &s + m.addselected_role = nil +} + +// SelectedRole returns the value of the "selected_role" field in the mutation. +func (m *RolePanelEditMutation) SelectedRole() (r snowflake.ID, exists bool) { + v := m.selected_role + if v == nil { + return + } + return *v, true +} + +// OldSelectedRole returns the old "selected_role" field's value of the RolePanelEdit entity. +// If the RolePanelEdit object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *RolePanelEditMutation) OldSelectedRole(ctx context.Context) (v *snowflake.ID, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldSelectedRole is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldSelectedRole requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldSelectedRole: %w", err) + } + return oldValue.SelectedRole, nil +} + +// AddSelectedRole adds s to the "selected_role" field. +func (m *RolePanelEditMutation) AddSelectedRole(s snowflake.ID) { + if m.addselected_role != nil { + *m.addselected_role += s + } else { + m.addselected_role = &s + } +} + +// AddedSelectedRole returns the value that was added to the "selected_role" field in this mutation. +func (m *RolePanelEditMutation) AddedSelectedRole() (r snowflake.ID, exists bool) { + v := m.addselected_role + if v == nil { + return + } + return *v, true +} + +// ClearSelectedRole clears the value of the "selected_role" field. +func (m *RolePanelEditMutation) ClearSelectedRole() { + m.selected_role = nil + m.addselected_role = nil + m.clearedFields[rolepaneledit.FieldSelectedRole] = struct{}{} +} + +// SelectedRoleCleared returns if the "selected_role" field was cleared in this mutation. +func (m *RolePanelEditMutation) SelectedRoleCleared() bool { + _, ok := m.clearedFields[rolepaneledit.FieldSelectedRole] + return ok +} + +// ResetSelectedRole resets all changes to the "selected_role" field. +func (m *RolePanelEditMutation) ResetSelectedRole() { + m.selected_role = nil + m.addselected_role = nil + delete(m.clearedFields, rolepaneledit.FieldSelectedRole) +} + +// SetModified sets the "modified" field. +func (m *RolePanelEditMutation) SetModified(b bool) { + m.modified = &b +} + +// Modified returns the value of the "modified" field in the mutation. +func (m *RolePanelEditMutation) Modified() (r bool, exists bool) { + v := m.modified + if v == nil { + return + } + return *v, true +} + +// OldModified returns the old "modified" field's value of the RolePanelEdit entity. +// If the RolePanelEdit object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *RolePanelEditMutation) OldModified(ctx context.Context) (v bool, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldModified is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldModified requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldModified: %w", err) + } + return oldValue.Modified, nil +} + +// ResetModified resets all changes to the "modified" field. +func (m *RolePanelEditMutation) ResetModified() { + m.modified = nil +} + +// SetName sets the "name" field. +func (m *RolePanelEditMutation) SetName(s string) { + m.name = &s +} + +// Name returns the value of the "name" field in the mutation. +func (m *RolePanelEditMutation) Name() (r string, exists bool) { + v := m.name + if v == nil { + return + } + return *v, true +} + +// OldName returns the old "name" field's value of the RolePanelEdit entity. +// If the RolePanelEdit object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *RolePanelEditMutation) OldName(ctx context.Context) (v *string, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldName is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldName requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldName: %w", err) + } + return oldValue.Name, nil +} + +// ClearName clears the value of the "name" field. +func (m *RolePanelEditMutation) ClearName() { + m.name = nil + m.clearedFields[rolepaneledit.FieldName] = struct{}{} +} + +// NameCleared returns if the "name" field was cleared in this mutation. +func (m *RolePanelEditMutation) NameCleared() bool { + _, ok := m.clearedFields[rolepaneledit.FieldName] + return ok +} + +// ResetName resets all changes to the "name" field. +func (m *RolePanelEditMutation) ResetName() { + m.name = nil + delete(m.clearedFields, rolepaneledit.FieldName) +} + +// SetDescription sets the "description" field. +func (m *RolePanelEditMutation) SetDescription(s string) { + m.description = &s +} + +// Description returns the value of the "description" field in the mutation. +func (m *RolePanelEditMutation) Description() (r string, exists bool) { + v := m.description + if v == nil { + return + } + return *v, true +} + +// OldDescription returns the old "description" field's value of the RolePanelEdit entity. +// If the RolePanelEdit object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *RolePanelEditMutation) OldDescription(ctx context.Context) (v *string, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldDescription is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldDescription requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldDescription: %w", err) + } + return oldValue.Description, nil +} + +// ClearDescription clears the value of the "description" field. +func (m *RolePanelEditMutation) ClearDescription() { + m.description = nil + m.clearedFields[rolepaneledit.FieldDescription] = struct{}{} +} + +// DescriptionCleared returns if the "description" field was cleared in this mutation. +func (m *RolePanelEditMutation) DescriptionCleared() bool { + _, ok := m.clearedFields[rolepaneledit.FieldDescription] + return ok +} + +// ResetDescription resets all changes to the "description" field. +func (m *RolePanelEditMutation) ResetDescription() { + m.description = nil + delete(m.clearedFields, rolepaneledit.FieldDescription) +} + +// SetRoles sets the "roles" field. +func (m *RolePanelEditMutation) SetRoles(s []schema.Role) { + m.roles = &s + m.appendroles = nil +} + +// Roles returns the value of the "roles" field in the mutation. +func (m *RolePanelEditMutation) Roles() (r []schema.Role, exists bool) { + v := m.roles + if v == nil { + return + } + return *v, true +} + +// OldRoles returns the old "roles" field's value of the RolePanelEdit entity. +// If the RolePanelEdit object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *RolePanelEditMutation) OldRoles(ctx context.Context) (v []schema.Role, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldRoles is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldRoles requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldRoles: %w", err) + } + return oldValue.Roles, nil +} + +// AppendRoles adds s to the "roles" field. +func (m *RolePanelEditMutation) AppendRoles(s []schema.Role) { + m.appendroles = append(m.appendroles, s...) +} + +// AppendedRoles returns the list of values that were appended to the "roles" field in this mutation. +func (m *RolePanelEditMutation) AppendedRoles() ([]schema.Role, bool) { + if len(m.appendroles) == 0 { + return nil, false + } + return m.appendroles, true +} + +// ClearRoles clears the value of the "roles" field. +func (m *RolePanelEditMutation) ClearRoles() { + m.roles = nil + m.appendroles = nil + m.clearedFields[rolepaneledit.FieldRoles] = struct{}{} +} + +// RolesCleared returns if the "roles" field was cleared in this mutation. +func (m *RolePanelEditMutation) RolesCleared() bool { + _, ok := m.clearedFields[rolepaneledit.FieldRoles] + return ok +} + +// ResetRoles resets all changes to the "roles" field. +func (m *RolePanelEditMutation) ResetRoles() { + m.roles = nil + m.appendroles = nil + delete(m.clearedFields, rolepaneledit.FieldRoles) +} + +// SetGuildID sets the "guild" edge to the Guild entity by id. +func (m *RolePanelEditMutation) SetGuildID(id snowflake.ID) { + m.guild = &id +} + +// ClearGuild clears the "guild" edge to the Guild entity. +func (m *RolePanelEditMutation) ClearGuild() { + m.clearedguild = true +} + +// GuildCleared reports if the "guild" edge to the Guild entity was cleared. +func (m *RolePanelEditMutation) GuildCleared() bool { + return m.clearedguild +} + +// GuildID returns the "guild" edge ID in the mutation. +func (m *RolePanelEditMutation) GuildID() (id snowflake.ID, exists bool) { + if m.guild != nil { + return *m.guild, true + } + return +} + +// GuildIDs returns the "guild" edge IDs in the mutation. +// Note that IDs always returns len(IDs) <= 1 for unique edges, and you should use +// GuildID instead. It exists only for internal usage by the builders. +func (m *RolePanelEditMutation) GuildIDs() (ids []snowflake.ID) { + if id := m.guild; id != nil { + ids = append(ids, *id) + } + return +} + +// ResetGuild resets all changes to the "guild" edge. +func (m *RolePanelEditMutation) ResetGuild() { + m.guild = nil + m.clearedguild = false +} + +// SetParentID sets the "parent" edge to the RolePanel entity by id. +func (m *RolePanelEditMutation) SetParentID(id uuid.UUID) { + m.parent = &id +} + +// ClearParent clears the "parent" edge to the RolePanel entity. +func (m *RolePanelEditMutation) ClearParent() { + m.clearedparent = true +} + +// ParentCleared reports if the "parent" edge to the RolePanel entity was cleared. +func (m *RolePanelEditMutation) ParentCleared() bool { + return m.clearedparent +} + +// ParentID returns the "parent" edge ID in the mutation. +func (m *RolePanelEditMutation) ParentID() (id uuid.UUID, exists bool) { + if m.parent != nil { + return *m.parent, true + } + return +} + +// ParentIDs returns the "parent" edge IDs in the mutation. +// Note that IDs always returns len(IDs) <= 1 for unique edges, and you should use +// ParentID instead. It exists only for internal usage by the builders. +func (m *RolePanelEditMutation) ParentIDs() (ids []uuid.UUID) { + if id := m.parent; id != nil { + ids = append(ids, *id) + } + return +} + +// ResetParent resets all changes to the "parent" edge. +func (m *RolePanelEditMutation) ResetParent() { + m.parent = nil + m.clearedparent = false +} + +// Where appends a list predicates to the RolePanelEditMutation builder. +func (m *RolePanelEditMutation) Where(ps ...predicate.RolePanelEdit) { + m.predicates = append(m.predicates, ps...) +} + +// WhereP appends storage-level predicates to the RolePanelEditMutation builder. Using this method, +// users can use type-assertion to append predicates that do not depend on any generated package. +func (m *RolePanelEditMutation) WhereP(ps ...func(*sql.Selector)) { + p := make([]predicate.RolePanelEdit, len(ps)) + for i := range ps { + p[i] = ps[i] + } + m.Where(p...) +} + +// Op returns the operation name. +func (m *RolePanelEditMutation) Op() Op { + return m.op +} + +// SetOp allows setting the mutation operation. +func (m *RolePanelEditMutation) SetOp(op Op) { + m.op = op +} + +// Type returns the node type of this mutation (RolePanelEdit). +func (m *RolePanelEditMutation) Type() string { + return m.typ +} + +// Fields returns all fields that were changed during this mutation. Note that in +// order to get all numeric fields that were incremented/decremented, call +// AddedFields(). +func (m *RolePanelEditMutation) Fields() []string { + fields := make([]string, 0, 8) + if m.channel_id != nil { + fields = append(fields, rolepaneledit.FieldChannelID) + } + if m.emoji_author != nil { + fields = append(fields, rolepaneledit.FieldEmojiAuthor) + } + if m.token != nil { + fields = append(fields, rolepaneledit.FieldToken) + } + if m.selected_role != nil { + fields = append(fields, rolepaneledit.FieldSelectedRole) + } + if m.modified != nil { + fields = append(fields, rolepaneledit.FieldModified) + } + if m.name != nil { + fields = append(fields, rolepaneledit.FieldName) + } + if m.description != nil { + fields = append(fields, rolepaneledit.FieldDescription) + } + if m.roles != nil { + fields = append(fields, rolepaneledit.FieldRoles) + } + return fields +} + +// Field returns the value of a field with the given name. The second boolean +// return value indicates that this field was not set, or was not defined in the +// schema. +func (m *RolePanelEditMutation) Field(name string) (ent.Value, bool) { + switch name { + case rolepaneledit.FieldChannelID: + return m.ChannelID() + case rolepaneledit.FieldEmojiAuthor: + return m.EmojiAuthor() + case rolepaneledit.FieldToken: + return m.Token() + case rolepaneledit.FieldSelectedRole: + return m.SelectedRole() + case rolepaneledit.FieldModified: + return m.Modified() + case rolepaneledit.FieldName: + return m.Name() + case rolepaneledit.FieldDescription: + return m.Description() + case rolepaneledit.FieldRoles: + return m.Roles() + } + return nil, false +} + +// OldField returns the old value of the field from the database. An error is +// returned if the mutation operation is not UpdateOne, or the query to the +// database failed. +func (m *RolePanelEditMutation) OldField(ctx context.Context, name string) (ent.Value, error) { + switch name { + case rolepaneledit.FieldChannelID: + return m.OldChannelID(ctx) + case rolepaneledit.FieldEmojiAuthor: + return m.OldEmojiAuthor(ctx) + case rolepaneledit.FieldToken: + return m.OldToken(ctx) + case rolepaneledit.FieldSelectedRole: + return m.OldSelectedRole(ctx) + case rolepaneledit.FieldModified: + return m.OldModified(ctx) + case rolepaneledit.FieldName: + return m.OldName(ctx) + case rolepaneledit.FieldDescription: + return m.OldDescription(ctx) + case rolepaneledit.FieldRoles: + return m.OldRoles(ctx) + } + return nil, fmt.Errorf("unknown RolePanelEdit field %s", name) +} + +// SetField sets the value of a field with the given name. It returns an error if +// the field is not defined in the schema, or if the type mismatched the field +// type. +func (m *RolePanelEditMutation) SetField(name string, value ent.Value) error { + switch name { + case rolepaneledit.FieldChannelID: + v, ok := value.(snowflake.ID) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetChannelID(v) + return nil + case rolepaneledit.FieldEmojiAuthor: + v, ok := value.(snowflake.ID) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetEmojiAuthor(v) + return nil + case rolepaneledit.FieldToken: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetToken(v) + return nil + case rolepaneledit.FieldSelectedRole: + v, ok := value.(snowflake.ID) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetSelectedRole(v) + return nil + case rolepaneledit.FieldModified: + v, ok := value.(bool) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetModified(v) + return nil + case rolepaneledit.FieldName: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetName(v) + return nil + case rolepaneledit.FieldDescription: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetDescription(v) + return nil + case rolepaneledit.FieldRoles: + v, ok := value.([]schema.Role) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetRoles(v) + return nil + } + return fmt.Errorf("unknown RolePanelEdit field %s", name) +} + +// AddedFields returns all numeric fields that were incremented/decremented during +// this mutation. +func (m *RolePanelEditMutation) AddedFields() []string { + var fields []string + if m.addchannel_id != nil { + fields = append(fields, rolepaneledit.FieldChannelID) + } + if m.addemoji_author != nil { + fields = append(fields, rolepaneledit.FieldEmojiAuthor) + } + if m.addselected_role != nil { + fields = append(fields, rolepaneledit.FieldSelectedRole) + } + return fields +} + +// AddedField returns the numeric value that was incremented/decremented on a field +// with the given name. The second boolean return value indicates that this field +// was not set, or was not defined in the schema. +func (m *RolePanelEditMutation) AddedField(name string) (ent.Value, bool) { + switch name { + case rolepaneledit.FieldChannelID: + return m.AddedChannelID() + case rolepaneledit.FieldEmojiAuthor: + return m.AddedEmojiAuthor() + case rolepaneledit.FieldSelectedRole: + return m.AddedSelectedRole() + } + return nil, false +} + +// AddField adds the value to the field with the given name. It returns an error if +// the field is not defined in the schema, or if the type mismatched the field +// type. +func (m *RolePanelEditMutation) AddField(name string, value ent.Value) error { + switch name { + case rolepaneledit.FieldChannelID: + v, ok := value.(snowflake.ID) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.AddChannelID(v) + return nil + case rolepaneledit.FieldEmojiAuthor: + v, ok := value.(snowflake.ID) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.AddEmojiAuthor(v) + return nil + case rolepaneledit.FieldSelectedRole: + v, ok := value.(snowflake.ID) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.AddSelectedRole(v) + return nil + } + return fmt.Errorf("unknown RolePanelEdit numeric field %s", name) +} + +// ClearedFields returns all nullable fields that were cleared during this +// mutation. +func (m *RolePanelEditMutation) ClearedFields() []string { + var fields []string + if m.FieldCleared(rolepaneledit.FieldEmojiAuthor) { + fields = append(fields, rolepaneledit.FieldEmojiAuthor) + } + if m.FieldCleared(rolepaneledit.FieldToken) { + fields = append(fields, rolepaneledit.FieldToken) + } + if m.FieldCleared(rolepaneledit.FieldSelectedRole) { + fields = append(fields, rolepaneledit.FieldSelectedRole) + } + if m.FieldCleared(rolepaneledit.FieldName) { + fields = append(fields, rolepaneledit.FieldName) + } + if m.FieldCleared(rolepaneledit.FieldDescription) { + fields = append(fields, rolepaneledit.FieldDescription) + } + if m.FieldCleared(rolepaneledit.FieldRoles) { + fields = append(fields, rolepaneledit.FieldRoles) + } + return fields +} + +// FieldCleared returns a boolean indicating if a field with the given name was +// cleared in this mutation. +func (m *RolePanelEditMutation) FieldCleared(name string) bool { + _, ok := m.clearedFields[name] + return ok +} + +// ClearField clears the value of the field with the given name. It returns an +// error if the field is not defined in the schema. +func (m *RolePanelEditMutation) ClearField(name string) error { + switch name { + case rolepaneledit.FieldEmojiAuthor: + m.ClearEmojiAuthor() + return nil + case rolepaneledit.FieldToken: + m.ClearToken() + return nil + case rolepaneledit.FieldSelectedRole: + m.ClearSelectedRole() + return nil + case rolepaneledit.FieldName: + m.ClearName() + return nil + case rolepaneledit.FieldDescription: + m.ClearDescription() + return nil + case rolepaneledit.FieldRoles: + m.ClearRoles() + return nil + } + return fmt.Errorf("unknown RolePanelEdit nullable field %s", name) +} + +// ResetField resets all changes in the mutation for the field with the given name. +// It returns an error if the field is not defined in the schema. +func (m *RolePanelEditMutation) ResetField(name string) error { + switch name { + case rolepaneledit.FieldChannelID: + m.ResetChannelID() + return nil + case rolepaneledit.FieldEmojiAuthor: + m.ResetEmojiAuthor() + return nil + case rolepaneledit.FieldToken: + m.ResetToken() + return nil + case rolepaneledit.FieldSelectedRole: + m.ResetSelectedRole() + return nil + case rolepaneledit.FieldModified: + m.ResetModified() + return nil + case rolepaneledit.FieldName: + m.ResetName() + return nil + case rolepaneledit.FieldDescription: + m.ResetDescription() + return nil + case rolepaneledit.FieldRoles: + m.ResetRoles() + return nil + } + return fmt.Errorf("unknown RolePanelEdit field %s", name) +} + +// AddedEdges returns all edge names that were set/added in this mutation. +func (m *RolePanelEditMutation) AddedEdges() []string { + edges := make([]string, 0, 2) + if m.guild != nil { + edges = append(edges, rolepaneledit.EdgeGuild) + } + if m.parent != nil { + edges = append(edges, rolepaneledit.EdgeParent) + } + return edges +} + +// AddedIDs returns all IDs (to other nodes) that were added for the given edge +// name in this mutation. +func (m *RolePanelEditMutation) AddedIDs(name string) []ent.Value { + switch name { + case rolepaneledit.EdgeGuild: + if id := m.guild; id != nil { + return []ent.Value{*id} + } + case rolepaneledit.EdgeParent: + if id := m.parent; id != nil { + return []ent.Value{*id} + } + } + return nil +} + +// RemovedEdges returns all edge names that were removed in this mutation. +func (m *RolePanelEditMutation) RemovedEdges() []string { + edges := make([]string, 0, 2) + return edges +} + +// RemovedIDs returns all IDs (to other nodes) that were removed for the edge with +// the given name in this mutation. +func (m *RolePanelEditMutation) RemovedIDs(name string) []ent.Value { + return nil +} + +// ClearedEdges returns all edge names that were cleared in this mutation. +func (m *RolePanelEditMutation) ClearedEdges() []string { + edges := make([]string, 0, 2) + if m.clearedguild { + edges = append(edges, rolepaneledit.EdgeGuild) + } + if m.clearedparent { + edges = append(edges, rolepaneledit.EdgeParent) + } + return edges +} + +// EdgeCleared returns a boolean which indicates if the edge with the given name +// was cleared in this mutation. +func (m *RolePanelEditMutation) EdgeCleared(name string) bool { + switch name { + case rolepaneledit.EdgeGuild: + return m.clearedguild + case rolepaneledit.EdgeParent: + return m.clearedparent + } + return false +} + +// ClearEdge clears the value of the edge with the given name. It returns an error +// if that edge is not defined in the schema. +func (m *RolePanelEditMutation) ClearEdge(name string) error { + switch name { + case rolepaneledit.EdgeGuild: + m.ClearGuild() + return nil + case rolepaneledit.EdgeParent: + m.ClearParent() + return nil + } + return fmt.Errorf("unknown RolePanelEdit unique edge %s", name) +} + +// ResetEdge resets all changes to the edge with the given name in this mutation. +// It returns an error if the edge is not defined in the schema. +func (m *RolePanelEditMutation) ResetEdge(name string) error { + switch name { + case rolepaneledit.EdgeGuild: + m.ResetGuild() + return nil + case rolepaneledit.EdgeParent: + m.ResetParent() + return nil + } + return fmt.Errorf("unknown RolePanelEdit edge %s", name) +} + +// RolePanelPlacedMutation represents an operation that mutates the RolePanelPlaced nodes in the graph. +type RolePanelPlacedMutation struct { + config + op Op + typ string + id *uuid.UUID + message_id *snowflake.ID + addmessage_id *snowflake.ID + channel_id *snowflake.ID + addchannel_id *snowflake.ID + _type *rolepanelplaced.Type + button_type *discord.ButtonStyle + addbutton_type *discord.ButtonStyle + show_name *bool + folding_select_menu *bool + hide_notice *bool + use_display_name *bool + created_at *time.Time + uses *int + adduses *int + name *string + description *string + roles *[]schema.Role + appendroles []schema.Role + updated_at *time.Time + clearedFields map[string]struct{} + guild *snowflake.ID + clearedguild bool + role_panel *uuid.UUID + clearedrole_panel bool + done bool + oldValue func(context.Context) (*RolePanelPlaced, error) + predicates []predicate.RolePanelPlaced +} + +var _ ent.Mutation = (*RolePanelPlacedMutation)(nil) + +// rolepanelplacedOption allows management of the mutation configuration using functional options. +type rolepanelplacedOption func(*RolePanelPlacedMutation) + +// newRolePanelPlacedMutation creates new mutation for the RolePanelPlaced entity. +func newRolePanelPlacedMutation(c config, op Op, opts ...rolepanelplacedOption) *RolePanelPlacedMutation { + m := &RolePanelPlacedMutation{ + config: c, + op: op, + typ: TypeRolePanelPlaced, + clearedFields: make(map[string]struct{}), + } + for _, opt := range opts { + opt(m) + } + return m +} + +// withRolePanelPlacedID sets the ID field of the mutation. +func withRolePanelPlacedID(id uuid.UUID) rolepanelplacedOption { + return func(m *RolePanelPlacedMutation) { + var ( + err error + once sync.Once + value *RolePanelPlaced + ) + m.oldValue = func(ctx context.Context) (*RolePanelPlaced, error) { + once.Do(func() { + if m.done { + err = errors.New("querying old values post mutation is not allowed") + } else { + value, err = m.Client().RolePanelPlaced.Get(ctx, id) + } + }) + return value, err + } + m.id = &id + } +} + +// withRolePanelPlaced sets the old RolePanelPlaced of the mutation. +func withRolePanelPlaced(node *RolePanelPlaced) rolepanelplacedOption { + return func(m *RolePanelPlacedMutation) { + m.oldValue = func(context.Context) (*RolePanelPlaced, error) { + return node, nil + } + m.id = &node.ID + } +} + +// Client returns a new `ent.Client` from the mutation. If the mutation was +// executed in a transaction (ent.Tx), a transactional client is returned. +func (m RolePanelPlacedMutation) Client() *Client { + client := &Client{config: m.config} + client.init() + return client +} + +// Tx returns an `ent.Tx` for mutations that were executed in transactions; +// it returns an error otherwise. +func (m RolePanelPlacedMutation) Tx() (*Tx, error) { + if _, ok := m.driver.(*txDriver); !ok { + return nil, errors.New("ent: mutation is not running in a transaction") + } + tx := &Tx{config: m.config} + tx.init() + return tx, nil +} + +// SetID sets the value of the id field. Note that this +// operation is only accepted on creation of RolePanelPlaced entities. +func (m *RolePanelPlacedMutation) SetID(id uuid.UUID) { + m.id = &id +} + +// ID returns the ID value in the mutation. Note that the ID is only available +// if it was provided to the builder or after it was returned from the database. +func (m *RolePanelPlacedMutation) ID() (id uuid.UUID, exists bool) { + if m.id == nil { + return + } + return *m.id, true +} + +// IDs queries the database and returns the entity ids that match the mutation's predicate. +// That means, if the mutation is applied within a transaction with an isolation level such +// as sql.LevelSerializable, the returned ids match the ids of the rows that will be updated +// or updated by the mutation. +func (m *RolePanelPlacedMutation) IDs(ctx context.Context) ([]uuid.UUID, error) { + switch { + case m.op.Is(OpUpdateOne | OpDeleteOne): + id, exists := m.ID() + if exists { + return []uuid.UUID{id}, nil + } + fallthrough + case m.op.Is(OpUpdate | OpDelete): + return m.Client().RolePanelPlaced.Query().Where(m.predicates...).IDs(ctx) + default: + return nil, fmt.Errorf("IDs is not allowed on %s operations", m.op) + } +} + +// SetMessageID sets the "message_id" field. +func (m *RolePanelPlacedMutation) SetMessageID(s snowflake.ID) { + m.message_id = &s + m.addmessage_id = nil +} + +// MessageID returns the value of the "message_id" field in the mutation. +func (m *RolePanelPlacedMutation) MessageID() (r snowflake.ID, exists bool) { + v := m.message_id + if v == nil { + return + } + return *v, true +} + +// OldMessageID returns the old "message_id" field's value of the RolePanelPlaced entity. +// If the RolePanelPlaced object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *RolePanelPlacedMutation) OldMessageID(ctx context.Context) (v *snowflake.ID, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldMessageID is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldMessageID requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldMessageID: %w", err) + } + return oldValue.MessageID, nil +} + +// AddMessageID adds s to the "message_id" field. +func (m *RolePanelPlacedMutation) AddMessageID(s snowflake.ID) { + if m.addmessage_id != nil { + *m.addmessage_id += s + } else { + m.addmessage_id = &s + } +} + +// AddedMessageID returns the value that was added to the "message_id" field in this mutation. +func (m *RolePanelPlacedMutation) AddedMessageID() (r snowflake.ID, exists bool) { + v := m.addmessage_id + if v == nil { + return + } + return *v, true +} + +// ClearMessageID clears the value of the "message_id" field. +func (m *RolePanelPlacedMutation) ClearMessageID() { + m.message_id = nil + m.addmessage_id = nil + m.clearedFields[rolepanelplaced.FieldMessageID] = struct{}{} +} + +// MessageIDCleared returns if the "message_id" field was cleared in this mutation. +func (m *RolePanelPlacedMutation) MessageIDCleared() bool { + _, ok := m.clearedFields[rolepanelplaced.FieldMessageID] + return ok +} + +// ResetMessageID resets all changes to the "message_id" field. +func (m *RolePanelPlacedMutation) ResetMessageID() { + m.message_id = nil + m.addmessage_id = nil + delete(m.clearedFields, rolepanelplaced.FieldMessageID) +} + +// SetChannelID sets the "channel_id" field. +func (m *RolePanelPlacedMutation) SetChannelID(s snowflake.ID) { + m.channel_id = &s + m.addchannel_id = nil +} + +// ChannelID returns the value of the "channel_id" field in the mutation. +func (m *RolePanelPlacedMutation) ChannelID() (r snowflake.ID, exists bool) { + v := m.channel_id + if v == nil { + return + } + return *v, true +} + +// OldChannelID returns the old "channel_id" field's value of the RolePanelPlaced entity. +// If the RolePanelPlaced object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *RolePanelPlacedMutation) OldChannelID(ctx context.Context) (v snowflake.ID, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldChannelID is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldChannelID requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldChannelID: %w", err) + } + return oldValue.ChannelID, nil +} + +// AddChannelID adds s to the "channel_id" field. +func (m *RolePanelPlacedMutation) AddChannelID(s snowflake.ID) { + if m.addchannel_id != nil { + *m.addchannel_id += s + } else { + m.addchannel_id = &s + } +} + +// AddedChannelID returns the value that was added to the "channel_id" field in this mutation. +func (m *RolePanelPlacedMutation) AddedChannelID() (r snowflake.ID, exists bool) { + v := m.addchannel_id + if v == nil { + return + } + return *v, true +} + +// ResetChannelID resets all changes to the "channel_id" field. +func (m *RolePanelPlacedMutation) ResetChannelID() { + m.channel_id = nil + m.addchannel_id = nil +} + +// SetType sets the "type" field. +func (m *RolePanelPlacedMutation) SetType(r rolepanelplaced.Type) { + m._type = &r +} + +// GetType returns the value of the "type" field in the mutation. +func (m *RolePanelPlacedMutation) GetType() (r rolepanelplaced.Type, exists bool) { + v := m._type + if v == nil { + return + } + return *v, true +} + +// OldType returns the old "type" field's value of the RolePanelPlaced entity. +// If the RolePanelPlaced object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *RolePanelPlacedMutation) OldType(ctx context.Context) (v rolepanelplaced.Type, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldType is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldType requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldType: %w", err) + } + return oldValue.Type, nil +} + +// ClearType clears the value of the "type" field. +func (m *RolePanelPlacedMutation) ClearType() { + m._type = nil + m.clearedFields[rolepanelplaced.FieldType] = struct{}{} +} + +// TypeCleared returns if the "type" field was cleared in this mutation. +func (m *RolePanelPlacedMutation) TypeCleared() bool { + _, ok := m.clearedFields[rolepanelplaced.FieldType] + return ok +} + +// ResetType resets all changes to the "type" field. +func (m *RolePanelPlacedMutation) ResetType() { + m._type = nil + delete(m.clearedFields, rolepanelplaced.FieldType) +} + +// SetButtonType sets the "button_type" field. +func (m *RolePanelPlacedMutation) SetButtonType(ds discord.ButtonStyle) { + m.button_type = &ds + m.addbutton_type = nil +} + +// ButtonType returns the value of the "button_type" field in the mutation. +func (m *RolePanelPlacedMutation) ButtonType() (r discord.ButtonStyle, exists bool) { + v := m.button_type + if v == nil { + return + } + return *v, true +} + +// OldButtonType returns the old "button_type" field's value of the RolePanelPlaced entity. +// If the RolePanelPlaced object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *RolePanelPlacedMutation) OldButtonType(ctx context.Context) (v discord.ButtonStyle, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldButtonType is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldButtonType requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldButtonType: %w", err) + } + return oldValue.ButtonType, nil +} + +// AddButtonType adds ds to the "button_type" field. +func (m *RolePanelPlacedMutation) AddButtonType(ds discord.ButtonStyle) { + if m.addbutton_type != nil { + *m.addbutton_type += ds + } else { + m.addbutton_type = &ds + } +} + +// AddedButtonType returns the value that was added to the "button_type" field in this mutation. +func (m *RolePanelPlacedMutation) AddedButtonType() (r discord.ButtonStyle, exists bool) { + v := m.addbutton_type + if v == nil { + return + } + return *v, true +} + +// ResetButtonType resets all changes to the "button_type" field. +func (m *RolePanelPlacedMutation) ResetButtonType() { + m.button_type = nil + m.addbutton_type = nil +} + +// SetShowName sets the "show_name" field. +func (m *RolePanelPlacedMutation) SetShowName(b bool) { + m.show_name = &b +} + +// ShowName returns the value of the "show_name" field in the mutation. +func (m *RolePanelPlacedMutation) ShowName() (r bool, exists bool) { + v := m.show_name + if v == nil { + return + } + return *v, true +} + +// OldShowName returns the old "show_name" field's value of the RolePanelPlaced entity. +// If the RolePanelPlaced object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *RolePanelPlacedMutation) OldShowName(ctx context.Context) (v bool, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldShowName is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldShowName requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldShowName: %w", err) + } + return oldValue.ShowName, nil +} + +// ResetShowName resets all changes to the "show_name" field. +func (m *RolePanelPlacedMutation) ResetShowName() { + m.show_name = nil +} + +// SetFoldingSelectMenu sets the "folding_select_menu" field. +func (m *RolePanelPlacedMutation) SetFoldingSelectMenu(b bool) { + m.folding_select_menu = &b +} + +// FoldingSelectMenu returns the value of the "folding_select_menu" field in the mutation. +func (m *RolePanelPlacedMutation) FoldingSelectMenu() (r bool, exists bool) { + v := m.folding_select_menu + if v == nil { + return + } + return *v, true +} + +// OldFoldingSelectMenu returns the old "folding_select_menu" field's value of the RolePanelPlaced entity. +// If the RolePanelPlaced object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *RolePanelPlacedMutation) OldFoldingSelectMenu(ctx context.Context) (v bool, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldFoldingSelectMenu is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldFoldingSelectMenu requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldFoldingSelectMenu: %w", err) + } + return oldValue.FoldingSelectMenu, nil +} + +// ResetFoldingSelectMenu resets all changes to the "folding_select_menu" field. +func (m *RolePanelPlacedMutation) ResetFoldingSelectMenu() { + m.folding_select_menu = nil +} + +// SetHideNotice sets the "hide_notice" field. +func (m *RolePanelPlacedMutation) SetHideNotice(b bool) { + m.hide_notice = &b +} + +// HideNotice returns the value of the "hide_notice" field in the mutation. +func (m *RolePanelPlacedMutation) HideNotice() (r bool, exists bool) { + v := m.hide_notice + if v == nil { + return + } + return *v, true +} + +// OldHideNotice returns the old "hide_notice" field's value of the RolePanelPlaced entity. +// If the RolePanelPlaced object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *RolePanelPlacedMutation) OldHideNotice(ctx context.Context) (v bool, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldHideNotice is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldHideNotice requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldHideNotice: %w", err) + } + return oldValue.HideNotice, nil +} + +// ResetHideNotice resets all changes to the "hide_notice" field. +func (m *RolePanelPlacedMutation) ResetHideNotice() { + m.hide_notice = nil +} + +// SetUseDisplayName sets the "use_display_name" field. +func (m *RolePanelPlacedMutation) SetUseDisplayName(b bool) { + m.use_display_name = &b +} + +// UseDisplayName returns the value of the "use_display_name" field in the mutation. +func (m *RolePanelPlacedMutation) UseDisplayName() (r bool, exists bool) { + v := m.use_display_name + if v == nil { + return + } + return *v, true +} + +// OldUseDisplayName returns the old "use_display_name" field's value of the RolePanelPlaced entity. +// If the RolePanelPlaced object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *RolePanelPlacedMutation) OldUseDisplayName(ctx context.Context) (v bool, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldUseDisplayName is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldUseDisplayName requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldUseDisplayName: %w", err) + } + return oldValue.UseDisplayName, nil +} + +// ResetUseDisplayName resets all changes to the "use_display_name" field. +func (m *RolePanelPlacedMutation) ResetUseDisplayName() { + m.use_display_name = nil +} + +// SetCreatedAt sets the "created_at" field. +func (m *RolePanelPlacedMutation) SetCreatedAt(t time.Time) { + m.created_at = &t +} + +// CreatedAt returns the value of the "created_at" field in the mutation. +func (m *RolePanelPlacedMutation) CreatedAt() (r time.Time, exists bool) { + v := m.created_at + if v == nil { + return + } + return *v, true +} + +// OldCreatedAt returns the old "created_at" field's value of the RolePanelPlaced entity. +// If the RolePanelPlaced object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *RolePanelPlacedMutation) OldCreatedAt(ctx context.Context) (v time.Time, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldCreatedAt is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldCreatedAt requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldCreatedAt: %w", err) + } + return oldValue.CreatedAt, nil +} + +// ResetCreatedAt resets all changes to the "created_at" field. +func (m *RolePanelPlacedMutation) ResetCreatedAt() { + m.created_at = nil +} + +// SetUses sets the "uses" field. +func (m *RolePanelPlacedMutation) SetUses(i int) { + m.uses = &i + m.adduses = nil +} + +// Uses returns the value of the "uses" field in the mutation. +func (m *RolePanelPlacedMutation) Uses() (r int, exists bool) { + v := m.uses + if v == nil { + return + } + return *v, true +} + +// OldUses returns the old "uses" field's value of the RolePanelPlaced entity. +// If the RolePanelPlaced object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *RolePanelPlacedMutation) OldUses(ctx context.Context) (v int, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldUses is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldUses requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldUses: %w", err) + } + return oldValue.Uses, nil +} + +// AddUses adds i to the "uses" field. +func (m *RolePanelPlacedMutation) AddUses(i int) { + if m.adduses != nil { + *m.adduses += i + } else { + m.adduses = &i + } +} + +// AddedUses returns the value that was added to the "uses" field in this mutation. +func (m *RolePanelPlacedMutation) AddedUses() (r int, exists bool) { + v := m.adduses + if v == nil { + return + } + return *v, true +} + +// ResetUses resets all changes to the "uses" field. +func (m *RolePanelPlacedMutation) ResetUses() { + m.uses = nil + m.adduses = nil +} + +// SetName sets the "name" field. +func (m *RolePanelPlacedMutation) SetName(s string) { + m.name = &s +} + +// Name returns the value of the "name" field in the mutation. +func (m *RolePanelPlacedMutation) Name() (r string, exists bool) { + v := m.name + if v == nil { + return + } + return *v, true +} + +// OldName returns the old "name" field's value of the RolePanelPlaced entity. +// If the RolePanelPlaced object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *RolePanelPlacedMutation) OldName(ctx context.Context) (v string, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldName is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldName requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldName: %w", err) + } + return oldValue.Name, nil +} + +// ResetName resets all changes to the "name" field. +func (m *RolePanelPlacedMutation) ResetName() { + m.name = nil +} + +// SetDescription sets the "description" field. +func (m *RolePanelPlacedMutation) SetDescription(s string) { + m.description = &s +} + +// Description returns the value of the "description" field in the mutation. +func (m *RolePanelPlacedMutation) Description() (r string, exists bool) { + v := m.description + if v == nil { + return + } + return *v, true +} + +// OldDescription returns the old "description" field's value of the RolePanelPlaced entity. +// If the RolePanelPlaced object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *RolePanelPlacedMutation) OldDescription(ctx context.Context) (v string, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldDescription is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldDescription requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldDescription: %w", err) + } + return oldValue.Description, nil +} + +// ResetDescription resets all changes to the "description" field. +func (m *RolePanelPlacedMutation) ResetDescription() { + m.description = nil +} + +// SetRoles sets the "roles" field. +func (m *RolePanelPlacedMutation) SetRoles(s []schema.Role) { + m.roles = &s + m.appendroles = nil +} + +// Roles returns the value of the "roles" field in the mutation. +func (m *RolePanelPlacedMutation) Roles() (r []schema.Role, exists bool) { + v := m.roles + if v == nil { + return + } + return *v, true +} + +// OldRoles returns the old "roles" field's value of the RolePanelPlaced entity. +// If the RolePanelPlaced object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *RolePanelPlacedMutation) OldRoles(ctx context.Context) (v []schema.Role, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldRoles is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldRoles requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldRoles: %w", err) + } + return oldValue.Roles, nil +} + +// AppendRoles adds s to the "roles" field. +func (m *RolePanelPlacedMutation) AppendRoles(s []schema.Role) { + m.appendroles = append(m.appendroles, s...) +} + +// AppendedRoles returns the list of values that were appended to the "roles" field in this mutation. +func (m *RolePanelPlacedMutation) AppendedRoles() ([]schema.Role, bool) { + if len(m.appendroles) == 0 { + return nil, false + } + return m.appendroles, true +} + +// ClearRoles clears the value of the "roles" field. +func (m *RolePanelPlacedMutation) ClearRoles() { + m.roles = nil + m.appendroles = nil + m.clearedFields[rolepanelplaced.FieldRoles] = struct{}{} +} + +// RolesCleared returns if the "roles" field was cleared in this mutation. +func (m *RolePanelPlacedMutation) RolesCleared() bool { + _, ok := m.clearedFields[rolepanelplaced.FieldRoles] + return ok +} + +// ResetRoles resets all changes to the "roles" field. +func (m *RolePanelPlacedMutation) ResetRoles() { + m.roles = nil + m.appendroles = nil + delete(m.clearedFields, rolepanelplaced.FieldRoles) +} + +// SetUpdatedAt sets the "updated_at" field. +func (m *RolePanelPlacedMutation) SetUpdatedAt(t time.Time) { + m.updated_at = &t +} + +// UpdatedAt returns the value of the "updated_at" field in the mutation. +func (m *RolePanelPlacedMutation) UpdatedAt() (r time.Time, exists bool) { + v := m.updated_at + if v == nil { + return + } + return *v, true +} + +// OldUpdatedAt returns the old "updated_at" field's value of the RolePanelPlaced entity. +// If the RolePanelPlaced object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *RolePanelPlacedMutation) OldUpdatedAt(ctx context.Context) (v time.Time, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldUpdatedAt is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldUpdatedAt requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldUpdatedAt: %w", err) + } + return oldValue.UpdatedAt, nil +} + +// ClearUpdatedAt clears the value of the "updated_at" field. +func (m *RolePanelPlacedMutation) ClearUpdatedAt() { + m.updated_at = nil + m.clearedFields[rolepanelplaced.FieldUpdatedAt] = struct{}{} +} + +// UpdatedAtCleared returns if the "updated_at" field was cleared in this mutation. +func (m *RolePanelPlacedMutation) UpdatedAtCleared() bool { + _, ok := m.clearedFields[rolepanelplaced.FieldUpdatedAt] + return ok +} + +// ResetUpdatedAt resets all changes to the "updated_at" field. +func (m *RolePanelPlacedMutation) ResetUpdatedAt() { + m.updated_at = nil + delete(m.clearedFields, rolepanelplaced.FieldUpdatedAt) +} + +// SetGuildID sets the "guild" edge to the Guild entity by id. +func (m *RolePanelPlacedMutation) SetGuildID(id snowflake.ID) { + m.guild = &id +} + +// ClearGuild clears the "guild" edge to the Guild entity. +func (m *RolePanelPlacedMutation) ClearGuild() { + m.clearedguild = true +} + +// GuildCleared reports if the "guild" edge to the Guild entity was cleared. +func (m *RolePanelPlacedMutation) GuildCleared() bool { + return m.clearedguild +} + +// GuildID returns the "guild" edge ID in the mutation. +func (m *RolePanelPlacedMutation) GuildID() (id snowflake.ID, exists bool) { + if m.guild != nil { + return *m.guild, true + } + return +} + +// GuildIDs returns the "guild" edge IDs in the mutation. +// Note that IDs always returns len(IDs) <= 1 for unique edges, and you should use +// GuildID instead. It exists only for internal usage by the builders. +func (m *RolePanelPlacedMutation) GuildIDs() (ids []snowflake.ID) { + if id := m.guild; id != nil { + ids = append(ids, *id) + } + return +} + +// ResetGuild resets all changes to the "guild" edge. +func (m *RolePanelPlacedMutation) ResetGuild() { + m.guild = nil + m.clearedguild = false +} + +// SetRolePanelID sets the "role_panel" edge to the RolePanel entity by id. +func (m *RolePanelPlacedMutation) SetRolePanelID(id uuid.UUID) { + m.role_panel = &id +} + +// ClearRolePanel clears the "role_panel" edge to the RolePanel entity. +func (m *RolePanelPlacedMutation) ClearRolePanel() { + m.clearedrole_panel = true +} + +// RolePanelCleared reports if the "role_panel" edge to the RolePanel entity was cleared. +func (m *RolePanelPlacedMutation) RolePanelCleared() bool { + return m.clearedrole_panel +} + +// RolePanelID returns the "role_panel" edge ID in the mutation. +func (m *RolePanelPlacedMutation) RolePanelID() (id uuid.UUID, exists bool) { + if m.role_panel != nil { + return *m.role_panel, true + } + return +} + +// RolePanelIDs returns the "role_panel" edge IDs in the mutation. +// Note that IDs always returns len(IDs) <= 1 for unique edges, and you should use +// RolePanelID instead. It exists only for internal usage by the builders. +func (m *RolePanelPlacedMutation) RolePanelIDs() (ids []uuid.UUID) { + if id := m.role_panel; id != nil { + ids = append(ids, *id) + } + return +} + +// ResetRolePanel resets all changes to the "role_panel" edge. +func (m *RolePanelPlacedMutation) ResetRolePanel() { + m.role_panel = nil + m.clearedrole_panel = false +} + +// Where appends a list predicates to the RolePanelPlacedMutation builder. +func (m *RolePanelPlacedMutation) Where(ps ...predicate.RolePanelPlaced) { + m.predicates = append(m.predicates, ps...) +} + +// WhereP appends storage-level predicates to the RolePanelPlacedMutation builder. Using this method, +// users can use type-assertion to append predicates that do not depend on any generated package. +func (m *RolePanelPlacedMutation) WhereP(ps ...func(*sql.Selector)) { + p := make([]predicate.RolePanelPlaced, len(ps)) + for i := range ps { + p[i] = ps[i] + } + m.Where(p...) +} + +// Op returns the operation name. +func (m *RolePanelPlacedMutation) Op() Op { + return m.op +} + +// SetOp allows setting the mutation operation. +func (m *RolePanelPlacedMutation) SetOp(op Op) { + m.op = op +} + +// Type returns the node type of this mutation (RolePanelPlaced). +func (m *RolePanelPlacedMutation) Type() string { + return m.typ +} + +// Fields returns all fields that were changed during this mutation. Note that in +// order to get all numeric fields that were incremented/decremented, call +// AddedFields(). +func (m *RolePanelPlacedMutation) Fields() []string { + fields := make([]string, 0, 14) + if m.message_id != nil { + fields = append(fields, rolepanelplaced.FieldMessageID) + } + if m.channel_id != nil { + fields = append(fields, rolepanelplaced.FieldChannelID) + } + if m._type != nil { + fields = append(fields, rolepanelplaced.FieldType) + } + if m.button_type != nil { + fields = append(fields, rolepanelplaced.FieldButtonType) + } + if m.show_name != nil { + fields = append(fields, rolepanelplaced.FieldShowName) + } + if m.folding_select_menu != nil { + fields = append(fields, rolepanelplaced.FieldFoldingSelectMenu) + } + if m.hide_notice != nil { + fields = append(fields, rolepanelplaced.FieldHideNotice) + } + if m.use_display_name != nil { + fields = append(fields, rolepanelplaced.FieldUseDisplayName) + } + if m.created_at != nil { + fields = append(fields, rolepanelplaced.FieldCreatedAt) + } + if m.uses != nil { + fields = append(fields, rolepanelplaced.FieldUses) + } + if m.name != nil { + fields = append(fields, rolepanelplaced.FieldName) + } + if m.description != nil { + fields = append(fields, rolepanelplaced.FieldDescription) + } + if m.roles != nil { + fields = append(fields, rolepanelplaced.FieldRoles) + } + if m.updated_at != nil { + fields = append(fields, rolepanelplaced.FieldUpdatedAt) + } + return fields +} + +// Field returns the value of a field with the given name. The second boolean +// return value indicates that this field was not set, or was not defined in the +// schema. +func (m *RolePanelPlacedMutation) Field(name string) (ent.Value, bool) { + switch name { + case rolepanelplaced.FieldMessageID: + return m.MessageID() + case rolepanelplaced.FieldChannelID: + return m.ChannelID() + case rolepanelplaced.FieldType: + return m.GetType() + case rolepanelplaced.FieldButtonType: + return m.ButtonType() + case rolepanelplaced.FieldShowName: + return m.ShowName() + case rolepanelplaced.FieldFoldingSelectMenu: + return m.FoldingSelectMenu() + case rolepanelplaced.FieldHideNotice: + return m.HideNotice() + case rolepanelplaced.FieldUseDisplayName: + return m.UseDisplayName() + case rolepanelplaced.FieldCreatedAt: + return m.CreatedAt() + case rolepanelplaced.FieldUses: + return m.Uses() + case rolepanelplaced.FieldName: + return m.Name() + case rolepanelplaced.FieldDescription: + return m.Description() + case rolepanelplaced.FieldRoles: + return m.Roles() + case rolepanelplaced.FieldUpdatedAt: + return m.UpdatedAt() + } + return nil, false +} + +// OldField returns the old value of the field from the database. An error is +// returned if the mutation operation is not UpdateOne, or the query to the +// database failed. +func (m *RolePanelPlacedMutation) OldField(ctx context.Context, name string) (ent.Value, error) { + switch name { + case rolepanelplaced.FieldMessageID: + return m.OldMessageID(ctx) + case rolepanelplaced.FieldChannelID: + return m.OldChannelID(ctx) + case rolepanelplaced.FieldType: + return m.OldType(ctx) + case rolepanelplaced.FieldButtonType: + return m.OldButtonType(ctx) + case rolepanelplaced.FieldShowName: + return m.OldShowName(ctx) + case rolepanelplaced.FieldFoldingSelectMenu: + return m.OldFoldingSelectMenu(ctx) + case rolepanelplaced.FieldHideNotice: + return m.OldHideNotice(ctx) + case rolepanelplaced.FieldUseDisplayName: + return m.OldUseDisplayName(ctx) + case rolepanelplaced.FieldCreatedAt: + return m.OldCreatedAt(ctx) + case rolepanelplaced.FieldUses: + return m.OldUses(ctx) + case rolepanelplaced.FieldName: + return m.OldName(ctx) + case rolepanelplaced.FieldDescription: + return m.OldDescription(ctx) + case rolepanelplaced.FieldRoles: + return m.OldRoles(ctx) + case rolepanelplaced.FieldUpdatedAt: + return m.OldUpdatedAt(ctx) + } + return nil, fmt.Errorf("unknown RolePanelPlaced field %s", name) +} + +// SetField sets the value of a field with the given name. It returns an error if +// the field is not defined in the schema, or if the type mismatched the field +// type. +func (m *RolePanelPlacedMutation) SetField(name string, value ent.Value) error { + switch name { + case rolepanelplaced.FieldMessageID: + v, ok := value.(snowflake.ID) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetMessageID(v) + return nil + case rolepanelplaced.FieldChannelID: + v, ok := value.(snowflake.ID) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetChannelID(v) + return nil + case rolepanelplaced.FieldType: + v, ok := value.(rolepanelplaced.Type) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetType(v) + return nil + case rolepanelplaced.FieldButtonType: + v, ok := value.(discord.ButtonStyle) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetButtonType(v) + return nil + case rolepanelplaced.FieldShowName: + v, ok := value.(bool) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetShowName(v) + return nil + case rolepanelplaced.FieldFoldingSelectMenu: + v, ok := value.(bool) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetFoldingSelectMenu(v) + return nil + case rolepanelplaced.FieldHideNotice: + v, ok := value.(bool) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetHideNotice(v) + return nil + case rolepanelplaced.FieldUseDisplayName: + v, ok := value.(bool) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetUseDisplayName(v) + return nil + case rolepanelplaced.FieldCreatedAt: + v, ok := value.(time.Time) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetCreatedAt(v) + return nil + case rolepanelplaced.FieldUses: + v, ok := value.(int) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetUses(v) + return nil + case rolepanelplaced.FieldName: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetName(v) + return nil + case rolepanelplaced.FieldDescription: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetDescription(v) + return nil + case rolepanelplaced.FieldRoles: + v, ok := value.([]schema.Role) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetRoles(v) + return nil + case rolepanelplaced.FieldUpdatedAt: + v, ok := value.(time.Time) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetUpdatedAt(v) + return nil + } + return fmt.Errorf("unknown RolePanelPlaced field %s", name) +} + +// AddedFields returns all numeric fields that were incremented/decremented during +// this mutation. +func (m *RolePanelPlacedMutation) AddedFields() []string { + var fields []string + if m.addmessage_id != nil { + fields = append(fields, rolepanelplaced.FieldMessageID) + } + if m.addchannel_id != nil { + fields = append(fields, rolepanelplaced.FieldChannelID) + } + if m.addbutton_type != nil { + fields = append(fields, rolepanelplaced.FieldButtonType) + } + if m.adduses != nil { + fields = append(fields, rolepanelplaced.FieldUses) + } + return fields +} + +// AddedField returns the numeric value that was incremented/decremented on a field +// with the given name. The second boolean return value indicates that this field +// was not set, or was not defined in the schema. +func (m *RolePanelPlacedMutation) AddedField(name string) (ent.Value, bool) { + switch name { + case rolepanelplaced.FieldMessageID: + return m.AddedMessageID() + case rolepanelplaced.FieldChannelID: + return m.AddedChannelID() + case rolepanelplaced.FieldButtonType: + return m.AddedButtonType() + case rolepanelplaced.FieldUses: + return m.AddedUses() + } + return nil, false +} + +// AddField adds the value to the field with the given name. It returns an error if +// the field is not defined in the schema, or if the type mismatched the field +// type. +func (m *RolePanelPlacedMutation) AddField(name string, value ent.Value) error { + switch name { + case rolepanelplaced.FieldMessageID: + v, ok := value.(snowflake.ID) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.AddMessageID(v) + return nil + case rolepanelplaced.FieldChannelID: + v, ok := value.(snowflake.ID) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.AddChannelID(v) + return nil + case rolepanelplaced.FieldButtonType: + v, ok := value.(discord.ButtonStyle) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.AddButtonType(v) + return nil + case rolepanelplaced.FieldUses: + v, ok := value.(int) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.AddUses(v) + return nil + } + return fmt.Errorf("unknown RolePanelPlaced numeric field %s", name) +} + +// ClearedFields returns all nullable fields that were cleared during this +// mutation. +func (m *RolePanelPlacedMutation) ClearedFields() []string { + var fields []string + if m.FieldCleared(rolepanelplaced.FieldMessageID) { + fields = append(fields, rolepanelplaced.FieldMessageID) + } + if m.FieldCleared(rolepanelplaced.FieldType) { + fields = append(fields, rolepanelplaced.FieldType) + } + if m.FieldCleared(rolepanelplaced.FieldRoles) { + fields = append(fields, rolepanelplaced.FieldRoles) + } + if m.FieldCleared(rolepanelplaced.FieldUpdatedAt) { + fields = append(fields, rolepanelplaced.FieldUpdatedAt) + } + return fields +} + +// FieldCleared returns a boolean indicating if a field with the given name was +// cleared in this mutation. +func (m *RolePanelPlacedMutation) FieldCleared(name string) bool { + _, ok := m.clearedFields[name] + return ok +} + +// ClearField clears the value of the field with the given name. It returns an +// error if the field is not defined in the schema. +func (m *RolePanelPlacedMutation) ClearField(name string) error { + switch name { + case rolepanelplaced.FieldMessageID: + m.ClearMessageID() + return nil + case rolepanelplaced.FieldType: + m.ClearType() + return nil + case rolepanelplaced.FieldRoles: + m.ClearRoles() + return nil + case rolepanelplaced.FieldUpdatedAt: + m.ClearUpdatedAt() + return nil + } + return fmt.Errorf("unknown RolePanelPlaced nullable field %s", name) +} + +// ResetField resets all changes in the mutation for the field with the given name. +// It returns an error if the field is not defined in the schema. +func (m *RolePanelPlacedMutation) ResetField(name string) error { + switch name { + case rolepanelplaced.FieldMessageID: + m.ResetMessageID() + return nil + case rolepanelplaced.FieldChannelID: + m.ResetChannelID() + return nil + case rolepanelplaced.FieldType: + m.ResetType() + return nil + case rolepanelplaced.FieldButtonType: + m.ResetButtonType() + return nil + case rolepanelplaced.FieldShowName: + m.ResetShowName() + return nil + case rolepanelplaced.FieldFoldingSelectMenu: + m.ResetFoldingSelectMenu() + return nil + case rolepanelplaced.FieldHideNotice: + m.ResetHideNotice() + return nil + case rolepanelplaced.FieldUseDisplayName: + m.ResetUseDisplayName() + return nil + case rolepanelplaced.FieldCreatedAt: + m.ResetCreatedAt() + return nil + case rolepanelplaced.FieldUses: + m.ResetUses() + return nil + case rolepanelplaced.FieldName: + m.ResetName() + return nil + case rolepanelplaced.FieldDescription: + m.ResetDescription() + return nil + case rolepanelplaced.FieldRoles: + m.ResetRoles() + return nil + case rolepanelplaced.FieldUpdatedAt: + m.ResetUpdatedAt() + return nil + } + return fmt.Errorf("unknown RolePanelPlaced field %s", name) +} + +// AddedEdges returns all edge names that were set/added in this mutation. +func (m *RolePanelPlacedMutation) AddedEdges() []string { + edges := make([]string, 0, 2) + if m.guild != nil { + edges = append(edges, rolepanelplaced.EdgeGuild) + } + if m.role_panel != nil { + edges = append(edges, rolepanelplaced.EdgeRolePanel) + } + return edges +} + +// AddedIDs returns all IDs (to other nodes) that were added for the given edge +// name in this mutation. +func (m *RolePanelPlacedMutation) AddedIDs(name string) []ent.Value { + switch name { + case rolepanelplaced.EdgeGuild: + if id := m.guild; id != nil { + return []ent.Value{*id} + } + case rolepanelplaced.EdgeRolePanel: + if id := m.role_panel; id != nil { + return []ent.Value{*id} + } + } + return nil +} + +// RemovedEdges returns all edge names that were removed in this mutation. +func (m *RolePanelPlacedMutation) RemovedEdges() []string { + edges := make([]string, 0, 2) + return edges +} + +// RemovedIDs returns all IDs (to other nodes) that were removed for the edge with +// the given name in this mutation. +func (m *RolePanelPlacedMutation) RemovedIDs(name string) []ent.Value { + return nil +} + +// ClearedEdges returns all edge names that were cleared in this mutation. +func (m *RolePanelPlacedMutation) ClearedEdges() []string { + edges := make([]string, 0, 2) + if m.clearedguild { + edges = append(edges, rolepanelplaced.EdgeGuild) + } + if m.clearedrole_panel { + edges = append(edges, rolepanelplaced.EdgeRolePanel) + } + return edges +} + +// EdgeCleared returns a boolean which indicates if the edge with the given name +// was cleared in this mutation. +func (m *RolePanelPlacedMutation) EdgeCleared(name string) bool { + switch name { + case rolepanelplaced.EdgeGuild: + return m.clearedguild + case rolepanelplaced.EdgeRolePanel: + return m.clearedrole_panel + } + return false +} + +// ClearEdge clears the value of the edge with the given name. It returns an error +// if that edge is not defined in the schema. +func (m *RolePanelPlacedMutation) ClearEdge(name string) error { + switch name { + case rolepanelplaced.EdgeGuild: + m.ClearGuild() + return nil + case rolepanelplaced.EdgeRolePanel: + m.ClearRolePanel() + return nil + } + return fmt.Errorf("unknown RolePanelPlaced unique edge %s", name) +} + +// ResetEdge resets all changes to the edge with the given name in this mutation. +// It returns an error if the edge is not defined in the schema. +func (m *RolePanelPlacedMutation) ResetEdge(name string) error { + switch name { + case rolepanelplaced.EdgeGuild: + m.ResetGuild() + return nil + case rolepanelplaced.EdgeRolePanel: + m.ResetRolePanel() + return nil + } + return fmt.Errorf("unknown RolePanelPlaced edge %s", name) +} + +// UserMutation represents an operation that mutates the User nodes in the graph. +type UserMutation struct { + config + op Op + typ string + id *snowflake.ID + name *string + created_at *time.Time + locale *discord.Locale + xp *xppoint.XP + addxp *xppoint.XP + clearedFields map[string]struct{} + own_guilds map[snowflake.ID]struct{} + removedown_guilds map[snowflake.ID]struct{} + clearedown_guilds bool + guilds map[int]struct{} + removedguilds map[int]struct{} + clearedguilds bool + word_suffix map[uuid.UUID]struct{} + removedword_suffix map[uuid.UUID]struct{} + clearedword_suffix bool + done bool + oldValue func(context.Context) (*User, error) + predicates []predicate.User +} + +var _ ent.Mutation = (*UserMutation)(nil) + +// userOption allows management of the mutation configuration using functional options. +type userOption func(*UserMutation) + +// newUserMutation creates new mutation for the User entity. +func newUserMutation(c config, op Op, opts ...userOption) *UserMutation { + m := &UserMutation{ + config: c, + op: op, + typ: TypeUser, + clearedFields: make(map[string]struct{}), + } + for _, opt := range opts { + opt(m) + } + return m +} + +// withUserID sets the ID field of the mutation. +func withUserID(id snowflake.ID) userOption { + return func(m *UserMutation) { + var ( + err error + once sync.Once + value *User + ) + m.oldValue = func(ctx context.Context) (*User, error) { + once.Do(func() { + if m.done { + err = errors.New("querying old values post mutation is not allowed") + } else { + value, err = m.Client().User.Get(ctx, id) + } + }) + return value, err + } + m.id = &id + } +} + +// withUser sets the old User of the mutation. +func withUser(node *User) userOption { + return func(m *UserMutation) { + m.oldValue = func(context.Context) (*User, error) { + return node, nil + } + m.id = &node.ID + } +} + +// Client returns a new `ent.Client` from the mutation. If the mutation was +// executed in a transaction (ent.Tx), a transactional client is returned. +func (m UserMutation) Client() *Client { + client := &Client{config: m.config} + client.init() + return client +} + +// Tx returns an `ent.Tx` for mutations that were executed in transactions; +// it returns an error otherwise. +func (m UserMutation) Tx() (*Tx, error) { + if _, ok := m.driver.(*txDriver); !ok { + return nil, errors.New("ent: mutation is not running in a transaction") + } + tx := &Tx{config: m.config} + tx.init() + return tx, nil +} + +// SetID sets the value of the id field. Note that this +// operation is only accepted on creation of User entities. +func (m *UserMutation) SetID(id snowflake.ID) { + m.id = &id +} + +// ID returns the ID value in the mutation. Note that the ID is only available +// if it was provided to the builder or after it was returned from the database. +func (m *UserMutation) ID() (id snowflake.ID, exists bool) { + if m.id == nil { + return + } + return *m.id, true +} + +// IDs queries the database and returns the entity ids that match the mutation's predicate. +// That means, if the mutation is applied within a transaction with an isolation level such +// as sql.LevelSerializable, the returned ids match the ids of the rows that will be updated +// or updated by the mutation. +func (m *UserMutation) IDs(ctx context.Context) ([]snowflake.ID, error) { + switch { + case m.op.Is(OpUpdateOne | OpDeleteOne): + id, exists := m.ID() + if exists { + return []snowflake.ID{id}, nil + } + fallthrough + case m.op.Is(OpUpdate | OpDelete): + return m.Client().User.Query().Where(m.predicates...).IDs(ctx) + default: + return nil, fmt.Errorf("IDs is not allowed on %s operations", m.op) + } +} + +// SetName sets the "name" field. +func (m *UserMutation) SetName(s string) { + m.name = &s +} + +// Name returns the value of the "name" field in the mutation. +func (m *UserMutation) Name() (r string, exists bool) { + v := m.name + if v == nil { + return + } + return *v, true +} + +// OldName returns the old "name" field's value of the User entity. +// If the User object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *UserMutation) OldName(ctx context.Context) (v string, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldName is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldName requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldName: %w", err) + } + return oldValue.Name, nil +} + +// ResetName resets all changes to the "name" field. +func (m *UserMutation) ResetName() { + m.name = nil +} + +// SetCreatedAt sets the "created_at" field. +func (m *UserMutation) SetCreatedAt(t time.Time) { + m.created_at = &t +} + +// CreatedAt returns the value of the "created_at" field in the mutation. +func (m *UserMutation) CreatedAt() (r time.Time, exists bool) { + v := m.created_at + if v == nil { + return + } + return *v, true +} + +// OldCreatedAt returns the old "created_at" field's value of the User entity. +// If the User object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *UserMutation) OldCreatedAt(ctx context.Context) (v time.Time, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldCreatedAt is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldCreatedAt requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldCreatedAt: %w", err) + } + return oldValue.CreatedAt, nil +} + +// ResetCreatedAt resets all changes to the "created_at" field. +func (m *UserMutation) ResetCreatedAt() { + m.created_at = nil +} + +// SetLocale sets the "locale" field. +func (m *UserMutation) SetLocale(d discord.Locale) { + m.locale = &d +} + +// Locale returns the value of the "locale" field in the mutation. +func (m *UserMutation) Locale() (r discord.Locale, exists bool) { + v := m.locale + if v == nil { + return + } + return *v, true +} + +// OldLocale returns the old "locale" field's value of the User entity. +// If the User object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *UserMutation) OldLocale(ctx context.Context) (v discord.Locale, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldLocale is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldLocale requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldLocale: %w", err) + } + return oldValue.Locale, nil +} + +// ResetLocale resets all changes to the "locale" field. +func (m *UserMutation) ResetLocale() { + m.locale = nil +} + +// SetXp sets the "xp" field. +func (m *UserMutation) SetXp(x xppoint.XP) { + m.xp = &x + m.addxp = nil +} + +// Xp returns the value of the "xp" field in the mutation. +func (m *UserMutation) Xp() (r xppoint.XP, exists bool) { + v := m.xp + if v == nil { + return + } + return *v, true +} + +// OldXp returns the old "xp" field's value of the User entity. +// If the User object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *UserMutation) OldXp(ctx context.Context) (v xppoint.XP, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldXp is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldXp requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldXp: %w", err) + } + return oldValue.Xp, nil +} + +// AddXp adds x to the "xp" field. +func (m *UserMutation) AddXp(x xppoint.XP) { + if m.addxp != nil { + *m.addxp += x + } else { + m.addxp = &x + } +} + +// AddedXp returns the value that was added to the "xp" field in this mutation. +func (m *UserMutation) AddedXp() (r xppoint.XP, exists bool) { + v := m.addxp + if v == nil { + return + } + return *v, true +} + +// ResetXp resets all changes to the "xp" field. +func (m *UserMutation) ResetXp() { + m.xp = nil + m.addxp = nil +} + +// AddOwnGuildIDs adds the "own_guilds" edge to the Guild entity by ids. +func (m *UserMutation) AddOwnGuildIDs(ids ...snowflake.ID) { + if m.own_guilds == nil { + m.own_guilds = make(map[snowflake.ID]struct{}) + } + for i := range ids { + m.own_guilds[ids[i]] = struct{}{} + } +} + +// ClearOwnGuilds clears the "own_guilds" edge to the Guild entity. +func (m *UserMutation) ClearOwnGuilds() { + m.clearedown_guilds = true +} + +// OwnGuildsCleared reports if the "own_guilds" edge to the Guild entity was cleared. +func (m *UserMutation) OwnGuildsCleared() bool { + return m.clearedown_guilds +} + +// RemoveOwnGuildIDs removes the "own_guilds" edge to the Guild entity by IDs. +func (m *UserMutation) RemoveOwnGuildIDs(ids ...snowflake.ID) { + if m.removedown_guilds == nil { + m.removedown_guilds = make(map[snowflake.ID]struct{}) + } + for i := range ids { + delete(m.own_guilds, ids[i]) + m.removedown_guilds[ids[i]] = struct{}{} + } +} + +// RemovedOwnGuilds returns the removed IDs of the "own_guilds" edge to the Guild entity. +func (m *UserMutation) RemovedOwnGuildsIDs() (ids []snowflake.ID) { + for id := range m.removedown_guilds { + ids = append(ids, id) + } + return +} + +// OwnGuildsIDs returns the "own_guilds" edge IDs in the mutation. +func (m *UserMutation) OwnGuildsIDs() (ids []snowflake.ID) { + for id := range m.own_guilds { + ids = append(ids, id) + } + return +} + +// ResetOwnGuilds resets all changes to the "own_guilds" edge. +func (m *UserMutation) ResetOwnGuilds() { + m.own_guilds = nil + m.clearedown_guilds = false + m.removedown_guilds = nil +} + +// AddGuildIDs adds the "guilds" edge to the Member entity by ids. +func (m *UserMutation) AddGuildIDs(ids ...int) { + if m.guilds == nil { + m.guilds = make(map[int]struct{}) + } + for i := range ids { + m.guilds[ids[i]] = struct{}{} + } +} + +// ClearGuilds clears the "guilds" edge to the Member entity. +func (m *UserMutation) ClearGuilds() { + m.clearedguilds = true +} + +// GuildsCleared reports if the "guilds" edge to the Member entity was cleared. +func (m *UserMutation) GuildsCleared() bool { + return m.clearedguilds +} + +// RemoveGuildIDs removes the "guilds" edge to the Member entity by IDs. +func (m *UserMutation) RemoveGuildIDs(ids ...int) { + if m.removedguilds == nil { + m.removedguilds = make(map[int]struct{}) + } + for i := range ids { + delete(m.guilds, ids[i]) + m.removedguilds[ids[i]] = struct{}{} + } +} + +// RemovedGuilds returns the removed IDs of the "guilds" edge to the Member entity. +func (m *UserMutation) RemovedGuildsIDs() (ids []int) { + for id := range m.removedguilds { + ids = append(ids, id) + } + return +} + +// GuildsIDs returns the "guilds" edge IDs in the mutation. +func (m *UserMutation) GuildsIDs() (ids []int) { + for id := range m.guilds { + ids = append(ids, id) + } + return +} + +// ResetGuilds resets all changes to the "guilds" edge. +func (m *UserMutation) ResetGuilds() { + m.guilds = nil + m.clearedguilds = false + m.removedguilds = nil +} + +// AddWordSuffixIDs adds the "word_suffix" edge to the WordSuffix entity by ids. +func (m *UserMutation) AddWordSuffixIDs(ids ...uuid.UUID) { + if m.word_suffix == nil { + m.word_suffix = make(map[uuid.UUID]struct{}) + } + for i := range ids { + m.word_suffix[ids[i]] = struct{}{} + } +} + +// ClearWordSuffix clears the "word_suffix" edge to the WordSuffix entity. +func (m *UserMutation) ClearWordSuffix() { + m.clearedword_suffix = true +} + +// WordSuffixCleared reports if the "word_suffix" edge to the WordSuffix entity was cleared. +func (m *UserMutation) WordSuffixCleared() bool { + return m.clearedword_suffix +} + +// RemoveWordSuffixIDs removes the "word_suffix" edge to the WordSuffix entity by IDs. +func (m *UserMutation) RemoveWordSuffixIDs(ids ...uuid.UUID) { + if m.removedword_suffix == nil { + m.removedword_suffix = make(map[uuid.UUID]struct{}) + } + for i := range ids { + delete(m.word_suffix, ids[i]) + m.removedword_suffix[ids[i]] = struct{}{} + } +} + +// RemovedWordSuffix returns the removed IDs of the "word_suffix" edge to the WordSuffix entity. +func (m *UserMutation) RemovedWordSuffixIDs() (ids []uuid.UUID) { + for id := range m.removedword_suffix { + ids = append(ids, id) + } + return +} + +// WordSuffixIDs returns the "word_suffix" edge IDs in the mutation. +func (m *UserMutation) WordSuffixIDs() (ids []uuid.UUID) { + for id := range m.word_suffix { + ids = append(ids, id) + } + return +} + +// ResetWordSuffix resets all changes to the "word_suffix" edge. +func (m *UserMutation) ResetWordSuffix() { + m.word_suffix = nil + m.clearedword_suffix = false + m.removedword_suffix = nil +} + +// Where appends a list predicates to the UserMutation builder. +func (m *UserMutation) Where(ps ...predicate.User) { + m.predicates = append(m.predicates, ps...) +} + +// WhereP appends storage-level predicates to the UserMutation builder. Using this method, +// users can use type-assertion to append predicates that do not depend on any generated package. +func (m *UserMutation) WhereP(ps ...func(*sql.Selector)) { + p := make([]predicate.User, len(ps)) + for i := range ps { + p[i] = ps[i] + } + m.Where(p...) +} + +// Op returns the operation name. +func (m *UserMutation) Op() Op { + return m.op +} + +// SetOp allows setting the mutation operation. +func (m *UserMutation) SetOp(op Op) { + m.op = op +} + +// Type returns the node type of this mutation (User). +func (m *UserMutation) Type() string { + return m.typ +} + +// Fields returns all fields that were changed during this mutation. Note that in +// order to get all numeric fields that were incremented/decremented, call +// AddedFields(). +func (m *UserMutation) Fields() []string { + fields := make([]string, 0, 4) + if m.name != nil { + fields = append(fields, user.FieldName) + } + if m.created_at != nil { + fields = append(fields, user.FieldCreatedAt) + } + if m.locale != nil { + fields = append(fields, user.FieldLocale) + } + if m.xp != nil { + fields = append(fields, user.FieldXp) + } + return fields +} + +// Field returns the value of a field with the given name. The second boolean +// return value indicates that this field was not set, or was not defined in the +// schema. +func (m *UserMutation) Field(name string) (ent.Value, bool) { + switch name { + case user.FieldName: + return m.Name() + case user.FieldCreatedAt: + return m.CreatedAt() + case user.FieldLocale: + return m.Locale() + case user.FieldXp: + return m.Xp() + } + return nil, false +} + +// OldField returns the old value of the field from the database. An error is +// returned if the mutation operation is not UpdateOne, or the query to the +// database failed. +func (m *UserMutation) OldField(ctx context.Context, name string) (ent.Value, error) { + switch name { + case user.FieldName: + return m.OldName(ctx) + case user.FieldCreatedAt: + return m.OldCreatedAt(ctx) + case user.FieldLocale: + return m.OldLocale(ctx) + case user.FieldXp: + return m.OldXp(ctx) + } + return nil, fmt.Errorf("unknown User field %s", name) +} + +// SetField sets the value of a field with the given name. It returns an error if +// the field is not defined in the schema, or if the type mismatched the field +// type. +func (m *UserMutation) SetField(name string, value ent.Value) error { + switch name { + case user.FieldName: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetName(v) + return nil + case user.FieldCreatedAt: + v, ok := value.(time.Time) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetCreatedAt(v) + return nil + case user.FieldLocale: + v, ok := value.(discord.Locale) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetLocale(v) + return nil + case user.FieldXp: + v, ok := value.(xppoint.XP) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetXp(v) + return nil + } + return fmt.Errorf("unknown User field %s", name) +} + +// AddedFields returns all numeric fields that were incremented/decremented during +// this mutation. +func (m *UserMutation) AddedFields() []string { + var fields []string + if m.addxp != nil { + fields = append(fields, user.FieldXp) + } + return fields +} + +// AddedField returns the numeric value that was incremented/decremented on a field +// with the given name. The second boolean return value indicates that this field +// was not set, or was not defined in the schema. +func (m *UserMutation) AddedField(name string) (ent.Value, bool) { + switch name { + case user.FieldXp: + return m.AddedXp() + } + return nil, false +} + +// AddField adds the value to the field with the given name. It returns an error if +// the field is not defined in the schema, or if the type mismatched the field +// type. +func (m *UserMutation) AddField(name string, value ent.Value) error { + switch name { + case user.FieldXp: + v, ok := value.(xppoint.XP) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.AddXp(v) + return nil + } + return fmt.Errorf("unknown User numeric field %s", name) +} + +// ClearedFields returns all nullable fields that were cleared during this +// mutation. +func (m *UserMutation) ClearedFields() []string { + return nil +} + +// FieldCleared returns a boolean indicating if a field with the given name was +// cleared in this mutation. +func (m *UserMutation) FieldCleared(name string) bool { + _, ok := m.clearedFields[name] + return ok +} + +// ClearField clears the value of the field with the given name. It returns an +// error if the field is not defined in the schema. +func (m *UserMutation) ClearField(name string) error { + return fmt.Errorf("unknown User nullable field %s", name) +} + +// ResetField resets all changes in the mutation for the field with the given name. +// It returns an error if the field is not defined in the schema. +func (m *UserMutation) ResetField(name string) error { + switch name { + case user.FieldName: + m.ResetName() + return nil + case user.FieldCreatedAt: + m.ResetCreatedAt() + return nil + case user.FieldLocale: + m.ResetLocale() + return nil + case user.FieldXp: + m.ResetXp() + return nil + } + return fmt.Errorf("unknown User field %s", name) +} + +// AddedEdges returns all edge names that were set/added in this mutation. +func (m *UserMutation) AddedEdges() []string { + edges := make([]string, 0, 3) + if m.own_guilds != nil { + edges = append(edges, user.EdgeOwnGuilds) + } + if m.guilds != nil { + edges = append(edges, user.EdgeGuilds) + } + if m.word_suffix != nil { + edges = append(edges, user.EdgeWordSuffix) + } + return edges +} + +// AddedIDs returns all IDs (to other nodes) that were added for the given edge +// name in this mutation. +func (m *UserMutation) AddedIDs(name string) []ent.Value { + switch name { + case user.EdgeOwnGuilds: + ids := make([]ent.Value, 0, len(m.own_guilds)) + for id := range m.own_guilds { + ids = append(ids, id) + } + return ids + case user.EdgeGuilds: + ids := make([]ent.Value, 0, len(m.guilds)) + for id := range m.guilds { + ids = append(ids, id) + } + return ids + case user.EdgeWordSuffix: + ids := make([]ent.Value, 0, len(m.word_suffix)) + for id := range m.word_suffix { + ids = append(ids, id) + } + return ids + } + return nil +} + +// RemovedEdges returns all edge names that were removed in this mutation. +func (m *UserMutation) RemovedEdges() []string { + edges := make([]string, 0, 3) + if m.removedown_guilds != nil { + edges = append(edges, user.EdgeOwnGuilds) + } + if m.removedguilds != nil { + edges = append(edges, user.EdgeGuilds) + } + if m.removedword_suffix != nil { + edges = append(edges, user.EdgeWordSuffix) + } + return edges +} + +// RemovedIDs returns all IDs (to other nodes) that were removed for the edge with +// the given name in this mutation. +func (m *UserMutation) RemovedIDs(name string) []ent.Value { + switch name { + case user.EdgeOwnGuilds: + ids := make([]ent.Value, 0, len(m.removedown_guilds)) + for id := range m.removedown_guilds { + ids = append(ids, id) + } + return ids + case user.EdgeGuilds: + ids := make([]ent.Value, 0, len(m.removedguilds)) + for id := range m.removedguilds { + ids = append(ids, id) + } + return ids + case user.EdgeWordSuffix: + ids := make([]ent.Value, 0, len(m.removedword_suffix)) + for id := range m.removedword_suffix { + ids = append(ids, id) + } + return ids + } + return nil +} + +// ClearedEdges returns all edge names that were cleared in this mutation. +func (m *UserMutation) ClearedEdges() []string { + edges := make([]string, 0, 3) + if m.clearedown_guilds { + edges = append(edges, user.EdgeOwnGuilds) + } + if m.clearedguilds { + edges = append(edges, user.EdgeGuilds) + } + if m.clearedword_suffix { + edges = append(edges, user.EdgeWordSuffix) + } + return edges +} + +// EdgeCleared returns a boolean which indicates if the edge with the given name +// was cleared in this mutation. +func (m *UserMutation) EdgeCleared(name string) bool { + switch name { + case user.EdgeOwnGuilds: + return m.clearedown_guilds + case user.EdgeGuilds: + return m.clearedguilds + case user.EdgeWordSuffix: + return m.clearedword_suffix + } + return false +} + +// ClearEdge clears the value of the edge with the given name. It returns an error +// if that edge is not defined in the schema. +func (m *UserMutation) ClearEdge(name string) error { + switch name { + } + return fmt.Errorf("unknown User unique edge %s", name) +} + +// ResetEdge resets all changes to the edge with the given name in this mutation. +// It returns an error if the edge is not defined in the schema. +func (m *UserMutation) ResetEdge(name string) error { + switch name { + case user.EdgeOwnGuilds: + m.ResetOwnGuilds() + return nil + case user.EdgeGuilds: + m.ResetGuilds() + return nil + case user.EdgeWordSuffix: + m.ResetWordSuffix() + return nil + } + return fmt.Errorf("unknown User edge %s", name) +} + +// WordSuffixMutation represents an operation that mutates the WordSuffix nodes in the graph. +type WordSuffixMutation struct { + config + op Op + typ string + id *uuid.UUID + suffix *string + expired *time.Time + rule *wordsuffix.Rule + clearedFields map[string]struct{} + guild *snowflake.ID + clearedguild bool + owner *snowflake.ID + clearedowner bool + done bool + oldValue func(context.Context) (*WordSuffix, error) + predicates []predicate.WordSuffix +} + +var _ ent.Mutation = (*WordSuffixMutation)(nil) + +// wordsuffixOption allows management of the mutation configuration using functional options. +type wordsuffixOption func(*WordSuffixMutation) + +// newWordSuffixMutation creates new mutation for the WordSuffix entity. +func newWordSuffixMutation(c config, op Op, opts ...wordsuffixOption) *WordSuffixMutation { + m := &WordSuffixMutation{ + config: c, + op: op, + typ: TypeWordSuffix, + clearedFields: make(map[string]struct{}), + } + for _, opt := range opts { + opt(m) + } + return m +} + +// withWordSuffixID sets the ID field of the mutation. +func withWordSuffixID(id uuid.UUID) wordsuffixOption { + return func(m *WordSuffixMutation) { + var ( + err error + once sync.Once + value *WordSuffix + ) + m.oldValue = func(ctx context.Context) (*WordSuffix, error) { + once.Do(func() { + if m.done { + err = errors.New("querying old values post mutation is not allowed") + } else { + value, err = m.Client().WordSuffix.Get(ctx, id) + } + }) + return value, err + } + m.id = &id + } +} + +// withWordSuffix sets the old WordSuffix of the mutation. +func withWordSuffix(node *WordSuffix) wordsuffixOption { + return func(m *WordSuffixMutation) { + m.oldValue = func(context.Context) (*WordSuffix, error) { + return node, nil + } + m.id = &node.ID + } +} + +// Client returns a new `ent.Client` from the mutation. If the mutation was +// executed in a transaction (ent.Tx), a transactional client is returned. +func (m WordSuffixMutation) Client() *Client { + client := &Client{config: m.config} + client.init() + return client +} + +// Tx returns an `ent.Tx` for mutations that were executed in transactions; +// it returns an error otherwise. +func (m WordSuffixMutation) Tx() (*Tx, error) { + if _, ok := m.driver.(*txDriver); !ok { + return nil, errors.New("ent: mutation is not running in a transaction") + } + tx := &Tx{config: m.config} + tx.init() + return tx, nil +} + +// SetID sets the value of the id field. Note that this +// operation is only accepted on creation of WordSuffix entities. +func (m *WordSuffixMutation) SetID(id uuid.UUID) { + m.id = &id +} + +// ID returns the ID value in the mutation. Note that the ID is only available +// if it was provided to the builder or after it was returned from the database. +func (m *WordSuffixMutation) ID() (id uuid.UUID, exists bool) { + if m.id == nil { + return + } + return *m.id, true +} + +// IDs queries the database and returns the entity ids that match the mutation's predicate. +// That means, if the mutation is applied within a transaction with an isolation level such +// as sql.LevelSerializable, the returned ids match the ids of the rows that will be updated +// or updated by the mutation. +func (m *WordSuffixMutation) IDs(ctx context.Context) ([]uuid.UUID, error) { + switch { + case m.op.Is(OpUpdateOne | OpDeleteOne): + id, exists := m.ID() + if exists { + return []uuid.UUID{id}, nil + } + fallthrough + case m.op.Is(OpUpdate | OpDelete): + return m.Client().WordSuffix.Query().Where(m.predicates...).IDs(ctx) + default: + return nil, fmt.Errorf("IDs is not allowed on %s operations", m.op) + } +} + +// SetSuffix sets the "suffix" field. +func (m *WordSuffixMutation) SetSuffix(s string) { + m.suffix = &s +} + +// Suffix returns the value of the "suffix" field in the mutation. +func (m *WordSuffixMutation) Suffix() (r string, exists bool) { + v := m.suffix + if v == nil { + return + } + return *v, true +} + +// OldSuffix returns the old "suffix" field's value of the WordSuffix entity. +// If the WordSuffix object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *WordSuffixMutation) OldSuffix(ctx context.Context) (v string, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldSuffix is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldSuffix requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldSuffix: %w", err) + } + return oldValue.Suffix, nil +} + +// ResetSuffix resets all changes to the "suffix" field. +func (m *WordSuffixMutation) ResetSuffix() { + m.suffix = nil +} + +// SetExpired sets the "expired" field. +func (m *WordSuffixMutation) SetExpired(t time.Time) { + m.expired = &t +} + +// Expired returns the value of the "expired" field in the mutation. +func (m *WordSuffixMutation) Expired() (r time.Time, exists bool) { + v := m.expired + if v == nil { + return + } + return *v, true +} + +// OldExpired returns the old "expired" field's value of the WordSuffix entity. +// If the WordSuffix object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *WordSuffixMutation) OldExpired(ctx context.Context) (v *time.Time, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldExpired is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldExpired requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldExpired: %w", err) + } + return oldValue.Expired, nil +} + +// ClearExpired clears the value of the "expired" field. +func (m *WordSuffixMutation) ClearExpired() { + m.expired = nil + m.clearedFields[wordsuffix.FieldExpired] = struct{}{} +} + +// ExpiredCleared returns if the "expired" field was cleared in this mutation. +func (m *WordSuffixMutation) ExpiredCleared() bool { + _, ok := m.clearedFields[wordsuffix.FieldExpired] + return ok +} + +// ResetExpired resets all changes to the "expired" field. +func (m *WordSuffixMutation) ResetExpired() { + m.expired = nil + delete(m.clearedFields, wordsuffix.FieldExpired) +} + +// SetGuildID sets the "guild_id" field. +func (m *WordSuffixMutation) SetGuildID(s snowflake.ID) { + m.guild = &s +} + +// GuildID returns the value of the "guild_id" field in the mutation. +func (m *WordSuffixMutation) GuildID() (r snowflake.ID, exists bool) { + v := m.guild + if v == nil { + return + } + return *v, true +} + +// OldGuildID returns the old "guild_id" field's value of the WordSuffix entity. +// If the WordSuffix object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *WordSuffixMutation) OldGuildID(ctx context.Context) (v *snowflake.ID, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldGuildID is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldGuildID requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldGuildID: %w", err) + } + return oldValue.GuildID, nil +} + +// ClearGuildID clears the value of the "guild_id" field. +func (m *WordSuffixMutation) ClearGuildID() { + m.guild = nil + m.clearedFields[wordsuffix.FieldGuildID] = struct{}{} +} + +// GuildIDCleared returns if the "guild_id" field was cleared in this mutation. +func (m *WordSuffixMutation) GuildIDCleared() bool { + _, ok := m.clearedFields[wordsuffix.FieldGuildID] + return ok +} + +// ResetGuildID resets all changes to the "guild_id" field. +func (m *WordSuffixMutation) ResetGuildID() { + m.guild = nil + delete(m.clearedFields, wordsuffix.FieldGuildID) +} + +// SetRule sets the "rule" field. +func (m *WordSuffixMutation) SetRule(w wordsuffix.Rule) { + m.rule = &w +} + +// Rule returns the value of the "rule" field in the mutation. +func (m *WordSuffixMutation) Rule() (r wordsuffix.Rule, exists bool) { + v := m.rule + if v == nil { + return + } + return *v, true +} + +// OldRule returns the old "rule" field's value of the WordSuffix entity. +// If the WordSuffix object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *WordSuffixMutation) OldRule(ctx context.Context) (v wordsuffix.Rule, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldRule is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldRule requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldRule: %w", err) + } + return oldValue.Rule, nil +} + +// ResetRule resets all changes to the "rule" field. +func (m *WordSuffixMutation) ResetRule() { + m.rule = nil +} + +// ClearGuild clears the "guild" edge to the Guild entity. +func (m *WordSuffixMutation) ClearGuild() { + m.clearedguild = true + m.clearedFields[wordsuffix.FieldGuildID] = struct{}{} +} + +// GuildCleared reports if the "guild" edge to the Guild entity was cleared. +func (m *WordSuffixMutation) GuildCleared() bool { + return m.GuildIDCleared() || m.clearedguild +} + +// GuildIDs returns the "guild" edge IDs in the mutation. +// Note that IDs always returns len(IDs) <= 1 for unique edges, and you should use +// GuildID instead. It exists only for internal usage by the builders. +func (m *WordSuffixMutation) GuildIDs() (ids []snowflake.ID) { + if id := m.guild; id != nil { + ids = append(ids, *id) + } + return +} + +// ResetGuild resets all changes to the "guild" edge. +func (m *WordSuffixMutation) ResetGuild() { + m.guild = nil + m.clearedguild = false +} + +// SetOwnerID sets the "owner" edge to the User entity by id. +func (m *WordSuffixMutation) SetOwnerID(id snowflake.ID) { + m.owner = &id +} + +// ClearOwner clears the "owner" edge to the User entity. +func (m *WordSuffixMutation) ClearOwner() { + m.clearedowner = true +} + +// OwnerCleared reports if the "owner" edge to the User entity was cleared. +func (m *WordSuffixMutation) OwnerCleared() bool { + return m.clearedowner +} + +// OwnerID returns the "owner" edge ID in the mutation. +func (m *WordSuffixMutation) OwnerID() (id snowflake.ID, exists bool) { + if m.owner != nil { + return *m.owner, true + } + return +} + +// OwnerIDs returns the "owner" edge IDs in the mutation. +// Note that IDs always returns len(IDs) <= 1 for unique edges, and you should use +// OwnerID instead. It exists only for internal usage by the builders. +func (m *WordSuffixMutation) OwnerIDs() (ids []snowflake.ID) { + if id := m.owner; id != nil { + ids = append(ids, *id) + } + return +} + +// ResetOwner resets all changes to the "owner" edge. +func (m *WordSuffixMutation) ResetOwner() { + m.owner = nil + m.clearedowner = false +} + +// Where appends a list predicates to the WordSuffixMutation builder. +func (m *WordSuffixMutation) Where(ps ...predicate.WordSuffix) { + m.predicates = append(m.predicates, ps...) +} + +// WhereP appends storage-level predicates to the WordSuffixMutation builder. Using this method, +// users can use type-assertion to append predicates that do not depend on any generated package. +func (m *WordSuffixMutation) WhereP(ps ...func(*sql.Selector)) { + p := make([]predicate.WordSuffix, len(ps)) + for i := range ps { + p[i] = ps[i] + } + m.Where(p...) +} + +// Op returns the operation name. +func (m *WordSuffixMutation) Op() Op { + return m.op +} + +// SetOp allows setting the mutation operation. +func (m *WordSuffixMutation) SetOp(op Op) { + m.op = op +} + +// Type returns the node type of this mutation (WordSuffix). +func (m *WordSuffixMutation) Type() string { + return m.typ +} + +// Fields returns all fields that were changed during this mutation. Note that in +// order to get all numeric fields that were incremented/decremented, call +// AddedFields(). +func (m *WordSuffixMutation) Fields() []string { + fields := make([]string, 0, 4) + if m.suffix != nil { + fields = append(fields, wordsuffix.FieldSuffix) + } + if m.expired != nil { + fields = append(fields, wordsuffix.FieldExpired) + } + if m.guild != nil { + fields = append(fields, wordsuffix.FieldGuildID) + } + if m.rule != nil { + fields = append(fields, wordsuffix.FieldRule) + } + return fields +} + +// Field returns the value of a field with the given name. The second boolean +// return value indicates that this field was not set, or was not defined in the +// schema. +func (m *WordSuffixMutation) Field(name string) (ent.Value, bool) { + switch name { + case wordsuffix.FieldSuffix: + return m.Suffix() + case wordsuffix.FieldExpired: + return m.Expired() + case wordsuffix.FieldGuildID: + return m.GuildID() + case wordsuffix.FieldRule: + return m.Rule() + } + return nil, false +} + +// OldField returns the old value of the field from the database. An error is +// returned if the mutation operation is not UpdateOne, or the query to the +// database failed. +func (m *WordSuffixMutation) OldField(ctx context.Context, name string) (ent.Value, error) { + switch name { + case wordsuffix.FieldSuffix: + return m.OldSuffix(ctx) + case wordsuffix.FieldExpired: + return m.OldExpired(ctx) + case wordsuffix.FieldGuildID: + return m.OldGuildID(ctx) + case wordsuffix.FieldRule: + return m.OldRule(ctx) + } + return nil, fmt.Errorf("unknown WordSuffix field %s", name) +} + +// SetField sets the value of a field with the given name. It returns an error if +// the field is not defined in the schema, or if the type mismatched the field +// type. +func (m *WordSuffixMutation) SetField(name string, value ent.Value) error { + switch name { + case wordsuffix.FieldSuffix: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetSuffix(v) + return nil + case wordsuffix.FieldExpired: + v, ok := value.(time.Time) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetExpired(v) + return nil + case wordsuffix.FieldGuildID: + v, ok := value.(snowflake.ID) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetGuildID(v) + return nil + case wordsuffix.FieldRule: + v, ok := value.(wordsuffix.Rule) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetRule(v) + return nil + } + return fmt.Errorf("unknown WordSuffix field %s", name) +} + +// AddedFields returns all numeric fields that were incremented/decremented during +// this mutation. +func (m *WordSuffixMutation) AddedFields() []string { + var fields []string + return fields +} + +// AddedField returns the numeric value that was incremented/decremented on a field +// with the given name. The second boolean return value indicates that this field +// was not set, or was not defined in the schema. +func (m *WordSuffixMutation) AddedField(name string) (ent.Value, bool) { + switch name { + } + return nil, false +} + +// AddField adds the value to the field with the given name. It returns an error if +// the field is not defined in the schema, or if the type mismatched the field +// type. +func (m *WordSuffixMutation) AddField(name string, value ent.Value) error { + switch name { + } + return fmt.Errorf("unknown WordSuffix numeric field %s", name) +} + +// ClearedFields returns all nullable fields that were cleared during this +// mutation. +func (m *WordSuffixMutation) ClearedFields() []string { + var fields []string + if m.FieldCleared(wordsuffix.FieldExpired) { + fields = append(fields, wordsuffix.FieldExpired) + } + if m.FieldCleared(wordsuffix.FieldGuildID) { + fields = append(fields, wordsuffix.FieldGuildID) + } + return fields +} + +// FieldCleared returns a boolean indicating if a field with the given name was +// cleared in this mutation. +func (m *WordSuffixMutation) FieldCleared(name string) bool { + _, ok := m.clearedFields[name] + return ok +} + +// ClearField clears the value of the field with the given name. It returns an +// error if the field is not defined in the schema. +func (m *WordSuffixMutation) ClearField(name string) error { + switch name { + case wordsuffix.FieldExpired: + m.ClearExpired() + return nil + case wordsuffix.FieldGuildID: + m.ClearGuildID() + return nil + } + return fmt.Errorf("unknown WordSuffix nullable field %s", name) +} + +// ResetField resets all changes in the mutation for the field with the given name. +// It returns an error if the field is not defined in the schema. +func (m *WordSuffixMutation) ResetField(name string) error { + switch name { + case wordsuffix.FieldSuffix: + m.ResetSuffix() + return nil + case wordsuffix.FieldExpired: + m.ResetExpired() + return nil + case wordsuffix.FieldGuildID: + m.ResetGuildID() + return nil + case wordsuffix.FieldRule: + m.ResetRule() + return nil + } + return fmt.Errorf("unknown WordSuffix field %s", name) +} + +// AddedEdges returns all edge names that were set/added in this mutation. +func (m *WordSuffixMutation) AddedEdges() []string { + edges := make([]string, 0, 2) + if m.guild != nil { + edges = append(edges, wordsuffix.EdgeGuild) + } + if m.owner != nil { + edges = append(edges, wordsuffix.EdgeOwner) + } + return edges +} + +// AddedIDs returns all IDs (to other nodes) that were added for the given edge +// name in this mutation. +func (m *WordSuffixMutation) AddedIDs(name string) []ent.Value { + switch name { + case wordsuffix.EdgeGuild: + if id := m.guild; id != nil { + return []ent.Value{*id} + } + case wordsuffix.EdgeOwner: + if id := m.owner; id != nil { + return []ent.Value{*id} + } + } + return nil +} + +// RemovedEdges returns all edge names that were removed in this mutation. +func (m *WordSuffixMutation) RemovedEdges() []string { + edges := make([]string, 0, 2) + return edges +} + +// RemovedIDs returns all IDs (to other nodes) that were removed for the edge with +// the given name in this mutation. +func (m *WordSuffixMutation) RemovedIDs(name string) []ent.Value { + return nil +} + +// ClearedEdges returns all edge names that were cleared in this mutation. +func (m *WordSuffixMutation) ClearedEdges() []string { + edges := make([]string, 0, 2) + if m.clearedguild { + edges = append(edges, wordsuffix.EdgeGuild) + } + if m.clearedowner { + edges = append(edges, wordsuffix.EdgeOwner) + } + return edges +} + +// EdgeCleared returns a boolean which indicates if the edge with the given name +// was cleared in this mutation. +func (m *WordSuffixMutation) EdgeCleared(name string) bool { + switch name { + case wordsuffix.EdgeGuild: + return m.clearedguild + case wordsuffix.EdgeOwner: + return m.clearedowner + } + return false +} + +// ClearEdge clears the value of the edge with the given name. It returns an error +// if that edge is not defined in the schema. +func (m *WordSuffixMutation) ClearEdge(name string) error { + switch name { + case wordsuffix.EdgeGuild: + m.ClearGuild() + return nil + case wordsuffix.EdgeOwner: + m.ClearOwner() + return nil + } + return fmt.Errorf("unknown WordSuffix unique edge %s", name) +} + +// ResetEdge resets all changes to the edge with the given name in this mutation. +// It returns an error if the edge is not defined in the schema. +func (m *WordSuffixMutation) ResetEdge(name string) error { + switch name { + case wordsuffix.EdgeGuild: + m.ResetGuild() + return nil + case wordsuffix.EdgeOwner: + m.ResetOwner() + return nil + } + return fmt.Errorf("unknown WordSuffix edge %s", name) +} diff --git a/ent/predicate/predicate.go b/ent/predicate/predicate.go new file mode 100644 index 00000000..502da56f --- /dev/null +++ b/ent/predicate/predicate.go @@ -0,0 +1,34 @@ +// Code generated by ent, DO NOT EDIT. + +package predicate + +import ( + "entgo.io/ent/dialect/sql" +) + +// Guild is the predicate function for guild builders. +type Guild func(*sql.Selector) + +// Member is the predicate function for member builders. +type Member func(*sql.Selector) + +// MessagePin is the predicate function for messagepin builders. +type MessagePin func(*sql.Selector) + +// MessageRemind is the predicate function for messageremind builders. +type MessageRemind func(*sql.Selector) + +// RolePanel is the predicate function for rolepanel builders. +type RolePanel func(*sql.Selector) + +// RolePanelEdit is the predicate function for rolepaneledit builders. +type RolePanelEdit func(*sql.Selector) + +// RolePanelPlaced is the predicate function for rolepanelplaced builders. +type RolePanelPlaced func(*sql.Selector) + +// User is the predicate function for user builders. +type User func(*sql.Selector) + +// WordSuffix is the predicate function for wordsuffix builders. +type WordSuffix func(*sql.Selector) diff --git a/ent/rolepanel.go b/ent/rolepanel.go new file mode 100644 index 00000000..3121b892 --- /dev/null +++ b/ent/rolepanel.go @@ -0,0 +1,232 @@ +// Code generated by ent, DO NOT EDIT. + +package ent + +import ( + "encoding/json" + "fmt" + "strings" + "time" + + "entgo.io/ent" + "entgo.io/ent/dialect/sql" + snowflake "github.com/disgoorg/snowflake/v2" + "github.com/google/uuid" + "github.com/sabafly/gobot/ent/guild" + "github.com/sabafly/gobot/ent/rolepanel" + "github.com/sabafly/gobot/ent/rolepaneledit" + "github.com/sabafly/gobot/ent/schema" +) + +// RolePanel is the model entity for the RolePanel schema. +type RolePanel struct { + config `json:"-"` + // ID of the ent. + ID uuid.UUID `json:"id,omitempty"` + // Name holds the value of the "name" field. + Name string `json:"name,omitempty"` + // Description holds the value of the "description" field. + Description string `json:"description,omitempty"` + // Roles holds the value of the "roles" field. + Roles []schema.Role `json:"roles,omitempty"` + // UpdatedAt holds the value of the "updated_at" field. + UpdatedAt time.Time `json:"updated_at,omitempty"` + // AppliedAt holds the value of the "applied_at" field. + AppliedAt time.Time `json:"applied_at,omitempty"` + // Edges holds the relations/edges for other nodes in the graph. + // The values are being populated by the RolePanelQuery when eager-loading is set. + Edges RolePanelEdges `json:"edges"` + guild_role_panels *snowflake.ID + selectValues sql.SelectValues +} + +// RolePanelEdges holds the relations/edges for other nodes in the graph. +type RolePanelEdges struct { + // Guild holds the value of the guild edge. + Guild *Guild `json:"guild,omitempty"` + // Placements holds the value of the placements edge. + Placements []*RolePanelPlaced `json:"placements,omitempty"` + // Edit holds the value of the edit edge. + Edit *RolePanelEdit `json:"edit,omitempty"` + // loadedTypes holds the information for reporting if a + // type was loaded (or requested) in eager-loading or not. + loadedTypes [3]bool +} + +// GuildOrErr returns the Guild value or an error if the edge +// was not loaded in eager-loading, or loaded but was not found. +func (e RolePanelEdges) GuildOrErr() (*Guild, error) { + if e.Guild != nil { + return e.Guild, nil + } else if e.loadedTypes[0] { + return nil, &NotFoundError{label: guild.Label} + } + return nil, &NotLoadedError{edge: "guild"} +} + +// PlacementsOrErr returns the Placements value or an error if the edge +// was not loaded in eager-loading. +func (e RolePanelEdges) PlacementsOrErr() ([]*RolePanelPlaced, error) { + if e.loadedTypes[1] { + return e.Placements, nil + } + return nil, &NotLoadedError{edge: "placements"} +} + +// EditOrErr returns the Edit value or an error if the edge +// was not loaded in eager-loading, or loaded but was not found. +func (e RolePanelEdges) EditOrErr() (*RolePanelEdit, error) { + if e.Edit != nil { + return e.Edit, nil + } else if e.loadedTypes[2] { + return nil, &NotFoundError{label: rolepaneledit.Label} + } + return nil, &NotLoadedError{edge: "edit"} +} + +// scanValues returns the types for scanning values from sql.Rows. +func (*RolePanel) scanValues(columns []string) ([]any, error) { + values := make([]any, len(columns)) + for i := range columns { + switch columns[i] { + case rolepanel.FieldRoles: + values[i] = new([]byte) + case rolepanel.FieldName, rolepanel.FieldDescription: + values[i] = new(sql.NullString) + case rolepanel.FieldUpdatedAt, rolepanel.FieldAppliedAt: + values[i] = new(sql.NullTime) + case rolepanel.FieldID: + values[i] = new(uuid.UUID) + case rolepanel.ForeignKeys[0]: // guild_role_panels + values[i] = new(sql.NullInt64) + default: + values[i] = new(sql.UnknownType) + } + } + return values, nil +} + +// assignValues assigns the values that were returned from sql.Rows (after scanning) +// to the RolePanel fields. +func (rp *RolePanel) assignValues(columns []string, values []any) error { + if m, n := len(values), len(columns); m < n { + return fmt.Errorf("mismatch number of scan values: %d != %d", m, n) + } + for i := range columns { + switch columns[i] { + case rolepanel.FieldID: + if value, ok := values[i].(*uuid.UUID); !ok { + return fmt.Errorf("unexpected type %T for field id", values[i]) + } else if value != nil { + rp.ID = *value + } + case rolepanel.FieldName: + if value, ok := values[i].(*sql.NullString); !ok { + return fmt.Errorf("unexpected type %T for field name", values[i]) + } else if value.Valid { + rp.Name = value.String + } + case rolepanel.FieldDescription: + if value, ok := values[i].(*sql.NullString); !ok { + return fmt.Errorf("unexpected type %T for field description", values[i]) + } else if value.Valid { + rp.Description = value.String + } + case rolepanel.FieldRoles: + if value, ok := values[i].(*[]byte); !ok { + return fmt.Errorf("unexpected type %T for field roles", values[i]) + } else if value != nil && len(*value) > 0 { + if err := json.Unmarshal(*value, &rp.Roles); err != nil { + return fmt.Errorf("unmarshal field roles: %w", err) + } + } + case rolepanel.FieldUpdatedAt: + if value, ok := values[i].(*sql.NullTime); !ok { + return fmt.Errorf("unexpected type %T for field updated_at", values[i]) + } else if value.Valid { + rp.UpdatedAt = value.Time + } + case rolepanel.FieldAppliedAt: + if value, ok := values[i].(*sql.NullTime); !ok { + return fmt.Errorf("unexpected type %T for field applied_at", values[i]) + } else if value.Valid { + rp.AppliedAt = value.Time + } + case rolepanel.ForeignKeys[0]: + if value, ok := values[i].(*sql.NullInt64); !ok { + return fmt.Errorf("unexpected type %T for field guild_role_panels", values[i]) + } else if value.Valid { + rp.guild_role_panels = new(snowflake.ID) + *rp.guild_role_panels = snowflake.ID(value.Int64) + } + default: + rp.selectValues.Set(columns[i], values[i]) + } + } + return nil +} + +// Value returns the ent.Value that was dynamically selected and assigned to the RolePanel. +// This includes values selected through modifiers, order, etc. +func (rp *RolePanel) Value(name string) (ent.Value, error) { + return rp.selectValues.Get(name) +} + +// QueryGuild queries the "guild" edge of the RolePanel entity. +func (rp *RolePanel) QueryGuild() *GuildQuery { + return NewRolePanelClient(rp.config).QueryGuild(rp) +} + +// QueryPlacements queries the "placements" edge of the RolePanel entity. +func (rp *RolePanel) QueryPlacements() *RolePanelPlacedQuery { + return NewRolePanelClient(rp.config).QueryPlacements(rp) +} + +// QueryEdit queries the "edit" edge of the RolePanel entity. +func (rp *RolePanel) QueryEdit() *RolePanelEditQuery { + return NewRolePanelClient(rp.config).QueryEdit(rp) +} + +// Update returns a builder for updating this RolePanel. +// Note that you need to call RolePanel.Unwrap() before calling this method if this RolePanel +// was returned from a transaction, and the transaction was committed or rolled back. +func (rp *RolePanel) Update() *RolePanelUpdateOne { + return NewRolePanelClient(rp.config).UpdateOne(rp) +} + +// Unwrap unwraps the RolePanel entity that was returned from a transaction after it was closed, +// so that all future queries will be executed through the driver which created the transaction. +func (rp *RolePanel) Unwrap() *RolePanel { + _tx, ok := rp.config.driver.(*txDriver) + if !ok { + panic("ent: RolePanel is not a transactional entity") + } + rp.config.driver = _tx.drv + return rp +} + +// String implements the fmt.Stringer. +func (rp *RolePanel) String() string { + var builder strings.Builder + builder.WriteString("RolePanel(") + builder.WriteString(fmt.Sprintf("id=%v, ", rp.ID)) + builder.WriteString("name=") + builder.WriteString(rp.Name) + builder.WriteString(", ") + builder.WriteString("description=") + builder.WriteString(rp.Description) + builder.WriteString(", ") + builder.WriteString("roles=") + builder.WriteString(fmt.Sprintf("%v", rp.Roles)) + builder.WriteString(", ") + builder.WriteString("updated_at=") + builder.WriteString(rp.UpdatedAt.Format(time.ANSIC)) + builder.WriteString(", ") + builder.WriteString("applied_at=") + builder.WriteString(rp.AppliedAt.Format(time.ANSIC)) + builder.WriteByte(')') + return builder.String() +} + +// RolePanels is a parsable slice of RolePanel. +type RolePanels []*RolePanel diff --git a/ent/rolepanel/rolepanel.go b/ent/rolepanel/rolepanel.go new file mode 100644 index 00000000..4d9fb8e0 --- /dev/null +++ b/ent/rolepanel/rolepanel.go @@ -0,0 +1,170 @@ +// Code generated by ent, DO NOT EDIT. + +package rolepanel + +import ( + "entgo.io/ent/dialect/sql" + "entgo.io/ent/dialect/sql/sqlgraph" + "github.com/google/uuid" +) + +const ( + // Label holds the string label denoting the rolepanel type in the database. + Label = "role_panel" + // FieldID holds the string denoting the id field in the database. + FieldID = "id" + // FieldName holds the string denoting the name field in the database. + FieldName = "name" + // FieldDescription holds the string denoting the description field in the database. + FieldDescription = "description" + // FieldRoles holds the string denoting the roles field in the database. + FieldRoles = "roles" + // FieldUpdatedAt holds the string denoting the updated_at field in the database. + FieldUpdatedAt = "updated_at" + // FieldAppliedAt holds the string denoting the applied_at field in the database. + FieldAppliedAt = "applied_at" + // EdgeGuild holds the string denoting the guild edge name in mutations. + EdgeGuild = "guild" + // EdgePlacements holds the string denoting the placements edge name in mutations. + EdgePlacements = "placements" + // EdgeEdit holds the string denoting the edit edge name in mutations. + EdgeEdit = "edit" + // Table holds the table name of the rolepanel in the database. + Table = "role_panels" + // GuildTable is the table that holds the guild relation/edge. + GuildTable = "role_panels" + // GuildInverseTable is the table name for the Guild entity. + // It exists in this package in order to avoid circular dependency with the "guild" package. + GuildInverseTable = "guilds" + // GuildColumn is the table column denoting the guild relation/edge. + GuildColumn = "guild_role_panels" + // PlacementsTable is the table that holds the placements relation/edge. + PlacementsTable = "role_panel_placeds" + // PlacementsInverseTable is the table name for the RolePanelPlaced entity. + // It exists in this package in order to avoid circular dependency with the "rolepanelplaced" package. + PlacementsInverseTable = "role_panel_placeds" + // PlacementsColumn is the table column denoting the placements relation/edge. + PlacementsColumn = "role_panel_placements" + // EditTable is the table that holds the edit relation/edge. + EditTable = "role_panel_edits" + // EditInverseTable is the table name for the RolePanelEdit entity. + // It exists in this package in order to avoid circular dependency with the "rolepaneledit" package. + EditInverseTable = "role_panel_edits" + // EditColumn is the table column denoting the edit relation/edge. + EditColumn = "role_panel_edit" +) + +// Columns holds all SQL columns for rolepanel fields. +var Columns = []string{ + FieldID, + FieldName, + FieldDescription, + FieldRoles, + FieldUpdatedAt, + FieldAppliedAt, +} + +// ForeignKeys holds the SQL foreign-keys that are owned by the "role_panels" +// table and are not defined as standalone fields in the schema. +var ForeignKeys = []string{ + "guild_role_panels", +} + +// ValidColumn reports if the column name is valid (part of the table columns). +func ValidColumn(column string) bool { + for i := range Columns { + if column == Columns[i] { + return true + } + } + for i := range ForeignKeys { + if column == ForeignKeys[i] { + return true + } + } + return false +} + +var ( + // NameValidator is a validator for the "name" field. It is called by the builders before save. + NameValidator func(string) error + // DefaultID holds the default value on creation for the "id" field. + DefaultID func() uuid.UUID +) + +// OrderOption defines the ordering options for the RolePanel queries. +type OrderOption func(*sql.Selector) + +// ByID orders the results by the id field. +func ByID(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldID, opts...).ToFunc() +} + +// ByName orders the results by the name field. +func ByName(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldName, opts...).ToFunc() +} + +// ByDescription orders the results by the description field. +func ByDescription(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldDescription, opts...).ToFunc() +} + +// ByUpdatedAt orders the results by the updated_at field. +func ByUpdatedAt(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldUpdatedAt, opts...).ToFunc() +} + +// ByAppliedAt orders the results by the applied_at field. +func ByAppliedAt(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldAppliedAt, opts...).ToFunc() +} + +// ByGuildField orders the results by guild field. +func ByGuildField(field string, opts ...sql.OrderTermOption) OrderOption { + return func(s *sql.Selector) { + sqlgraph.OrderByNeighborTerms(s, newGuildStep(), sql.OrderByField(field, opts...)) + } +} + +// ByPlacementsCount orders the results by placements count. +func ByPlacementsCount(opts ...sql.OrderTermOption) OrderOption { + return func(s *sql.Selector) { + sqlgraph.OrderByNeighborsCount(s, newPlacementsStep(), opts...) + } +} + +// ByPlacements orders the results by placements terms. +func ByPlacements(term sql.OrderTerm, terms ...sql.OrderTerm) OrderOption { + return func(s *sql.Selector) { + sqlgraph.OrderByNeighborTerms(s, newPlacementsStep(), append([]sql.OrderTerm{term}, terms...)...) + } +} + +// ByEditField orders the results by edit field. +func ByEditField(field string, opts ...sql.OrderTermOption) OrderOption { + return func(s *sql.Selector) { + sqlgraph.OrderByNeighborTerms(s, newEditStep(), sql.OrderByField(field, opts...)) + } +} +func newGuildStep() *sqlgraph.Step { + return sqlgraph.NewStep( + sqlgraph.From(Table, FieldID), + sqlgraph.To(GuildInverseTable, FieldID), + sqlgraph.Edge(sqlgraph.M2O, true, GuildTable, GuildColumn), + ) +} +func newPlacementsStep() *sqlgraph.Step { + return sqlgraph.NewStep( + sqlgraph.From(Table, FieldID), + sqlgraph.To(PlacementsInverseTable, FieldID), + sqlgraph.Edge(sqlgraph.O2M, false, PlacementsTable, PlacementsColumn), + ) +} +func newEditStep() *sqlgraph.Step { + return sqlgraph.NewStep( + sqlgraph.From(Table, FieldID), + sqlgraph.To(EditInverseTable, FieldID), + sqlgraph.Edge(sqlgraph.O2O, false, EditTable, EditColumn), + ) +} diff --git a/ent/rolepanel/where.go b/ent/rolepanel/where.go new file mode 100644 index 00000000..6eaca76a --- /dev/null +++ b/ent/rolepanel/where.go @@ -0,0 +1,401 @@ +// Code generated by ent, DO NOT EDIT. + +package rolepanel + +import ( + "time" + + "entgo.io/ent/dialect/sql" + "entgo.io/ent/dialect/sql/sqlgraph" + "github.com/google/uuid" + "github.com/sabafly/gobot/ent/predicate" +) + +// ID filters vertices based on their ID field. +func ID(id uuid.UUID) predicate.RolePanel { + return predicate.RolePanel(sql.FieldEQ(FieldID, id)) +} + +// IDEQ applies the EQ predicate on the ID field. +func IDEQ(id uuid.UUID) predicate.RolePanel { + return predicate.RolePanel(sql.FieldEQ(FieldID, id)) +} + +// IDNEQ applies the NEQ predicate on the ID field. +func IDNEQ(id uuid.UUID) predicate.RolePanel { + return predicate.RolePanel(sql.FieldNEQ(FieldID, id)) +} + +// IDIn applies the In predicate on the ID field. +func IDIn(ids ...uuid.UUID) predicate.RolePanel { + return predicate.RolePanel(sql.FieldIn(FieldID, ids...)) +} + +// IDNotIn applies the NotIn predicate on the ID field. +func IDNotIn(ids ...uuid.UUID) predicate.RolePanel { + return predicate.RolePanel(sql.FieldNotIn(FieldID, ids...)) +} + +// IDGT applies the GT predicate on the ID field. +func IDGT(id uuid.UUID) predicate.RolePanel { + return predicate.RolePanel(sql.FieldGT(FieldID, id)) +} + +// IDGTE applies the GTE predicate on the ID field. +func IDGTE(id uuid.UUID) predicate.RolePanel { + return predicate.RolePanel(sql.FieldGTE(FieldID, id)) +} + +// IDLT applies the LT predicate on the ID field. +func IDLT(id uuid.UUID) predicate.RolePanel { + return predicate.RolePanel(sql.FieldLT(FieldID, id)) +} + +// IDLTE applies the LTE predicate on the ID field. +func IDLTE(id uuid.UUID) predicate.RolePanel { + return predicate.RolePanel(sql.FieldLTE(FieldID, id)) +} + +// Name applies equality check predicate on the "name" field. It's identical to NameEQ. +func Name(v string) predicate.RolePanel { + return predicate.RolePanel(sql.FieldEQ(FieldName, v)) +} + +// Description applies equality check predicate on the "description" field. It's identical to DescriptionEQ. +func Description(v string) predicate.RolePanel { + return predicate.RolePanel(sql.FieldEQ(FieldDescription, v)) +} + +// UpdatedAt applies equality check predicate on the "updated_at" field. It's identical to UpdatedAtEQ. +func UpdatedAt(v time.Time) predicate.RolePanel { + return predicate.RolePanel(sql.FieldEQ(FieldUpdatedAt, v)) +} + +// AppliedAt applies equality check predicate on the "applied_at" field. It's identical to AppliedAtEQ. +func AppliedAt(v time.Time) predicate.RolePanel { + return predicate.RolePanel(sql.FieldEQ(FieldAppliedAt, v)) +} + +// NameEQ applies the EQ predicate on the "name" field. +func NameEQ(v string) predicate.RolePanel { + return predicate.RolePanel(sql.FieldEQ(FieldName, v)) +} + +// NameNEQ applies the NEQ predicate on the "name" field. +func NameNEQ(v string) predicate.RolePanel { + return predicate.RolePanel(sql.FieldNEQ(FieldName, v)) +} + +// NameIn applies the In predicate on the "name" field. +func NameIn(vs ...string) predicate.RolePanel { + return predicate.RolePanel(sql.FieldIn(FieldName, vs...)) +} + +// NameNotIn applies the NotIn predicate on the "name" field. +func NameNotIn(vs ...string) predicate.RolePanel { + return predicate.RolePanel(sql.FieldNotIn(FieldName, vs...)) +} + +// NameGT applies the GT predicate on the "name" field. +func NameGT(v string) predicate.RolePanel { + return predicate.RolePanel(sql.FieldGT(FieldName, v)) +} + +// NameGTE applies the GTE predicate on the "name" field. +func NameGTE(v string) predicate.RolePanel { + return predicate.RolePanel(sql.FieldGTE(FieldName, v)) +} + +// NameLT applies the LT predicate on the "name" field. +func NameLT(v string) predicate.RolePanel { + return predicate.RolePanel(sql.FieldLT(FieldName, v)) +} + +// NameLTE applies the LTE predicate on the "name" field. +func NameLTE(v string) predicate.RolePanel { + return predicate.RolePanel(sql.FieldLTE(FieldName, v)) +} + +// NameContains applies the Contains predicate on the "name" field. +func NameContains(v string) predicate.RolePanel { + return predicate.RolePanel(sql.FieldContains(FieldName, v)) +} + +// NameHasPrefix applies the HasPrefix predicate on the "name" field. +func NameHasPrefix(v string) predicate.RolePanel { + return predicate.RolePanel(sql.FieldHasPrefix(FieldName, v)) +} + +// NameHasSuffix applies the HasSuffix predicate on the "name" field. +func NameHasSuffix(v string) predicate.RolePanel { + return predicate.RolePanel(sql.FieldHasSuffix(FieldName, v)) +} + +// NameEqualFold applies the EqualFold predicate on the "name" field. +func NameEqualFold(v string) predicate.RolePanel { + return predicate.RolePanel(sql.FieldEqualFold(FieldName, v)) +} + +// NameContainsFold applies the ContainsFold predicate on the "name" field. +func NameContainsFold(v string) predicate.RolePanel { + return predicate.RolePanel(sql.FieldContainsFold(FieldName, v)) +} + +// DescriptionEQ applies the EQ predicate on the "description" field. +func DescriptionEQ(v string) predicate.RolePanel { + return predicate.RolePanel(sql.FieldEQ(FieldDescription, v)) +} + +// DescriptionNEQ applies the NEQ predicate on the "description" field. +func DescriptionNEQ(v string) predicate.RolePanel { + return predicate.RolePanel(sql.FieldNEQ(FieldDescription, v)) +} + +// DescriptionIn applies the In predicate on the "description" field. +func DescriptionIn(vs ...string) predicate.RolePanel { + return predicate.RolePanel(sql.FieldIn(FieldDescription, vs...)) +} + +// DescriptionNotIn applies the NotIn predicate on the "description" field. +func DescriptionNotIn(vs ...string) predicate.RolePanel { + return predicate.RolePanel(sql.FieldNotIn(FieldDescription, vs...)) +} + +// DescriptionGT applies the GT predicate on the "description" field. +func DescriptionGT(v string) predicate.RolePanel { + return predicate.RolePanel(sql.FieldGT(FieldDescription, v)) +} + +// DescriptionGTE applies the GTE predicate on the "description" field. +func DescriptionGTE(v string) predicate.RolePanel { + return predicate.RolePanel(sql.FieldGTE(FieldDescription, v)) +} + +// DescriptionLT applies the LT predicate on the "description" field. +func DescriptionLT(v string) predicate.RolePanel { + return predicate.RolePanel(sql.FieldLT(FieldDescription, v)) +} + +// DescriptionLTE applies the LTE predicate on the "description" field. +func DescriptionLTE(v string) predicate.RolePanel { + return predicate.RolePanel(sql.FieldLTE(FieldDescription, v)) +} + +// DescriptionContains applies the Contains predicate on the "description" field. +func DescriptionContains(v string) predicate.RolePanel { + return predicate.RolePanel(sql.FieldContains(FieldDescription, v)) +} + +// DescriptionHasPrefix applies the HasPrefix predicate on the "description" field. +func DescriptionHasPrefix(v string) predicate.RolePanel { + return predicate.RolePanel(sql.FieldHasPrefix(FieldDescription, v)) +} + +// DescriptionHasSuffix applies the HasSuffix predicate on the "description" field. +func DescriptionHasSuffix(v string) predicate.RolePanel { + return predicate.RolePanel(sql.FieldHasSuffix(FieldDescription, v)) +} + +// DescriptionEqualFold applies the EqualFold predicate on the "description" field. +func DescriptionEqualFold(v string) predicate.RolePanel { + return predicate.RolePanel(sql.FieldEqualFold(FieldDescription, v)) +} + +// DescriptionContainsFold applies the ContainsFold predicate on the "description" field. +func DescriptionContainsFold(v string) predicate.RolePanel { + return predicate.RolePanel(sql.FieldContainsFold(FieldDescription, v)) +} + +// RolesIsNil applies the IsNil predicate on the "roles" field. +func RolesIsNil() predicate.RolePanel { + return predicate.RolePanel(sql.FieldIsNull(FieldRoles)) +} + +// RolesNotNil applies the NotNil predicate on the "roles" field. +func RolesNotNil() predicate.RolePanel { + return predicate.RolePanel(sql.FieldNotNull(FieldRoles)) +} + +// UpdatedAtEQ applies the EQ predicate on the "updated_at" field. +func UpdatedAtEQ(v time.Time) predicate.RolePanel { + return predicate.RolePanel(sql.FieldEQ(FieldUpdatedAt, v)) +} + +// UpdatedAtNEQ applies the NEQ predicate on the "updated_at" field. +func UpdatedAtNEQ(v time.Time) predicate.RolePanel { + return predicate.RolePanel(sql.FieldNEQ(FieldUpdatedAt, v)) +} + +// UpdatedAtIn applies the In predicate on the "updated_at" field. +func UpdatedAtIn(vs ...time.Time) predicate.RolePanel { + return predicate.RolePanel(sql.FieldIn(FieldUpdatedAt, vs...)) +} + +// UpdatedAtNotIn applies the NotIn predicate on the "updated_at" field. +func UpdatedAtNotIn(vs ...time.Time) predicate.RolePanel { + return predicate.RolePanel(sql.FieldNotIn(FieldUpdatedAt, vs...)) +} + +// UpdatedAtGT applies the GT predicate on the "updated_at" field. +func UpdatedAtGT(v time.Time) predicate.RolePanel { + return predicate.RolePanel(sql.FieldGT(FieldUpdatedAt, v)) +} + +// UpdatedAtGTE applies the GTE predicate on the "updated_at" field. +func UpdatedAtGTE(v time.Time) predicate.RolePanel { + return predicate.RolePanel(sql.FieldGTE(FieldUpdatedAt, v)) +} + +// UpdatedAtLT applies the LT predicate on the "updated_at" field. +func UpdatedAtLT(v time.Time) predicate.RolePanel { + return predicate.RolePanel(sql.FieldLT(FieldUpdatedAt, v)) +} + +// UpdatedAtLTE applies the LTE predicate on the "updated_at" field. +func UpdatedAtLTE(v time.Time) predicate.RolePanel { + return predicate.RolePanel(sql.FieldLTE(FieldUpdatedAt, v)) +} + +// UpdatedAtIsNil applies the IsNil predicate on the "updated_at" field. +func UpdatedAtIsNil() predicate.RolePanel { + return predicate.RolePanel(sql.FieldIsNull(FieldUpdatedAt)) +} + +// UpdatedAtNotNil applies the NotNil predicate on the "updated_at" field. +func UpdatedAtNotNil() predicate.RolePanel { + return predicate.RolePanel(sql.FieldNotNull(FieldUpdatedAt)) +} + +// AppliedAtEQ applies the EQ predicate on the "applied_at" field. +func AppliedAtEQ(v time.Time) predicate.RolePanel { + return predicate.RolePanel(sql.FieldEQ(FieldAppliedAt, v)) +} + +// AppliedAtNEQ applies the NEQ predicate on the "applied_at" field. +func AppliedAtNEQ(v time.Time) predicate.RolePanel { + return predicate.RolePanel(sql.FieldNEQ(FieldAppliedAt, v)) +} + +// AppliedAtIn applies the In predicate on the "applied_at" field. +func AppliedAtIn(vs ...time.Time) predicate.RolePanel { + return predicate.RolePanel(sql.FieldIn(FieldAppliedAt, vs...)) +} + +// AppliedAtNotIn applies the NotIn predicate on the "applied_at" field. +func AppliedAtNotIn(vs ...time.Time) predicate.RolePanel { + return predicate.RolePanel(sql.FieldNotIn(FieldAppliedAt, vs...)) +} + +// AppliedAtGT applies the GT predicate on the "applied_at" field. +func AppliedAtGT(v time.Time) predicate.RolePanel { + return predicate.RolePanel(sql.FieldGT(FieldAppliedAt, v)) +} + +// AppliedAtGTE applies the GTE predicate on the "applied_at" field. +func AppliedAtGTE(v time.Time) predicate.RolePanel { + return predicate.RolePanel(sql.FieldGTE(FieldAppliedAt, v)) +} + +// AppliedAtLT applies the LT predicate on the "applied_at" field. +func AppliedAtLT(v time.Time) predicate.RolePanel { + return predicate.RolePanel(sql.FieldLT(FieldAppliedAt, v)) +} + +// AppliedAtLTE applies the LTE predicate on the "applied_at" field. +func AppliedAtLTE(v time.Time) predicate.RolePanel { + return predicate.RolePanel(sql.FieldLTE(FieldAppliedAt, v)) +} + +// AppliedAtIsNil applies the IsNil predicate on the "applied_at" field. +func AppliedAtIsNil() predicate.RolePanel { + return predicate.RolePanel(sql.FieldIsNull(FieldAppliedAt)) +} + +// AppliedAtNotNil applies the NotNil predicate on the "applied_at" field. +func AppliedAtNotNil() predicate.RolePanel { + return predicate.RolePanel(sql.FieldNotNull(FieldAppliedAt)) +} + +// HasGuild applies the HasEdge predicate on the "guild" edge. +func HasGuild() predicate.RolePanel { + return predicate.RolePanel(func(s *sql.Selector) { + step := sqlgraph.NewStep( + sqlgraph.From(Table, FieldID), + sqlgraph.Edge(sqlgraph.M2O, true, GuildTable, GuildColumn), + ) + sqlgraph.HasNeighbors(s, step) + }) +} + +// HasGuildWith applies the HasEdge predicate on the "guild" edge with a given conditions (other predicates). +func HasGuildWith(preds ...predicate.Guild) predicate.RolePanel { + return predicate.RolePanel(func(s *sql.Selector) { + step := newGuildStep() + sqlgraph.HasNeighborsWith(s, step, func(s *sql.Selector) { + for _, p := range preds { + p(s) + } + }) + }) +} + +// HasPlacements applies the HasEdge predicate on the "placements" edge. +func HasPlacements() predicate.RolePanel { + return predicate.RolePanel(func(s *sql.Selector) { + step := sqlgraph.NewStep( + sqlgraph.From(Table, FieldID), + sqlgraph.Edge(sqlgraph.O2M, false, PlacementsTable, PlacementsColumn), + ) + sqlgraph.HasNeighbors(s, step) + }) +} + +// HasPlacementsWith applies the HasEdge predicate on the "placements" edge with a given conditions (other predicates). +func HasPlacementsWith(preds ...predicate.RolePanelPlaced) predicate.RolePanel { + return predicate.RolePanel(func(s *sql.Selector) { + step := newPlacementsStep() + sqlgraph.HasNeighborsWith(s, step, func(s *sql.Selector) { + for _, p := range preds { + p(s) + } + }) + }) +} + +// HasEdit applies the HasEdge predicate on the "edit" edge. +func HasEdit() predicate.RolePanel { + return predicate.RolePanel(func(s *sql.Selector) { + step := sqlgraph.NewStep( + sqlgraph.From(Table, FieldID), + sqlgraph.Edge(sqlgraph.O2O, false, EditTable, EditColumn), + ) + sqlgraph.HasNeighbors(s, step) + }) +} + +// HasEditWith applies the HasEdge predicate on the "edit" edge with a given conditions (other predicates). +func HasEditWith(preds ...predicate.RolePanelEdit) predicate.RolePanel { + return predicate.RolePanel(func(s *sql.Selector) { + step := newEditStep() + sqlgraph.HasNeighborsWith(s, step, func(s *sql.Selector) { + for _, p := range preds { + p(s) + } + }) + }) +} + +// And groups predicates with the AND operator between them. +func And(predicates ...predicate.RolePanel) predicate.RolePanel { + return predicate.RolePanel(sql.AndPredicates(predicates...)) +} + +// Or groups predicates with the OR operator between them. +func Or(predicates ...predicate.RolePanel) predicate.RolePanel { + return predicate.RolePanel(sql.OrPredicates(predicates...)) +} + +// Not applies the not operator on the given predicate. +func Not(p predicate.RolePanel) predicate.RolePanel { + return predicate.RolePanel(sql.NotPredicates(p)) +} diff --git a/ent/rolepanel_create.go b/ent/rolepanel_create.go new file mode 100644 index 00000000..3c3adff2 --- /dev/null +++ b/ent/rolepanel_create.go @@ -0,0 +1,380 @@ +// Code generated by ent, DO NOT EDIT. + +package ent + +import ( + "context" + "errors" + "fmt" + "time" + + "entgo.io/ent/dialect/sql/sqlgraph" + "entgo.io/ent/schema/field" + snowflake "github.com/disgoorg/snowflake/v2" + "github.com/google/uuid" + "github.com/sabafly/gobot/ent/guild" + "github.com/sabafly/gobot/ent/rolepanel" + "github.com/sabafly/gobot/ent/rolepaneledit" + "github.com/sabafly/gobot/ent/rolepanelplaced" + "github.com/sabafly/gobot/ent/schema" +) + +// RolePanelCreate is the builder for creating a RolePanel entity. +type RolePanelCreate struct { + config + mutation *RolePanelMutation + hooks []Hook +} + +// SetName sets the "name" field. +func (rpc *RolePanelCreate) SetName(s string) *RolePanelCreate { + rpc.mutation.SetName(s) + return rpc +} + +// SetDescription sets the "description" field. +func (rpc *RolePanelCreate) SetDescription(s string) *RolePanelCreate { + rpc.mutation.SetDescription(s) + return rpc +} + +// SetRoles sets the "roles" field. +func (rpc *RolePanelCreate) SetRoles(s []schema.Role) *RolePanelCreate { + rpc.mutation.SetRoles(s) + return rpc +} + +// SetUpdatedAt sets the "updated_at" field. +func (rpc *RolePanelCreate) SetUpdatedAt(t time.Time) *RolePanelCreate { + rpc.mutation.SetUpdatedAt(t) + return rpc +} + +// SetNillableUpdatedAt sets the "updated_at" field if the given value is not nil. +func (rpc *RolePanelCreate) SetNillableUpdatedAt(t *time.Time) *RolePanelCreate { + if t != nil { + rpc.SetUpdatedAt(*t) + } + return rpc +} + +// SetAppliedAt sets the "applied_at" field. +func (rpc *RolePanelCreate) SetAppliedAt(t time.Time) *RolePanelCreate { + rpc.mutation.SetAppliedAt(t) + return rpc +} + +// SetNillableAppliedAt sets the "applied_at" field if the given value is not nil. +func (rpc *RolePanelCreate) SetNillableAppliedAt(t *time.Time) *RolePanelCreate { + if t != nil { + rpc.SetAppliedAt(*t) + } + return rpc +} + +// SetID sets the "id" field. +func (rpc *RolePanelCreate) SetID(u uuid.UUID) *RolePanelCreate { + rpc.mutation.SetID(u) + return rpc +} + +// SetNillableID sets the "id" field if the given value is not nil. +func (rpc *RolePanelCreate) SetNillableID(u *uuid.UUID) *RolePanelCreate { + if u != nil { + rpc.SetID(*u) + } + return rpc +} + +// SetGuildID sets the "guild" edge to the Guild entity by ID. +func (rpc *RolePanelCreate) SetGuildID(id snowflake.ID) *RolePanelCreate { + rpc.mutation.SetGuildID(id) + return rpc +} + +// SetGuild sets the "guild" edge to the Guild entity. +func (rpc *RolePanelCreate) SetGuild(g *Guild) *RolePanelCreate { + return rpc.SetGuildID(g.ID) +} + +// AddPlacementIDs adds the "placements" edge to the RolePanelPlaced entity by IDs. +func (rpc *RolePanelCreate) AddPlacementIDs(ids ...uuid.UUID) *RolePanelCreate { + rpc.mutation.AddPlacementIDs(ids...) + return rpc +} + +// AddPlacements adds the "placements" edges to the RolePanelPlaced entity. +func (rpc *RolePanelCreate) AddPlacements(r ...*RolePanelPlaced) *RolePanelCreate { + ids := make([]uuid.UUID, len(r)) + for i := range r { + ids[i] = r[i].ID + } + return rpc.AddPlacementIDs(ids...) +} + +// SetEditID sets the "edit" edge to the RolePanelEdit entity by ID. +func (rpc *RolePanelCreate) SetEditID(id uuid.UUID) *RolePanelCreate { + rpc.mutation.SetEditID(id) + return rpc +} + +// SetNillableEditID sets the "edit" edge to the RolePanelEdit entity by ID if the given value is not nil. +func (rpc *RolePanelCreate) SetNillableEditID(id *uuid.UUID) *RolePanelCreate { + if id != nil { + rpc = rpc.SetEditID(*id) + } + return rpc +} + +// SetEdit sets the "edit" edge to the RolePanelEdit entity. +func (rpc *RolePanelCreate) SetEdit(r *RolePanelEdit) *RolePanelCreate { + return rpc.SetEditID(r.ID) +} + +// Mutation returns the RolePanelMutation object of the builder. +func (rpc *RolePanelCreate) Mutation() *RolePanelMutation { + return rpc.mutation +} + +// Save creates the RolePanel in the database. +func (rpc *RolePanelCreate) Save(ctx context.Context) (*RolePanel, error) { + rpc.defaults() + return withHooks(ctx, rpc.sqlSave, rpc.mutation, rpc.hooks) +} + +// SaveX calls Save and panics if Save returns an error. +func (rpc *RolePanelCreate) SaveX(ctx context.Context) *RolePanel { + v, err := rpc.Save(ctx) + if err != nil { + panic(err) + } + return v +} + +// Exec executes the query. +func (rpc *RolePanelCreate) Exec(ctx context.Context) error { + _, err := rpc.Save(ctx) + return err +} + +// ExecX is like Exec, but panics if an error occurs. +func (rpc *RolePanelCreate) ExecX(ctx context.Context) { + if err := rpc.Exec(ctx); err != nil { + panic(err) + } +} + +// defaults sets the default values of the builder before save. +func (rpc *RolePanelCreate) defaults() { + if _, ok := rpc.mutation.ID(); !ok { + v := rolepanel.DefaultID() + rpc.mutation.SetID(v) + } +} + +// check runs all checks and user-defined validators on the builder. +func (rpc *RolePanelCreate) check() error { + if _, ok := rpc.mutation.Name(); !ok { + return &ValidationError{Name: "name", err: errors.New(`ent: missing required field "RolePanel.name"`)} + } + if v, ok := rpc.mutation.Name(); ok { + if err := rolepanel.NameValidator(v); err != nil { + return &ValidationError{Name: "name", err: fmt.Errorf(`ent: validator failed for field "RolePanel.name": %w`, err)} + } + } + if _, ok := rpc.mutation.Description(); !ok { + return &ValidationError{Name: "description", err: errors.New(`ent: missing required field "RolePanel.description"`)} + } + if _, ok := rpc.mutation.GuildID(); !ok { + return &ValidationError{Name: "guild", err: errors.New(`ent: missing required edge "RolePanel.guild"`)} + } + return nil +} + +func (rpc *RolePanelCreate) sqlSave(ctx context.Context) (*RolePanel, error) { + if err := rpc.check(); err != nil { + return nil, err + } + _node, _spec := rpc.createSpec() + if err := sqlgraph.CreateNode(ctx, rpc.driver, _spec); err != nil { + if sqlgraph.IsConstraintError(err) { + err = &ConstraintError{msg: err.Error(), wrap: err} + } + return nil, err + } + if _spec.ID.Value != nil { + if id, ok := _spec.ID.Value.(*uuid.UUID); ok { + _node.ID = *id + } else if err := _node.ID.Scan(_spec.ID.Value); err != nil { + return nil, err + } + } + rpc.mutation.id = &_node.ID + rpc.mutation.done = true + return _node, nil +} + +func (rpc *RolePanelCreate) createSpec() (*RolePanel, *sqlgraph.CreateSpec) { + var ( + _node = &RolePanel{config: rpc.config} + _spec = sqlgraph.NewCreateSpec(rolepanel.Table, sqlgraph.NewFieldSpec(rolepanel.FieldID, field.TypeUUID)) + ) + if id, ok := rpc.mutation.ID(); ok { + _node.ID = id + _spec.ID.Value = &id + } + if value, ok := rpc.mutation.Name(); ok { + _spec.SetField(rolepanel.FieldName, field.TypeString, value) + _node.Name = value + } + if value, ok := rpc.mutation.Description(); ok { + _spec.SetField(rolepanel.FieldDescription, field.TypeString, value) + _node.Description = value + } + if value, ok := rpc.mutation.Roles(); ok { + _spec.SetField(rolepanel.FieldRoles, field.TypeJSON, value) + _node.Roles = value + } + if value, ok := rpc.mutation.UpdatedAt(); ok { + _spec.SetField(rolepanel.FieldUpdatedAt, field.TypeTime, value) + _node.UpdatedAt = value + } + if value, ok := rpc.mutation.AppliedAt(); ok { + _spec.SetField(rolepanel.FieldAppliedAt, field.TypeTime, value) + _node.AppliedAt = value + } + if nodes := rpc.mutation.GuildIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.M2O, + Inverse: true, + Table: rolepanel.GuildTable, + Columns: []string{rolepanel.GuildColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(guild.FieldID, field.TypeUint64), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _node.guild_role_panels = &nodes[0] + _spec.Edges = append(_spec.Edges, edge) + } + if nodes := rpc.mutation.PlacementsIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: false, + Table: rolepanel.PlacementsTable, + Columns: []string{rolepanel.PlacementsColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(rolepanelplaced.FieldID, field.TypeUUID), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges = append(_spec.Edges, edge) + } + if nodes := rpc.mutation.EditIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2O, + Inverse: false, + Table: rolepanel.EditTable, + Columns: []string{rolepanel.EditColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(rolepaneledit.FieldID, field.TypeUUID), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges = append(_spec.Edges, edge) + } + return _node, _spec +} + +// RolePanelCreateBulk is the builder for creating many RolePanel entities in bulk. +type RolePanelCreateBulk struct { + config + err error + builders []*RolePanelCreate +} + +// Save creates the RolePanel entities in the database. +func (rpcb *RolePanelCreateBulk) Save(ctx context.Context) ([]*RolePanel, error) { + if rpcb.err != nil { + return nil, rpcb.err + } + specs := make([]*sqlgraph.CreateSpec, len(rpcb.builders)) + nodes := make([]*RolePanel, len(rpcb.builders)) + mutators := make([]Mutator, len(rpcb.builders)) + for i := range rpcb.builders { + func(i int, root context.Context) { + builder := rpcb.builders[i] + builder.defaults() + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*RolePanelMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + if err := builder.check(); err != nil { + return nil, err + } + builder.mutation = mutation + var err error + nodes[i], specs[i] = builder.createSpec() + if i < len(mutators)-1 { + _, err = mutators[i+1].Mutate(root, rpcb.builders[i+1].mutation) + } else { + spec := &sqlgraph.BatchCreateSpec{Nodes: specs} + // Invoke the actual operation on the latest mutation in the chain. + if err = sqlgraph.BatchCreate(ctx, rpcb.driver, spec); err != nil { + if sqlgraph.IsConstraintError(err) { + err = &ConstraintError{msg: err.Error(), wrap: err} + } + } + } + if err != nil { + return nil, err + } + mutation.id = &nodes[i].ID + mutation.done = true + return nodes[i], nil + }) + for i := len(builder.hooks) - 1; i >= 0; i-- { + mut = builder.hooks[i](mut) + } + mutators[i] = mut + }(i, ctx) + } + if len(mutators) > 0 { + if _, err := mutators[0].Mutate(ctx, rpcb.builders[0].mutation); err != nil { + return nil, err + } + } + return nodes, nil +} + +// SaveX is like Save, but panics if an error occurs. +func (rpcb *RolePanelCreateBulk) SaveX(ctx context.Context) []*RolePanel { + v, err := rpcb.Save(ctx) + if err != nil { + panic(err) + } + return v +} + +// Exec executes the query. +func (rpcb *RolePanelCreateBulk) Exec(ctx context.Context) error { + _, err := rpcb.Save(ctx) + return err +} + +// ExecX is like Exec, but panics if an error occurs. +func (rpcb *RolePanelCreateBulk) ExecX(ctx context.Context) { + if err := rpcb.Exec(ctx); err != nil { + panic(err) + } +} diff --git a/ent/rolepanel_delete.go b/ent/rolepanel_delete.go new file mode 100644 index 00000000..4c043e5f --- /dev/null +++ b/ent/rolepanel_delete.go @@ -0,0 +1,88 @@ +// Code generated by ent, DO NOT EDIT. + +package ent + +import ( + "context" + + "entgo.io/ent/dialect/sql" + "entgo.io/ent/dialect/sql/sqlgraph" + "entgo.io/ent/schema/field" + "github.com/sabafly/gobot/ent/predicate" + "github.com/sabafly/gobot/ent/rolepanel" +) + +// RolePanelDelete is the builder for deleting a RolePanel entity. +type RolePanelDelete struct { + config + hooks []Hook + mutation *RolePanelMutation +} + +// Where appends a list predicates to the RolePanelDelete builder. +func (rpd *RolePanelDelete) Where(ps ...predicate.RolePanel) *RolePanelDelete { + rpd.mutation.Where(ps...) + return rpd +} + +// Exec executes the deletion query and returns how many vertices were deleted. +func (rpd *RolePanelDelete) Exec(ctx context.Context) (int, error) { + return withHooks(ctx, rpd.sqlExec, rpd.mutation, rpd.hooks) +} + +// ExecX is like Exec, but panics if an error occurs. +func (rpd *RolePanelDelete) ExecX(ctx context.Context) int { + n, err := rpd.Exec(ctx) + if err != nil { + panic(err) + } + return n +} + +func (rpd *RolePanelDelete) sqlExec(ctx context.Context) (int, error) { + _spec := sqlgraph.NewDeleteSpec(rolepanel.Table, sqlgraph.NewFieldSpec(rolepanel.FieldID, field.TypeUUID)) + if ps := rpd.mutation.predicates; len(ps) > 0 { + _spec.Predicate = func(selector *sql.Selector) { + for i := range ps { + ps[i](selector) + } + } + } + affected, err := sqlgraph.DeleteNodes(ctx, rpd.driver, _spec) + if err != nil && sqlgraph.IsConstraintError(err) { + err = &ConstraintError{msg: err.Error(), wrap: err} + } + rpd.mutation.done = true + return affected, err +} + +// RolePanelDeleteOne is the builder for deleting a single RolePanel entity. +type RolePanelDeleteOne struct { + rpd *RolePanelDelete +} + +// Where appends a list predicates to the RolePanelDelete builder. +func (rpdo *RolePanelDeleteOne) Where(ps ...predicate.RolePanel) *RolePanelDeleteOne { + rpdo.rpd.mutation.Where(ps...) + return rpdo +} + +// Exec executes the deletion query. +func (rpdo *RolePanelDeleteOne) Exec(ctx context.Context) error { + n, err := rpdo.rpd.Exec(ctx) + switch { + case err != nil: + return err + case n == 0: + return &NotFoundError{rolepanel.Label} + default: + return nil + } +} + +// ExecX is like Exec, but panics if an error occurs. +func (rpdo *RolePanelDeleteOne) ExecX(ctx context.Context) { + if err := rpdo.Exec(ctx); err != nil { + panic(err) + } +} diff --git a/ent/rolepanel_query.go b/ent/rolepanel_query.go new file mode 100644 index 00000000..3946c24e --- /dev/null +++ b/ent/rolepanel_query.go @@ -0,0 +1,762 @@ +// Code generated by ent, DO NOT EDIT. + +package ent + +import ( + "context" + "database/sql/driver" + "fmt" + "math" + + "entgo.io/ent/dialect/sql" + "entgo.io/ent/dialect/sql/sqlgraph" + "entgo.io/ent/schema/field" + snowflake "github.com/disgoorg/snowflake/v2" + "github.com/google/uuid" + "github.com/sabafly/gobot/ent/guild" + "github.com/sabafly/gobot/ent/predicate" + "github.com/sabafly/gobot/ent/rolepanel" + "github.com/sabafly/gobot/ent/rolepaneledit" + "github.com/sabafly/gobot/ent/rolepanelplaced" +) + +// RolePanelQuery is the builder for querying RolePanel entities. +type RolePanelQuery struct { + config + ctx *QueryContext + order []rolepanel.OrderOption + inters []Interceptor + predicates []predicate.RolePanel + withGuild *GuildQuery + withPlacements *RolePanelPlacedQuery + withEdit *RolePanelEditQuery + withFKs bool + // intermediate query (i.e. traversal path). + sql *sql.Selector + path func(context.Context) (*sql.Selector, error) +} + +// Where adds a new predicate for the RolePanelQuery builder. +func (rpq *RolePanelQuery) Where(ps ...predicate.RolePanel) *RolePanelQuery { + rpq.predicates = append(rpq.predicates, ps...) + return rpq +} + +// Limit the number of records to be returned by this query. +func (rpq *RolePanelQuery) Limit(limit int) *RolePanelQuery { + rpq.ctx.Limit = &limit + return rpq +} + +// Offset to start from. +func (rpq *RolePanelQuery) Offset(offset int) *RolePanelQuery { + rpq.ctx.Offset = &offset + return rpq +} + +// Unique configures the query builder to filter duplicate records on query. +// By default, unique is set to true, and can be disabled using this method. +func (rpq *RolePanelQuery) Unique(unique bool) *RolePanelQuery { + rpq.ctx.Unique = &unique + return rpq +} + +// Order specifies how the records should be ordered. +func (rpq *RolePanelQuery) Order(o ...rolepanel.OrderOption) *RolePanelQuery { + rpq.order = append(rpq.order, o...) + return rpq +} + +// QueryGuild chains the current query on the "guild" edge. +func (rpq *RolePanelQuery) QueryGuild() *GuildQuery { + query := (&GuildClient{config: rpq.config}).Query() + query.path = func(ctx context.Context) (fromU *sql.Selector, err error) { + if err := rpq.prepareQuery(ctx); err != nil { + return nil, err + } + selector := rpq.sqlQuery(ctx) + if err := selector.Err(); err != nil { + return nil, err + } + step := sqlgraph.NewStep( + sqlgraph.From(rolepanel.Table, rolepanel.FieldID, selector), + sqlgraph.To(guild.Table, guild.FieldID), + sqlgraph.Edge(sqlgraph.M2O, true, rolepanel.GuildTable, rolepanel.GuildColumn), + ) + fromU = sqlgraph.SetNeighbors(rpq.driver.Dialect(), step) + return fromU, nil + } + return query +} + +// QueryPlacements chains the current query on the "placements" edge. +func (rpq *RolePanelQuery) QueryPlacements() *RolePanelPlacedQuery { + query := (&RolePanelPlacedClient{config: rpq.config}).Query() + query.path = func(ctx context.Context) (fromU *sql.Selector, err error) { + if err := rpq.prepareQuery(ctx); err != nil { + return nil, err + } + selector := rpq.sqlQuery(ctx) + if err := selector.Err(); err != nil { + return nil, err + } + step := sqlgraph.NewStep( + sqlgraph.From(rolepanel.Table, rolepanel.FieldID, selector), + sqlgraph.To(rolepanelplaced.Table, rolepanelplaced.FieldID), + sqlgraph.Edge(sqlgraph.O2M, false, rolepanel.PlacementsTable, rolepanel.PlacementsColumn), + ) + fromU = sqlgraph.SetNeighbors(rpq.driver.Dialect(), step) + return fromU, nil + } + return query +} + +// QueryEdit chains the current query on the "edit" edge. +func (rpq *RolePanelQuery) QueryEdit() *RolePanelEditQuery { + query := (&RolePanelEditClient{config: rpq.config}).Query() + query.path = func(ctx context.Context) (fromU *sql.Selector, err error) { + if err := rpq.prepareQuery(ctx); err != nil { + return nil, err + } + selector := rpq.sqlQuery(ctx) + if err := selector.Err(); err != nil { + return nil, err + } + step := sqlgraph.NewStep( + sqlgraph.From(rolepanel.Table, rolepanel.FieldID, selector), + sqlgraph.To(rolepaneledit.Table, rolepaneledit.FieldID), + sqlgraph.Edge(sqlgraph.O2O, false, rolepanel.EditTable, rolepanel.EditColumn), + ) + fromU = sqlgraph.SetNeighbors(rpq.driver.Dialect(), step) + return fromU, nil + } + return query +} + +// First returns the first RolePanel entity from the query. +// Returns a *NotFoundError when no RolePanel was found. +func (rpq *RolePanelQuery) First(ctx context.Context) (*RolePanel, error) { + nodes, err := rpq.Limit(1).All(setContextOp(ctx, rpq.ctx, "First")) + if err != nil { + return nil, err + } + if len(nodes) == 0 { + return nil, &NotFoundError{rolepanel.Label} + } + return nodes[0], nil +} + +// FirstX is like First, but panics if an error occurs. +func (rpq *RolePanelQuery) FirstX(ctx context.Context) *RolePanel { + node, err := rpq.First(ctx) + if err != nil && !IsNotFound(err) { + panic(err) + } + return node +} + +// FirstID returns the first RolePanel ID from the query. +// Returns a *NotFoundError when no RolePanel ID was found. +func (rpq *RolePanelQuery) FirstID(ctx context.Context) (id uuid.UUID, err error) { + var ids []uuid.UUID + if ids, err = rpq.Limit(1).IDs(setContextOp(ctx, rpq.ctx, "FirstID")); err != nil { + return + } + if len(ids) == 0 { + err = &NotFoundError{rolepanel.Label} + return + } + return ids[0], nil +} + +// FirstIDX is like FirstID, but panics if an error occurs. +func (rpq *RolePanelQuery) FirstIDX(ctx context.Context) uuid.UUID { + id, err := rpq.FirstID(ctx) + if err != nil && !IsNotFound(err) { + panic(err) + } + return id +} + +// Only returns a single RolePanel entity found by the query, ensuring it only returns one. +// Returns a *NotSingularError when more than one RolePanel entity is found. +// Returns a *NotFoundError when no RolePanel entities are found. +func (rpq *RolePanelQuery) Only(ctx context.Context) (*RolePanel, error) { + nodes, err := rpq.Limit(2).All(setContextOp(ctx, rpq.ctx, "Only")) + if err != nil { + return nil, err + } + switch len(nodes) { + case 1: + return nodes[0], nil + case 0: + return nil, &NotFoundError{rolepanel.Label} + default: + return nil, &NotSingularError{rolepanel.Label} + } +} + +// OnlyX is like Only, but panics if an error occurs. +func (rpq *RolePanelQuery) OnlyX(ctx context.Context) *RolePanel { + node, err := rpq.Only(ctx) + if err != nil { + panic(err) + } + return node +} + +// OnlyID is like Only, but returns the only RolePanel ID in the query. +// Returns a *NotSingularError when more than one RolePanel ID is found. +// Returns a *NotFoundError when no entities are found. +func (rpq *RolePanelQuery) OnlyID(ctx context.Context) (id uuid.UUID, err error) { + var ids []uuid.UUID + if ids, err = rpq.Limit(2).IDs(setContextOp(ctx, rpq.ctx, "OnlyID")); err != nil { + return + } + switch len(ids) { + case 1: + id = ids[0] + case 0: + err = &NotFoundError{rolepanel.Label} + default: + err = &NotSingularError{rolepanel.Label} + } + return +} + +// OnlyIDX is like OnlyID, but panics if an error occurs. +func (rpq *RolePanelQuery) OnlyIDX(ctx context.Context) uuid.UUID { + id, err := rpq.OnlyID(ctx) + if err != nil { + panic(err) + } + return id +} + +// All executes the query and returns a list of RolePanels. +func (rpq *RolePanelQuery) All(ctx context.Context) ([]*RolePanel, error) { + ctx = setContextOp(ctx, rpq.ctx, "All") + if err := rpq.prepareQuery(ctx); err != nil { + return nil, err + } + qr := querierAll[[]*RolePanel, *RolePanelQuery]() + return withInterceptors[[]*RolePanel](ctx, rpq, qr, rpq.inters) +} + +// AllX is like All, but panics if an error occurs. +func (rpq *RolePanelQuery) AllX(ctx context.Context) []*RolePanel { + nodes, err := rpq.All(ctx) + if err != nil { + panic(err) + } + return nodes +} + +// IDs executes the query and returns a list of RolePanel IDs. +func (rpq *RolePanelQuery) IDs(ctx context.Context) (ids []uuid.UUID, err error) { + if rpq.ctx.Unique == nil && rpq.path != nil { + rpq.Unique(true) + } + ctx = setContextOp(ctx, rpq.ctx, "IDs") + if err = rpq.Select(rolepanel.FieldID).Scan(ctx, &ids); err != nil { + return nil, err + } + return ids, nil +} + +// IDsX is like IDs, but panics if an error occurs. +func (rpq *RolePanelQuery) IDsX(ctx context.Context) []uuid.UUID { + ids, err := rpq.IDs(ctx) + if err != nil { + panic(err) + } + return ids +} + +// Count returns the count of the given query. +func (rpq *RolePanelQuery) Count(ctx context.Context) (int, error) { + ctx = setContextOp(ctx, rpq.ctx, "Count") + if err := rpq.prepareQuery(ctx); err != nil { + return 0, err + } + return withInterceptors[int](ctx, rpq, querierCount[*RolePanelQuery](), rpq.inters) +} + +// CountX is like Count, but panics if an error occurs. +func (rpq *RolePanelQuery) CountX(ctx context.Context) int { + count, err := rpq.Count(ctx) + if err != nil { + panic(err) + } + return count +} + +// Exist returns true if the query has elements in the graph. +func (rpq *RolePanelQuery) Exist(ctx context.Context) (bool, error) { + ctx = setContextOp(ctx, rpq.ctx, "Exist") + switch _, err := rpq.FirstID(ctx); { + case IsNotFound(err): + return false, nil + case err != nil: + return false, fmt.Errorf("ent: check existence: %w", err) + default: + return true, nil + } +} + +// ExistX is like Exist, but panics if an error occurs. +func (rpq *RolePanelQuery) ExistX(ctx context.Context) bool { + exist, err := rpq.Exist(ctx) + if err != nil { + panic(err) + } + return exist +} + +// Clone returns a duplicate of the RolePanelQuery builder, including all associated steps. It can be +// used to prepare common query builders and use them differently after the clone is made. +func (rpq *RolePanelQuery) Clone() *RolePanelQuery { + if rpq == nil { + return nil + } + return &RolePanelQuery{ + config: rpq.config, + ctx: rpq.ctx.Clone(), + order: append([]rolepanel.OrderOption{}, rpq.order...), + inters: append([]Interceptor{}, rpq.inters...), + predicates: append([]predicate.RolePanel{}, rpq.predicates...), + withGuild: rpq.withGuild.Clone(), + withPlacements: rpq.withPlacements.Clone(), + withEdit: rpq.withEdit.Clone(), + // clone intermediate query. + sql: rpq.sql.Clone(), + path: rpq.path, + } +} + +// WithGuild tells the query-builder to eager-load the nodes that are connected to +// the "guild" edge. The optional arguments are used to configure the query builder of the edge. +func (rpq *RolePanelQuery) WithGuild(opts ...func(*GuildQuery)) *RolePanelQuery { + query := (&GuildClient{config: rpq.config}).Query() + for _, opt := range opts { + opt(query) + } + rpq.withGuild = query + return rpq +} + +// WithPlacements tells the query-builder to eager-load the nodes that are connected to +// the "placements" edge. The optional arguments are used to configure the query builder of the edge. +func (rpq *RolePanelQuery) WithPlacements(opts ...func(*RolePanelPlacedQuery)) *RolePanelQuery { + query := (&RolePanelPlacedClient{config: rpq.config}).Query() + for _, opt := range opts { + opt(query) + } + rpq.withPlacements = query + return rpq +} + +// WithEdit tells the query-builder to eager-load the nodes that are connected to +// the "edit" edge. The optional arguments are used to configure the query builder of the edge. +func (rpq *RolePanelQuery) WithEdit(opts ...func(*RolePanelEditQuery)) *RolePanelQuery { + query := (&RolePanelEditClient{config: rpq.config}).Query() + for _, opt := range opts { + opt(query) + } + rpq.withEdit = query + return rpq +} + +// GroupBy is used to group vertices by one or more fields/columns. +// It is often used with aggregate functions, like: count, max, mean, min, sum. +// +// Example: +// +// var v []struct { +// Name string `json:"name,omitempty"` +// Count int `json:"count,omitempty"` +// } +// +// client.RolePanel.Query(). +// GroupBy(rolepanel.FieldName). +// Aggregate(ent.Count()). +// Scan(ctx, &v) +func (rpq *RolePanelQuery) GroupBy(field string, fields ...string) *RolePanelGroupBy { + rpq.ctx.Fields = append([]string{field}, fields...) + grbuild := &RolePanelGroupBy{build: rpq} + grbuild.flds = &rpq.ctx.Fields + grbuild.label = rolepanel.Label + grbuild.scan = grbuild.Scan + return grbuild +} + +// Select allows the selection one or more fields/columns for the given query, +// instead of selecting all fields in the entity. +// +// Example: +// +// var v []struct { +// Name string `json:"name,omitempty"` +// } +// +// client.RolePanel.Query(). +// Select(rolepanel.FieldName). +// Scan(ctx, &v) +func (rpq *RolePanelQuery) Select(fields ...string) *RolePanelSelect { + rpq.ctx.Fields = append(rpq.ctx.Fields, fields...) + sbuild := &RolePanelSelect{RolePanelQuery: rpq} + sbuild.label = rolepanel.Label + sbuild.flds, sbuild.scan = &rpq.ctx.Fields, sbuild.Scan + return sbuild +} + +// Aggregate returns a RolePanelSelect configured with the given aggregations. +func (rpq *RolePanelQuery) Aggregate(fns ...AggregateFunc) *RolePanelSelect { + return rpq.Select().Aggregate(fns...) +} + +func (rpq *RolePanelQuery) prepareQuery(ctx context.Context) error { + for _, inter := range rpq.inters { + if inter == nil { + return fmt.Errorf("ent: uninitialized interceptor (forgotten import ent/runtime?)") + } + if trv, ok := inter.(Traverser); ok { + if err := trv.Traverse(ctx, rpq); err != nil { + return err + } + } + } + for _, f := range rpq.ctx.Fields { + if !rolepanel.ValidColumn(f) { + return &ValidationError{Name: f, err: fmt.Errorf("ent: invalid field %q for query", f)} + } + } + if rpq.path != nil { + prev, err := rpq.path(ctx) + if err != nil { + return err + } + rpq.sql = prev + } + return nil +} + +func (rpq *RolePanelQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*RolePanel, error) { + var ( + nodes = []*RolePanel{} + withFKs = rpq.withFKs + _spec = rpq.querySpec() + loadedTypes = [3]bool{ + rpq.withGuild != nil, + rpq.withPlacements != nil, + rpq.withEdit != nil, + } + ) + if rpq.withGuild != nil { + withFKs = true + } + if withFKs { + _spec.Node.Columns = append(_spec.Node.Columns, rolepanel.ForeignKeys...) + } + _spec.ScanValues = func(columns []string) ([]any, error) { + return (*RolePanel).scanValues(nil, columns) + } + _spec.Assign = func(columns []string, values []any) error { + node := &RolePanel{config: rpq.config} + nodes = append(nodes, node) + node.Edges.loadedTypes = loadedTypes + return node.assignValues(columns, values) + } + for i := range hooks { + hooks[i](ctx, _spec) + } + if err := sqlgraph.QueryNodes(ctx, rpq.driver, _spec); err != nil { + return nil, err + } + if len(nodes) == 0 { + return nodes, nil + } + if query := rpq.withGuild; query != nil { + if err := rpq.loadGuild(ctx, query, nodes, nil, + func(n *RolePanel, e *Guild) { n.Edges.Guild = e }); err != nil { + return nil, err + } + } + if query := rpq.withPlacements; query != nil { + if err := rpq.loadPlacements(ctx, query, nodes, + func(n *RolePanel) { n.Edges.Placements = []*RolePanelPlaced{} }, + func(n *RolePanel, e *RolePanelPlaced) { n.Edges.Placements = append(n.Edges.Placements, e) }); err != nil { + return nil, err + } + } + if query := rpq.withEdit; query != nil { + if err := rpq.loadEdit(ctx, query, nodes, nil, + func(n *RolePanel, e *RolePanelEdit) { n.Edges.Edit = e }); err != nil { + return nil, err + } + } + return nodes, nil +} + +func (rpq *RolePanelQuery) loadGuild(ctx context.Context, query *GuildQuery, nodes []*RolePanel, init func(*RolePanel), assign func(*RolePanel, *Guild)) error { + ids := make([]snowflake.ID, 0, len(nodes)) + nodeids := make(map[snowflake.ID][]*RolePanel) + for i := range nodes { + if nodes[i].guild_role_panels == nil { + continue + } + fk := *nodes[i].guild_role_panels + if _, ok := nodeids[fk]; !ok { + ids = append(ids, fk) + } + nodeids[fk] = append(nodeids[fk], nodes[i]) + } + if len(ids) == 0 { + return nil + } + query.Where(guild.IDIn(ids...)) + neighbors, err := query.All(ctx) + if err != nil { + return err + } + for _, n := range neighbors { + nodes, ok := nodeids[n.ID] + if !ok { + return fmt.Errorf(`unexpected foreign-key "guild_role_panels" returned %v`, n.ID) + } + for i := range nodes { + assign(nodes[i], n) + } + } + return nil +} +func (rpq *RolePanelQuery) loadPlacements(ctx context.Context, query *RolePanelPlacedQuery, nodes []*RolePanel, init func(*RolePanel), assign func(*RolePanel, *RolePanelPlaced)) error { + fks := make([]driver.Value, 0, len(nodes)) + nodeids := make(map[uuid.UUID]*RolePanel) + for i := range nodes { + fks = append(fks, nodes[i].ID) + nodeids[nodes[i].ID] = nodes[i] + if init != nil { + init(nodes[i]) + } + } + query.withFKs = true + query.Where(predicate.RolePanelPlaced(func(s *sql.Selector) { + s.Where(sql.InValues(s.C(rolepanel.PlacementsColumn), fks...)) + })) + neighbors, err := query.All(ctx) + if err != nil { + return err + } + for _, n := range neighbors { + fk := n.role_panel_placements + if fk == nil { + return fmt.Errorf(`foreign-key "role_panel_placements" is nil for node %v`, n.ID) + } + node, ok := nodeids[*fk] + if !ok { + return fmt.Errorf(`unexpected referenced foreign-key "role_panel_placements" returned %v for node %v`, *fk, n.ID) + } + assign(node, n) + } + return nil +} +func (rpq *RolePanelQuery) loadEdit(ctx context.Context, query *RolePanelEditQuery, nodes []*RolePanel, init func(*RolePanel), assign func(*RolePanel, *RolePanelEdit)) error { + fks := make([]driver.Value, 0, len(nodes)) + nodeids := make(map[uuid.UUID]*RolePanel) + for i := range nodes { + fks = append(fks, nodes[i].ID) + nodeids[nodes[i].ID] = nodes[i] + } + query.withFKs = true + query.Where(predicate.RolePanelEdit(func(s *sql.Selector) { + s.Where(sql.InValues(s.C(rolepanel.EditColumn), fks...)) + })) + neighbors, err := query.All(ctx) + if err != nil { + return err + } + for _, n := range neighbors { + fk := n.role_panel_edit + if fk == nil { + return fmt.Errorf(`foreign-key "role_panel_edit" is nil for node %v`, n.ID) + } + node, ok := nodeids[*fk] + if !ok { + return fmt.Errorf(`unexpected referenced foreign-key "role_panel_edit" returned %v for node %v`, *fk, n.ID) + } + assign(node, n) + } + return nil +} + +func (rpq *RolePanelQuery) sqlCount(ctx context.Context) (int, error) { + _spec := rpq.querySpec() + _spec.Node.Columns = rpq.ctx.Fields + if len(rpq.ctx.Fields) > 0 { + _spec.Unique = rpq.ctx.Unique != nil && *rpq.ctx.Unique + } + return sqlgraph.CountNodes(ctx, rpq.driver, _spec) +} + +func (rpq *RolePanelQuery) querySpec() *sqlgraph.QuerySpec { + _spec := sqlgraph.NewQuerySpec(rolepanel.Table, rolepanel.Columns, sqlgraph.NewFieldSpec(rolepanel.FieldID, field.TypeUUID)) + _spec.From = rpq.sql + if unique := rpq.ctx.Unique; unique != nil { + _spec.Unique = *unique + } else if rpq.path != nil { + _spec.Unique = true + } + if fields := rpq.ctx.Fields; len(fields) > 0 { + _spec.Node.Columns = make([]string, 0, len(fields)) + _spec.Node.Columns = append(_spec.Node.Columns, rolepanel.FieldID) + for i := range fields { + if fields[i] != rolepanel.FieldID { + _spec.Node.Columns = append(_spec.Node.Columns, fields[i]) + } + } + } + if ps := rpq.predicates; len(ps) > 0 { + _spec.Predicate = func(selector *sql.Selector) { + for i := range ps { + ps[i](selector) + } + } + } + if limit := rpq.ctx.Limit; limit != nil { + _spec.Limit = *limit + } + if offset := rpq.ctx.Offset; offset != nil { + _spec.Offset = *offset + } + if ps := rpq.order; len(ps) > 0 { + _spec.Order = func(selector *sql.Selector) { + for i := range ps { + ps[i](selector) + } + } + } + return _spec +} + +func (rpq *RolePanelQuery) sqlQuery(ctx context.Context) *sql.Selector { + builder := sql.Dialect(rpq.driver.Dialect()) + t1 := builder.Table(rolepanel.Table) + columns := rpq.ctx.Fields + if len(columns) == 0 { + columns = rolepanel.Columns + } + selector := builder.Select(t1.Columns(columns...)...).From(t1) + if rpq.sql != nil { + selector = rpq.sql + selector.Select(selector.Columns(columns...)...) + } + if rpq.ctx.Unique != nil && *rpq.ctx.Unique { + selector.Distinct() + } + for _, p := range rpq.predicates { + p(selector) + } + for _, p := range rpq.order { + p(selector) + } + if offset := rpq.ctx.Offset; offset != nil { + // limit is mandatory for offset clause. We start + // with default value, and override it below if needed. + selector.Offset(*offset).Limit(math.MaxInt32) + } + if limit := rpq.ctx.Limit; limit != nil { + selector.Limit(*limit) + } + return selector +} + +// RolePanelGroupBy is the group-by builder for RolePanel entities. +type RolePanelGroupBy struct { + selector + build *RolePanelQuery +} + +// Aggregate adds the given aggregation functions to the group-by query. +func (rpgb *RolePanelGroupBy) Aggregate(fns ...AggregateFunc) *RolePanelGroupBy { + rpgb.fns = append(rpgb.fns, fns...) + return rpgb +} + +// Scan applies the selector query and scans the result into the given value. +func (rpgb *RolePanelGroupBy) Scan(ctx context.Context, v any) error { + ctx = setContextOp(ctx, rpgb.build.ctx, "GroupBy") + if err := rpgb.build.prepareQuery(ctx); err != nil { + return err + } + return scanWithInterceptors[*RolePanelQuery, *RolePanelGroupBy](ctx, rpgb.build, rpgb, rpgb.build.inters, v) +} + +func (rpgb *RolePanelGroupBy) sqlScan(ctx context.Context, root *RolePanelQuery, v any) error { + selector := root.sqlQuery(ctx).Select() + aggregation := make([]string, 0, len(rpgb.fns)) + for _, fn := range rpgb.fns { + aggregation = append(aggregation, fn(selector)) + } + if len(selector.SelectedColumns()) == 0 { + columns := make([]string, 0, len(*rpgb.flds)+len(rpgb.fns)) + for _, f := range *rpgb.flds { + columns = append(columns, selector.C(f)) + } + columns = append(columns, aggregation...) + selector.Select(columns...) + } + selector.GroupBy(selector.Columns(*rpgb.flds...)...) + if err := selector.Err(); err != nil { + return err + } + rows := &sql.Rows{} + query, args := selector.Query() + if err := rpgb.build.driver.Query(ctx, query, args, rows); err != nil { + return err + } + defer rows.Close() + return sql.ScanSlice(rows, v) +} + +// RolePanelSelect is the builder for selecting fields of RolePanel entities. +type RolePanelSelect struct { + *RolePanelQuery + selector +} + +// Aggregate adds the given aggregation functions to the selector query. +func (rps *RolePanelSelect) Aggregate(fns ...AggregateFunc) *RolePanelSelect { + rps.fns = append(rps.fns, fns...) + return rps +} + +// Scan applies the selector query and scans the result into the given value. +func (rps *RolePanelSelect) Scan(ctx context.Context, v any) error { + ctx = setContextOp(ctx, rps.ctx, "Select") + if err := rps.prepareQuery(ctx); err != nil { + return err + } + return scanWithInterceptors[*RolePanelQuery, *RolePanelSelect](ctx, rps.RolePanelQuery, rps, rps.inters, v) +} + +func (rps *RolePanelSelect) sqlScan(ctx context.Context, root *RolePanelQuery, v any) error { + selector := root.sqlQuery(ctx) + aggregation := make([]string, 0, len(rps.fns)) + for _, fn := range rps.fns { + aggregation = append(aggregation, fn(selector)) + } + switch n := len(*rps.selector.flds); { + case n == 0 && len(aggregation) > 0: + selector.Select(aggregation...) + case n != 0 && len(aggregation) > 0: + selector.AppendSelect(aggregation...) + } + rows := &sql.Rows{} + query, args := selector.Query() + if err := rps.driver.Query(ctx, query, args, rows); err != nil { + return err + } + defer rows.Close() + return sql.ScanSlice(rows, v) +} diff --git a/ent/rolepanel_update.go b/ent/rolepanel_update.go new file mode 100644 index 00000000..09ced114 --- /dev/null +++ b/ent/rolepanel_update.go @@ -0,0 +1,807 @@ +// Code generated by ent, DO NOT EDIT. + +package ent + +import ( + "context" + "errors" + "fmt" + "time" + + "entgo.io/ent/dialect/sql" + "entgo.io/ent/dialect/sql/sqlgraph" + "entgo.io/ent/dialect/sql/sqljson" + "entgo.io/ent/schema/field" + snowflake "github.com/disgoorg/snowflake/v2" + "github.com/google/uuid" + "github.com/sabafly/gobot/ent/guild" + "github.com/sabafly/gobot/ent/predicate" + "github.com/sabafly/gobot/ent/rolepanel" + "github.com/sabafly/gobot/ent/rolepaneledit" + "github.com/sabafly/gobot/ent/rolepanelplaced" + "github.com/sabafly/gobot/ent/schema" +) + +// RolePanelUpdate is the builder for updating RolePanel entities. +type RolePanelUpdate struct { + config + hooks []Hook + mutation *RolePanelMutation +} + +// Where appends a list predicates to the RolePanelUpdate builder. +func (rpu *RolePanelUpdate) Where(ps ...predicate.RolePanel) *RolePanelUpdate { + rpu.mutation.Where(ps...) + return rpu +} + +// SetName sets the "name" field. +func (rpu *RolePanelUpdate) SetName(s string) *RolePanelUpdate { + rpu.mutation.SetName(s) + return rpu +} + +// SetNillableName sets the "name" field if the given value is not nil. +func (rpu *RolePanelUpdate) SetNillableName(s *string) *RolePanelUpdate { + if s != nil { + rpu.SetName(*s) + } + return rpu +} + +// SetDescription sets the "description" field. +func (rpu *RolePanelUpdate) SetDescription(s string) *RolePanelUpdate { + rpu.mutation.SetDescription(s) + return rpu +} + +// SetNillableDescription sets the "description" field if the given value is not nil. +func (rpu *RolePanelUpdate) SetNillableDescription(s *string) *RolePanelUpdate { + if s != nil { + rpu.SetDescription(*s) + } + return rpu +} + +// SetRoles sets the "roles" field. +func (rpu *RolePanelUpdate) SetRoles(s []schema.Role) *RolePanelUpdate { + rpu.mutation.SetRoles(s) + return rpu +} + +// AppendRoles appends s to the "roles" field. +func (rpu *RolePanelUpdate) AppendRoles(s []schema.Role) *RolePanelUpdate { + rpu.mutation.AppendRoles(s) + return rpu +} + +// ClearRoles clears the value of the "roles" field. +func (rpu *RolePanelUpdate) ClearRoles() *RolePanelUpdate { + rpu.mutation.ClearRoles() + return rpu +} + +// SetUpdatedAt sets the "updated_at" field. +func (rpu *RolePanelUpdate) SetUpdatedAt(t time.Time) *RolePanelUpdate { + rpu.mutation.SetUpdatedAt(t) + return rpu +} + +// SetNillableUpdatedAt sets the "updated_at" field if the given value is not nil. +func (rpu *RolePanelUpdate) SetNillableUpdatedAt(t *time.Time) *RolePanelUpdate { + if t != nil { + rpu.SetUpdatedAt(*t) + } + return rpu +} + +// ClearUpdatedAt clears the value of the "updated_at" field. +func (rpu *RolePanelUpdate) ClearUpdatedAt() *RolePanelUpdate { + rpu.mutation.ClearUpdatedAt() + return rpu +} + +// SetAppliedAt sets the "applied_at" field. +func (rpu *RolePanelUpdate) SetAppliedAt(t time.Time) *RolePanelUpdate { + rpu.mutation.SetAppliedAt(t) + return rpu +} + +// SetNillableAppliedAt sets the "applied_at" field if the given value is not nil. +func (rpu *RolePanelUpdate) SetNillableAppliedAt(t *time.Time) *RolePanelUpdate { + if t != nil { + rpu.SetAppliedAt(*t) + } + return rpu +} + +// ClearAppliedAt clears the value of the "applied_at" field. +func (rpu *RolePanelUpdate) ClearAppliedAt() *RolePanelUpdate { + rpu.mutation.ClearAppliedAt() + return rpu +} + +// SetGuildID sets the "guild" edge to the Guild entity by ID. +func (rpu *RolePanelUpdate) SetGuildID(id snowflake.ID) *RolePanelUpdate { + rpu.mutation.SetGuildID(id) + return rpu +} + +// SetGuild sets the "guild" edge to the Guild entity. +func (rpu *RolePanelUpdate) SetGuild(g *Guild) *RolePanelUpdate { + return rpu.SetGuildID(g.ID) +} + +// AddPlacementIDs adds the "placements" edge to the RolePanelPlaced entity by IDs. +func (rpu *RolePanelUpdate) AddPlacementIDs(ids ...uuid.UUID) *RolePanelUpdate { + rpu.mutation.AddPlacementIDs(ids...) + return rpu +} + +// AddPlacements adds the "placements" edges to the RolePanelPlaced entity. +func (rpu *RolePanelUpdate) AddPlacements(r ...*RolePanelPlaced) *RolePanelUpdate { + ids := make([]uuid.UUID, len(r)) + for i := range r { + ids[i] = r[i].ID + } + return rpu.AddPlacementIDs(ids...) +} + +// SetEditID sets the "edit" edge to the RolePanelEdit entity by ID. +func (rpu *RolePanelUpdate) SetEditID(id uuid.UUID) *RolePanelUpdate { + rpu.mutation.SetEditID(id) + return rpu +} + +// SetNillableEditID sets the "edit" edge to the RolePanelEdit entity by ID if the given value is not nil. +func (rpu *RolePanelUpdate) SetNillableEditID(id *uuid.UUID) *RolePanelUpdate { + if id != nil { + rpu = rpu.SetEditID(*id) + } + return rpu +} + +// SetEdit sets the "edit" edge to the RolePanelEdit entity. +func (rpu *RolePanelUpdate) SetEdit(r *RolePanelEdit) *RolePanelUpdate { + return rpu.SetEditID(r.ID) +} + +// Mutation returns the RolePanelMutation object of the builder. +func (rpu *RolePanelUpdate) Mutation() *RolePanelMutation { + return rpu.mutation +} + +// ClearGuild clears the "guild" edge to the Guild entity. +func (rpu *RolePanelUpdate) ClearGuild() *RolePanelUpdate { + rpu.mutation.ClearGuild() + return rpu +} + +// ClearPlacements clears all "placements" edges to the RolePanelPlaced entity. +func (rpu *RolePanelUpdate) ClearPlacements() *RolePanelUpdate { + rpu.mutation.ClearPlacements() + return rpu +} + +// RemovePlacementIDs removes the "placements" edge to RolePanelPlaced entities by IDs. +func (rpu *RolePanelUpdate) RemovePlacementIDs(ids ...uuid.UUID) *RolePanelUpdate { + rpu.mutation.RemovePlacementIDs(ids...) + return rpu +} + +// RemovePlacements removes "placements" edges to RolePanelPlaced entities. +func (rpu *RolePanelUpdate) RemovePlacements(r ...*RolePanelPlaced) *RolePanelUpdate { + ids := make([]uuid.UUID, len(r)) + for i := range r { + ids[i] = r[i].ID + } + return rpu.RemovePlacementIDs(ids...) +} + +// ClearEdit clears the "edit" edge to the RolePanelEdit entity. +func (rpu *RolePanelUpdate) ClearEdit() *RolePanelUpdate { + rpu.mutation.ClearEdit() + return rpu +} + +// Save executes the query and returns the number of nodes affected by the update operation. +func (rpu *RolePanelUpdate) Save(ctx context.Context) (int, error) { + return withHooks(ctx, rpu.sqlSave, rpu.mutation, rpu.hooks) +} + +// SaveX is like Save, but panics if an error occurs. +func (rpu *RolePanelUpdate) SaveX(ctx context.Context) int { + affected, err := rpu.Save(ctx) + if err != nil { + panic(err) + } + return affected +} + +// Exec executes the query. +func (rpu *RolePanelUpdate) Exec(ctx context.Context) error { + _, err := rpu.Save(ctx) + return err +} + +// ExecX is like Exec, but panics if an error occurs. +func (rpu *RolePanelUpdate) ExecX(ctx context.Context) { + if err := rpu.Exec(ctx); err != nil { + panic(err) + } +} + +// check runs all checks and user-defined validators on the builder. +func (rpu *RolePanelUpdate) check() error { + if v, ok := rpu.mutation.Name(); ok { + if err := rolepanel.NameValidator(v); err != nil { + return &ValidationError{Name: "name", err: fmt.Errorf(`ent: validator failed for field "RolePanel.name": %w`, err)} + } + } + if _, ok := rpu.mutation.GuildID(); rpu.mutation.GuildCleared() && !ok { + return errors.New(`ent: clearing a required unique edge "RolePanel.guild"`) + } + return nil +} + +func (rpu *RolePanelUpdate) sqlSave(ctx context.Context) (n int, err error) { + if err := rpu.check(); err != nil { + return n, err + } + _spec := sqlgraph.NewUpdateSpec(rolepanel.Table, rolepanel.Columns, sqlgraph.NewFieldSpec(rolepanel.FieldID, field.TypeUUID)) + if ps := rpu.mutation.predicates; len(ps) > 0 { + _spec.Predicate = func(selector *sql.Selector) { + for i := range ps { + ps[i](selector) + } + } + } + if value, ok := rpu.mutation.Name(); ok { + _spec.SetField(rolepanel.FieldName, field.TypeString, value) + } + if value, ok := rpu.mutation.Description(); ok { + _spec.SetField(rolepanel.FieldDescription, field.TypeString, value) + } + if value, ok := rpu.mutation.Roles(); ok { + _spec.SetField(rolepanel.FieldRoles, field.TypeJSON, value) + } + if value, ok := rpu.mutation.AppendedRoles(); ok { + _spec.AddModifier(func(u *sql.UpdateBuilder) { + sqljson.Append(u, rolepanel.FieldRoles, value) + }) + } + if rpu.mutation.RolesCleared() { + _spec.ClearField(rolepanel.FieldRoles, field.TypeJSON) + } + if value, ok := rpu.mutation.UpdatedAt(); ok { + _spec.SetField(rolepanel.FieldUpdatedAt, field.TypeTime, value) + } + if rpu.mutation.UpdatedAtCleared() { + _spec.ClearField(rolepanel.FieldUpdatedAt, field.TypeTime) + } + if value, ok := rpu.mutation.AppliedAt(); ok { + _spec.SetField(rolepanel.FieldAppliedAt, field.TypeTime, value) + } + if rpu.mutation.AppliedAtCleared() { + _spec.ClearField(rolepanel.FieldAppliedAt, field.TypeTime) + } + if rpu.mutation.GuildCleared() { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.M2O, + Inverse: true, + Table: rolepanel.GuildTable, + Columns: []string{rolepanel.GuildColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(guild.FieldID, field.TypeUint64), + }, + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := rpu.mutation.GuildIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.M2O, + Inverse: true, + Table: rolepanel.GuildTable, + Columns: []string{rolepanel.GuildColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(guild.FieldID, field.TypeUint64), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Add = append(_spec.Edges.Add, edge) + } + if rpu.mutation.PlacementsCleared() { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: false, + Table: rolepanel.PlacementsTable, + Columns: []string{rolepanel.PlacementsColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(rolepanelplaced.FieldID, field.TypeUUID), + }, + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := rpu.mutation.RemovedPlacementsIDs(); len(nodes) > 0 && !rpu.mutation.PlacementsCleared() { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: false, + Table: rolepanel.PlacementsTable, + Columns: []string{rolepanel.PlacementsColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(rolepanelplaced.FieldID, field.TypeUUID), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := rpu.mutation.PlacementsIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: false, + Table: rolepanel.PlacementsTable, + Columns: []string{rolepanel.PlacementsColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(rolepanelplaced.FieldID, field.TypeUUID), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Add = append(_spec.Edges.Add, edge) + } + if rpu.mutation.EditCleared() { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2O, + Inverse: false, + Table: rolepanel.EditTable, + Columns: []string{rolepanel.EditColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(rolepaneledit.FieldID, field.TypeUUID), + }, + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := rpu.mutation.EditIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2O, + Inverse: false, + Table: rolepanel.EditTable, + Columns: []string{rolepanel.EditColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(rolepaneledit.FieldID, field.TypeUUID), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Add = append(_spec.Edges.Add, edge) + } + if n, err = sqlgraph.UpdateNodes(ctx, rpu.driver, _spec); err != nil { + if _, ok := err.(*sqlgraph.NotFoundError); ok { + err = &NotFoundError{rolepanel.Label} + } else if sqlgraph.IsConstraintError(err) { + err = &ConstraintError{msg: err.Error(), wrap: err} + } + return 0, err + } + rpu.mutation.done = true + return n, nil +} + +// RolePanelUpdateOne is the builder for updating a single RolePanel entity. +type RolePanelUpdateOne struct { + config + fields []string + hooks []Hook + mutation *RolePanelMutation +} + +// SetName sets the "name" field. +func (rpuo *RolePanelUpdateOne) SetName(s string) *RolePanelUpdateOne { + rpuo.mutation.SetName(s) + return rpuo +} + +// SetNillableName sets the "name" field if the given value is not nil. +func (rpuo *RolePanelUpdateOne) SetNillableName(s *string) *RolePanelUpdateOne { + if s != nil { + rpuo.SetName(*s) + } + return rpuo +} + +// SetDescription sets the "description" field. +func (rpuo *RolePanelUpdateOne) SetDescription(s string) *RolePanelUpdateOne { + rpuo.mutation.SetDescription(s) + return rpuo +} + +// SetNillableDescription sets the "description" field if the given value is not nil. +func (rpuo *RolePanelUpdateOne) SetNillableDescription(s *string) *RolePanelUpdateOne { + if s != nil { + rpuo.SetDescription(*s) + } + return rpuo +} + +// SetRoles sets the "roles" field. +func (rpuo *RolePanelUpdateOne) SetRoles(s []schema.Role) *RolePanelUpdateOne { + rpuo.mutation.SetRoles(s) + return rpuo +} + +// AppendRoles appends s to the "roles" field. +func (rpuo *RolePanelUpdateOne) AppendRoles(s []schema.Role) *RolePanelUpdateOne { + rpuo.mutation.AppendRoles(s) + return rpuo +} + +// ClearRoles clears the value of the "roles" field. +func (rpuo *RolePanelUpdateOne) ClearRoles() *RolePanelUpdateOne { + rpuo.mutation.ClearRoles() + return rpuo +} + +// SetUpdatedAt sets the "updated_at" field. +func (rpuo *RolePanelUpdateOne) SetUpdatedAt(t time.Time) *RolePanelUpdateOne { + rpuo.mutation.SetUpdatedAt(t) + return rpuo +} + +// SetNillableUpdatedAt sets the "updated_at" field if the given value is not nil. +func (rpuo *RolePanelUpdateOne) SetNillableUpdatedAt(t *time.Time) *RolePanelUpdateOne { + if t != nil { + rpuo.SetUpdatedAt(*t) + } + return rpuo +} + +// ClearUpdatedAt clears the value of the "updated_at" field. +func (rpuo *RolePanelUpdateOne) ClearUpdatedAt() *RolePanelUpdateOne { + rpuo.mutation.ClearUpdatedAt() + return rpuo +} + +// SetAppliedAt sets the "applied_at" field. +func (rpuo *RolePanelUpdateOne) SetAppliedAt(t time.Time) *RolePanelUpdateOne { + rpuo.mutation.SetAppliedAt(t) + return rpuo +} + +// SetNillableAppliedAt sets the "applied_at" field if the given value is not nil. +func (rpuo *RolePanelUpdateOne) SetNillableAppliedAt(t *time.Time) *RolePanelUpdateOne { + if t != nil { + rpuo.SetAppliedAt(*t) + } + return rpuo +} + +// ClearAppliedAt clears the value of the "applied_at" field. +func (rpuo *RolePanelUpdateOne) ClearAppliedAt() *RolePanelUpdateOne { + rpuo.mutation.ClearAppliedAt() + return rpuo +} + +// SetGuildID sets the "guild" edge to the Guild entity by ID. +func (rpuo *RolePanelUpdateOne) SetGuildID(id snowflake.ID) *RolePanelUpdateOne { + rpuo.mutation.SetGuildID(id) + return rpuo +} + +// SetGuild sets the "guild" edge to the Guild entity. +func (rpuo *RolePanelUpdateOne) SetGuild(g *Guild) *RolePanelUpdateOne { + return rpuo.SetGuildID(g.ID) +} + +// AddPlacementIDs adds the "placements" edge to the RolePanelPlaced entity by IDs. +func (rpuo *RolePanelUpdateOne) AddPlacementIDs(ids ...uuid.UUID) *RolePanelUpdateOne { + rpuo.mutation.AddPlacementIDs(ids...) + return rpuo +} + +// AddPlacements adds the "placements" edges to the RolePanelPlaced entity. +func (rpuo *RolePanelUpdateOne) AddPlacements(r ...*RolePanelPlaced) *RolePanelUpdateOne { + ids := make([]uuid.UUID, len(r)) + for i := range r { + ids[i] = r[i].ID + } + return rpuo.AddPlacementIDs(ids...) +} + +// SetEditID sets the "edit" edge to the RolePanelEdit entity by ID. +func (rpuo *RolePanelUpdateOne) SetEditID(id uuid.UUID) *RolePanelUpdateOne { + rpuo.mutation.SetEditID(id) + return rpuo +} + +// SetNillableEditID sets the "edit" edge to the RolePanelEdit entity by ID if the given value is not nil. +func (rpuo *RolePanelUpdateOne) SetNillableEditID(id *uuid.UUID) *RolePanelUpdateOne { + if id != nil { + rpuo = rpuo.SetEditID(*id) + } + return rpuo +} + +// SetEdit sets the "edit" edge to the RolePanelEdit entity. +func (rpuo *RolePanelUpdateOne) SetEdit(r *RolePanelEdit) *RolePanelUpdateOne { + return rpuo.SetEditID(r.ID) +} + +// Mutation returns the RolePanelMutation object of the builder. +func (rpuo *RolePanelUpdateOne) Mutation() *RolePanelMutation { + return rpuo.mutation +} + +// ClearGuild clears the "guild" edge to the Guild entity. +func (rpuo *RolePanelUpdateOne) ClearGuild() *RolePanelUpdateOne { + rpuo.mutation.ClearGuild() + return rpuo +} + +// ClearPlacements clears all "placements" edges to the RolePanelPlaced entity. +func (rpuo *RolePanelUpdateOne) ClearPlacements() *RolePanelUpdateOne { + rpuo.mutation.ClearPlacements() + return rpuo +} + +// RemovePlacementIDs removes the "placements" edge to RolePanelPlaced entities by IDs. +func (rpuo *RolePanelUpdateOne) RemovePlacementIDs(ids ...uuid.UUID) *RolePanelUpdateOne { + rpuo.mutation.RemovePlacementIDs(ids...) + return rpuo +} + +// RemovePlacements removes "placements" edges to RolePanelPlaced entities. +func (rpuo *RolePanelUpdateOne) RemovePlacements(r ...*RolePanelPlaced) *RolePanelUpdateOne { + ids := make([]uuid.UUID, len(r)) + for i := range r { + ids[i] = r[i].ID + } + return rpuo.RemovePlacementIDs(ids...) +} + +// ClearEdit clears the "edit" edge to the RolePanelEdit entity. +func (rpuo *RolePanelUpdateOne) ClearEdit() *RolePanelUpdateOne { + rpuo.mutation.ClearEdit() + return rpuo +} + +// Where appends a list predicates to the RolePanelUpdate builder. +func (rpuo *RolePanelUpdateOne) Where(ps ...predicate.RolePanel) *RolePanelUpdateOne { + rpuo.mutation.Where(ps...) + return rpuo +} + +// Select allows selecting one or more fields (columns) of the returned entity. +// The default is selecting all fields defined in the entity schema. +func (rpuo *RolePanelUpdateOne) Select(field string, fields ...string) *RolePanelUpdateOne { + rpuo.fields = append([]string{field}, fields...) + return rpuo +} + +// Save executes the query and returns the updated RolePanel entity. +func (rpuo *RolePanelUpdateOne) Save(ctx context.Context) (*RolePanel, error) { + return withHooks(ctx, rpuo.sqlSave, rpuo.mutation, rpuo.hooks) +} + +// SaveX is like Save, but panics if an error occurs. +func (rpuo *RolePanelUpdateOne) SaveX(ctx context.Context) *RolePanel { + node, err := rpuo.Save(ctx) + if err != nil { + panic(err) + } + return node +} + +// Exec executes the query on the entity. +func (rpuo *RolePanelUpdateOne) Exec(ctx context.Context) error { + _, err := rpuo.Save(ctx) + return err +} + +// ExecX is like Exec, but panics if an error occurs. +func (rpuo *RolePanelUpdateOne) ExecX(ctx context.Context) { + if err := rpuo.Exec(ctx); err != nil { + panic(err) + } +} + +// check runs all checks and user-defined validators on the builder. +func (rpuo *RolePanelUpdateOne) check() error { + if v, ok := rpuo.mutation.Name(); ok { + if err := rolepanel.NameValidator(v); err != nil { + return &ValidationError{Name: "name", err: fmt.Errorf(`ent: validator failed for field "RolePanel.name": %w`, err)} + } + } + if _, ok := rpuo.mutation.GuildID(); rpuo.mutation.GuildCleared() && !ok { + return errors.New(`ent: clearing a required unique edge "RolePanel.guild"`) + } + return nil +} + +func (rpuo *RolePanelUpdateOne) sqlSave(ctx context.Context) (_node *RolePanel, err error) { + if err := rpuo.check(); err != nil { + return _node, err + } + _spec := sqlgraph.NewUpdateSpec(rolepanel.Table, rolepanel.Columns, sqlgraph.NewFieldSpec(rolepanel.FieldID, field.TypeUUID)) + id, ok := rpuo.mutation.ID() + if !ok { + return nil, &ValidationError{Name: "id", err: errors.New(`ent: missing "RolePanel.id" for update`)} + } + _spec.Node.ID.Value = id + if fields := rpuo.fields; len(fields) > 0 { + _spec.Node.Columns = make([]string, 0, len(fields)) + _spec.Node.Columns = append(_spec.Node.Columns, rolepanel.FieldID) + for _, f := range fields { + if !rolepanel.ValidColumn(f) { + return nil, &ValidationError{Name: f, err: fmt.Errorf("ent: invalid field %q for query", f)} + } + if f != rolepanel.FieldID { + _spec.Node.Columns = append(_spec.Node.Columns, f) + } + } + } + if ps := rpuo.mutation.predicates; len(ps) > 0 { + _spec.Predicate = func(selector *sql.Selector) { + for i := range ps { + ps[i](selector) + } + } + } + if value, ok := rpuo.mutation.Name(); ok { + _spec.SetField(rolepanel.FieldName, field.TypeString, value) + } + if value, ok := rpuo.mutation.Description(); ok { + _spec.SetField(rolepanel.FieldDescription, field.TypeString, value) + } + if value, ok := rpuo.mutation.Roles(); ok { + _spec.SetField(rolepanel.FieldRoles, field.TypeJSON, value) + } + if value, ok := rpuo.mutation.AppendedRoles(); ok { + _spec.AddModifier(func(u *sql.UpdateBuilder) { + sqljson.Append(u, rolepanel.FieldRoles, value) + }) + } + if rpuo.mutation.RolesCleared() { + _spec.ClearField(rolepanel.FieldRoles, field.TypeJSON) + } + if value, ok := rpuo.mutation.UpdatedAt(); ok { + _spec.SetField(rolepanel.FieldUpdatedAt, field.TypeTime, value) + } + if rpuo.mutation.UpdatedAtCleared() { + _spec.ClearField(rolepanel.FieldUpdatedAt, field.TypeTime) + } + if value, ok := rpuo.mutation.AppliedAt(); ok { + _spec.SetField(rolepanel.FieldAppliedAt, field.TypeTime, value) + } + if rpuo.mutation.AppliedAtCleared() { + _spec.ClearField(rolepanel.FieldAppliedAt, field.TypeTime) + } + if rpuo.mutation.GuildCleared() { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.M2O, + Inverse: true, + Table: rolepanel.GuildTable, + Columns: []string{rolepanel.GuildColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(guild.FieldID, field.TypeUint64), + }, + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := rpuo.mutation.GuildIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.M2O, + Inverse: true, + Table: rolepanel.GuildTable, + Columns: []string{rolepanel.GuildColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(guild.FieldID, field.TypeUint64), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Add = append(_spec.Edges.Add, edge) + } + if rpuo.mutation.PlacementsCleared() { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: false, + Table: rolepanel.PlacementsTable, + Columns: []string{rolepanel.PlacementsColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(rolepanelplaced.FieldID, field.TypeUUID), + }, + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := rpuo.mutation.RemovedPlacementsIDs(); len(nodes) > 0 && !rpuo.mutation.PlacementsCleared() { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: false, + Table: rolepanel.PlacementsTable, + Columns: []string{rolepanel.PlacementsColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(rolepanelplaced.FieldID, field.TypeUUID), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := rpuo.mutation.PlacementsIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: false, + Table: rolepanel.PlacementsTable, + Columns: []string{rolepanel.PlacementsColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(rolepanelplaced.FieldID, field.TypeUUID), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Add = append(_spec.Edges.Add, edge) + } + if rpuo.mutation.EditCleared() { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2O, + Inverse: false, + Table: rolepanel.EditTable, + Columns: []string{rolepanel.EditColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(rolepaneledit.FieldID, field.TypeUUID), + }, + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := rpuo.mutation.EditIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2O, + Inverse: false, + Table: rolepanel.EditTable, + Columns: []string{rolepanel.EditColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(rolepaneledit.FieldID, field.TypeUUID), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Add = append(_spec.Edges.Add, edge) + } + _node = &RolePanel{config: rpuo.config} + _spec.Assign = _node.assignValues + _spec.ScanValues = _node.scanValues + if err = sqlgraph.UpdateNode(ctx, rpuo.driver, _spec); err != nil { + if _, ok := err.(*sqlgraph.NotFoundError); ok { + err = &NotFoundError{rolepanel.Label} + } else if sqlgraph.IsConstraintError(err) { + err = &ConstraintError{msg: err.Error(), wrap: err} + } + return nil, err + } + rpuo.mutation.done = true + return _node, nil +} diff --git a/ent/rolepaneledit.go b/ent/rolepaneledit.go new file mode 100644 index 00000000..48f6f774 --- /dev/null +++ b/ent/rolepaneledit.go @@ -0,0 +1,275 @@ +// Code generated by ent, DO NOT EDIT. + +package ent + +import ( + "encoding/json" + "fmt" + "strings" + + "entgo.io/ent" + "entgo.io/ent/dialect/sql" + snowflake "github.com/disgoorg/snowflake/v2" + "github.com/google/uuid" + "github.com/sabafly/gobot/ent/guild" + "github.com/sabafly/gobot/ent/rolepanel" + "github.com/sabafly/gobot/ent/rolepaneledit" + "github.com/sabafly/gobot/ent/schema" +) + +// RolePanelEdit is the model entity for the RolePanelEdit schema. +type RolePanelEdit struct { + config `json:"-"` + // ID of the ent. + ID uuid.UUID `json:"id,omitempty"` + // ChannelID holds the value of the "channel_id" field. + ChannelID snowflake.ID `json:"channel_id,omitempty"` + // EmojiAuthor holds the value of the "emoji_author" field. + EmojiAuthor *snowflake.ID `json:"emoji_author,omitempty"` + // Token holds the value of the "token" field. + Token *string `json:"token,omitempty"` + // SelectedRole holds the value of the "selected_role" field. + SelectedRole *snowflake.ID `json:"selected_role,omitempty"` + // Modified holds the value of the "modified" field. + Modified bool `json:"modified,omitempty"` + // Name holds the value of the "name" field. + Name *string `json:"name,omitempty"` + // Description holds the value of the "description" field. + Description *string `json:"description,omitempty"` + // Roles holds the value of the "roles" field. + Roles []schema.Role `json:"roles,omitempty"` + // Edges holds the relations/edges for other nodes in the graph. + // The values are being populated by the RolePanelEditQuery when eager-loading is set. + Edges RolePanelEditEdges `json:"edges"` + guild_role_panel_edits *snowflake.ID + role_panel_edit *uuid.UUID + selectValues sql.SelectValues +} + +// RolePanelEditEdges holds the relations/edges for other nodes in the graph. +type RolePanelEditEdges struct { + // Guild holds the value of the guild edge. + Guild *Guild `json:"guild,omitempty"` + // Parent holds the value of the parent edge. + Parent *RolePanel `json:"parent,omitempty"` + // loadedTypes holds the information for reporting if a + // type was loaded (or requested) in eager-loading or not. + loadedTypes [2]bool +} + +// GuildOrErr returns the Guild value or an error if the edge +// was not loaded in eager-loading, or loaded but was not found. +func (e RolePanelEditEdges) GuildOrErr() (*Guild, error) { + if e.Guild != nil { + return e.Guild, nil + } else if e.loadedTypes[0] { + return nil, &NotFoundError{label: guild.Label} + } + return nil, &NotLoadedError{edge: "guild"} +} + +// ParentOrErr returns the Parent value or an error if the edge +// was not loaded in eager-loading, or loaded but was not found. +func (e RolePanelEditEdges) ParentOrErr() (*RolePanel, error) { + if e.Parent != nil { + return e.Parent, nil + } else if e.loadedTypes[1] { + return nil, &NotFoundError{label: rolepanel.Label} + } + return nil, &NotLoadedError{edge: "parent"} +} + +// scanValues returns the types for scanning values from sql.Rows. +func (*RolePanelEdit) scanValues(columns []string) ([]any, error) { + values := make([]any, len(columns)) + for i := range columns { + switch columns[i] { + case rolepaneledit.FieldRoles: + values[i] = new([]byte) + case rolepaneledit.FieldModified: + values[i] = new(sql.NullBool) + case rolepaneledit.FieldChannelID, rolepaneledit.FieldEmojiAuthor, rolepaneledit.FieldSelectedRole: + values[i] = new(sql.NullInt64) + case rolepaneledit.FieldToken, rolepaneledit.FieldName, rolepaneledit.FieldDescription: + values[i] = new(sql.NullString) + case rolepaneledit.FieldID: + values[i] = new(uuid.UUID) + case rolepaneledit.ForeignKeys[0]: // guild_role_panel_edits + values[i] = new(sql.NullInt64) + case rolepaneledit.ForeignKeys[1]: // role_panel_edit + values[i] = &sql.NullScanner{S: new(uuid.UUID)} + default: + values[i] = new(sql.UnknownType) + } + } + return values, nil +} + +// assignValues assigns the values that were returned from sql.Rows (after scanning) +// to the RolePanelEdit fields. +func (rpe *RolePanelEdit) assignValues(columns []string, values []any) error { + if m, n := len(values), len(columns); m < n { + return fmt.Errorf("mismatch number of scan values: %d != %d", m, n) + } + for i := range columns { + switch columns[i] { + case rolepaneledit.FieldID: + if value, ok := values[i].(*uuid.UUID); !ok { + return fmt.Errorf("unexpected type %T for field id", values[i]) + } else if value != nil { + rpe.ID = *value + } + case rolepaneledit.FieldChannelID: + if value, ok := values[i].(*sql.NullInt64); !ok { + return fmt.Errorf("unexpected type %T for field channel_id", values[i]) + } else if value.Valid { + rpe.ChannelID = snowflake.ID(value.Int64) + } + case rolepaneledit.FieldEmojiAuthor: + if value, ok := values[i].(*sql.NullInt64); !ok { + return fmt.Errorf("unexpected type %T for field emoji_author", values[i]) + } else if value.Valid { + rpe.EmojiAuthor = new(snowflake.ID) + *rpe.EmojiAuthor = snowflake.ID(value.Int64) + } + case rolepaneledit.FieldToken: + if value, ok := values[i].(*sql.NullString); !ok { + return fmt.Errorf("unexpected type %T for field token", values[i]) + } else if value.Valid { + rpe.Token = new(string) + *rpe.Token = value.String + } + case rolepaneledit.FieldSelectedRole: + if value, ok := values[i].(*sql.NullInt64); !ok { + return fmt.Errorf("unexpected type %T for field selected_role", values[i]) + } else if value.Valid { + rpe.SelectedRole = new(snowflake.ID) + *rpe.SelectedRole = snowflake.ID(value.Int64) + } + case rolepaneledit.FieldModified: + if value, ok := values[i].(*sql.NullBool); !ok { + return fmt.Errorf("unexpected type %T for field modified", values[i]) + } else if value.Valid { + rpe.Modified = value.Bool + } + case rolepaneledit.FieldName: + if value, ok := values[i].(*sql.NullString); !ok { + return fmt.Errorf("unexpected type %T for field name", values[i]) + } else if value.Valid { + rpe.Name = new(string) + *rpe.Name = value.String + } + case rolepaneledit.FieldDescription: + if value, ok := values[i].(*sql.NullString); !ok { + return fmt.Errorf("unexpected type %T for field description", values[i]) + } else if value.Valid { + rpe.Description = new(string) + *rpe.Description = value.String + } + case rolepaneledit.FieldRoles: + if value, ok := values[i].(*[]byte); !ok { + return fmt.Errorf("unexpected type %T for field roles", values[i]) + } else if value != nil && len(*value) > 0 { + if err := json.Unmarshal(*value, &rpe.Roles); err != nil { + return fmt.Errorf("unmarshal field roles: %w", err) + } + } + case rolepaneledit.ForeignKeys[0]: + if value, ok := values[i].(*sql.NullInt64); !ok { + return fmt.Errorf("unexpected type %T for field guild_role_panel_edits", values[i]) + } else if value.Valid { + rpe.guild_role_panel_edits = new(snowflake.ID) + *rpe.guild_role_panel_edits = snowflake.ID(value.Int64) + } + case rolepaneledit.ForeignKeys[1]: + if value, ok := values[i].(*sql.NullScanner); !ok { + return fmt.Errorf("unexpected type %T for field role_panel_edit", values[i]) + } else if value.Valid { + rpe.role_panel_edit = new(uuid.UUID) + *rpe.role_panel_edit = *value.S.(*uuid.UUID) + } + default: + rpe.selectValues.Set(columns[i], values[i]) + } + } + return nil +} + +// Value returns the ent.Value that was dynamically selected and assigned to the RolePanelEdit. +// This includes values selected through modifiers, order, etc. +func (rpe *RolePanelEdit) Value(name string) (ent.Value, error) { + return rpe.selectValues.Get(name) +} + +// QueryGuild queries the "guild" edge of the RolePanelEdit entity. +func (rpe *RolePanelEdit) QueryGuild() *GuildQuery { + return NewRolePanelEditClient(rpe.config).QueryGuild(rpe) +} + +// QueryParent queries the "parent" edge of the RolePanelEdit entity. +func (rpe *RolePanelEdit) QueryParent() *RolePanelQuery { + return NewRolePanelEditClient(rpe.config).QueryParent(rpe) +} + +// Update returns a builder for updating this RolePanelEdit. +// Note that you need to call RolePanelEdit.Unwrap() before calling this method if this RolePanelEdit +// was returned from a transaction, and the transaction was committed or rolled back. +func (rpe *RolePanelEdit) Update() *RolePanelEditUpdateOne { + return NewRolePanelEditClient(rpe.config).UpdateOne(rpe) +} + +// Unwrap unwraps the RolePanelEdit entity that was returned from a transaction after it was closed, +// so that all future queries will be executed through the driver which created the transaction. +func (rpe *RolePanelEdit) Unwrap() *RolePanelEdit { + _tx, ok := rpe.config.driver.(*txDriver) + if !ok { + panic("ent: RolePanelEdit is not a transactional entity") + } + rpe.config.driver = _tx.drv + return rpe +} + +// String implements the fmt.Stringer. +func (rpe *RolePanelEdit) String() string { + var builder strings.Builder + builder.WriteString("RolePanelEdit(") + builder.WriteString(fmt.Sprintf("id=%v, ", rpe.ID)) + builder.WriteString("channel_id=") + builder.WriteString(fmt.Sprintf("%v", rpe.ChannelID)) + builder.WriteString(", ") + if v := rpe.EmojiAuthor; v != nil { + builder.WriteString("emoji_author=") + builder.WriteString(fmt.Sprintf("%v", *v)) + } + builder.WriteString(", ") + if v := rpe.Token; v != nil { + builder.WriteString("token=") + builder.WriteString(*v) + } + builder.WriteString(", ") + if v := rpe.SelectedRole; v != nil { + builder.WriteString("selected_role=") + builder.WriteString(fmt.Sprintf("%v", *v)) + } + builder.WriteString(", ") + builder.WriteString("modified=") + builder.WriteString(fmt.Sprintf("%v", rpe.Modified)) + builder.WriteString(", ") + if v := rpe.Name; v != nil { + builder.WriteString("name=") + builder.WriteString(*v) + } + builder.WriteString(", ") + if v := rpe.Description; v != nil { + builder.WriteString("description=") + builder.WriteString(*v) + } + builder.WriteString(", ") + builder.WriteString("roles=") + builder.WriteString(fmt.Sprintf("%v", rpe.Roles)) + builder.WriteByte(')') + return builder.String() +} + +// RolePanelEdits is a parsable slice of RolePanelEdit. +type RolePanelEdits []*RolePanelEdit diff --git a/ent/rolepaneledit/rolepaneledit.go b/ent/rolepaneledit/rolepaneledit.go new file mode 100644 index 00000000..0a7b7ba3 --- /dev/null +++ b/ent/rolepaneledit/rolepaneledit.go @@ -0,0 +1,167 @@ +// Code generated by ent, DO NOT EDIT. + +package rolepaneledit + +import ( + "entgo.io/ent/dialect/sql" + "entgo.io/ent/dialect/sql/sqlgraph" + "github.com/google/uuid" +) + +const ( + // Label holds the string label denoting the rolepaneledit type in the database. + Label = "role_panel_edit" + // FieldID holds the string denoting the id field in the database. + FieldID = "id" + // FieldChannelID holds the string denoting the channel_id field in the database. + FieldChannelID = "channel_id" + // FieldEmojiAuthor holds the string denoting the emoji_author field in the database. + FieldEmojiAuthor = "emoji_author" + // FieldToken holds the string denoting the token field in the database. + FieldToken = "token" + // FieldSelectedRole holds the string denoting the selected_role field in the database. + FieldSelectedRole = "selected_role" + // FieldModified holds the string denoting the modified field in the database. + FieldModified = "modified" + // FieldName holds the string denoting the name field in the database. + FieldName = "name" + // FieldDescription holds the string denoting the description field in the database. + FieldDescription = "description" + // FieldRoles holds the string denoting the roles field in the database. + FieldRoles = "roles" + // EdgeGuild holds the string denoting the guild edge name in mutations. + EdgeGuild = "guild" + // EdgeParent holds the string denoting the parent edge name in mutations. + EdgeParent = "parent" + // Table holds the table name of the rolepaneledit in the database. + Table = "role_panel_edits" + // GuildTable is the table that holds the guild relation/edge. + GuildTable = "role_panel_edits" + // GuildInverseTable is the table name for the Guild entity. + // It exists in this package in order to avoid circular dependency with the "guild" package. + GuildInverseTable = "guilds" + // GuildColumn is the table column denoting the guild relation/edge. + GuildColumn = "guild_role_panel_edits" + // ParentTable is the table that holds the parent relation/edge. + ParentTable = "role_panel_edits" + // ParentInverseTable is the table name for the RolePanel entity. + // It exists in this package in order to avoid circular dependency with the "rolepanel" package. + ParentInverseTable = "role_panels" + // ParentColumn is the table column denoting the parent relation/edge. + ParentColumn = "role_panel_edit" +) + +// Columns holds all SQL columns for rolepaneledit fields. +var Columns = []string{ + FieldID, + FieldChannelID, + FieldEmojiAuthor, + FieldToken, + FieldSelectedRole, + FieldModified, + FieldName, + FieldDescription, + FieldRoles, +} + +// ForeignKeys holds the SQL foreign-keys that are owned by the "role_panel_edits" +// table and are not defined as standalone fields in the schema. +var ForeignKeys = []string{ + "guild_role_panel_edits", + "role_panel_edit", +} + +// ValidColumn reports if the column name is valid (part of the table columns). +func ValidColumn(column string) bool { + for i := range Columns { + if column == Columns[i] { + return true + } + } + for i := range ForeignKeys { + if column == ForeignKeys[i] { + return true + } + } + return false +} + +var ( + // DefaultModified holds the default value on creation for the "modified" field. + DefaultModified bool + // NameValidator is a validator for the "name" field. It is called by the builders before save. + NameValidator func(string) error + // DefaultID holds the default value on creation for the "id" field. + DefaultID func() uuid.UUID +) + +// OrderOption defines the ordering options for the RolePanelEdit queries. +type OrderOption func(*sql.Selector) + +// ByID orders the results by the id field. +func ByID(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldID, opts...).ToFunc() +} + +// ByChannelID orders the results by the channel_id field. +func ByChannelID(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldChannelID, opts...).ToFunc() +} + +// ByEmojiAuthor orders the results by the emoji_author field. +func ByEmojiAuthor(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldEmojiAuthor, opts...).ToFunc() +} + +// ByToken orders the results by the token field. +func ByToken(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldToken, opts...).ToFunc() +} + +// BySelectedRole orders the results by the selected_role field. +func BySelectedRole(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldSelectedRole, opts...).ToFunc() +} + +// ByModified orders the results by the modified field. +func ByModified(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldModified, opts...).ToFunc() +} + +// ByName orders the results by the name field. +func ByName(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldName, opts...).ToFunc() +} + +// ByDescription orders the results by the description field. +func ByDescription(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldDescription, opts...).ToFunc() +} + +// ByGuildField orders the results by guild field. +func ByGuildField(field string, opts ...sql.OrderTermOption) OrderOption { + return func(s *sql.Selector) { + sqlgraph.OrderByNeighborTerms(s, newGuildStep(), sql.OrderByField(field, opts...)) + } +} + +// ByParentField orders the results by parent field. +func ByParentField(field string, opts ...sql.OrderTermOption) OrderOption { + return func(s *sql.Selector) { + sqlgraph.OrderByNeighborTerms(s, newParentStep(), sql.OrderByField(field, opts...)) + } +} +func newGuildStep() *sqlgraph.Step { + return sqlgraph.NewStep( + sqlgraph.From(Table, FieldID), + sqlgraph.To(GuildInverseTable, FieldID), + sqlgraph.Edge(sqlgraph.M2O, true, GuildTable, GuildColumn), + ) +} +func newParentStep() *sqlgraph.Step { + return sqlgraph.NewStep( + sqlgraph.From(Table, FieldID), + sqlgraph.To(ParentInverseTable, FieldID), + sqlgraph.Edge(sqlgraph.O2O, true, ParentTable, ParentColumn), + ) +} diff --git a/ent/rolepaneledit/where.go b/ent/rolepaneledit/where.go new file mode 100644 index 00000000..fb12a485 --- /dev/null +++ b/ent/rolepaneledit/where.go @@ -0,0 +1,582 @@ +// Code generated by ent, DO NOT EDIT. + +package rolepaneledit + +import ( + "entgo.io/ent/dialect/sql" + "entgo.io/ent/dialect/sql/sqlgraph" + snowflake "github.com/disgoorg/snowflake/v2" + "github.com/google/uuid" + "github.com/sabafly/gobot/ent/predicate" +) + +// ID filters vertices based on their ID field. +func ID(id uuid.UUID) predicate.RolePanelEdit { + return predicate.RolePanelEdit(sql.FieldEQ(FieldID, id)) +} + +// IDEQ applies the EQ predicate on the ID field. +func IDEQ(id uuid.UUID) predicate.RolePanelEdit { + return predicate.RolePanelEdit(sql.FieldEQ(FieldID, id)) +} + +// IDNEQ applies the NEQ predicate on the ID field. +func IDNEQ(id uuid.UUID) predicate.RolePanelEdit { + return predicate.RolePanelEdit(sql.FieldNEQ(FieldID, id)) +} + +// IDIn applies the In predicate on the ID field. +func IDIn(ids ...uuid.UUID) predicate.RolePanelEdit { + return predicate.RolePanelEdit(sql.FieldIn(FieldID, ids...)) +} + +// IDNotIn applies the NotIn predicate on the ID field. +func IDNotIn(ids ...uuid.UUID) predicate.RolePanelEdit { + return predicate.RolePanelEdit(sql.FieldNotIn(FieldID, ids...)) +} + +// IDGT applies the GT predicate on the ID field. +func IDGT(id uuid.UUID) predicate.RolePanelEdit { + return predicate.RolePanelEdit(sql.FieldGT(FieldID, id)) +} + +// IDGTE applies the GTE predicate on the ID field. +func IDGTE(id uuid.UUID) predicate.RolePanelEdit { + return predicate.RolePanelEdit(sql.FieldGTE(FieldID, id)) +} + +// IDLT applies the LT predicate on the ID field. +func IDLT(id uuid.UUID) predicate.RolePanelEdit { + return predicate.RolePanelEdit(sql.FieldLT(FieldID, id)) +} + +// IDLTE applies the LTE predicate on the ID field. +func IDLTE(id uuid.UUID) predicate.RolePanelEdit { + return predicate.RolePanelEdit(sql.FieldLTE(FieldID, id)) +} + +// ChannelID applies equality check predicate on the "channel_id" field. It's identical to ChannelIDEQ. +func ChannelID(v snowflake.ID) predicate.RolePanelEdit { + vc := uint64(v) + return predicate.RolePanelEdit(sql.FieldEQ(FieldChannelID, vc)) +} + +// EmojiAuthor applies equality check predicate on the "emoji_author" field. It's identical to EmojiAuthorEQ. +func EmojiAuthor(v snowflake.ID) predicate.RolePanelEdit { + vc := uint64(v) + return predicate.RolePanelEdit(sql.FieldEQ(FieldEmojiAuthor, vc)) +} + +// Token applies equality check predicate on the "token" field. It's identical to TokenEQ. +func Token(v string) predicate.RolePanelEdit { + return predicate.RolePanelEdit(sql.FieldEQ(FieldToken, v)) +} + +// SelectedRole applies equality check predicate on the "selected_role" field. It's identical to SelectedRoleEQ. +func SelectedRole(v snowflake.ID) predicate.RolePanelEdit { + vc := uint64(v) + return predicate.RolePanelEdit(sql.FieldEQ(FieldSelectedRole, vc)) +} + +// Modified applies equality check predicate on the "modified" field. It's identical to ModifiedEQ. +func Modified(v bool) predicate.RolePanelEdit { + return predicate.RolePanelEdit(sql.FieldEQ(FieldModified, v)) +} + +// Name applies equality check predicate on the "name" field. It's identical to NameEQ. +func Name(v string) predicate.RolePanelEdit { + return predicate.RolePanelEdit(sql.FieldEQ(FieldName, v)) +} + +// Description applies equality check predicate on the "description" field. It's identical to DescriptionEQ. +func Description(v string) predicate.RolePanelEdit { + return predicate.RolePanelEdit(sql.FieldEQ(FieldDescription, v)) +} + +// ChannelIDEQ applies the EQ predicate on the "channel_id" field. +func ChannelIDEQ(v snowflake.ID) predicate.RolePanelEdit { + vc := uint64(v) + return predicate.RolePanelEdit(sql.FieldEQ(FieldChannelID, vc)) +} + +// ChannelIDNEQ applies the NEQ predicate on the "channel_id" field. +func ChannelIDNEQ(v snowflake.ID) predicate.RolePanelEdit { + vc := uint64(v) + return predicate.RolePanelEdit(sql.FieldNEQ(FieldChannelID, vc)) +} + +// ChannelIDIn applies the In predicate on the "channel_id" field. +func ChannelIDIn(vs ...snowflake.ID) predicate.RolePanelEdit { + v := make([]any, len(vs)) + for i := range v { + v[i] = uint64(vs[i]) + } + return predicate.RolePanelEdit(sql.FieldIn(FieldChannelID, v...)) +} + +// ChannelIDNotIn applies the NotIn predicate on the "channel_id" field. +func ChannelIDNotIn(vs ...snowflake.ID) predicate.RolePanelEdit { + v := make([]any, len(vs)) + for i := range v { + v[i] = uint64(vs[i]) + } + return predicate.RolePanelEdit(sql.FieldNotIn(FieldChannelID, v...)) +} + +// ChannelIDGT applies the GT predicate on the "channel_id" field. +func ChannelIDGT(v snowflake.ID) predicate.RolePanelEdit { + vc := uint64(v) + return predicate.RolePanelEdit(sql.FieldGT(FieldChannelID, vc)) +} + +// ChannelIDGTE applies the GTE predicate on the "channel_id" field. +func ChannelIDGTE(v snowflake.ID) predicate.RolePanelEdit { + vc := uint64(v) + return predicate.RolePanelEdit(sql.FieldGTE(FieldChannelID, vc)) +} + +// ChannelIDLT applies the LT predicate on the "channel_id" field. +func ChannelIDLT(v snowflake.ID) predicate.RolePanelEdit { + vc := uint64(v) + return predicate.RolePanelEdit(sql.FieldLT(FieldChannelID, vc)) +} + +// ChannelIDLTE applies the LTE predicate on the "channel_id" field. +func ChannelIDLTE(v snowflake.ID) predicate.RolePanelEdit { + vc := uint64(v) + return predicate.RolePanelEdit(sql.FieldLTE(FieldChannelID, vc)) +} + +// EmojiAuthorEQ applies the EQ predicate on the "emoji_author" field. +func EmojiAuthorEQ(v snowflake.ID) predicate.RolePanelEdit { + vc := uint64(v) + return predicate.RolePanelEdit(sql.FieldEQ(FieldEmojiAuthor, vc)) +} + +// EmojiAuthorNEQ applies the NEQ predicate on the "emoji_author" field. +func EmojiAuthorNEQ(v snowflake.ID) predicate.RolePanelEdit { + vc := uint64(v) + return predicate.RolePanelEdit(sql.FieldNEQ(FieldEmojiAuthor, vc)) +} + +// EmojiAuthorIn applies the In predicate on the "emoji_author" field. +func EmojiAuthorIn(vs ...snowflake.ID) predicate.RolePanelEdit { + v := make([]any, len(vs)) + for i := range v { + v[i] = uint64(vs[i]) + } + return predicate.RolePanelEdit(sql.FieldIn(FieldEmojiAuthor, v...)) +} + +// EmojiAuthorNotIn applies the NotIn predicate on the "emoji_author" field. +func EmojiAuthorNotIn(vs ...snowflake.ID) predicate.RolePanelEdit { + v := make([]any, len(vs)) + for i := range v { + v[i] = uint64(vs[i]) + } + return predicate.RolePanelEdit(sql.FieldNotIn(FieldEmojiAuthor, v...)) +} + +// EmojiAuthorGT applies the GT predicate on the "emoji_author" field. +func EmojiAuthorGT(v snowflake.ID) predicate.RolePanelEdit { + vc := uint64(v) + return predicate.RolePanelEdit(sql.FieldGT(FieldEmojiAuthor, vc)) +} + +// EmojiAuthorGTE applies the GTE predicate on the "emoji_author" field. +func EmojiAuthorGTE(v snowflake.ID) predicate.RolePanelEdit { + vc := uint64(v) + return predicate.RolePanelEdit(sql.FieldGTE(FieldEmojiAuthor, vc)) +} + +// EmojiAuthorLT applies the LT predicate on the "emoji_author" field. +func EmojiAuthorLT(v snowflake.ID) predicate.RolePanelEdit { + vc := uint64(v) + return predicate.RolePanelEdit(sql.FieldLT(FieldEmojiAuthor, vc)) +} + +// EmojiAuthorLTE applies the LTE predicate on the "emoji_author" field. +func EmojiAuthorLTE(v snowflake.ID) predicate.RolePanelEdit { + vc := uint64(v) + return predicate.RolePanelEdit(sql.FieldLTE(FieldEmojiAuthor, vc)) +} + +// EmojiAuthorIsNil applies the IsNil predicate on the "emoji_author" field. +func EmojiAuthorIsNil() predicate.RolePanelEdit { + return predicate.RolePanelEdit(sql.FieldIsNull(FieldEmojiAuthor)) +} + +// EmojiAuthorNotNil applies the NotNil predicate on the "emoji_author" field. +func EmojiAuthorNotNil() predicate.RolePanelEdit { + return predicate.RolePanelEdit(sql.FieldNotNull(FieldEmojiAuthor)) +} + +// TokenEQ applies the EQ predicate on the "token" field. +func TokenEQ(v string) predicate.RolePanelEdit { + return predicate.RolePanelEdit(sql.FieldEQ(FieldToken, v)) +} + +// TokenNEQ applies the NEQ predicate on the "token" field. +func TokenNEQ(v string) predicate.RolePanelEdit { + return predicate.RolePanelEdit(sql.FieldNEQ(FieldToken, v)) +} + +// TokenIn applies the In predicate on the "token" field. +func TokenIn(vs ...string) predicate.RolePanelEdit { + return predicate.RolePanelEdit(sql.FieldIn(FieldToken, vs...)) +} + +// TokenNotIn applies the NotIn predicate on the "token" field. +func TokenNotIn(vs ...string) predicate.RolePanelEdit { + return predicate.RolePanelEdit(sql.FieldNotIn(FieldToken, vs...)) +} + +// TokenGT applies the GT predicate on the "token" field. +func TokenGT(v string) predicate.RolePanelEdit { + return predicate.RolePanelEdit(sql.FieldGT(FieldToken, v)) +} + +// TokenGTE applies the GTE predicate on the "token" field. +func TokenGTE(v string) predicate.RolePanelEdit { + return predicate.RolePanelEdit(sql.FieldGTE(FieldToken, v)) +} + +// TokenLT applies the LT predicate on the "token" field. +func TokenLT(v string) predicate.RolePanelEdit { + return predicate.RolePanelEdit(sql.FieldLT(FieldToken, v)) +} + +// TokenLTE applies the LTE predicate on the "token" field. +func TokenLTE(v string) predicate.RolePanelEdit { + return predicate.RolePanelEdit(sql.FieldLTE(FieldToken, v)) +} + +// TokenContains applies the Contains predicate on the "token" field. +func TokenContains(v string) predicate.RolePanelEdit { + return predicate.RolePanelEdit(sql.FieldContains(FieldToken, v)) +} + +// TokenHasPrefix applies the HasPrefix predicate on the "token" field. +func TokenHasPrefix(v string) predicate.RolePanelEdit { + return predicate.RolePanelEdit(sql.FieldHasPrefix(FieldToken, v)) +} + +// TokenHasSuffix applies the HasSuffix predicate on the "token" field. +func TokenHasSuffix(v string) predicate.RolePanelEdit { + return predicate.RolePanelEdit(sql.FieldHasSuffix(FieldToken, v)) +} + +// TokenIsNil applies the IsNil predicate on the "token" field. +func TokenIsNil() predicate.RolePanelEdit { + return predicate.RolePanelEdit(sql.FieldIsNull(FieldToken)) +} + +// TokenNotNil applies the NotNil predicate on the "token" field. +func TokenNotNil() predicate.RolePanelEdit { + return predicate.RolePanelEdit(sql.FieldNotNull(FieldToken)) +} + +// TokenEqualFold applies the EqualFold predicate on the "token" field. +func TokenEqualFold(v string) predicate.RolePanelEdit { + return predicate.RolePanelEdit(sql.FieldEqualFold(FieldToken, v)) +} + +// TokenContainsFold applies the ContainsFold predicate on the "token" field. +func TokenContainsFold(v string) predicate.RolePanelEdit { + return predicate.RolePanelEdit(sql.FieldContainsFold(FieldToken, v)) +} + +// SelectedRoleEQ applies the EQ predicate on the "selected_role" field. +func SelectedRoleEQ(v snowflake.ID) predicate.RolePanelEdit { + vc := uint64(v) + return predicate.RolePanelEdit(sql.FieldEQ(FieldSelectedRole, vc)) +} + +// SelectedRoleNEQ applies the NEQ predicate on the "selected_role" field. +func SelectedRoleNEQ(v snowflake.ID) predicate.RolePanelEdit { + vc := uint64(v) + return predicate.RolePanelEdit(sql.FieldNEQ(FieldSelectedRole, vc)) +} + +// SelectedRoleIn applies the In predicate on the "selected_role" field. +func SelectedRoleIn(vs ...snowflake.ID) predicate.RolePanelEdit { + v := make([]any, len(vs)) + for i := range v { + v[i] = uint64(vs[i]) + } + return predicate.RolePanelEdit(sql.FieldIn(FieldSelectedRole, v...)) +} + +// SelectedRoleNotIn applies the NotIn predicate on the "selected_role" field. +func SelectedRoleNotIn(vs ...snowflake.ID) predicate.RolePanelEdit { + v := make([]any, len(vs)) + for i := range v { + v[i] = uint64(vs[i]) + } + return predicate.RolePanelEdit(sql.FieldNotIn(FieldSelectedRole, v...)) +} + +// SelectedRoleGT applies the GT predicate on the "selected_role" field. +func SelectedRoleGT(v snowflake.ID) predicate.RolePanelEdit { + vc := uint64(v) + return predicate.RolePanelEdit(sql.FieldGT(FieldSelectedRole, vc)) +} + +// SelectedRoleGTE applies the GTE predicate on the "selected_role" field. +func SelectedRoleGTE(v snowflake.ID) predicate.RolePanelEdit { + vc := uint64(v) + return predicate.RolePanelEdit(sql.FieldGTE(FieldSelectedRole, vc)) +} + +// SelectedRoleLT applies the LT predicate on the "selected_role" field. +func SelectedRoleLT(v snowflake.ID) predicate.RolePanelEdit { + vc := uint64(v) + return predicate.RolePanelEdit(sql.FieldLT(FieldSelectedRole, vc)) +} + +// SelectedRoleLTE applies the LTE predicate on the "selected_role" field. +func SelectedRoleLTE(v snowflake.ID) predicate.RolePanelEdit { + vc := uint64(v) + return predicate.RolePanelEdit(sql.FieldLTE(FieldSelectedRole, vc)) +} + +// SelectedRoleIsNil applies the IsNil predicate on the "selected_role" field. +func SelectedRoleIsNil() predicate.RolePanelEdit { + return predicate.RolePanelEdit(sql.FieldIsNull(FieldSelectedRole)) +} + +// SelectedRoleNotNil applies the NotNil predicate on the "selected_role" field. +func SelectedRoleNotNil() predicate.RolePanelEdit { + return predicate.RolePanelEdit(sql.FieldNotNull(FieldSelectedRole)) +} + +// ModifiedEQ applies the EQ predicate on the "modified" field. +func ModifiedEQ(v bool) predicate.RolePanelEdit { + return predicate.RolePanelEdit(sql.FieldEQ(FieldModified, v)) +} + +// ModifiedNEQ applies the NEQ predicate on the "modified" field. +func ModifiedNEQ(v bool) predicate.RolePanelEdit { + return predicate.RolePanelEdit(sql.FieldNEQ(FieldModified, v)) +} + +// NameEQ applies the EQ predicate on the "name" field. +func NameEQ(v string) predicate.RolePanelEdit { + return predicate.RolePanelEdit(sql.FieldEQ(FieldName, v)) +} + +// NameNEQ applies the NEQ predicate on the "name" field. +func NameNEQ(v string) predicate.RolePanelEdit { + return predicate.RolePanelEdit(sql.FieldNEQ(FieldName, v)) +} + +// NameIn applies the In predicate on the "name" field. +func NameIn(vs ...string) predicate.RolePanelEdit { + return predicate.RolePanelEdit(sql.FieldIn(FieldName, vs...)) +} + +// NameNotIn applies the NotIn predicate on the "name" field. +func NameNotIn(vs ...string) predicate.RolePanelEdit { + return predicate.RolePanelEdit(sql.FieldNotIn(FieldName, vs...)) +} + +// NameGT applies the GT predicate on the "name" field. +func NameGT(v string) predicate.RolePanelEdit { + return predicate.RolePanelEdit(sql.FieldGT(FieldName, v)) +} + +// NameGTE applies the GTE predicate on the "name" field. +func NameGTE(v string) predicate.RolePanelEdit { + return predicate.RolePanelEdit(sql.FieldGTE(FieldName, v)) +} + +// NameLT applies the LT predicate on the "name" field. +func NameLT(v string) predicate.RolePanelEdit { + return predicate.RolePanelEdit(sql.FieldLT(FieldName, v)) +} + +// NameLTE applies the LTE predicate on the "name" field. +func NameLTE(v string) predicate.RolePanelEdit { + return predicate.RolePanelEdit(sql.FieldLTE(FieldName, v)) +} + +// NameContains applies the Contains predicate on the "name" field. +func NameContains(v string) predicate.RolePanelEdit { + return predicate.RolePanelEdit(sql.FieldContains(FieldName, v)) +} + +// NameHasPrefix applies the HasPrefix predicate on the "name" field. +func NameHasPrefix(v string) predicate.RolePanelEdit { + return predicate.RolePanelEdit(sql.FieldHasPrefix(FieldName, v)) +} + +// NameHasSuffix applies the HasSuffix predicate on the "name" field. +func NameHasSuffix(v string) predicate.RolePanelEdit { + return predicate.RolePanelEdit(sql.FieldHasSuffix(FieldName, v)) +} + +// NameIsNil applies the IsNil predicate on the "name" field. +func NameIsNil() predicate.RolePanelEdit { + return predicate.RolePanelEdit(sql.FieldIsNull(FieldName)) +} + +// NameNotNil applies the NotNil predicate on the "name" field. +func NameNotNil() predicate.RolePanelEdit { + return predicate.RolePanelEdit(sql.FieldNotNull(FieldName)) +} + +// NameEqualFold applies the EqualFold predicate on the "name" field. +func NameEqualFold(v string) predicate.RolePanelEdit { + return predicate.RolePanelEdit(sql.FieldEqualFold(FieldName, v)) +} + +// NameContainsFold applies the ContainsFold predicate on the "name" field. +func NameContainsFold(v string) predicate.RolePanelEdit { + return predicate.RolePanelEdit(sql.FieldContainsFold(FieldName, v)) +} + +// DescriptionEQ applies the EQ predicate on the "description" field. +func DescriptionEQ(v string) predicate.RolePanelEdit { + return predicate.RolePanelEdit(sql.FieldEQ(FieldDescription, v)) +} + +// DescriptionNEQ applies the NEQ predicate on the "description" field. +func DescriptionNEQ(v string) predicate.RolePanelEdit { + return predicate.RolePanelEdit(sql.FieldNEQ(FieldDescription, v)) +} + +// DescriptionIn applies the In predicate on the "description" field. +func DescriptionIn(vs ...string) predicate.RolePanelEdit { + return predicate.RolePanelEdit(sql.FieldIn(FieldDescription, vs...)) +} + +// DescriptionNotIn applies the NotIn predicate on the "description" field. +func DescriptionNotIn(vs ...string) predicate.RolePanelEdit { + return predicate.RolePanelEdit(sql.FieldNotIn(FieldDescription, vs...)) +} + +// DescriptionGT applies the GT predicate on the "description" field. +func DescriptionGT(v string) predicate.RolePanelEdit { + return predicate.RolePanelEdit(sql.FieldGT(FieldDescription, v)) +} + +// DescriptionGTE applies the GTE predicate on the "description" field. +func DescriptionGTE(v string) predicate.RolePanelEdit { + return predicate.RolePanelEdit(sql.FieldGTE(FieldDescription, v)) +} + +// DescriptionLT applies the LT predicate on the "description" field. +func DescriptionLT(v string) predicate.RolePanelEdit { + return predicate.RolePanelEdit(sql.FieldLT(FieldDescription, v)) +} + +// DescriptionLTE applies the LTE predicate on the "description" field. +func DescriptionLTE(v string) predicate.RolePanelEdit { + return predicate.RolePanelEdit(sql.FieldLTE(FieldDescription, v)) +} + +// DescriptionContains applies the Contains predicate on the "description" field. +func DescriptionContains(v string) predicate.RolePanelEdit { + return predicate.RolePanelEdit(sql.FieldContains(FieldDescription, v)) +} + +// DescriptionHasPrefix applies the HasPrefix predicate on the "description" field. +func DescriptionHasPrefix(v string) predicate.RolePanelEdit { + return predicate.RolePanelEdit(sql.FieldHasPrefix(FieldDescription, v)) +} + +// DescriptionHasSuffix applies the HasSuffix predicate on the "description" field. +func DescriptionHasSuffix(v string) predicate.RolePanelEdit { + return predicate.RolePanelEdit(sql.FieldHasSuffix(FieldDescription, v)) +} + +// DescriptionIsNil applies the IsNil predicate on the "description" field. +func DescriptionIsNil() predicate.RolePanelEdit { + return predicate.RolePanelEdit(sql.FieldIsNull(FieldDescription)) +} + +// DescriptionNotNil applies the NotNil predicate on the "description" field. +func DescriptionNotNil() predicate.RolePanelEdit { + return predicate.RolePanelEdit(sql.FieldNotNull(FieldDescription)) +} + +// DescriptionEqualFold applies the EqualFold predicate on the "description" field. +func DescriptionEqualFold(v string) predicate.RolePanelEdit { + return predicate.RolePanelEdit(sql.FieldEqualFold(FieldDescription, v)) +} + +// DescriptionContainsFold applies the ContainsFold predicate on the "description" field. +func DescriptionContainsFold(v string) predicate.RolePanelEdit { + return predicate.RolePanelEdit(sql.FieldContainsFold(FieldDescription, v)) +} + +// RolesIsNil applies the IsNil predicate on the "roles" field. +func RolesIsNil() predicate.RolePanelEdit { + return predicate.RolePanelEdit(sql.FieldIsNull(FieldRoles)) +} + +// RolesNotNil applies the NotNil predicate on the "roles" field. +func RolesNotNil() predicate.RolePanelEdit { + return predicate.RolePanelEdit(sql.FieldNotNull(FieldRoles)) +} + +// HasGuild applies the HasEdge predicate on the "guild" edge. +func HasGuild() predicate.RolePanelEdit { + return predicate.RolePanelEdit(func(s *sql.Selector) { + step := sqlgraph.NewStep( + sqlgraph.From(Table, FieldID), + sqlgraph.Edge(sqlgraph.M2O, true, GuildTable, GuildColumn), + ) + sqlgraph.HasNeighbors(s, step) + }) +} + +// HasGuildWith applies the HasEdge predicate on the "guild" edge with a given conditions (other predicates). +func HasGuildWith(preds ...predicate.Guild) predicate.RolePanelEdit { + return predicate.RolePanelEdit(func(s *sql.Selector) { + step := newGuildStep() + sqlgraph.HasNeighborsWith(s, step, func(s *sql.Selector) { + for _, p := range preds { + p(s) + } + }) + }) +} + +// HasParent applies the HasEdge predicate on the "parent" edge. +func HasParent() predicate.RolePanelEdit { + return predicate.RolePanelEdit(func(s *sql.Selector) { + step := sqlgraph.NewStep( + sqlgraph.From(Table, FieldID), + sqlgraph.Edge(sqlgraph.O2O, true, ParentTable, ParentColumn), + ) + sqlgraph.HasNeighbors(s, step) + }) +} + +// HasParentWith applies the HasEdge predicate on the "parent" edge with a given conditions (other predicates). +func HasParentWith(preds ...predicate.RolePanel) predicate.RolePanelEdit { + return predicate.RolePanelEdit(func(s *sql.Selector) { + step := newParentStep() + sqlgraph.HasNeighborsWith(s, step, func(s *sql.Selector) { + for _, p := range preds { + p(s) + } + }) + }) +} + +// And groups predicates with the AND operator between them. +func And(predicates ...predicate.RolePanelEdit) predicate.RolePanelEdit { + return predicate.RolePanelEdit(sql.AndPredicates(predicates...)) +} + +// Or groups predicates with the OR operator between them. +func Or(predicates ...predicate.RolePanelEdit) predicate.RolePanelEdit { + return predicate.RolePanelEdit(sql.OrPredicates(predicates...)) +} + +// Not applies the not operator on the given predicate. +func Not(p predicate.RolePanelEdit) predicate.RolePanelEdit { + return predicate.RolePanelEdit(sql.NotPredicates(p)) +} diff --git a/ent/rolepaneledit_create.go b/ent/rolepaneledit_create.go new file mode 100644 index 00000000..bb4f7f1d --- /dev/null +++ b/ent/rolepaneledit_create.go @@ -0,0 +1,409 @@ +// Code generated by ent, DO NOT EDIT. + +package ent + +import ( + "context" + "errors" + "fmt" + + "entgo.io/ent/dialect/sql/sqlgraph" + "entgo.io/ent/schema/field" + snowflake "github.com/disgoorg/snowflake/v2" + "github.com/google/uuid" + "github.com/sabafly/gobot/ent/guild" + "github.com/sabafly/gobot/ent/rolepanel" + "github.com/sabafly/gobot/ent/rolepaneledit" + "github.com/sabafly/gobot/ent/schema" +) + +// RolePanelEditCreate is the builder for creating a RolePanelEdit entity. +type RolePanelEditCreate struct { + config + mutation *RolePanelEditMutation + hooks []Hook +} + +// SetChannelID sets the "channel_id" field. +func (rpec *RolePanelEditCreate) SetChannelID(s snowflake.ID) *RolePanelEditCreate { + rpec.mutation.SetChannelID(s) + return rpec +} + +// SetEmojiAuthor sets the "emoji_author" field. +func (rpec *RolePanelEditCreate) SetEmojiAuthor(s snowflake.ID) *RolePanelEditCreate { + rpec.mutation.SetEmojiAuthor(s) + return rpec +} + +// SetNillableEmojiAuthor sets the "emoji_author" field if the given value is not nil. +func (rpec *RolePanelEditCreate) SetNillableEmojiAuthor(s *snowflake.ID) *RolePanelEditCreate { + if s != nil { + rpec.SetEmojiAuthor(*s) + } + return rpec +} + +// SetToken sets the "token" field. +func (rpec *RolePanelEditCreate) SetToken(s string) *RolePanelEditCreate { + rpec.mutation.SetToken(s) + return rpec +} + +// SetNillableToken sets the "token" field if the given value is not nil. +func (rpec *RolePanelEditCreate) SetNillableToken(s *string) *RolePanelEditCreate { + if s != nil { + rpec.SetToken(*s) + } + return rpec +} + +// SetSelectedRole sets the "selected_role" field. +func (rpec *RolePanelEditCreate) SetSelectedRole(s snowflake.ID) *RolePanelEditCreate { + rpec.mutation.SetSelectedRole(s) + return rpec +} + +// SetNillableSelectedRole sets the "selected_role" field if the given value is not nil. +func (rpec *RolePanelEditCreate) SetNillableSelectedRole(s *snowflake.ID) *RolePanelEditCreate { + if s != nil { + rpec.SetSelectedRole(*s) + } + return rpec +} + +// SetModified sets the "modified" field. +func (rpec *RolePanelEditCreate) SetModified(b bool) *RolePanelEditCreate { + rpec.mutation.SetModified(b) + return rpec +} + +// SetNillableModified sets the "modified" field if the given value is not nil. +func (rpec *RolePanelEditCreate) SetNillableModified(b *bool) *RolePanelEditCreate { + if b != nil { + rpec.SetModified(*b) + } + return rpec +} + +// SetName sets the "name" field. +func (rpec *RolePanelEditCreate) SetName(s string) *RolePanelEditCreate { + rpec.mutation.SetName(s) + return rpec +} + +// SetNillableName sets the "name" field if the given value is not nil. +func (rpec *RolePanelEditCreate) SetNillableName(s *string) *RolePanelEditCreate { + if s != nil { + rpec.SetName(*s) + } + return rpec +} + +// SetDescription sets the "description" field. +func (rpec *RolePanelEditCreate) SetDescription(s string) *RolePanelEditCreate { + rpec.mutation.SetDescription(s) + return rpec +} + +// SetNillableDescription sets the "description" field if the given value is not nil. +func (rpec *RolePanelEditCreate) SetNillableDescription(s *string) *RolePanelEditCreate { + if s != nil { + rpec.SetDescription(*s) + } + return rpec +} + +// SetRoles sets the "roles" field. +func (rpec *RolePanelEditCreate) SetRoles(s []schema.Role) *RolePanelEditCreate { + rpec.mutation.SetRoles(s) + return rpec +} + +// SetID sets the "id" field. +func (rpec *RolePanelEditCreate) SetID(u uuid.UUID) *RolePanelEditCreate { + rpec.mutation.SetID(u) + return rpec +} + +// SetNillableID sets the "id" field if the given value is not nil. +func (rpec *RolePanelEditCreate) SetNillableID(u *uuid.UUID) *RolePanelEditCreate { + if u != nil { + rpec.SetID(*u) + } + return rpec +} + +// SetGuildID sets the "guild" edge to the Guild entity by ID. +func (rpec *RolePanelEditCreate) SetGuildID(id snowflake.ID) *RolePanelEditCreate { + rpec.mutation.SetGuildID(id) + return rpec +} + +// SetGuild sets the "guild" edge to the Guild entity. +func (rpec *RolePanelEditCreate) SetGuild(g *Guild) *RolePanelEditCreate { + return rpec.SetGuildID(g.ID) +} + +// SetParentID sets the "parent" edge to the RolePanel entity by ID. +func (rpec *RolePanelEditCreate) SetParentID(id uuid.UUID) *RolePanelEditCreate { + rpec.mutation.SetParentID(id) + return rpec +} + +// SetParent sets the "parent" edge to the RolePanel entity. +func (rpec *RolePanelEditCreate) SetParent(r *RolePanel) *RolePanelEditCreate { + return rpec.SetParentID(r.ID) +} + +// Mutation returns the RolePanelEditMutation object of the builder. +func (rpec *RolePanelEditCreate) Mutation() *RolePanelEditMutation { + return rpec.mutation +} + +// Save creates the RolePanelEdit in the database. +func (rpec *RolePanelEditCreate) Save(ctx context.Context) (*RolePanelEdit, error) { + rpec.defaults() + return withHooks(ctx, rpec.sqlSave, rpec.mutation, rpec.hooks) +} + +// SaveX calls Save and panics if Save returns an error. +func (rpec *RolePanelEditCreate) SaveX(ctx context.Context) *RolePanelEdit { + v, err := rpec.Save(ctx) + if err != nil { + panic(err) + } + return v +} + +// Exec executes the query. +func (rpec *RolePanelEditCreate) Exec(ctx context.Context) error { + _, err := rpec.Save(ctx) + return err +} + +// ExecX is like Exec, but panics if an error occurs. +func (rpec *RolePanelEditCreate) ExecX(ctx context.Context) { + if err := rpec.Exec(ctx); err != nil { + panic(err) + } +} + +// defaults sets the default values of the builder before save. +func (rpec *RolePanelEditCreate) defaults() { + if _, ok := rpec.mutation.Modified(); !ok { + v := rolepaneledit.DefaultModified + rpec.mutation.SetModified(v) + } + if _, ok := rpec.mutation.ID(); !ok { + v := rolepaneledit.DefaultID() + rpec.mutation.SetID(v) + } +} + +// check runs all checks and user-defined validators on the builder. +func (rpec *RolePanelEditCreate) check() error { + if _, ok := rpec.mutation.ChannelID(); !ok { + return &ValidationError{Name: "channel_id", err: errors.New(`ent: missing required field "RolePanelEdit.channel_id"`)} + } + if _, ok := rpec.mutation.Modified(); !ok { + return &ValidationError{Name: "modified", err: errors.New(`ent: missing required field "RolePanelEdit.modified"`)} + } + if v, ok := rpec.mutation.Name(); ok { + if err := rolepaneledit.NameValidator(v); err != nil { + return &ValidationError{Name: "name", err: fmt.Errorf(`ent: validator failed for field "RolePanelEdit.name": %w`, err)} + } + } + if _, ok := rpec.mutation.GuildID(); !ok { + return &ValidationError{Name: "guild", err: errors.New(`ent: missing required edge "RolePanelEdit.guild"`)} + } + if _, ok := rpec.mutation.ParentID(); !ok { + return &ValidationError{Name: "parent", err: errors.New(`ent: missing required edge "RolePanelEdit.parent"`)} + } + return nil +} + +func (rpec *RolePanelEditCreate) sqlSave(ctx context.Context) (*RolePanelEdit, error) { + if err := rpec.check(); err != nil { + return nil, err + } + _node, _spec := rpec.createSpec() + if err := sqlgraph.CreateNode(ctx, rpec.driver, _spec); err != nil { + if sqlgraph.IsConstraintError(err) { + err = &ConstraintError{msg: err.Error(), wrap: err} + } + return nil, err + } + if _spec.ID.Value != nil { + if id, ok := _spec.ID.Value.(*uuid.UUID); ok { + _node.ID = *id + } else if err := _node.ID.Scan(_spec.ID.Value); err != nil { + return nil, err + } + } + rpec.mutation.id = &_node.ID + rpec.mutation.done = true + return _node, nil +} + +func (rpec *RolePanelEditCreate) createSpec() (*RolePanelEdit, *sqlgraph.CreateSpec) { + var ( + _node = &RolePanelEdit{config: rpec.config} + _spec = sqlgraph.NewCreateSpec(rolepaneledit.Table, sqlgraph.NewFieldSpec(rolepaneledit.FieldID, field.TypeUUID)) + ) + if id, ok := rpec.mutation.ID(); ok { + _node.ID = id + _spec.ID.Value = &id + } + if value, ok := rpec.mutation.ChannelID(); ok { + _spec.SetField(rolepaneledit.FieldChannelID, field.TypeUint64, value) + _node.ChannelID = value + } + if value, ok := rpec.mutation.EmojiAuthor(); ok { + _spec.SetField(rolepaneledit.FieldEmojiAuthor, field.TypeUint64, value) + _node.EmojiAuthor = &value + } + if value, ok := rpec.mutation.Token(); ok { + _spec.SetField(rolepaneledit.FieldToken, field.TypeString, value) + _node.Token = &value + } + if value, ok := rpec.mutation.SelectedRole(); ok { + _spec.SetField(rolepaneledit.FieldSelectedRole, field.TypeUint64, value) + _node.SelectedRole = &value + } + if value, ok := rpec.mutation.Modified(); ok { + _spec.SetField(rolepaneledit.FieldModified, field.TypeBool, value) + _node.Modified = value + } + if value, ok := rpec.mutation.Name(); ok { + _spec.SetField(rolepaneledit.FieldName, field.TypeString, value) + _node.Name = &value + } + if value, ok := rpec.mutation.Description(); ok { + _spec.SetField(rolepaneledit.FieldDescription, field.TypeString, value) + _node.Description = &value + } + if value, ok := rpec.mutation.Roles(); ok { + _spec.SetField(rolepaneledit.FieldRoles, field.TypeJSON, value) + _node.Roles = value + } + if nodes := rpec.mutation.GuildIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.M2O, + Inverse: true, + Table: rolepaneledit.GuildTable, + Columns: []string{rolepaneledit.GuildColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(guild.FieldID, field.TypeUint64), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _node.guild_role_panel_edits = &nodes[0] + _spec.Edges = append(_spec.Edges, edge) + } + if nodes := rpec.mutation.ParentIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2O, + Inverse: true, + Table: rolepaneledit.ParentTable, + Columns: []string{rolepaneledit.ParentColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(rolepanel.FieldID, field.TypeUUID), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _node.role_panel_edit = &nodes[0] + _spec.Edges = append(_spec.Edges, edge) + } + return _node, _spec +} + +// RolePanelEditCreateBulk is the builder for creating many RolePanelEdit entities in bulk. +type RolePanelEditCreateBulk struct { + config + err error + builders []*RolePanelEditCreate +} + +// Save creates the RolePanelEdit entities in the database. +func (rpecb *RolePanelEditCreateBulk) Save(ctx context.Context) ([]*RolePanelEdit, error) { + if rpecb.err != nil { + return nil, rpecb.err + } + specs := make([]*sqlgraph.CreateSpec, len(rpecb.builders)) + nodes := make([]*RolePanelEdit, len(rpecb.builders)) + mutators := make([]Mutator, len(rpecb.builders)) + for i := range rpecb.builders { + func(i int, root context.Context) { + builder := rpecb.builders[i] + builder.defaults() + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*RolePanelEditMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + if err := builder.check(); err != nil { + return nil, err + } + builder.mutation = mutation + var err error + nodes[i], specs[i] = builder.createSpec() + if i < len(mutators)-1 { + _, err = mutators[i+1].Mutate(root, rpecb.builders[i+1].mutation) + } else { + spec := &sqlgraph.BatchCreateSpec{Nodes: specs} + // Invoke the actual operation on the latest mutation in the chain. + if err = sqlgraph.BatchCreate(ctx, rpecb.driver, spec); err != nil { + if sqlgraph.IsConstraintError(err) { + err = &ConstraintError{msg: err.Error(), wrap: err} + } + } + } + if err != nil { + return nil, err + } + mutation.id = &nodes[i].ID + mutation.done = true + return nodes[i], nil + }) + for i := len(builder.hooks) - 1; i >= 0; i-- { + mut = builder.hooks[i](mut) + } + mutators[i] = mut + }(i, ctx) + } + if len(mutators) > 0 { + if _, err := mutators[0].Mutate(ctx, rpecb.builders[0].mutation); err != nil { + return nil, err + } + } + return nodes, nil +} + +// SaveX is like Save, but panics if an error occurs. +func (rpecb *RolePanelEditCreateBulk) SaveX(ctx context.Context) []*RolePanelEdit { + v, err := rpecb.Save(ctx) + if err != nil { + panic(err) + } + return v +} + +// Exec executes the query. +func (rpecb *RolePanelEditCreateBulk) Exec(ctx context.Context) error { + _, err := rpecb.Save(ctx) + return err +} + +// ExecX is like Exec, but panics if an error occurs. +func (rpecb *RolePanelEditCreateBulk) ExecX(ctx context.Context) { + if err := rpecb.Exec(ctx); err != nil { + panic(err) + } +} diff --git a/ent/rolepaneledit_delete.go b/ent/rolepaneledit_delete.go new file mode 100644 index 00000000..06f480d1 --- /dev/null +++ b/ent/rolepaneledit_delete.go @@ -0,0 +1,88 @@ +// Code generated by ent, DO NOT EDIT. + +package ent + +import ( + "context" + + "entgo.io/ent/dialect/sql" + "entgo.io/ent/dialect/sql/sqlgraph" + "entgo.io/ent/schema/field" + "github.com/sabafly/gobot/ent/predicate" + "github.com/sabafly/gobot/ent/rolepaneledit" +) + +// RolePanelEditDelete is the builder for deleting a RolePanelEdit entity. +type RolePanelEditDelete struct { + config + hooks []Hook + mutation *RolePanelEditMutation +} + +// Where appends a list predicates to the RolePanelEditDelete builder. +func (rped *RolePanelEditDelete) Where(ps ...predicate.RolePanelEdit) *RolePanelEditDelete { + rped.mutation.Where(ps...) + return rped +} + +// Exec executes the deletion query and returns how many vertices were deleted. +func (rped *RolePanelEditDelete) Exec(ctx context.Context) (int, error) { + return withHooks(ctx, rped.sqlExec, rped.mutation, rped.hooks) +} + +// ExecX is like Exec, but panics if an error occurs. +func (rped *RolePanelEditDelete) ExecX(ctx context.Context) int { + n, err := rped.Exec(ctx) + if err != nil { + panic(err) + } + return n +} + +func (rped *RolePanelEditDelete) sqlExec(ctx context.Context) (int, error) { + _spec := sqlgraph.NewDeleteSpec(rolepaneledit.Table, sqlgraph.NewFieldSpec(rolepaneledit.FieldID, field.TypeUUID)) + if ps := rped.mutation.predicates; len(ps) > 0 { + _spec.Predicate = func(selector *sql.Selector) { + for i := range ps { + ps[i](selector) + } + } + } + affected, err := sqlgraph.DeleteNodes(ctx, rped.driver, _spec) + if err != nil && sqlgraph.IsConstraintError(err) { + err = &ConstraintError{msg: err.Error(), wrap: err} + } + rped.mutation.done = true + return affected, err +} + +// RolePanelEditDeleteOne is the builder for deleting a single RolePanelEdit entity. +type RolePanelEditDeleteOne struct { + rped *RolePanelEditDelete +} + +// Where appends a list predicates to the RolePanelEditDelete builder. +func (rpedo *RolePanelEditDeleteOne) Where(ps ...predicate.RolePanelEdit) *RolePanelEditDeleteOne { + rpedo.rped.mutation.Where(ps...) + return rpedo +} + +// Exec executes the deletion query. +func (rpedo *RolePanelEditDeleteOne) Exec(ctx context.Context) error { + n, err := rpedo.rped.Exec(ctx) + switch { + case err != nil: + return err + case n == 0: + return &NotFoundError{rolepaneledit.Label} + default: + return nil + } +} + +// ExecX is like Exec, but panics if an error occurs. +func (rpedo *RolePanelEditDeleteOne) ExecX(ctx context.Context) { + if err := rpedo.Exec(ctx); err != nil { + panic(err) + } +} diff --git a/ent/rolepaneledit_query.go b/ent/rolepaneledit_query.go new file mode 100644 index 00000000..96c1cbdd --- /dev/null +++ b/ent/rolepaneledit_query.go @@ -0,0 +1,690 @@ +// Code generated by ent, DO NOT EDIT. + +package ent + +import ( + "context" + "fmt" + "math" + + "entgo.io/ent/dialect/sql" + "entgo.io/ent/dialect/sql/sqlgraph" + "entgo.io/ent/schema/field" + snowflake "github.com/disgoorg/snowflake/v2" + "github.com/google/uuid" + "github.com/sabafly/gobot/ent/guild" + "github.com/sabafly/gobot/ent/predicate" + "github.com/sabafly/gobot/ent/rolepanel" + "github.com/sabafly/gobot/ent/rolepaneledit" +) + +// RolePanelEditQuery is the builder for querying RolePanelEdit entities. +type RolePanelEditQuery struct { + config + ctx *QueryContext + order []rolepaneledit.OrderOption + inters []Interceptor + predicates []predicate.RolePanelEdit + withGuild *GuildQuery + withParent *RolePanelQuery + withFKs bool + // intermediate query (i.e. traversal path). + sql *sql.Selector + path func(context.Context) (*sql.Selector, error) +} + +// Where adds a new predicate for the RolePanelEditQuery builder. +func (rpeq *RolePanelEditQuery) Where(ps ...predicate.RolePanelEdit) *RolePanelEditQuery { + rpeq.predicates = append(rpeq.predicates, ps...) + return rpeq +} + +// Limit the number of records to be returned by this query. +func (rpeq *RolePanelEditQuery) Limit(limit int) *RolePanelEditQuery { + rpeq.ctx.Limit = &limit + return rpeq +} + +// Offset to start from. +func (rpeq *RolePanelEditQuery) Offset(offset int) *RolePanelEditQuery { + rpeq.ctx.Offset = &offset + return rpeq +} + +// Unique configures the query builder to filter duplicate records on query. +// By default, unique is set to true, and can be disabled using this method. +func (rpeq *RolePanelEditQuery) Unique(unique bool) *RolePanelEditQuery { + rpeq.ctx.Unique = &unique + return rpeq +} + +// Order specifies how the records should be ordered. +func (rpeq *RolePanelEditQuery) Order(o ...rolepaneledit.OrderOption) *RolePanelEditQuery { + rpeq.order = append(rpeq.order, o...) + return rpeq +} + +// QueryGuild chains the current query on the "guild" edge. +func (rpeq *RolePanelEditQuery) QueryGuild() *GuildQuery { + query := (&GuildClient{config: rpeq.config}).Query() + query.path = func(ctx context.Context) (fromU *sql.Selector, err error) { + if err := rpeq.prepareQuery(ctx); err != nil { + return nil, err + } + selector := rpeq.sqlQuery(ctx) + if err := selector.Err(); err != nil { + return nil, err + } + step := sqlgraph.NewStep( + sqlgraph.From(rolepaneledit.Table, rolepaneledit.FieldID, selector), + sqlgraph.To(guild.Table, guild.FieldID), + sqlgraph.Edge(sqlgraph.M2O, true, rolepaneledit.GuildTable, rolepaneledit.GuildColumn), + ) + fromU = sqlgraph.SetNeighbors(rpeq.driver.Dialect(), step) + return fromU, nil + } + return query +} + +// QueryParent chains the current query on the "parent" edge. +func (rpeq *RolePanelEditQuery) QueryParent() *RolePanelQuery { + query := (&RolePanelClient{config: rpeq.config}).Query() + query.path = func(ctx context.Context) (fromU *sql.Selector, err error) { + if err := rpeq.prepareQuery(ctx); err != nil { + return nil, err + } + selector := rpeq.sqlQuery(ctx) + if err := selector.Err(); err != nil { + return nil, err + } + step := sqlgraph.NewStep( + sqlgraph.From(rolepaneledit.Table, rolepaneledit.FieldID, selector), + sqlgraph.To(rolepanel.Table, rolepanel.FieldID), + sqlgraph.Edge(sqlgraph.O2O, true, rolepaneledit.ParentTable, rolepaneledit.ParentColumn), + ) + fromU = sqlgraph.SetNeighbors(rpeq.driver.Dialect(), step) + return fromU, nil + } + return query +} + +// First returns the first RolePanelEdit entity from the query. +// Returns a *NotFoundError when no RolePanelEdit was found. +func (rpeq *RolePanelEditQuery) First(ctx context.Context) (*RolePanelEdit, error) { + nodes, err := rpeq.Limit(1).All(setContextOp(ctx, rpeq.ctx, "First")) + if err != nil { + return nil, err + } + if len(nodes) == 0 { + return nil, &NotFoundError{rolepaneledit.Label} + } + return nodes[0], nil +} + +// FirstX is like First, but panics if an error occurs. +func (rpeq *RolePanelEditQuery) FirstX(ctx context.Context) *RolePanelEdit { + node, err := rpeq.First(ctx) + if err != nil && !IsNotFound(err) { + panic(err) + } + return node +} + +// FirstID returns the first RolePanelEdit ID from the query. +// Returns a *NotFoundError when no RolePanelEdit ID was found. +func (rpeq *RolePanelEditQuery) FirstID(ctx context.Context) (id uuid.UUID, err error) { + var ids []uuid.UUID + if ids, err = rpeq.Limit(1).IDs(setContextOp(ctx, rpeq.ctx, "FirstID")); err != nil { + return + } + if len(ids) == 0 { + err = &NotFoundError{rolepaneledit.Label} + return + } + return ids[0], nil +} + +// FirstIDX is like FirstID, but panics if an error occurs. +func (rpeq *RolePanelEditQuery) FirstIDX(ctx context.Context) uuid.UUID { + id, err := rpeq.FirstID(ctx) + if err != nil && !IsNotFound(err) { + panic(err) + } + return id +} + +// Only returns a single RolePanelEdit entity found by the query, ensuring it only returns one. +// Returns a *NotSingularError when more than one RolePanelEdit entity is found. +// Returns a *NotFoundError when no RolePanelEdit entities are found. +func (rpeq *RolePanelEditQuery) Only(ctx context.Context) (*RolePanelEdit, error) { + nodes, err := rpeq.Limit(2).All(setContextOp(ctx, rpeq.ctx, "Only")) + if err != nil { + return nil, err + } + switch len(nodes) { + case 1: + return nodes[0], nil + case 0: + return nil, &NotFoundError{rolepaneledit.Label} + default: + return nil, &NotSingularError{rolepaneledit.Label} + } +} + +// OnlyX is like Only, but panics if an error occurs. +func (rpeq *RolePanelEditQuery) OnlyX(ctx context.Context) *RolePanelEdit { + node, err := rpeq.Only(ctx) + if err != nil { + panic(err) + } + return node +} + +// OnlyID is like Only, but returns the only RolePanelEdit ID in the query. +// Returns a *NotSingularError when more than one RolePanelEdit ID is found. +// Returns a *NotFoundError when no entities are found. +func (rpeq *RolePanelEditQuery) OnlyID(ctx context.Context) (id uuid.UUID, err error) { + var ids []uuid.UUID + if ids, err = rpeq.Limit(2).IDs(setContextOp(ctx, rpeq.ctx, "OnlyID")); err != nil { + return + } + switch len(ids) { + case 1: + id = ids[0] + case 0: + err = &NotFoundError{rolepaneledit.Label} + default: + err = &NotSingularError{rolepaneledit.Label} + } + return +} + +// OnlyIDX is like OnlyID, but panics if an error occurs. +func (rpeq *RolePanelEditQuery) OnlyIDX(ctx context.Context) uuid.UUID { + id, err := rpeq.OnlyID(ctx) + if err != nil { + panic(err) + } + return id +} + +// All executes the query and returns a list of RolePanelEdits. +func (rpeq *RolePanelEditQuery) All(ctx context.Context) ([]*RolePanelEdit, error) { + ctx = setContextOp(ctx, rpeq.ctx, "All") + if err := rpeq.prepareQuery(ctx); err != nil { + return nil, err + } + qr := querierAll[[]*RolePanelEdit, *RolePanelEditQuery]() + return withInterceptors[[]*RolePanelEdit](ctx, rpeq, qr, rpeq.inters) +} + +// AllX is like All, but panics if an error occurs. +func (rpeq *RolePanelEditQuery) AllX(ctx context.Context) []*RolePanelEdit { + nodes, err := rpeq.All(ctx) + if err != nil { + panic(err) + } + return nodes +} + +// IDs executes the query and returns a list of RolePanelEdit IDs. +func (rpeq *RolePanelEditQuery) IDs(ctx context.Context) (ids []uuid.UUID, err error) { + if rpeq.ctx.Unique == nil && rpeq.path != nil { + rpeq.Unique(true) + } + ctx = setContextOp(ctx, rpeq.ctx, "IDs") + if err = rpeq.Select(rolepaneledit.FieldID).Scan(ctx, &ids); err != nil { + return nil, err + } + return ids, nil +} + +// IDsX is like IDs, but panics if an error occurs. +func (rpeq *RolePanelEditQuery) IDsX(ctx context.Context) []uuid.UUID { + ids, err := rpeq.IDs(ctx) + if err != nil { + panic(err) + } + return ids +} + +// Count returns the count of the given query. +func (rpeq *RolePanelEditQuery) Count(ctx context.Context) (int, error) { + ctx = setContextOp(ctx, rpeq.ctx, "Count") + if err := rpeq.prepareQuery(ctx); err != nil { + return 0, err + } + return withInterceptors[int](ctx, rpeq, querierCount[*RolePanelEditQuery](), rpeq.inters) +} + +// CountX is like Count, but panics if an error occurs. +func (rpeq *RolePanelEditQuery) CountX(ctx context.Context) int { + count, err := rpeq.Count(ctx) + if err != nil { + panic(err) + } + return count +} + +// Exist returns true if the query has elements in the graph. +func (rpeq *RolePanelEditQuery) Exist(ctx context.Context) (bool, error) { + ctx = setContextOp(ctx, rpeq.ctx, "Exist") + switch _, err := rpeq.FirstID(ctx); { + case IsNotFound(err): + return false, nil + case err != nil: + return false, fmt.Errorf("ent: check existence: %w", err) + default: + return true, nil + } +} + +// ExistX is like Exist, but panics if an error occurs. +func (rpeq *RolePanelEditQuery) ExistX(ctx context.Context) bool { + exist, err := rpeq.Exist(ctx) + if err != nil { + panic(err) + } + return exist +} + +// Clone returns a duplicate of the RolePanelEditQuery builder, including all associated steps. It can be +// used to prepare common query builders and use them differently after the clone is made. +func (rpeq *RolePanelEditQuery) Clone() *RolePanelEditQuery { + if rpeq == nil { + return nil + } + return &RolePanelEditQuery{ + config: rpeq.config, + ctx: rpeq.ctx.Clone(), + order: append([]rolepaneledit.OrderOption{}, rpeq.order...), + inters: append([]Interceptor{}, rpeq.inters...), + predicates: append([]predicate.RolePanelEdit{}, rpeq.predicates...), + withGuild: rpeq.withGuild.Clone(), + withParent: rpeq.withParent.Clone(), + // clone intermediate query. + sql: rpeq.sql.Clone(), + path: rpeq.path, + } +} + +// WithGuild tells the query-builder to eager-load the nodes that are connected to +// the "guild" edge. The optional arguments are used to configure the query builder of the edge. +func (rpeq *RolePanelEditQuery) WithGuild(opts ...func(*GuildQuery)) *RolePanelEditQuery { + query := (&GuildClient{config: rpeq.config}).Query() + for _, opt := range opts { + opt(query) + } + rpeq.withGuild = query + return rpeq +} + +// WithParent tells the query-builder to eager-load the nodes that are connected to +// the "parent" edge. The optional arguments are used to configure the query builder of the edge. +func (rpeq *RolePanelEditQuery) WithParent(opts ...func(*RolePanelQuery)) *RolePanelEditQuery { + query := (&RolePanelClient{config: rpeq.config}).Query() + for _, opt := range opts { + opt(query) + } + rpeq.withParent = query + return rpeq +} + +// GroupBy is used to group vertices by one or more fields/columns. +// It is often used with aggregate functions, like: count, max, mean, min, sum. +// +// Example: +// +// var v []struct { +// ChannelID snowflake.ID `json:"channel_id,omitempty"` +// Count int `json:"count,omitempty"` +// } +// +// client.RolePanelEdit.Query(). +// GroupBy(rolepaneledit.FieldChannelID). +// Aggregate(ent.Count()). +// Scan(ctx, &v) +func (rpeq *RolePanelEditQuery) GroupBy(field string, fields ...string) *RolePanelEditGroupBy { + rpeq.ctx.Fields = append([]string{field}, fields...) + grbuild := &RolePanelEditGroupBy{build: rpeq} + grbuild.flds = &rpeq.ctx.Fields + grbuild.label = rolepaneledit.Label + grbuild.scan = grbuild.Scan + return grbuild +} + +// Select allows the selection one or more fields/columns for the given query, +// instead of selecting all fields in the entity. +// +// Example: +// +// var v []struct { +// ChannelID snowflake.ID `json:"channel_id,omitempty"` +// } +// +// client.RolePanelEdit.Query(). +// Select(rolepaneledit.FieldChannelID). +// Scan(ctx, &v) +func (rpeq *RolePanelEditQuery) Select(fields ...string) *RolePanelEditSelect { + rpeq.ctx.Fields = append(rpeq.ctx.Fields, fields...) + sbuild := &RolePanelEditSelect{RolePanelEditQuery: rpeq} + sbuild.label = rolepaneledit.Label + sbuild.flds, sbuild.scan = &rpeq.ctx.Fields, sbuild.Scan + return sbuild +} + +// Aggregate returns a RolePanelEditSelect configured with the given aggregations. +func (rpeq *RolePanelEditQuery) Aggregate(fns ...AggregateFunc) *RolePanelEditSelect { + return rpeq.Select().Aggregate(fns...) +} + +func (rpeq *RolePanelEditQuery) prepareQuery(ctx context.Context) error { + for _, inter := range rpeq.inters { + if inter == nil { + return fmt.Errorf("ent: uninitialized interceptor (forgotten import ent/runtime?)") + } + if trv, ok := inter.(Traverser); ok { + if err := trv.Traverse(ctx, rpeq); err != nil { + return err + } + } + } + for _, f := range rpeq.ctx.Fields { + if !rolepaneledit.ValidColumn(f) { + return &ValidationError{Name: f, err: fmt.Errorf("ent: invalid field %q for query", f)} + } + } + if rpeq.path != nil { + prev, err := rpeq.path(ctx) + if err != nil { + return err + } + rpeq.sql = prev + } + return nil +} + +func (rpeq *RolePanelEditQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*RolePanelEdit, error) { + var ( + nodes = []*RolePanelEdit{} + withFKs = rpeq.withFKs + _spec = rpeq.querySpec() + loadedTypes = [2]bool{ + rpeq.withGuild != nil, + rpeq.withParent != nil, + } + ) + if rpeq.withGuild != nil || rpeq.withParent != nil { + withFKs = true + } + if withFKs { + _spec.Node.Columns = append(_spec.Node.Columns, rolepaneledit.ForeignKeys...) + } + _spec.ScanValues = func(columns []string) ([]any, error) { + return (*RolePanelEdit).scanValues(nil, columns) + } + _spec.Assign = func(columns []string, values []any) error { + node := &RolePanelEdit{config: rpeq.config} + nodes = append(nodes, node) + node.Edges.loadedTypes = loadedTypes + return node.assignValues(columns, values) + } + for i := range hooks { + hooks[i](ctx, _spec) + } + if err := sqlgraph.QueryNodes(ctx, rpeq.driver, _spec); err != nil { + return nil, err + } + if len(nodes) == 0 { + return nodes, nil + } + if query := rpeq.withGuild; query != nil { + if err := rpeq.loadGuild(ctx, query, nodes, nil, + func(n *RolePanelEdit, e *Guild) { n.Edges.Guild = e }); err != nil { + return nil, err + } + } + if query := rpeq.withParent; query != nil { + if err := rpeq.loadParent(ctx, query, nodes, nil, + func(n *RolePanelEdit, e *RolePanel) { n.Edges.Parent = e }); err != nil { + return nil, err + } + } + return nodes, nil +} + +func (rpeq *RolePanelEditQuery) loadGuild(ctx context.Context, query *GuildQuery, nodes []*RolePanelEdit, init func(*RolePanelEdit), assign func(*RolePanelEdit, *Guild)) error { + ids := make([]snowflake.ID, 0, len(nodes)) + nodeids := make(map[snowflake.ID][]*RolePanelEdit) + for i := range nodes { + if nodes[i].guild_role_panel_edits == nil { + continue + } + fk := *nodes[i].guild_role_panel_edits + if _, ok := nodeids[fk]; !ok { + ids = append(ids, fk) + } + nodeids[fk] = append(nodeids[fk], nodes[i]) + } + if len(ids) == 0 { + return nil + } + query.Where(guild.IDIn(ids...)) + neighbors, err := query.All(ctx) + if err != nil { + return err + } + for _, n := range neighbors { + nodes, ok := nodeids[n.ID] + if !ok { + return fmt.Errorf(`unexpected foreign-key "guild_role_panel_edits" returned %v`, n.ID) + } + for i := range nodes { + assign(nodes[i], n) + } + } + return nil +} +func (rpeq *RolePanelEditQuery) loadParent(ctx context.Context, query *RolePanelQuery, nodes []*RolePanelEdit, init func(*RolePanelEdit), assign func(*RolePanelEdit, *RolePanel)) error { + ids := make([]uuid.UUID, 0, len(nodes)) + nodeids := make(map[uuid.UUID][]*RolePanelEdit) + for i := range nodes { + if nodes[i].role_panel_edit == nil { + continue + } + fk := *nodes[i].role_panel_edit + if _, ok := nodeids[fk]; !ok { + ids = append(ids, fk) + } + nodeids[fk] = append(nodeids[fk], nodes[i]) + } + if len(ids) == 0 { + return nil + } + query.Where(rolepanel.IDIn(ids...)) + neighbors, err := query.All(ctx) + if err != nil { + return err + } + for _, n := range neighbors { + nodes, ok := nodeids[n.ID] + if !ok { + return fmt.Errorf(`unexpected foreign-key "role_panel_edit" returned %v`, n.ID) + } + for i := range nodes { + assign(nodes[i], n) + } + } + return nil +} + +func (rpeq *RolePanelEditQuery) sqlCount(ctx context.Context) (int, error) { + _spec := rpeq.querySpec() + _spec.Node.Columns = rpeq.ctx.Fields + if len(rpeq.ctx.Fields) > 0 { + _spec.Unique = rpeq.ctx.Unique != nil && *rpeq.ctx.Unique + } + return sqlgraph.CountNodes(ctx, rpeq.driver, _spec) +} + +func (rpeq *RolePanelEditQuery) querySpec() *sqlgraph.QuerySpec { + _spec := sqlgraph.NewQuerySpec(rolepaneledit.Table, rolepaneledit.Columns, sqlgraph.NewFieldSpec(rolepaneledit.FieldID, field.TypeUUID)) + _spec.From = rpeq.sql + if unique := rpeq.ctx.Unique; unique != nil { + _spec.Unique = *unique + } else if rpeq.path != nil { + _spec.Unique = true + } + if fields := rpeq.ctx.Fields; len(fields) > 0 { + _spec.Node.Columns = make([]string, 0, len(fields)) + _spec.Node.Columns = append(_spec.Node.Columns, rolepaneledit.FieldID) + for i := range fields { + if fields[i] != rolepaneledit.FieldID { + _spec.Node.Columns = append(_spec.Node.Columns, fields[i]) + } + } + } + if ps := rpeq.predicates; len(ps) > 0 { + _spec.Predicate = func(selector *sql.Selector) { + for i := range ps { + ps[i](selector) + } + } + } + if limit := rpeq.ctx.Limit; limit != nil { + _spec.Limit = *limit + } + if offset := rpeq.ctx.Offset; offset != nil { + _spec.Offset = *offset + } + if ps := rpeq.order; len(ps) > 0 { + _spec.Order = func(selector *sql.Selector) { + for i := range ps { + ps[i](selector) + } + } + } + return _spec +} + +func (rpeq *RolePanelEditQuery) sqlQuery(ctx context.Context) *sql.Selector { + builder := sql.Dialect(rpeq.driver.Dialect()) + t1 := builder.Table(rolepaneledit.Table) + columns := rpeq.ctx.Fields + if len(columns) == 0 { + columns = rolepaneledit.Columns + } + selector := builder.Select(t1.Columns(columns...)...).From(t1) + if rpeq.sql != nil { + selector = rpeq.sql + selector.Select(selector.Columns(columns...)...) + } + if rpeq.ctx.Unique != nil && *rpeq.ctx.Unique { + selector.Distinct() + } + for _, p := range rpeq.predicates { + p(selector) + } + for _, p := range rpeq.order { + p(selector) + } + if offset := rpeq.ctx.Offset; offset != nil { + // limit is mandatory for offset clause. We start + // with default value, and override it below if needed. + selector.Offset(*offset).Limit(math.MaxInt32) + } + if limit := rpeq.ctx.Limit; limit != nil { + selector.Limit(*limit) + } + return selector +} + +// RolePanelEditGroupBy is the group-by builder for RolePanelEdit entities. +type RolePanelEditGroupBy struct { + selector + build *RolePanelEditQuery +} + +// Aggregate adds the given aggregation functions to the group-by query. +func (rpegb *RolePanelEditGroupBy) Aggregate(fns ...AggregateFunc) *RolePanelEditGroupBy { + rpegb.fns = append(rpegb.fns, fns...) + return rpegb +} + +// Scan applies the selector query and scans the result into the given value. +func (rpegb *RolePanelEditGroupBy) Scan(ctx context.Context, v any) error { + ctx = setContextOp(ctx, rpegb.build.ctx, "GroupBy") + if err := rpegb.build.prepareQuery(ctx); err != nil { + return err + } + return scanWithInterceptors[*RolePanelEditQuery, *RolePanelEditGroupBy](ctx, rpegb.build, rpegb, rpegb.build.inters, v) +} + +func (rpegb *RolePanelEditGroupBy) sqlScan(ctx context.Context, root *RolePanelEditQuery, v any) error { + selector := root.sqlQuery(ctx).Select() + aggregation := make([]string, 0, len(rpegb.fns)) + for _, fn := range rpegb.fns { + aggregation = append(aggregation, fn(selector)) + } + if len(selector.SelectedColumns()) == 0 { + columns := make([]string, 0, len(*rpegb.flds)+len(rpegb.fns)) + for _, f := range *rpegb.flds { + columns = append(columns, selector.C(f)) + } + columns = append(columns, aggregation...) + selector.Select(columns...) + } + selector.GroupBy(selector.Columns(*rpegb.flds...)...) + if err := selector.Err(); err != nil { + return err + } + rows := &sql.Rows{} + query, args := selector.Query() + if err := rpegb.build.driver.Query(ctx, query, args, rows); err != nil { + return err + } + defer rows.Close() + return sql.ScanSlice(rows, v) +} + +// RolePanelEditSelect is the builder for selecting fields of RolePanelEdit entities. +type RolePanelEditSelect struct { + *RolePanelEditQuery + selector +} + +// Aggregate adds the given aggregation functions to the selector query. +func (rpes *RolePanelEditSelect) Aggregate(fns ...AggregateFunc) *RolePanelEditSelect { + rpes.fns = append(rpes.fns, fns...) + return rpes +} + +// Scan applies the selector query and scans the result into the given value. +func (rpes *RolePanelEditSelect) Scan(ctx context.Context, v any) error { + ctx = setContextOp(ctx, rpes.ctx, "Select") + if err := rpes.prepareQuery(ctx); err != nil { + return err + } + return scanWithInterceptors[*RolePanelEditQuery, *RolePanelEditSelect](ctx, rpes.RolePanelEditQuery, rpes, rpes.inters, v) +} + +func (rpes *RolePanelEditSelect) sqlScan(ctx context.Context, root *RolePanelEditQuery, v any) error { + selector := root.sqlQuery(ctx) + aggregation := make([]string, 0, len(rpes.fns)) + for _, fn := range rpes.fns { + aggregation = append(aggregation, fn(selector)) + } + switch n := len(*rpes.selector.flds); { + case n == 0 && len(aggregation) > 0: + selector.Select(aggregation...) + case n != 0 && len(aggregation) > 0: + selector.AppendSelect(aggregation...) + } + rows := &sql.Rows{} + query, args := selector.Query() + if err := rpes.driver.Query(ctx, query, args, rows); err != nil { + return err + } + defer rows.Close() + return sql.ScanSlice(rows, v) +} diff --git a/ent/rolepaneledit_update.go b/ent/rolepaneledit_update.go new file mode 100644 index 00000000..ecd6e5a1 --- /dev/null +++ b/ent/rolepaneledit_update.go @@ -0,0 +1,662 @@ +// Code generated by ent, DO NOT EDIT. + +package ent + +import ( + "context" + "errors" + "fmt" + + "entgo.io/ent/dialect/sql" + "entgo.io/ent/dialect/sql/sqlgraph" + "entgo.io/ent/dialect/sql/sqljson" + "entgo.io/ent/schema/field" + snowflake "github.com/disgoorg/snowflake/v2" + "github.com/sabafly/gobot/ent/predicate" + "github.com/sabafly/gobot/ent/rolepaneledit" + "github.com/sabafly/gobot/ent/schema" +) + +// RolePanelEditUpdate is the builder for updating RolePanelEdit entities. +type RolePanelEditUpdate struct { + config + hooks []Hook + mutation *RolePanelEditMutation +} + +// Where appends a list predicates to the RolePanelEditUpdate builder. +func (rpeu *RolePanelEditUpdate) Where(ps ...predicate.RolePanelEdit) *RolePanelEditUpdate { + rpeu.mutation.Where(ps...) + return rpeu +} + +// SetChannelID sets the "channel_id" field. +func (rpeu *RolePanelEditUpdate) SetChannelID(s snowflake.ID) *RolePanelEditUpdate { + rpeu.mutation.ResetChannelID() + rpeu.mutation.SetChannelID(s) + return rpeu +} + +// SetNillableChannelID sets the "channel_id" field if the given value is not nil. +func (rpeu *RolePanelEditUpdate) SetNillableChannelID(s *snowflake.ID) *RolePanelEditUpdate { + if s != nil { + rpeu.SetChannelID(*s) + } + return rpeu +} + +// AddChannelID adds s to the "channel_id" field. +func (rpeu *RolePanelEditUpdate) AddChannelID(s snowflake.ID) *RolePanelEditUpdate { + rpeu.mutation.AddChannelID(s) + return rpeu +} + +// SetEmojiAuthor sets the "emoji_author" field. +func (rpeu *RolePanelEditUpdate) SetEmojiAuthor(s snowflake.ID) *RolePanelEditUpdate { + rpeu.mutation.ResetEmojiAuthor() + rpeu.mutation.SetEmojiAuthor(s) + return rpeu +} + +// SetNillableEmojiAuthor sets the "emoji_author" field if the given value is not nil. +func (rpeu *RolePanelEditUpdate) SetNillableEmojiAuthor(s *snowflake.ID) *RolePanelEditUpdate { + if s != nil { + rpeu.SetEmojiAuthor(*s) + } + return rpeu +} + +// AddEmojiAuthor adds s to the "emoji_author" field. +func (rpeu *RolePanelEditUpdate) AddEmojiAuthor(s snowflake.ID) *RolePanelEditUpdate { + rpeu.mutation.AddEmojiAuthor(s) + return rpeu +} + +// ClearEmojiAuthor clears the value of the "emoji_author" field. +func (rpeu *RolePanelEditUpdate) ClearEmojiAuthor() *RolePanelEditUpdate { + rpeu.mutation.ClearEmojiAuthor() + return rpeu +} + +// SetToken sets the "token" field. +func (rpeu *RolePanelEditUpdate) SetToken(s string) *RolePanelEditUpdate { + rpeu.mutation.SetToken(s) + return rpeu +} + +// SetNillableToken sets the "token" field if the given value is not nil. +func (rpeu *RolePanelEditUpdate) SetNillableToken(s *string) *RolePanelEditUpdate { + if s != nil { + rpeu.SetToken(*s) + } + return rpeu +} + +// ClearToken clears the value of the "token" field. +func (rpeu *RolePanelEditUpdate) ClearToken() *RolePanelEditUpdate { + rpeu.mutation.ClearToken() + return rpeu +} + +// SetSelectedRole sets the "selected_role" field. +func (rpeu *RolePanelEditUpdate) SetSelectedRole(s snowflake.ID) *RolePanelEditUpdate { + rpeu.mutation.ResetSelectedRole() + rpeu.mutation.SetSelectedRole(s) + return rpeu +} + +// SetNillableSelectedRole sets the "selected_role" field if the given value is not nil. +func (rpeu *RolePanelEditUpdate) SetNillableSelectedRole(s *snowflake.ID) *RolePanelEditUpdate { + if s != nil { + rpeu.SetSelectedRole(*s) + } + return rpeu +} + +// AddSelectedRole adds s to the "selected_role" field. +func (rpeu *RolePanelEditUpdate) AddSelectedRole(s snowflake.ID) *RolePanelEditUpdate { + rpeu.mutation.AddSelectedRole(s) + return rpeu +} + +// ClearSelectedRole clears the value of the "selected_role" field. +func (rpeu *RolePanelEditUpdate) ClearSelectedRole() *RolePanelEditUpdate { + rpeu.mutation.ClearSelectedRole() + return rpeu +} + +// SetModified sets the "modified" field. +func (rpeu *RolePanelEditUpdate) SetModified(b bool) *RolePanelEditUpdate { + rpeu.mutation.SetModified(b) + return rpeu +} + +// SetNillableModified sets the "modified" field if the given value is not nil. +func (rpeu *RolePanelEditUpdate) SetNillableModified(b *bool) *RolePanelEditUpdate { + if b != nil { + rpeu.SetModified(*b) + } + return rpeu +} + +// SetName sets the "name" field. +func (rpeu *RolePanelEditUpdate) SetName(s string) *RolePanelEditUpdate { + rpeu.mutation.SetName(s) + return rpeu +} + +// SetNillableName sets the "name" field if the given value is not nil. +func (rpeu *RolePanelEditUpdate) SetNillableName(s *string) *RolePanelEditUpdate { + if s != nil { + rpeu.SetName(*s) + } + return rpeu +} + +// ClearName clears the value of the "name" field. +func (rpeu *RolePanelEditUpdate) ClearName() *RolePanelEditUpdate { + rpeu.mutation.ClearName() + return rpeu +} + +// SetDescription sets the "description" field. +func (rpeu *RolePanelEditUpdate) SetDescription(s string) *RolePanelEditUpdate { + rpeu.mutation.SetDescription(s) + return rpeu +} + +// SetNillableDescription sets the "description" field if the given value is not nil. +func (rpeu *RolePanelEditUpdate) SetNillableDescription(s *string) *RolePanelEditUpdate { + if s != nil { + rpeu.SetDescription(*s) + } + return rpeu +} + +// ClearDescription clears the value of the "description" field. +func (rpeu *RolePanelEditUpdate) ClearDescription() *RolePanelEditUpdate { + rpeu.mutation.ClearDescription() + return rpeu +} + +// SetRoles sets the "roles" field. +func (rpeu *RolePanelEditUpdate) SetRoles(s []schema.Role) *RolePanelEditUpdate { + rpeu.mutation.SetRoles(s) + return rpeu +} + +// AppendRoles appends s to the "roles" field. +func (rpeu *RolePanelEditUpdate) AppendRoles(s []schema.Role) *RolePanelEditUpdate { + rpeu.mutation.AppendRoles(s) + return rpeu +} + +// ClearRoles clears the value of the "roles" field. +func (rpeu *RolePanelEditUpdate) ClearRoles() *RolePanelEditUpdate { + rpeu.mutation.ClearRoles() + return rpeu +} + +// Mutation returns the RolePanelEditMutation object of the builder. +func (rpeu *RolePanelEditUpdate) Mutation() *RolePanelEditMutation { + return rpeu.mutation +} + +// Save executes the query and returns the number of nodes affected by the update operation. +func (rpeu *RolePanelEditUpdate) Save(ctx context.Context) (int, error) { + return withHooks(ctx, rpeu.sqlSave, rpeu.mutation, rpeu.hooks) +} + +// SaveX is like Save, but panics if an error occurs. +func (rpeu *RolePanelEditUpdate) SaveX(ctx context.Context) int { + affected, err := rpeu.Save(ctx) + if err != nil { + panic(err) + } + return affected +} + +// Exec executes the query. +func (rpeu *RolePanelEditUpdate) Exec(ctx context.Context) error { + _, err := rpeu.Save(ctx) + return err +} + +// ExecX is like Exec, but panics if an error occurs. +func (rpeu *RolePanelEditUpdate) ExecX(ctx context.Context) { + if err := rpeu.Exec(ctx); err != nil { + panic(err) + } +} + +// check runs all checks and user-defined validators on the builder. +func (rpeu *RolePanelEditUpdate) check() error { + if v, ok := rpeu.mutation.Name(); ok { + if err := rolepaneledit.NameValidator(v); err != nil { + return &ValidationError{Name: "name", err: fmt.Errorf(`ent: validator failed for field "RolePanelEdit.name": %w`, err)} + } + } + if _, ok := rpeu.mutation.GuildID(); rpeu.mutation.GuildCleared() && !ok { + return errors.New(`ent: clearing a required unique edge "RolePanelEdit.guild"`) + } + if _, ok := rpeu.mutation.ParentID(); rpeu.mutation.ParentCleared() && !ok { + return errors.New(`ent: clearing a required unique edge "RolePanelEdit.parent"`) + } + return nil +} + +func (rpeu *RolePanelEditUpdate) sqlSave(ctx context.Context) (n int, err error) { + if err := rpeu.check(); err != nil { + return n, err + } + _spec := sqlgraph.NewUpdateSpec(rolepaneledit.Table, rolepaneledit.Columns, sqlgraph.NewFieldSpec(rolepaneledit.FieldID, field.TypeUUID)) + if ps := rpeu.mutation.predicates; len(ps) > 0 { + _spec.Predicate = func(selector *sql.Selector) { + for i := range ps { + ps[i](selector) + } + } + } + if value, ok := rpeu.mutation.ChannelID(); ok { + _spec.SetField(rolepaneledit.FieldChannelID, field.TypeUint64, value) + } + if value, ok := rpeu.mutation.AddedChannelID(); ok { + _spec.AddField(rolepaneledit.FieldChannelID, field.TypeUint64, value) + } + if value, ok := rpeu.mutation.EmojiAuthor(); ok { + _spec.SetField(rolepaneledit.FieldEmojiAuthor, field.TypeUint64, value) + } + if value, ok := rpeu.mutation.AddedEmojiAuthor(); ok { + _spec.AddField(rolepaneledit.FieldEmojiAuthor, field.TypeUint64, value) + } + if rpeu.mutation.EmojiAuthorCleared() { + _spec.ClearField(rolepaneledit.FieldEmojiAuthor, field.TypeUint64) + } + if value, ok := rpeu.mutation.Token(); ok { + _spec.SetField(rolepaneledit.FieldToken, field.TypeString, value) + } + if rpeu.mutation.TokenCleared() { + _spec.ClearField(rolepaneledit.FieldToken, field.TypeString) + } + if value, ok := rpeu.mutation.SelectedRole(); ok { + _spec.SetField(rolepaneledit.FieldSelectedRole, field.TypeUint64, value) + } + if value, ok := rpeu.mutation.AddedSelectedRole(); ok { + _spec.AddField(rolepaneledit.FieldSelectedRole, field.TypeUint64, value) + } + if rpeu.mutation.SelectedRoleCleared() { + _spec.ClearField(rolepaneledit.FieldSelectedRole, field.TypeUint64) + } + if value, ok := rpeu.mutation.Modified(); ok { + _spec.SetField(rolepaneledit.FieldModified, field.TypeBool, value) + } + if value, ok := rpeu.mutation.Name(); ok { + _spec.SetField(rolepaneledit.FieldName, field.TypeString, value) + } + if rpeu.mutation.NameCleared() { + _spec.ClearField(rolepaneledit.FieldName, field.TypeString) + } + if value, ok := rpeu.mutation.Description(); ok { + _spec.SetField(rolepaneledit.FieldDescription, field.TypeString, value) + } + if rpeu.mutation.DescriptionCleared() { + _spec.ClearField(rolepaneledit.FieldDescription, field.TypeString) + } + if value, ok := rpeu.mutation.Roles(); ok { + _spec.SetField(rolepaneledit.FieldRoles, field.TypeJSON, value) + } + if value, ok := rpeu.mutation.AppendedRoles(); ok { + _spec.AddModifier(func(u *sql.UpdateBuilder) { + sqljson.Append(u, rolepaneledit.FieldRoles, value) + }) + } + if rpeu.mutation.RolesCleared() { + _spec.ClearField(rolepaneledit.FieldRoles, field.TypeJSON) + } + if n, err = sqlgraph.UpdateNodes(ctx, rpeu.driver, _spec); err != nil { + if _, ok := err.(*sqlgraph.NotFoundError); ok { + err = &NotFoundError{rolepaneledit.Label} + } else if sqlgraph.IsConstraintError(err) { + err = &ConstraintError{msg: err.Error(), wrap: err} + } + return 0, err + } + rpeu.mutation.done = true + return n, nil +} + +// RolePanelEditUpdateOne is the builder for updating a single RolePanelEdit entity. +type RolePanelEditUpdateOne struct { + config + fields []string + hooks []Hook + mutation *RolePanelEditMutation +} + +// SetChannelID sets the "channel_id" field. +func (rpeuo *RolePanelEditUpdateOne) SetChannelID(s snowflake.ID) *RolePanelEditUpdateOne { + rpeuo.mutation.ResetChannelID() + rpeuo.mutation.SetChannelID(s) + return rpeuo +} + +// SetNillableChannelID sets the "channel_id" field if the given value is not nil. +func (rpeuo *RolePanelEditUpdateOne) SetNillableChannelID(s *snowflake.ID) *RolePanelEditUpdateOne { + if s != nil { + rpeuo.SetChannelID(*s) + } + return rpeuo +} + +// AddChannelID adds s to the "channel_id" field. +func (rpeuo *RolePanelEditUpdateOne) AddChannelID(s snowflake.ID) *RolePanelEditUpdateOne { + rpeuo.mutation.AddChannelID(s) + return rpeuo +} + +// SetEmojiAuthor sets the "emoji_author" field. +func (rpeuo *RolePanelEditUpdateOne) SetEmojiAuthor(s snowflake.ID) *RolePanelEditUpdateOne { + rpeuo.mutation.ResetEmojiAuthor() + rpeuo.mutation.SetEmojiAuthor(s) + return rpeuo +} + +// SetNillableEmojiAuthor sets the "emoji_author" field if the given value is not nil. +func (rpeuo *RolePanelEditUpdateOne) SetNillableEmojiAuthor(s *snowflake.ID) *RolePanelEditUpdateOne { + if s != nil { + rpeuo.SetEmojiAuthor(*s) + } + return rpeuo +} + +// AddEmojiAuthor adds s to the "emoji_author" field. +func (rpeuo *RolePanelEditUpdateOne) AddEmojiAuthor(s snowflake.ID) *RolePanelEditUpdateOne { + rpeuo.mutation.AddEmojiAuthor(s) + return rpeuo +} + +// ClearEmojiAuthor clears the value of the "emoji_author" field. +func (rpeuo *RolePanelEditUpdateOne) ClearEmojiAuthor() *RolePanelEditUpdateOne { + rpeuo.mutation.ClearEmojiAuthor() + return rpeuo +} + +// SetToken sets the "token" field. +func (rpeuo *RolePanelEditUpdateOne) SetToken(s string) *RolePanelEditUpdateOne { + rpeuo.mutation.SetToken(s) + return rpeuo +} + +// SetNillableToken sets the "token" field if the given value is not nil. +func (rpeuo *RolePanelEditUpdateOne) SetNillableToken(s *string) *RolePanelEditUpdateOne { + if s != nil { + rpeuo.SetToken(*s) + } + return rpeuo +} + +// ClearToken clears the value of the "token" field. +func (rpeuo *RolePanelEditUpdateOne) ClearToken() *RolePanelEditUpdateOne { + rpeuo.mutation.ClearToken() + return rpeuo +} + +// SetSelectedRole sets the "selected_role" field. +func (rpeuo *RolePanelEditUpdateOne) SetSelectedRole(s snowflake.ID) *RolePanelEditUpdateOne { + rpeuo.mutation.ResetSelectedRole() + rpeuo.mutation.SetSelectedRole(s) + return rpeuo +} + +// SetNillableSelectedRole sets the "selected_role" field if the given value is not nil. +func (rpeuo *RolePanelEditUpdateOne) SetNillableSelectedRole(s *snowflake.ID) *RolePanelEditUpdateOne { + if s != nil { + rpeuo.SetSelectedRole(*s) + } + return rpeuo +} + +// AddSelectedRole adds s to the "selected_role" field. +func (rpeuo *RolePanelEditUpdateOne) AddSelectedRole(s snowflake.ID) *RolePanelEditUpdateOne { + rpeuo.mutation.AddSelectedRole(s) + return rpeuo +} + +// ClearSelectedRole clears the value of the "selected_role" field. +func (rpeuo *RolePanelEditUpdateOne) ClearSelectedRole() *RolePanelEditUpdateOne { + rpeuo.mutation.ClearSelectedRole() + return rpeuo +} + +// SetModified sets the "modified" field. +func (rpeuo *RolePanelEditUpdateOne) SetModified(b bool) *RolePanelEditUpdateOne { + rpeuo.mutation.SetModified(b) + return rpeuo +} + +// SetNillableModified sets the "modified" field if the given value is not nil. +func (rpeuo *RolePanelEditUpdateOne) SetNillableModified(b *bool) *RolePanelEditUpdateOne { + if b != nil { + rpeuo.SetModified(*b) + } + return rpeuo +} + +// SetName sets the "name" field. +func (rpeuo *RolePanelEditUpdateOne) SetName(s string) *RolePanelEditUpdateOne { + rpeuo.mutation.SetName(s) + return rpeuo +} + +// SetNillableName sets the "name" field if the given value is not nil. +func (rpeuo *RolePanelEditUpdateOne) SetNillableName(s *string) *RolePanelEditUpdateOne { + if s != nil { + rpeuo.SetName(*s) + } + return rpeuo +} + +// ClearName clears the value of the "name" field. +func (rpeuo *RolePanelEditUpdateOne) ClearName() *RolePanelEditUpdateOne { + rpeuo.mutation.ClearName() + return rpeuo +} + +// SetDescription sets the "description" field. +func (rpeuo *RolePanelEditUpdateOne) SetDescription(s string) *RolePanelEditUpdateOne { + rpeuo.mutation.SetDescription(s) + return rpeuo +} + +// SetNillableDescription sets the "description" field if the given value is not nil. +func (rpeuo *RolePanelEditUpdateOne) SetNillableDescription(s *string) *RolePanelEditUpdateOne { + if s != nil { + rpeuo.SetDescription(*s) + } + return rpeuo +} + +// ClearDescription clears the value of the "description" field. +func (rpeuo *RolePanelEditUpdateOne) ClearDescription() *RolePanelEditUpdateOne { + rpeuo.mutation.ClearDescription() + return rpeuo +} + +// SetRoles sets the "roles" field. +func (rpeuo *RolePanelEditUpdateOne) SetRoles(s []schema.Role) *RolePanelEditUpdateOne { + rpeuo.mutation.SetRoles(s) + return rpeuo +} + +// AppendRoles appends s to the "roles" field. +func (rpeuo *RolePanelEditUpdateOne) AppendRoles(s []schema.Role) *RolePanelEditUpdateOne { + rpeuo.mutation.AppendRoles(s) + return rpeuo +} + +// ClearRoles clears the value of the "roles" field. +func (rpeuo *RolePanelEditUpdateOne) ClearRoles() *RolePanelEditUpdateOne { + rpeuo.mutation.ClearRoles() + return rpeuo +} + +// Mutation returns the RolePanelEditMutation object of the builder. +func (rpeuo *RolePanelEditUpdateOne) Mutation() *RolePanelEditMutation { + return rpeuo.mutation +} + +// Where appends a list predicates to the RolePanelEditUpdate builder. +func (rpeuo *RolePanelEditUpdateOne) Where(ps ...predicate.RolePanelEdit) *RolePanelEditUpdateOne { + rpeuo.mutation.Where(ps...) + return rpeuo +} + +// Select allows selecting one or more fields (columns) of the returned entity. +// The default is selecting all fields defined in the entity schema. +func (rpeuo *RolePanelEditUpdateOne) Select(field string, fields ...string) *RolePanelEditUpdateOne { + rpeuo.fields = append([]string{field}, fields...) + return rpeuo +} + +// Save executes the query and returns the updated RolePanelEdit entity. +func (rpeuo *RolePanelEditUpdateOne) Save(ctx context.Context) (*RolePanelEdit, error) { + return withHooks(ctx, rpeuo.sqlSave, rpeuo.mutation, rpeuo.hooks) +} + +// SaveX is like Save, but panics if an error occurs. +func (rpeuo *RolePanelEditUpdateOne) SaveX(ctx context.Context) *RolePanelEdit { + node, err := rpeuo.Save(ctx) + if err != nil { + panic(err) + } + return node +} + +// Exec executes the query on the entity. +func (rpeuo *RolePanelEditUpdateOne) Exec(ctx context.Context) error { + _, err := rpeuo.Save(ctx) + return err +} + +// ExecX is like Exec, but panics if an error occurs. +func (rpeuo *RolePanelEditUpdateOne) ExecX(ctx context.Context) { + if err := rpeuo.Exec(ctx); err != nil { + panic(err) + } +} + +// check runs all checks and user-defined validators on the builder. +func (rpeuo *RolePanelEditUpdateOne) check() error { + if v, ok := rpeuo.mutation.Name(); ok { + if err := rolepaneledit.NameValidator(v); err != nil { + return &ValidationError{Name: "name", err: fmt.Errorf(`ent: validator failed for field "RolePanelEdit.name": %w`, err)} + } + } + if _, ok := rpeuo.mutation.GuildID(); rpeuo.mutation.GuildCleared() && !ok { + return errors.New(`ent: clearing a required unique edge "RolePanelEdit.guild"`) + } + if _, ok := rpeuo.mutation.ParentID(); rpeuo.mutation.ParentCleared() && !ok { + return errors.New(`ent: clearing a required unique edge "RolePanelEdit.parent"`) + } + return nil +} + +func (rpeuo *RolePanelEditUpdateOne) sqlSave(ctx context.Context) (_node *RolePanelEdit, err error) { + if err := rpeuo.check(); err != nil { + return _node, err + } + _spec := sqlgraph.NewUpdateSpec(rolepaneledit.Table, rolepaneledit.Columns, sqlgraph.NewFieldSpec(rolepaneledit.FieldID, field.TypeUUID)) + id, ok := rpeuo.mutation.ID() + if !ok { + return nil, &ValidationError{Name: "id", err: errors.New(`ent: missing "RolePanelEdit.id" for update`)} + } + _spec.Node.ID.Value = id + if fields := rpeuo.fields; len(fields) > 0 { + _spec.Node.Columns = make([]string, 0, len(fields)) + _spec.Node.Columns = append(_spec.Node.Columns, rolepaneledit.FieldID) + for _, f := range fields { + if !rolepaneledit.ValidColumn(f) { + return nil, &ValidationError{Name: f, err: fmt.Errorf("ent: invalid field %q for query", f)} + } + if f != rolepaneledit.FieldID { + _spec.Node.Columns = append(_spec.Node.Columns, f) + } + } + } + if ps := rpeuo.mutation.predicates; len(ps) > 0 { + _spec.Predicate = func(selector *sql.Selector) { + for i := range ps { + ps[i](selector) + } + } + } + if value, ok := rpeuo.mutation.ChannelID(); ok { + _spec.SetField(rolepaneledit.FieldChannelID, field.TypeUint64, value) + } + if value, ok := rpeuo.mutation.AddedChannelID(); ok { + _spec.AddField(rolepaneledit.FieldChannelID, field.TypeUint64, value) + } + if value, ok := rpeuo.mutation.EmojiAuthor(); ok { + _spec.SetField(rolepaneledit.FieldEmojiAuthor, field.TypeUint64, value) + } + if value, ok := rpeuo.mutation.AddedEmojiAuthor(); ok { + _spec.AddField(rolepaneledit.FieldEmojiAuthor, field.TypeUint64, value) + } + if rpeuo.mutation.EmojiAuthorCleared() { + _spec.ClearField(rolepaneledit.FieldEmojiAuthor, field.TypeUint64) + } + if value, ok := rpeuo.mutation.Token(); ok { + _spec.SetField(rolepaneledit.FieldToken, field.TypeString, value) + } + if rpeuo.mutation.TokenCleared() { + _spec.ClearField(rolepaneledit.FieldToken, field.TypeString) + } + if value, ok := rpeuo.mutation.SelectedRole(); ok { + _spec.SetField(rolepaneledit.FieldSelectedRole, field.TypeUint64, value) + } + if value, ok := rpeuo.mutation.AddedSelectedRole(); ok { + _spec.AddField(rolepaneledit.FieldSelectedRole, field.TypeUint64, value) + } + if rpeuo.mutation.SelectedRoleCleared() { + _spec.ClearField(rolepaneledit.FieldSelectedRole, field.TypeUint64) + } + if value, ok := rpeuo.mutation.Modified(); ok { + _spec.SetField(rolepaneledit.FieldModified, field.TypeBool, value) + } + if value, ok := rpeuo.mutation.Name(); ok { + _spec.SetField(rolepaneledit.FieldName, field.TypeString, value) + } + if rpeuo.mutation.NameCleared() { + _spec.ClearField(rolepaneledit.FieldName, field.TypeString) + } + if value, ok := rpeuo.mutation.Description(); ok { + _spec.SetField(rolepaneledit.FieldDescription, field.TypeString, value) + } + if rpeuo.mutation.DescriptionCleared() { + _spec.ClearField(rolepaneledit.FieldDescription, field.TypeString) + } + if value, ok := rpeuo.mutation.Roles(); ok { + _spec.SetField(rolepaneledit.FieldRoles, field.TypeJSON, value) + } + if value, ok := rpeuo.mutation.AppendedRoles(); ok { + _spec.AddModifier(func(u *sql.UpdateBuilder) { + sqljson.Append(u, rolepaneledit.FieldRoles, value) + }) + } + if rpeuo.mutation.RolesCleared() { + _spec.ClearField(rolepaneledit.FieldRoles, field.TypeJSON) + } + _node = &RolePanelEdit{config: rpeuo.config} + _spec.Assign = _node.assignValues + _spec.ScanValues = _node.scanValues + if err = sqlgraph.UpdateNode(ctx, rpeuo.driver, _spec); err != nil { + if _, ok := err.(*sqlgraph.NotFoundError); ok { + err = &NotFoundError{rolepaneledit.Label} + } else if sqlgraph.IsConstraintError(err) { + err = &ConstraintError{msg: err.Error(), wrap: err} + } + return nil, err + } + rpeuo.mutation.done = true + return _node, nil +} diff --git a/ent/rolepanelplaced.go b/ent/rolepanelplaced.go new file mode 100644 index 00000000..d069f11e --- /dev/null +++ b/ent/rolepanelplaced.go @@ -0,0 +1,333 @@ +// Code generated by ent, DO NOT EDIT. + +package ent + +import ( + "encoding/json" + "fmt" + "strings" + "time" + + "entgo.io/ent" + "entgo.io/ent/dialect/sql" + "github.com/disgoorg/disgo/discord" + snowflake "github.com/disgoorg/snowflake/v2" + "github.com/google/uuid" + "github.com/sabafly/gobot/ent/guild" + "github.com/sabafly/gobot/ent/rolepanel" + "github.com/sabafly/gobot/ent/rolepanelplaced" + "github.com/sabafly/gobot/ent/schema" +) + +// RolePanelPlaced is the model entity for the RolePanelPlaced schema. +type RolePanelPlaced struct { + config `json:"-"` + // ID of the ent. + ID uuid.UUID `json:"id,omitempty"` + // MessageID holds the value of the "message_id" field. + MessageID *snowflake.ID `json:"message_id,omitempty"` + // ChannelID holds the value of the "channel_id" field. + ChannelID snowflake.ID `json:"channel_id,omitempty"` + // Type holds the value of the "type" field. + Type rolepanelplaced.Type `json:"type,omitempty"` + // ButtonType holds the value of the "button_type" field. + ButtonType discord.ButtonStyle `json:"button_type,omitempty"` + // ShowName holds the value of the "show_name" field. + ShowName bool `json:"show_name,omitempty"` + // FoldingSelectMenu holds the value of the "folding_select_menu" field. + FoldingSelectMenu bool `json:"folding_select_menu,omitempty"` + // HideNotice holds the value of the "hide_notice" field. + HideNotice bool `json:"hide_notice,omitempty"` + // UseDisplayName holds the value of the "use_display_name" field. + UseDisplayName bool `json:"use_display_name,omitempty"` + // CreatedAt holds the value of the "created_at" field. + CreatedAt time.Time `json:"created_at,omitempty"` + // Uses holds the value of the "uses" field. + Uses int `json:"uses,omitempty"` + // Name holds the value of the "name" field. + Name string `json:"name,omitempty"` + // Description holds the value of the "description" field. + Description string `json:"description,omitempty"` + // Roles holds the value of the "roles" field. + Roles []schema.Role `json:"roles,omitempty"` + // UpdatedAt holds the value of the "updated_at" field. + UpdatedAt time.Time `json:"updated_at,omitempty"` + // Edges holds the relations/edges for other nodes in the graph. + // The values are being populated by the RolePanelPlacedQuery when eager-loading is set. + Edges RolePanelPlacedEdges `json:"edges"` + guild_role_panel_placements *snowflake.ID + role_panel_placements *uuid.UUID + selectValues sql.SelectValues +} + +// RolePanelPlacedEdges holds the relations/edges for other nodes in the graph. +type RolePanelPlacedEdges struct { + // Guild holds the value of the guild edge. + Guild *Guild `json:"guild,omitempty"` + // RolePanel holds the value of the role_panel edge. + RolePanel *RolePanel `json:"role_panel,omitempty"` + // loadedTypes holds the information for reporting if a + // type was loaded (or requested) in eager-loading or not. + loadedTypes [2]bool +} + +// GuildOrErr returns the Guild value or an error if the edge +// was not loaded in eager-loading, or loaded but was not found. +func (e RolePanelPlacedEdges) GuildOrErr() (*Guild, error) { + if e.Guild != nil { + return e.Guild, nil + } else if e.loadedTypes[0] { + return nil, &NotFoundError{label: guild.Label} + } + return nil, &NotLoadedError{edge: "guild"} +} + +// RolePanelOrErr returns the RolePanel value or an error if the edge +// was not loaded in eager-loading, or loaded but was not found. +func (e RolePanelPlacedEdges) RolePanelOrErr() (*RolePanel, error) { + if e.RolePanel != nil { + return e.RolePanel, nil + } else if e.loadedTypes[1] { + return nil, &NotFoundError{label: rolepanel.Label} + } + return nil, &NotLoadedError{edge: "role_panel"} +} + +// scanValues returns the types for scanning values from sql.Rows. +func (*RolePanelPlaced) scanValues(columns []string) ([]any, error) { + values := make([]any, len(columns)) + for i := range columns { + switch columns[i] { + case rolepanelplaced.FieldRoles: + values[i] = new([]byte) + case rolepanelplaced.FieldShowName, rolepanelplaced.FieldFoldingSelectMenu, rolepanelplaced.FieldHideNotice, rolepanelplaced.FieldUseDisplayName: + values[i] = new(sql.NullBool) + case rolepanelplaced.FieldMessageID, rolepanelplaced.FieldChannelID, rolepanelplaced.FieldButtonType, rolepanelplaced.FieldUses: + values[i] = new(sql.NullInt64) + case rolepanelplaced.FieldType, rolepanelplaced.FieldName, rolepanelplaced.FieldDescription: + values[i] = new(sql.NullString) + case rolepanelplaced.FieldCreatedAt, rolepanelplaced.FieldUpdatedAt: + values[i] = new(sql.NullTime) + case rolepanelplaced.FieldID: + values[i] = new(uuid.UUID) + case rolepanelplaced.ForeignKeys[0]: // guild_role_panel_placements + values[i] = new(sql.NullInt64) + case rolepanelplaced.ForeignKeys[1]: // role_panel_placements + values[i] = &sql.NullScanner{S: new(uuid.UUID)} + default: + values[i] = new(sql.UnknownType) + } + } + return values, nil +} + +// assignValues assigns the values that were returned from sql.Rows (after scanning) +// to the RolePanelPlaced fields. +func (rpp *RolePanelPlaced) assignValues(columns []string, values []any) error { + if m, n := len(values), len(columns); m < n { + return fmt.Errorf("mismatch number of scan values: %d != %d", m, n) + } + for i := range columns { + switch columns[i] { + case rolepanelplaced.FieldID: + if value, ok := values[i].(*uuid.UUID); !ok { + return fmt.Errorf("unexpected type %T for field id", values[i]) + } else if value != nil { + rpp.ID = *value + } + case rolepanelplaced.FieldMessageID: + if value, ok := values[i].(*sql.NullInt64); !ok { + return fmt.Errorf("unexpected type %T for field message_id", values[i]) + } else if value.Valid { + rpp.MessageID = new(snowflake.ID) + *rpp.MessageID = snowflake.ID(value.Int64) + } + case rolepanelplaced.FieldChannelID: + if value, ok := values[i].(*sql.NullInt64); !ok { + return fmt.Errorf("unexpected type %T for field channel_id", values[i]) + } else if value.Valid { + rpp.ChannelID = snowflake.ID(value.Int64) + } + case rolepanelplaced.FieldType: + if value, ok := values[i].(*sql.NullString); !ok { + return fmt.Errorf("unexpected type %T for field type", values[i]) + } else if value.Valid { + rpp.Type = rolepanelplaced.Type(value.String) + } + case rolepanelplaced.FieldButtonType: + if value, ok := values[i].(*sql.NullInt64); !ok { + return fmt.Errorf("unexpected type %T for field button_type", values[i]) + } else if value.Valid { + rpp.ButtonType = discord.ButtonStyle(value.Int64) + } + case rolepanelplaced.FieldShowName: + if value, ok := values[i].(*sql.NullBool); !ok { + return fmt.Errorf("unexpected type %T for field show_name", values[i]) + } else if value.Valid { + rpp.ShowName = value.Bool + } + case rolepanelplaced.FieldFoldingSelectMenu: + if value, ok := values[i].(*sql.NullBool); !ok { + return fmt.Errorf("unexpected type %T for field folding_select_menu", values[i]) + } else if value.Valid { + rpp.FoldingSelectMenu = value.Bool + } + case rolepanelplaced.FieldHideNotice: + if value, ok := values[i].(*sql.NullBool); !ok { + return fmt.Errorf("unexpected type %T for field hide_notice", values[i]) + } else if value.Valid { + rpp.HideNotice = value.Bool + } + case rolepanelplaced.FieldUseDisplayName: + if value, ok := values[i].(*sql.NullBool); !ok { + return fmt.Errorf("unexpected type %T for field use_display_name", values[i]) + } else if value.Valid { + rpp.UseDisplayName = value.Bool + } + case rolepanelplaced.FieldCreatedAt: + if value, ok := values[i].(*sql.NullTime); !ok { + return fmt.Errorf("unexpected type %T for field created_at", values[i]) + } else if value.Valid { + rpp.CreatedAt = value.Time + } + case rolepanelplaced.FieldUses: + if value, ok := values[i].(*sql.NullInt64); !ok { + return fmt.Errorf("unexpected type %T for field uses", values[i]) + } else if value.Valid { + rpp.Uses = int(value.Int64) + } + case rolepanelplaced.FieldName: + if value, ok := values[i].(*sql.NullString); !ok { + return fmt.Errorf("unexpected type %T for field name", values[i]) + } else if value.Valid { + rpp.Name = value.String + } + case rolepanelplaced.FieldDescription: + if value, ok := values[i].(*sql.NullString); !ok { + return fmt.Errorf("unexpected type %T for field description", values[i]) + } else if value.Valid { + rpp.Description = value.String + } + case rolepanelplaced.FieldRoles: + if value, ok := values[i].(*[]byte); !ok { + return fmt.Errorf("unexpected type %T for field roles", values[i]) + } else if value != nil && len(*value) > 0 { + if err := json.Unmarshal(*value, &rpp.Roles); err != nil { + return fmt.Errorf("unmarshal field roles: %w", err) + } + } + case rolepanelplaced.FieldUpdatedAt: + if value, ok := values[i].(*sql.NullTime); !ok { + return fmt.Errorf("unexpected type %T for field updated_at", values[i]) + } else if value.Valid { + rpp.UpdatedAt = value.Time + } + case rolepanelplaced.ForeignKeys[0]: + if value, ok := values[i].(*sql.NullInt64); !ok { + return fmt.Errorf("unexpected type %T for field guild_role_panel_placements", values[i]) + } else if value.Valid { + rpp.guild_role_panel_placements = new(snowflake.ID) + *rpp.guild_role_panel_placements = snowflake.ID(value.Int64) + } + case rolepanelplaced.ForeignKeys[1]: + if value, ok := values[i].(*sql.NullScanner); !ok { + return fmt.Errorf("unexpected type %T for field role_panel_placements", values[i]) + } else if value.Valid { + rpp.role_panel_placements = new(uuid.UUID) + *rpp.role_panel_placements = *value.S.(*uuid.UUID) + } + default: + rpp.selectValues.Set(columns[i], values[i]) + } + } + return nil +} + +// Value returns the ent.Value that was dynamically selected and assigned to the RolePanelPlaced. +// This includes values selected through modifiers, order, etc. +func (rpp *RolePanelPlaced) Value(name string) (ent.Value, error) { + return rpp.selectValues.Get(name) +} + +// QueryGuild queries the "guild" edge of the RolePanelPlaced entity. +func (rpp *RolePanelPlaced) QueryGuild() *GuildQuery { + return NewRolePanelPlacedClient(rpp.config).QueryGuild(rpp) +} + +// QueryRolePanel queries the "role_panel" edge of the RolePanelPlaced entity. +func (rpp *RolePanelPlaced) QueryRolePanel() *RolePanelQuery { + return NewRolePanelPlacedClient(rpp.config).QueryRolePanel(rpp) +} + +// Update returns a builder for updating this RolePanelPlaced. +// Note that you need to call RolePanelPlaced.Unwrap() before calling this method if this RolePanelPlaced +// was returned from a transaction, and the transaction was committed or rolled back. +func (rpp *RolePanelPlaced) Update() *RolePanelPlacedUpdateOne { + return NewRolePanelPlacedClient(rpp.config).UpdateOne(rpp) +} + +// Unwrap unwraps the RolePanelPlaced entity that was returned from a transaction after it was closed, +// so that all future queries will be executed through the driver which created the transaction. +func (rpp *RolePanelPlaced) Unwrap() *RolePanelPlaced { + _tx, ok := rpp.config.driver.(*txDriver) + if !ok { + panic("ent: RolePanelPlaced is not a transactional entity") + } + rpp.config.driver = _tx.drv + return rpp +} + +// String implements the fmt.Stringer. +func (rpp *RolePanelPlaced) String() string { + var builder strings.Builder + builder.WriteString("RolePanelPlaced(") + builder.WriteString(fmt.Sprintf("id=%v, ", rpp.ID)) + if v := rpp.MessageID; v != nil { + builder.WriteString("message_id=") + builder.WriteString(fmt.Sprintf("%v", *v)) + } + builder.WriteString(", ") + builder.WriteString("channel_id=") + builder.WriteString(fmt.Sprintf("%v", rpp.ChannelID)) + builder.WriteString(", ") + builder.WriteString("type=") + builder.WriteString(fmt.Sprintf("%v", rpp.Type)) + builder.WriteString(", ") + builder.WriteString("button_type=") + builder.WriteString(fmt.Sprintf("%v", rpp.ButtonType)) + builder.WriteString(", ") + builder.WriteString("show_name=") + builder.WriteString(fmt.Sprintf("%v", rpp.ShowName)) + builder.WriteString(", ") + builder.WriteString("folding_select_menu=") + builder.WriteString(fmt.Sprintf("%v", rpp.FoldingSelectMenu)) + builder.WriteString(", ") + builder.WriteString("hide_notice=") + builder.WriteString(fmt.Sprintf("%v", rpp.HideNotice)) + builder.WriteString(", ") + builder.WriteString("use_display_name=") + builder.WriteString(fmt.Sprintf("%v", rpp.UseDisplayName)) + builder.WriteString(", ") + builder.WriteString("created_at=") + builder.WriteString(rpp.CreatedAt.Format(time.ANSIC)) + builder.WriteString(", ") + builder.WriteString("uses=") + builder.WriteString(fmt.Sprintf("%v", rpp.Uses)) + builder.WriteString(", ") + builder.WriteString("name=") + builder.WriteString(rpp.Name) + builder.WriteString(", ") + builder.WriteString("description=") + builder.WriteString(rpp.Description) + builder.WriteString(", ") + builder.WriteString("roles=") + builder.WriteString(fmt.Sprintf("%v", rpp.Roles)) + builder.WriteString(", ") + builder.WriteString("updated_at=") + builder.WriteString(rpp.UpdatedAt.Format(time.ANSIC)) + builder.WriteByte(')') + return builder.String() +} + +// RolePanelPlaceds is a parsable slice of RolePanelPlaced. +type RolePanelPlaceds []*RolePanelPlaced diff --git a/ent/rolepanelplaced/rolepanelplaced.go b/ent/rolepanelplaced/rolepanelplaced.go new file mode 100644 index 00000000..422cdbe5 --- /dev/null +++ b/ent/rolepanelplaced/rolepanelplaced.go @@ -0,0 +1,257 @@ +// Code generated by ent, DO NOT EDIT. + +package rolepanelplaced + +import ( + "fmt" + "time" + + "entgo.io/ent/dialect/sql" + "entgo.io/ent/dialect/sql/sqlgraph" + "github.com/disgoorg/disgo/discord" + "github.com/google/uuid" +) + +const ( + // Label holds the string label denoting the rolepanelplaced type in the database. + Label = "role_panel_placed" + // FieldID holds the string denoting the id field in the database. + FieldID = "id" + // FieldMessageID holds the string denoting the message_id field in the database. + FieldMessageID = "message_id" + // FieldChannelID holds the string denoting the channel_id field in the database. + FieldChannelID = "channel_id" + // FieldType holds the string denoting the type field in the database. + FieldType = "type" + // FieldButtonType holds the string denoting the button_type field in the database. + FieldButtonType = "button_type" + // FieldShowName holds the string denoting the show_name field in the database. + FieldShowName = "show_name" + // FieldFoldingSelectMenu holds the string denoting the folding_select_menu field in the database. + FieldFoldingSelectMenu = "folding_select_menu" + // FieldHideNotice holds the string denoting the hide_notice field in the database. + FieldHideNotice = "hide_notice" + // FieldUseDisplayName holds the string denoting the use_display_name field in the database. + FieldUseDisplayName = "use_display_name" + // FieldCreatedAt holds the string denoting the created_at field in the database. + FieldCreatedAt = "created_at" + // FieldUses holds the string denoting the uses field in the database. + FieldUses = "uses" + // FieldName holds the string denoting the name field in the database. + FieldName = "name" + // FieldDescription holds the string denoting the description field in the database. + FieldDescription = "description" + // FieldRoles holds the string denoting the roles field in the database. + FieldRoles = "roles" + // FieldUpdatedAt holds the string denoting the updated_at field in the database. + FieldUpdatedAt = "updated_at" + // EdgeGuild holds the string denoting the guild edge name in mutations. + EdgeGuild = "guild" + // EdgeRolePanel holds the string denoting the role_panel edge name in mutations. + EdgeRolePanel = "role_panel" + // Table holds the table name of the rolepanelplaced in the database. + Table = "role_panel_placeds" + // GuildTable is the table that holds the guild relation/edge. + GuildTable = "role_panel_placeds" + // GuildInverseTable is the table name for the Guild entity. + // It exists in this package in order to avoid circular dependency with the "guild" package. + GuildInverseTable = "guilds" + // GuildColumn is the table column denoting the guild relation/edge. + GuildColumn = "guild_role_panel_placements" + // RolePanelTable is the table that holds the role_panel relation/edge. + RolePanelTable = "role_panel_placeds" + // RolePanelInverseTable is the table name for the RolePanel entity. + // It exists in this package in order to avoid circular dependency with the "rolepanel" package. + RolePanelInverseTable = "role_panels" + // RolePanelColumn is the table column denoting the role_panel relation/edge. + RolePanelColumn = "role_panel_placements" +) + +// Columns holds all SQL columns for rolepanelplaced fields. +var Columns = []string{ + FieldID, + FieldMessageID, + FieldChannelID, + FieldType, + FieldButtonType, + FieldShowName, + FieldFoldingSelectMenu, + FieldHideNotice, + FieldUseDisplayName, + FieldCreatedAt, + FieldUses, + FieldName, + FieldDescription, + FieldRoles, + FieldUpdatedAt, +} + +// ForeignKeys holds the SQL foreign-keys that are owned by the "role_panel_placeds" +// table and are not defined as standalone fields in the schema. +var ForeignKeys = []string{ + "guild_role_panel_placements", + "role_panel_placements", +} + +// ValidColumn reports if the column name is valid (part of the table columns). +func ValidColumn(column string) bool { + for i := range Columns { + if column == Columns[i] { + return true + } + } + for i := range ForeignKeys { + if column == ForeignKeys[i] { + return true + } + } + return false +} + +var ( + // DefaultButtonType holds the default value on creation for the "button_type" field. + DefaultButtonType discord.ButtonStyle + // ButtonTypeValidator is a validator for the "button_type" field. It is called by the builders before save. + ButtonTypeValidator func(int) error + // DefaultShowName holds the default value on creation for the "show_name" field. + DefaultShowName bool + // DefaultFoldingSelectMenu holds the default value on creation for the "folding_select_menu" field. + DefaultFoldingSelectMenu bool + // DefaultHideNotice holds the default value on creation for the "hide_notice" field. + DefaultHideNotice bool + // DefaultUseDisplayName holds the default value on creation for the "use_display_name" field. + DefaultUseDisplayName bool + // DefaultCreatedAt holds the default value on creation for the "created_at" field. + DefaultCreatedAt func() time.Time + // DefaultUses holds the default value on creation for the "uses" field. + DefaultUses int + // NameValidator is a validator for the "name" field. It is called by the builders before save. + NameValidator func(string) error + // DefaultID holds the default value on creation for the "id" field. + DefaultID func() uuid.UUID +) + +// Type defines the type for the "type" enum field. +type Type string + +// Type values. +const ( + TypeButton Type = "button" + TypeReaction Type = "reaction" + TypeSelectMenu Type = "select_menu" +) + +func (_type Type) String() string { + return string(_type) +} + +// TypeValidator is a validator for the "type" field enum values. It is called by the builders before save. +func TypeValidator(_type Type) error { + switch _type { + case TypeButton, TypeReaction, TypeSelectMenu: + return nil + default: + return fmt.Errorf("rolepanelplaced: invalid enum value for type field: %q", _type) + } +} + +// OrderOption defines the ordering options for the RolePanelPlaced queries. +type OrderOption func(*sql.Selector) + +// ByID orders the results by the id field. +func ByID(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldID, opts...).ToFunc() +} + +// ByMessageID orders the results by the message_id field. +func ByMessageID(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldMessageID, opts...).ToFunc() +} + +// ByChannelID orders the results by the channel_id field. +func ByChannelID(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldChannelID, opts...).ToFunc() +} + +// ByType orders the results by the type field. +func ByType(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldType, opts...).ToFunc() +} + +// ByButtonType orders the results by the button_type field. +func ByButtonType(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldButtonType, opts...).ToFunc() +} + +// ByShowName orders the results by the show_name field. +func ByShowName(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldShowName, opts...).ToFunc() +} + +// ByFoldingSelectMenu orders the results by the folding_select_menu field. +func ByFoldingSelectMenu(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldFoldingSelectMenu, opts...).ToFunc() +} + +// ByHideNotice orders the results by the hide_notice field. +func ByHideNotice(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldHideNotice, opts...).ToFunc() +} + +// ByUseDisplayName orders the results by the use_display_name field. +func ByUseDisplayName(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldUseDisplayName, opts...).ToFunc() +} + +// ByCreatedAt orders the results by the created_at field. +func ByCreatedAt(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldCreatedAt, opts...).ToFunc() +} + +// ByUses orders the results by the uses field. +func ByUses(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldUses, opts...).ToFunc() +} + +// ByName orders the results by the name field. +func ByName(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldName, opts...).ToFunc() +} + +// ByDescription orders the results by the description field. +func ByDescription(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldDescription, opts...).ToFunc() +} + +// ByUpdatedAt orders the results by the updated_at field. +func ByUpdatedAt(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldUpdatedAt, opts...).ToFunc() +} + +// ByGuildField orders the results by guild field. +func ByGuildField(field string, opts ...sql.OrderTermOption) OrderOption { + return func(s *sql.Selector) { + sqlgraph.OrderByNeighborTerms(s, newGuildStep(), sql.OrderByField(field, opts...)) + } +} + +// ByRolePanelField orders the results by role_panel field. +func ByRolePanelField(field string, opts ...sql.OrderTermOption) OrderOption { + return func(s *sql.Selector) { + sqlgraph.OrderByNeighborTerms(s, newRolePanelStep(), sql.OrderByField(field, opts...)) + } +} +func newGuildStep() *sqlgraph.Step { + return sqlgraph.NewStep( + sqlgraph.From(Table, FieldID), + sqlgraph.To(GuildInverseTable, FieldID), + sqlgraph.Edge(sqlgraph.M2O, true, GuildTable, GuildColumn), + ) +} +func newRolePanelStep() *sqlgraph.Step { + return sqlgraph.NewStep( + sqlgraph.From(Table, FieldID), + sqlgraph.To(RolePanelInverseTable, FieldID), + sqlgraph.Edge(sqlgraph.M2O, true, RolePanelTable, RolePanelColumn), + ) +} diff --git a/ent/rolepanelplaced/where.go b/ent/rolepanelplaced/where.go new file mode 100644 index 00000000..6e470e86 --- /dev/null +++ b/ent/rolepanelplaced/where.go @@ -0,0 +1,695 @@ +// Code generated by ent, DO NOT EDIT. + +package rolepanelplaced + +import ( + "time" + + "entgo.io/ent/dialect/sql" + "entgo.io/ent/dialect/sql/sqlgraph" + "github.com/disgoorg/disgo/discord" + snowflake "github.com/disgoorg/snowflake/v2" + "github.com/google/uuid" + "github.com/sabafly/gobot/ent/predicate" +) + +// ID filters vertices based on their ID field. +func ID(id uuid.UUID) predicate.RolePanelPlaced { + return predicate.RolePanelPlaced(sql.FieldEQ(FieldID, id)) +} + +// IDEQ applies the EQ predicate on the ID field. +func IDEQ(id uuid.UUID) predicate.RolePanelPlaced { + return predicate.RolePanelPlaced(sql.FieldEQ(FieldID, id)) +} + +// IDNEQ applies the NEQ predicate on the ID field. +func IDNEQ(id uuid.UUID) predicate.RolePanelPlaced { + return predicate.RolePanelPlaced(sql.FieldNEQ(FieldID, id)) +} + +// IDIn applies the In predicate on the ID field. +func IDIn(ids ...uuid.UUID) predicate.RolePanelPlaced { + return predicate.RolePanelPlaced(sql.FieldIn(FieldID, ids...)) +} + +// IDNotIn applies the NotIn predicate on the ID field. +func IDNotIn(ids ...uuid.UUID) predicate.RolePanelPlaced { + return predicate.RolePanelPlaced(sql.FieldNotIn(FieldID, ids...)) +} + +// IDGT applies the GT predicate on the ID field. +func IDGT(id uuid.UUID) predicate.RolePanelPlaced { + return predicate.RolePanelPlaced(sql.FieldGT(FieldID, id)) +} + +// IDGTE applies the GTE predicate on the ID field. +func IDGTE(id uuid.UUID) predicate.RolePanelPlaced { + return predicate.RolePanelPlaced(sql.FieldGTE(FieldID, id)) +} + +// IDLT applies the LT predicate on the ID field. +func IDLT(id uuid.UUID) predicate.RolePanelPlaced { + return predicate.RolePanelPlaced(sql.FieldLT(FieldID, id)) +} + +// IDLTE applies the LTE predicate on the ID field. +func IDLTE(id uuid.UUID) predicate.RolePanelPlaced { + return predicate.RolePanelPlaced(sql.FieldLTE(FieldID, id)) +} + +// MessageID applies equality check predicate on the "message_id" field. It's identical to MessageIDEQ. +func MessageID(v snowflake.ID) predicate.RolePanelPlaced { + vc := uint64(v) + return predicate.RolePanelPlaced(sql.FieldEQ(FieldMessageID, vc)) +} + +// ChannelID applies equality check predicate on the "channel_id" field. It's identical to ChannelIDEQ. +func ChannelID(v snowflake.ID) predicate.RolePanelPlaced { + vc := uint64(v) + return predicate.RolePanelPlaced(sql.FieldEQ(FieldChannelID, vc)) +} + +// ButtonType applies equality check predicate on the "button_type" field. It's identical to ButtonTypeEQ. +func ButtonType(v discord.ButtonStyle) predicate.RolePanelPlaced { + vc := int(v) + return predicate.RolePanelPlaced(sql.FieldEQ(FieldButtonType, vc)) +} + +// ShowName applies equality check predicate on the "show_name" field. It's identical to ShowNameEQ. +func ShowName(v bool) predicate.RolePanelPlaced { + return predicate.RolePanelPlaced(sql.FieldEQ(FieldShowName, v)) +} + +// FoldingSelectMenu applies equality check predicate on the "folding_select_menu" field. It's identical to FoldingSelectMenuEQ. +func FoldingSelectMenu(v bool) predicate.RolePanelPlaced { + return predicate.RolePanelPlaced(sql.FieldEQ(FieldFoldingSelectMenu, v)) +} + +// HideNotice applies equality check predicate on the "hide_notice" field. It's identical to HideNoticeEQ. +func HideNotice(v bool) predicate.RolePanelPlaced { + return predicate.RolePanelPlaced(sql.FieldEQ(FieldHideNotice, v)) +} + +// UseDisplayName applies equality check predicate on the "use_display_name" field. It's identical to UseDisplayNameEQ. +func UseDisplayName(v bool) predicate.RolePanelPlaced { + return predicate.RolePanelPlaced(sql.FieldEQ(FieldUseDisplayName, v)) +} + +// CreatedAt applies equality check predicate on the "created_at" field. It's identical to CreatedAtEQ. +func CreatedAt(v time.Time) predicate.RolePanelPlaced { + return predicate.RolePanelPlaced(sql.FieldEQ(FieldCreatedAt, v)) +} + +// Uses applies equality check predicate on the "uses" field. It's identical to UsesEQ. +func Uses(v int) predicate.RolePanelPlaced { + return predicate.RolePanelPlaced(sql.FieldEQ(FieldUses, v)) +} + +// Name applies equality check predicate on the "name" field. It's identical to NameEQ. +func Name(v string) predicate.RolePanelPlaced { + return predicate.RolePanelPlaced(sql.FieldEQ(FieldName, v)) +} + +// Description applies equality check predicate on the "description" field. It's identical to DescriptionEQ. +func Description(v string) predicate.RolePanelPlaced { + return predicate.RolePanelPlaced(sql.FieldEQ(FieldDescription, v)) +} + +// UpdatedAt applies equality check predicate on the "updated_at" field. It's identical to UpdatedAtEQ. +func UpdatedAt(v time.Time) predicate.RolePanelPlaced { + return predicate.RolePanelPlaced(sql.FieldEQ(FieldUpdatedAt, v)) +} + +// MessageIDEQ applies the EQ predicate on the "message_id" field. +func MessageIDEQ(v snowflake.ID) predicate.RolePanelPlaced { + vc := uint64(v) + return predicate.RolePanelPlaced(sql.FieldEQ(FieldMessageID, vc)) +} + +// MessageIDNEQ applies the NEQ predicate on the "message_id" field. +func MessageIDNEQ(v snowflake.ID) predicate.RolePanelPlaced { + vc := uint64(v) + return predicate.RolePanelPlaced(sql.FieldNEQ(FieldMessageID, vc)) +} + +// MessageIDIn applies the In predicate on the "message_id" field. +func MessageIDIn(vs ...snowflake.ID) predicate.RolePanelPlaced { + v := make([]any, len(vs)) + for i := range v { + v[i] = uint64(vs[i]) + } + return predicate.RolePanelPlaced(sql.FieldIn(FieldMessageID, v...)) +} + +// MessageIDNotIn applies the NotIn predicate on the "message_id" field. +func MessageIDNotIn(vs ...snowflake.ID) predicate.RolePanelPlaced { + v := make([]any, len(vs)) + for i := range v { + v[i] = uint64(vs[i]) + } + return predicate.RolePanelPlaced(sql.FieldNotIn(FieldMessageID, v...)) +} + +// MessageIDGT applies the GT predicate on the "message_id" field. +func MessageIDGT(v snowflake.ID) predicate.RolePanelPlaced { + vc := uint64(v) + return predicate.RolePanelPlaced(sql.FieldGT(FieldMessageID, vc)) +} + +// MessageIDGTE applies the GTE predicate on the "message_id" field. +func MessageIDGTE(v snowflake.ID) predicate.RolePanelPlaced { + vc := uint64(v) + return predicate.RolePanelPlaced(sql.FieldGTE(FieldMessageID, vc)) +} + +// MessageIDLT applies the LT predicate on the "message_id" field. +func MessageIDLT(v snowflake.ID) predicate.RolePanelPlaced { + vc := uint64(v) + return predicate.RolePanelPlaced(sql.FieldLT(FieldMessageID, vc)) +} + +// MessageIDLTE applies the LTE predicate on the "message_id" field. +func MessageIDLTE(v snowflake.ID) predicate.RolePanelPlaced { + vc := uint64(v) + return predicate.RolePanelPlaced(sql.FieldLTE(FieldMessageID, vc)) +} + +// MessageIDIsNil applies the IsNil predicate on the "message_id" field. +func MessageIDIsNil() predicate.RolePanelPlaced { + return predicate.RolePanelPlaced(sql.FieldIsNull(FieldMessageID)) +} + +// MessageIDNotNil applies the NotNil predicate on the "message_id" field. +func MessageIDNotNil() predicate.RolePanelPlaced { + return predicate.RolePanelPlaced(sql.FieldNotNull(FieldMessageID)) +} + +// ChannelIDEQ applies the EQ predicate on the "channel_id" field. +func ChannelIDEQ(v snowflake.ID) predicate.RolePanelPlaced { + vc := uint64(v) + return predicate.RolePanelPlaced(sql.FieldEQ(FieldChannelID, vc)) +} + +// ChannelIDNEQ applies the NEQ predicate on the "channel_id" field. +func ChannelIDNEQ(v snowflake.ID) predicate.RolePanelPlaced { + vc := uint64(v) + return predicate.RolePanelPlaced(sql.FieldNEQ(FieldChannelID, vc)) +} + +// ChannelIDIn applies the In predicate on the "channel_id" field. +func ChannelIDIn(vs ...snowflake.ID) predicate.RolePanelPlaced { + v := make([]any, len(vs)) + for i := range v { + v[i] = uint64(vs[i]) + } + return predicate.RolePanelPlaced(sql.FieldIn(FieldChannelID, v...)) +} + +// ChannelIDNotIn applies the NotIn predicate on the "channel_id" field. +func ChannelIDNotIn(vs ...snowflake.ID) predicate.RolePanelPlaced { + v := make([]any, len(vs)) + for i := range v { + v[i] = uint64(vs[i]) + } + return predicate.RolePanelPlaced(sql.FieldNotIn(FieldChannelID, v...)) +} + +// ChannelIDGT applies the GT predicate on the "channel_id" field. +func ChannelIDGT(v snowflake.ID) predicate.RolePanelPlaced { + vc := uint64(v) + return predicate.RolePanelPlaced(sql.FieldGT(FieldChannelID, vc)) +} + +// ChannelIDGTE applies the GTE predicate on the "channel_id" field. +func ChannelIDGTE(v snowflake.ID) predicate.RolePanelPlaced { + vc := uint64(v) + return predicate.RolePanelPlaced(sql.FieldGTE(FieldChannelID, vc)) +} + +// ChannelIDLT applies the LT predicate on the "channel_id" field. +func ChannelIDLT(v snowflake.ID) predicate.RolePanelPlaced { + vc := uint64(v) + return predicate.RolePanelPlaced(sql.FieldLT(FieldChannelID, vc)) +} + +// ChannelIDLTE applies the LTE predicate on the "channel_id" field. +func ChannelIDLTE(v snowflake.ID) predicate.RolePanelPlaced { + vc := uint64(v) + return predicate.RolePanelPlaced(sql.FieldLTE(FieldChannelID, vc)) +} + +// TypeEQ applies the EQ predicate on the "type" field. +func TypeEQ(v Type) predicate.RolePanelPlaced { + return predicate.RolePanelPlaced(sql.FieldEQ(FieldType, v)) +} + +// TypeNEQ applies the NEQ predicate on the "type" field. +func TypeNEQ(v Type) predicate.RolePanelPlaced { + return predicate.RolePanelPlaced(sql.FieldNEQ(FieldType, v)) +} + +// TypeIn applies the In predicate on the "type" field. +func TypeIn(vs ...Type) predicate.RolePanelPlaced { + return predicate.RolePanelPlaced(sql.FieldIn(FieldType, vs...)) +} + +// TypeNotIn applies the NotIn predicate on the "type" field. +func TypeNotIn(vs ...Type) predicate.RolePanelPlaced { + return predicate.RolePanelPlaced(sql.FieldNotIn(FieldType, vs...)) +} + +// TypeIsNil applies the IsNil predicate on the "type" field. +func TypeIsNil() predicate.RolePanelPlaced { + return predicate.RolePanelPlaced(sql.FieldIsNull(FieldType)) +} + +// TypeNotNil applies the NotNil predicate on the "type" field. +func TypeNotNil() predicate.RolePanelPlaced { + return predicate.RolePanelPlaced(sql.FieldNotNull(FieldType)) +} + +// ButtonTypeEQ applies the EQ predicate on the "button_type" field. +func ButtonTypeEQ(v discord.ButtonStyle) predicate.RolePanelPlaced { + vc := int(v) + return predicate.RolePanelPlaced(sql.FieldEQ(FieldButtonType, vc)) +} + +// ButtonTypeNEQ applies the NEQ predicate on the "button_type" field. +func ButtonTypeNEQ(v discord.ButtonStyle) predicate.RolePanelPlaced { + vc := int(v) + return predicate.RolePanelPlaced(sql.FieldNEQ(FieldButtonType, vc)) +} + +// ButtonTypeIn applies the In predicate on the "button_type" field. +func ButtonTypeIn(vs ...discord.ButtonStyle) predicate.RolePanelPlaced { + v := make([]any, len(vs)) + for i := range v { + v[i] = int(vs[i]) + } + return predicate.RolePanelPlaced(sql.FieldIn(FieldButtonType, v...)) +} + +// ButtonTypeNotIn applies the NotIn predicate on the "button_type" field. +func ButtonTypeNotIn(vs ...discord.ButtonStyle) predicate.RolePanelPlaced { + v := make([]any, len(vs)) + for i := range v { + v[i] = int(vs[i]) + } + return predicate.RolePanelPlaced(sql.FieldNotIn(FieldButtonType, v...)) +} + +// ButtonTypeGT applies the GT predicate on the "button_type" field. +func ButtonTypeGT(v discord.ButtonStyle) predicate.RolePanelPlaced { + vc := int(v) + return predicate.RolePanelPlaced(sql.FieldGT(FieldButtonType, vc)) +} + +// ButtonTypeGTE applies the GTE predicate on the "button_type" field. +func ButtonTypeGTE(v discord.ButtonStyle) predicate.RolePanelPlaced { + vc := int(v) + return predicate.RolePanelPlaced(sql.FieldGTE(FieldButtonType, vc)) +} + +// ButtonTypeLT applies the LT predicate on the "button_type" field. +func ButtonTypeLT(v discord.ButtonStyle) predicate.RolePanelPlaced { + vc := int(v) + return predicate.RolePanelPlaced(sql.FieldLT(FieldButtonType, vc)) +} + +// ButtonTypeLTE applies the LTE predicate on the "button_type" field. +func ButtonTypeLTE(v discord.ButtonStyle) predicate.RolePanelPlaced { + vc := int(v) + return predicate.RolePanelPlaced(sql.FieldLTE(FieldButtonType, vc)) +} + +// ShowNameEQ applies the EQ predicate on the "show_name" field. +func ShowNameEQ(v bool) predicate.RolePanelPlaced { + return predicate.RolePanelPlaced(sql.FieldEQ(FieldShowName, v)) +} + +// ShowNameNEQ applies the NEQ predicate on the "show_name" field. +func ShowNameNEQ(v bool) predicate.RolePanelPlaced { + return predicate.RolePanelPlaced(sql.FieldNEQ(FieldShowName, v)) +} + +// FoldingSelectMenuEQ applies the EQ predicate on the "folding_select_menu" field. +func FoldingSelectMenuEQ(v bool) predicate.RolePanelPlaced { + return predicate.RolePanelPlaced(sql.FieldEQ(FieldFoldingSelectMenu, v)) +} + +// FoldingSelectMenuNEQ applies the NEQ predicate on the "folding_select_menu" field. +func FoldingSelectMenuNEQ(v bool) predicate.RolePanelPlaced { + return predicate.RolePanelPlaced(sql.FieldNEQ(FieldFoldingSelectMenu, v)) +} + +// HideNoticeEQ applies the EQ predicate on the "hide_notice" field. +func HideNoticeEQ(v bool) predicate.RolePanelPlaced { + return predicate.RolePanelPlaced(sql.FieldEQ(FieldHideNotice, v)) +} + +// HideNoticeNEQ applies the NEQ predicate on the "hide_notice" field. +func HideNoticeNEQ(v bool) predicate.RolePanelPlaced { + return predicate.RolePanelPlaced(sql.FieldNEQ(FieldHideNotice, v)) +} + +// UseDisplayNameEQ applies the EQ predicate on the "use_display_name" field. +func UseDisplayNameEQ(v bool) predicate.RolePanelPlaced { + return predicate.RolePanelPlaced(sql.FieldEQ(FieldUseDisplayName, v)) +} + +// UseDisplayNameNEQ applies the NEQ predicate on the "use_display_name" field. +func UseDisplayNameNEQ(v bool) predicate.RolePanelPlaced { + return predicate.RolePanelPlaced(sql.FieldNEQ(FieldUseDisplayName, v)) +} + +// CreatedAtEQ applies the EQ predicate on the "created_at" field. +func CreatedAtEQ(v time.Time) predicate.RolePanelPlaced { + return predicate.RolePanelPlaced(sql.FieldEQ(FieldCreatedAt, v)) +} + +// CreatedAtNEQ applies the NEQ predicate on the "created_at" field. +func CreatedAtNEQ(v time.Time) predicate.RolePanelPlaced { + return predicate.RolePanelPlaced(sql.FieldNEQ(FieldCreatedAt, v)) +} + +// CreatedAtIn applies the In predicate on the "created_at" field. +func CreatedAtIn(vs ...time.Time) predicate.RolePanelPlaced { + return predicate.RolePanelPlaced(sql.FieldIn(FieldCreatedAt, vs...)) +} + +// CreatedAtNotIn applies the NotIn predicate on the "created_at" field. +func CreatedAtNotIn(vs ...time.Time) predicate.RolePanelPlaced { + return predicate.RolePanelPlaced(sql.FieldNotIn(FieldCreatedAt, vs...)) +} + +// CreatedAtGT applies the GT predicate on the "created_at" field. +func CreatedAtGT(v time.Time) predicate.RolePanelPlaced { + return predicate.RolePanelPlaced(sql.FieldGT(FieldCreatedAt, v)) +} + +// CreatedAtGTE applies the GTE predicate on the "created_at" field. +func CreatedAtGTE(v time.Time) predicate.RolePanelPlaced { + return predicate.RolePanelPlaced(sql.FieldGTE(FieldCreatedAt, v)) +} + +// CreatedAtLT applies the LT predicate on the "created_at" field. +func CreatedAtLT(v time.Time) predicate.RolePanelPlaced { + return predicate.RolePanelPlaced(sql.FieldLT(FieldCreatedAt, v)) +} + +// CreatedAtLTE applies the LTE predicate on the "created_at" field. +func CreatedAtLTE(v time.Time) predicate.RolePanelPlaced { + return predicate.RolePanelPlaced(sql.FieldLTE(FieldCreatedAt, v)) +} + +// UsesEQ applies the EQ predicate on the "uses" field. +func UsesEQ(v int) predicate.RolePanelPlaced { + return predicate.RolePanelPlaced(sql.FieldEQ(FieldUses, v)) +} + +// UsesNEQ applies the NEQ predicate on the "uses" field. +func UsesNEQ(v int) predicate.RolePanelPlaced { + return predicate.RolePanelPlaced(sql.FieldNEQ(FieldUses, v)) +} + +// UsesIn applies the In predicate on the "uses" field. +func UsesIn(vs ...int) predicate.RolePanelPlaced { + return predicate.RolePanelPlaced(sql.FieldIn(FieldUses, vs...)) +} + +// UsesNotIn applies the NotIn predicate on the "uses" field. +func UsesNotIn(vs ...int) predicate.RolePanelPlaced { + return predicate.RolePanelPlaced(sql.FieldNotIn(FieldUses, vs...)) +} + +// UsesGT applies the GT predicate on the "uses" field. +func UsesGT(v int) predicate.RolePanelPlaced { + return predicate.RolePanelPlaced(sql.FieldGT(FieldUses, v)) +} + +// UsesGTE applies the GTE predicate on the "uses" field. +func UsesGTE(v int) predicate.RolePanelPlaced { + return predicate.RolePanelPlaced(sql.FieldGTE(FieldUses, v)) +} + +// UsesLT applies the LT predicate on the "uses" field. +func UsesLT(v int) predicate.RolePanelPlaced { + return predicate.RolePanelPlaced(sql.FieldLT(FieldUses, v)) +} + +// UsesLTE applies the LTE predicate on the "uses" field. +func UsesLTE(v int) predicate.RolePanelPlaced { + return predicate.RolePanelPlaced(sql.FieldLTE(FieldUses, v)) +} + +// NameEQ applies the EQ predicate on the "name" field. +func NameEQ(v string) predicate.RolePanelPlaced { + return predicate.RolePanelPlaced(sql.FieldEQ(FieldName, v)) +} + +// NameNEQ applies the NEQ predicate on the "name" field. +func NameNEQ(v string) predicate.RolePanelPlaced { + return predicate.RolePanelPlaced(sql.FieldNEQ(FieldName, v)) +} + +// NameIn applies the In predicate on the "name" field. +func NameIn(vs ...string) predicate.RolePanelPlaced { + return predicate.RolePanelPlaced(sql.FieldIn(FieldName, vs...)) +} + +// NameNotIn applies the NotIn predicate on the "name" field. +func NameNotIn(vs ...string) predicate.RolePanelPlaced { + return predicate.RolePanelPlaced(sql.FieldNotIn(FieldName, vs...)) +} + +// NameGT applies the GT predicate on the "name" field. +func NameGT(v string) predicate.RolePanelPlaced { + return predicate.RolePanelPlaced(sql.FieldGT(FieldName, v)) +} + +// NameGTE applies the GTE predicate on the "name" field. +func NameGTE(v string) predicate.RolePanelPlaced { + return predicate.RolePanelPlaced(sql.FieldGTE(FieldName, v)) +} + +// NameLT applies the LT predicate on the "name" field. +func NameLT(v string) predicate.RolePanelPlaced { + return predicate.RolePanelPlaced(sql.FieldLT(FieldName, v)) +} + +// NameLTE applies the LTE predicate on the "name" field. +func NameLTE(v string) predicate.RolePanelPlaced { + return predicate.RolePanelPlaced(sql.FieldLTE(FieldName, v)) +} + +// NameContains applies the Contains predicate on the "name" field. +func NameContains(v string) predicate.RolePanelPlaced { + return predicate.RolePanelPlaced(sql.FieldContains(FieldName, v)) +} + +// NameHasPrefix applies the HasPrefix predicate on the "name" field. +func NameHasPrefix(v string) predicate.RolePanelPlaced { + return predicate.RolePanelPlaced(sql.FieldHasPrefix(FieldName, v)) +} + +// NameHasSuffix applies the HasSuffix predicate on the "name" field. +func NameHasSuffix(v string) predicate.RolePanelPlaced { + return predicate.RolePanelPlaced(sql.FieldHasSuffix(FieldName, v)) +} + +// NameEqualFold applies the EqualFold predicate on the "name" field. +func NameEqualFold(v string) predicate.RolePanelPlaced { + return predicate.RolePanelPlaced(sql.FieldEqualFold(FieldName, v)) +} + +// NameContainsFold applies the ContainsFold predicate on the "name" field. +func NameContainsFold(v string) predicate.RolePanelPlaced { + return predicate.RolePanelPlaced(sql.FieldContainsFold(FieldName, v)) +} + +// DescriptionEQ applies the EQ predicate on the "description" field. +func DescriptionEQ(v string) predicate.RolePanelPlaced { + return predicate.RolePanelPlaced(sql.FieldEQ(FieldDescription, v)) +} + +// DescriptionNEQ applies the NEQ predicate on the "description" field. +func DescriptionNEQ(v string) predicate.RolePanelPlaced { + return predicate.RolePanelPlaced(sql.FieldNEQ(FieldDescription, v)) +} + +// DescriptionIn applies the In predicate on the "description" field. +func DescriptionIn(vs ...string) predicate.RolePanelPlaced { + return predicate.RolePanelPlaced(sql.FieldIn(FieldDescription, vs...)) +} + +// DescriptionNotIn applies the NotIn predicate on the "description" field. +func DescriptionNotIn(vs ...string) predicate.RolePanelPlaced { + return predicate.RolePanelPlaced(sql.FieldNotIn(FieldDescription, vs...)) +} + +// DescriptionGT applies the GT predicate on the "description" field. +func DescriptionGT(v string) predicate.RolePanelPlaced { + return predicate.RolePanelPlaced(sql.FieldGT(FieldDescription, v)) +} + +// DescriptionGTE applies the GTE predicate on the "description" field. +func DescriptionGTE(v string) predicate.RolePanelPlaced { + return predicate.RolePanelPlaced(sql.FieldGTE(FieldDescription, v)) +} + +// DescriptionLT applies the LT predicate on the "description" field. +func DescriptionLT(v string) predicate.RolePanelPlaced { + return predicate.RolePanelPlaced(sql.FieldLT(FieldDescription, v)) +} + +// DescriptionLTE applies the LTE predicate on the "description" field. +func DescriptionLTE(v string) predicate.RolePanelPlaced { + return predicate.RolePanelPlaced(sql.FieldLTE(FieldDescription, v)) +} + +// DescriptionContains applies the Contains predicate on the "description" field. +func DescriptionContains(v string) predicate.RolePanelPlaced { + return predicate.RolePanelPlaced(sql.FieldContains(FieldDescription, v)) +} + +// DescriptionHasPrefix applies the HasPrefix predicate on the "description" field. +func DescriptionHasPrefix(v string) predicate.RolePanelPlaced { + return predicate.RolePanelPlaced(sql.FieldHasPrefix(FieldDescription, v)) +} + +// DescriptionHasSuffix applies the HasSuffix predicate on the "description" field. +func DescriptionHasSuffix(v string) predicate.RolePanelPlaced { + return predicate.RolePanelPlaced(sql.FieldHasSuffix(FieldDescription, v)) +} + +// DescriptionEqualFold applies the EqualFold predicate on the "description" field. +func DescriptionEqualFold(v string) predicate.RolePanelPlaced { + return predicate.RolePanelPlaced(sql.FieldEqualFold(FieldDescription, v)) +} + +// DescriptionContainsFold applies the ContainsFold predicate on the "description" field. +func DescriptionContainsFold(v string) predicate.RolePanelPlaced { + return predicate.RolePanelPlaced(sql.FieldContainsFold(FieldDescription, v)) +} + +// RolesIsNil applies the IsNil predicate on the "roles" field. +func RolesIsNil() predicate.RolePanelPlaced { + return predicate.RolePanelPlaced(sql.FieldIsNull(FieldRoles)) +} + +// RolesNotNil applies the NotNil predicate on the "roles" field. +func RolesNotNil() predicate.RolePanelPlaced { + return predicate.RolePanelPlaced(sql.FieldNotNull(FieldRoles)) +} + +// UpdatedAtEQ applies the EQ predicate on the "updated_at" field. +func UpdatedAtEQ(v time.Time) predicate.RolePanelPlaced { + return predicate.RolePanelPlaced(sql.FieldEQ(FieldUpdatedAt, v)) +} + +// UpdatedAtNEQ applies the NEQ predicate on the "updated_at" field. +func UpdatedAtNEQ(v time.Time) predicate.RolePanelPlaced { + return predicate.RolePanelPlaced(sql.FieldNEQ(FieldUpdatedAt, v)) +} + +// UpdatedAtIn applies the In predicate on the "updated_at" field. +func UpdatedAtIn(vs ...time.Time) predicate.RolePanelPlaced { + return predicate.RolePanelPlaced(sql.FieldIn(FieldUpdatedAt, vs...)) +} + +// UpdatedAtNotIn applies the NotIn predicate on the "updated_at" field. +func UpdatedAtNotIn(vs ...time.Time) predicate.RolePanelPlaced { + return predicate.RolePanelPlaced(sql.FieldNotIn(FieldUpdatedAt, vs...)) +} + +// UpdatedAtGT applies the GT predicate on the "updated_at" field. +func UpdatedAtGT(v time.Time) predicate.RolePanelPlaced { + return predicate.RolePanelPlaced(sql.FieldGT(FieldUpdatedAt, v)) +} + +// UpdatedAtGTE applies the GTE predicate on the "updated_at" field. +func UpdatedAtGTE(v time.Time) predicate.RolePanelPlaced { + return predicate.RolePanelPlaced(sql.FieldGTE(FieldUpdatedAt, v)) +} + +// UpdatedAtLT applies the LT predicate on the "updated_at" field. +func UpdatedAtLT(v time.Time) predicate.RolePanelPlaced { + return predicate.RolePanelPlaced(sql.FieldLT(FieldUpdatedAt, v)) +} + +// UpdatedAtLTE applies the LTE predicate on the "updated_at" field. +func UpdatedAtLTE(v time.Time) predicate.RolePanelPlaced { + return predicate.RolePanelPlaced(sql.FieldLTE(FieldUpdatedAt, v)) +} + +// UpdatedAtIsNil applies the IsNil predicate on the "updated_at" field. +func UpdatedAtIsNil() predicate.RolePanelPlaced { + return predicate.RolePanelPlaced(sql.FieldIsNull(FieldUpdatedAt)) +} + +// UpdatedAtNotNil applies the NotNil predicate on the "updated_at" field. +func UpdatedAtNotNil() predicate.RolePanelPlaced { + return predicate.RolePanelPlaced(sql.FieldNotNull(FieldUpdatedAt)) +} + +// HasGuild applies the HasEdge predicate on the "guild" edge. +func HasGuild() predicate.RolePanelPlaced { + return predicate.RolePanelPlaced(func(s *sql.Selector) { + step := sqlgraph.NewStep( + sqlgraph.From(Table, FieldID), + sqlgraph.Edge(sqlgraph.M2O, true, GuildTable, GuildColumn), + ) + sqlgraph.HasNeighbors(s, step) + }) +} + +// HasGuildWith applies the HasEdge predicate on the "guild" edge with a given conditions (other predicates). +func HasGuildWith(preds ...predicate.Guild) predicate.RolePanelPlaced { + return predicate.RolePanelPlaced(func(s *sql.Selector) { + step := newGuildStep() + sqlgraph.HasNeighborsWith(s, step, func(s *sql.Selector) { + for _, p := range preds { + p(s) + } + }) + }) +} + +// HasRolePanel applies the HasEdge predicate on the "role_panel" edge. +func HasRolePanel() predicate.RolePanelPlaced { + return predicate.RolePanelPlaced(func(s *sql.Selector) { + step := sqlgraph.NewStep( + sqlgraph.From(Table, FieldID), + sqlgraph.Edge(sqlgraph.M2O, true, RolePanelTable, RolePanelColumn), + ) + sqlgraph.HasNeighbors(s, step) + }) +} + +// HasRolePanelWith applies the HasEdge predicate on the "role_panel" edge with a given conditions (other predicates). +func HasRolePanelWith(preds ...predicate.RolePanel) predicate.RolePanelPlaced { + return predicate.RolePanelPlaced(func(s *sql.Selector) { + step := newRolePanelStep() + sqlgraph.HasNeighborsWith(s, step, func(s *sql.Selector) { + for _, p := range preds { + p(s) + } + }) + }) +} + +// And groups predicates with the AND operator between them. +func And(predicates ...predicate.RolePanelPlaced) predicate.RolePanelPlaced { + return predicate.RolePanelPlaced(sql.AndPredicates(predicates...)) +} + +// Or groups predicates with the OR operator between them. +func Or(predicates ...predicate.RolePanelPlaced) predicate.RolePanelPlaced { + return predicate.RolePanelPlaced(sql.OrPredicates(predicates...)) +} + +// Not applies the not operator on the given predicate. +func Not(p predicate.RolePanelPlaced) predicate.RolePanelPlaced { + return predicate.RolePanelPlaced(sql.NotPredicates(p)) +} diff --git a/ent/rolepanelplaced_create.go b/ent/rolepanelplaced_create.go new file mode 100644 index 00000000..71430bf5 --- /dev/null +++ b/ent/rolepanelplaced_create.go @@ -0,0 +1,561 @@ +// Code generated by ent, DO NOT EDIT. + +package ent + +import ( + "context" + "errors" + "fmt" + "time" + + "entgo.io/ent/dialect/sql/sqlgraph" + "entgo.io/ent/schema/field" + "github.com/disgoorg/disgo/discord" + snowflake "github.com/disgoorg/snowflake/v2" + "github.com/google/uuid" + "github.com/sabafly/gobot/ent/guild" + "github.com/sabafly/gobot/ent/rolepanel" + "github.com/sabafly/gobot/ent/rolepanelplaced" + "github.com/sabafly/gobot/ent/schema" +) + +// RolePanelPlacedCreate is the builder for creating a RolePanelPlaced entity. +type RolePanelPlacedCreate struct { + config + mutation *RolePanelPlacedMutation + hooks []Hook +} + +// SetMessageID sets the "message_id" field. +func (rppc *RolePanelPlacedCreate) SetMessageID(s snowflake.ID) *RolePanelPlacedCreate { + rppc.mutation.SetMessageID(s) + return rppc +} + +// SetNillableMessageID sets the "message_id" field if the given value is not nil. +func (rppc *RolePanelPlacedCreate) SetNillableMessageID(s *snowflake.ID) *RolePanelPlacedCreate { + if s != nil { + rppc.SetMessageID(*s) + } + return rppc +} + +// SetChannelID sets the "channel_id" field. +func (rppc *RolePanelPlacedCreate) SetChannelID(s snowflake.ID) *RolePanelPlacedCreate { + rppc.mutation.SetChannelID(s) + return rppc +} + +// SetType sets the "type" field. +func (rppc *RolePanelPlacedCreate) SetType(r rolepanelplaced.Type) *RolePanelPlacedCreate { + rppc.mutation.SetType(r) + return rppc +} + +// SetNillableType sets the "type" field if the given value is not nil. +func (rppc *RolePanelPlacedCreate) SetNillableType(r *rolepanelplaced.Type) *RolePanelPlacedCreate { + if r != nil { + rppc.SetType(*r) + } + return rppc +} + +// SetButtonType sets the "button_type" field. +func (rppc *RolePanelPlacedCreate) SetButtonType(ds discord.ButtonStyle) *RolePanelPlacedCreate { + rppc.mutation.SetButtonType(ds) + return rppc +} + +// SetNillableButtonType sets the "button_type" field if the given value is not nil. +func (rppc *RolePanelPlacedCreate) SetNillableButtonType(ds *discord.ButtonStyle) *RolePanelPlacedCreate { + if ds != nil { + rppc.SetButtonType(*ds) + } + return rppc +} + +// SetShowName sets the "show_name" field. +func (rppc *RolePanelPlacedCreate) SetShowName(b bool) *RolePanelPlacedCreate { + rppc.mutation.SetShowName(b) + return rppc +} + +// SetNillableShowName sets the "show_name" field if the given value is not nil. +func (rppc *RolePanelPlacedCreate) SetNillableShowName(b *bool) *RolePanelPlacedCreate { + if b != nil { + rppc.SetShowName(*b) + } + return rppc +} + +// SetFoldingSelectMenu sets the "folding_select_menu" field. +func (rppc *RolePanelPlacedCreate) SetFoldingSelectMenu(b bool) *RolePanelPlacedCreate { + rppc.mutation.SetFoldingSelectMenu(b) + return rppc +} + +// SetNillableFoldingSelectMenu sets the "folding_select_menu" field if the given value is not nil. +func (rppc *RolePanelPlacedCreate) SetNillableFoldingSelectMenu(b *bool) *RolePanelPlacedCreate { + if b != nil { + rppc.SetFoldingSelectMenu(*b) + } + return rppc +} + +// SetHideNotice sets the "hide_notice" field. +func (rppc *RolePanelPlacedCreate) SetHideNotice(b bool) *RolePanelPlacedCreate { + rppc.mutation.SetHideNotice(b) + return rppc +} + +// SetNillableHideNotice sets the "hide_notice" field if the given value is not nil. +func (rppc *RolePanelPlacedCreate) SetNillableHideNotice(b *bool) *RolePanelPlacedCreate { + if b != nil { + rppc.SetHideNotice(*b) + } + return rppc +} + +// SetUseDisplayName sets the "use_display_name" field. +func (rppc *RolePanelPlacedCreate) SetUseDisplayName(b bool) *RolePanelPlacedCreate { + rppc.mutation.SetUseDisplayName(b) + return rppc +} + +// SetNillableUseDisplayName sets the "use_display_name" field if the given value is not nil. +func (rppc *RolePanelPlacedCreate) SetNillableUseDisplayName(b *bool) *RolePanelPlacedCreate { + if b != nil { + rppc.SetUseDisplayName(*b) + } + return rppc +} + +// SetCreatedAt sets the "created_at" field. +func (rppc *RolePanelPlacedCreate) SetCreatedAt(t time.Time) *RolePanelPlacedCreate { + rppc.mutation.SetCreatedAt(t) + return rppc +} + +// SetNillableCreatedAt sets the "created_at" field if the given value is not nil. +func (rppc *RolePanelPlacedCreate) SetNillableCreatedAt(t *time.Time) *RolePanelPlacedCreate { + if t != nil { + rppc.SetCreatedAt(*t) + } + return rppc +} + +// SetUses sets the "uses" field. +func (rppc *RolePanelPlacedCreate) SetUses(i int) *RolePanelPlacedCreate { + rppc.mutation.SetUses(i) + return rppc +} + +// SetNillableUses sets the "uses" field if the given value is not nil. +func (rppc *RolePanelPlacedCreate) SetNillableUses(i *int) *RolePanelPlacedCreate { + if i != nil { + rppc.SetUses(*i) + } + return rppc +} + +// SetName sets the "name" field. +func (rppc *RolePanelPlacedCreate) SetName(s string) *RolePanelPlacedCreate { + rppc.mutation.SetName(s) + return rppc +} + +// SetDescription sets the "description" field. +func (rppc *RolePanelPlacedCreate) SetDescription(s string) *RolePanelPlacedCreate { + rppc.mutation.SetDescription(s) + return rppc +} + +// SetRoles sets the "roles" field. +func (rppc *RolePanelPlacedCreate) SetRoles(s []schema.Role) *RolePanelPlacedCreate { + rppc.mutation.SetRoles(s) + return rppc +} + +// SetUpdatedAt sets the "updated_at" field. +func (rppc *RolePanelPlacedCreate) SetUpdatedAt(t time.Time) *RolePanelPlacedCreate { + rppc.mutation.SetUpdatedAt(t) + return rppc +} + +// SetNillableUpdatedAt sets the "updated_at" field if the given value is not nil. +func (rppc *RolePanelPlacedCreate) SetNillableUpdatedAt(t *time.Time) *RolePanelPlacedCreate { + if t != nil { + rppc.SetUpdatedAt(*t) + } + return rppc +} + +// SetID sets the "id" field. +func (rppc *RolePanelPlacedCreate) SetID(u uuid.UUID) *RolePanelPlacedCreate { + rppc.mutation.SetID(u) + return rppc +} + +// SetNillableID sets the "id" field if the given value is not nil. +func (rppc *RolePanelPlacedCreate) SetNillableID(u *uuid.UUID) *RolePanelPlacedCreate { + if u != nil { + rppc.SetID(*u) + } + return rppc +} + +// SetGuildID sets the "guild" edge to the Guild entity by ID. +func (rppc *RolePanelPlacedCreate) SetGuildID(id snowflake.ID) *RolePanelPlacedCreate { + rppc.mutation.SetGuildID(id) + return rppc +} + +// SetGuild sets the "guild" edge to the Guild entity. +func (rppc *RolePanelPlacedCreate) SetGuild(g *Guild) *RolePanelPlacedCreate { + return rppc.SetGuildID(g.ID) +} + +// SetRolePanelID sets the "role_panel" edge to the RolePanel entity by ID. +func (rppc *RolePanelPlacedCreate) SetRolePanelID(id uuid.UUID) *RolePanelPlacedCreate { + rppc.mutation.SetRolePanelID(id) + return rppc +} + +// SetRolePanel sets the "role_panel" edge to the RolePanel entity. +func (rppc *RolePanelPlacedCreate) SetRolePanel(r *RolePanel) *RolePanelPlacedCreate { + return rppc.SetRolePanelID(r.ID) +} + +// Mutation returns the RolePanelPlacedMutation object of the builder. +func (rppc *RolePanelPlacedCreate) Mutation() *RolePanelPlacedMutation { + return rppc.mutation +} + +// Save creates the RolePanelPlaced in the database. +func (rppc *RolePanelPlacedCreate) Save(ctx context.Context) (*RolePanelPlaced, error) { + rppc.defaults() + return withHooks(ctx, rppc.sqlSave, rppc.mutation, rppc.hooks) +} + +// SaveX calls Save and panics if Save returns an error. +func (rppc *RolePanelPlacedCreate) SaveX(ctx context.Context) *RolePanelPlaced { + v, err := rppc.Save(ctx) + if err != nil { + panic(err) + } + return v +} + +// Exec executes the query. +func (rppc *RolePanelPlacedCreate) Exec(ctx context.Context) error { + _, err := rppc.Save(ctx) + return err +} + +// ExecX is like Exec, but panics if an error occurs. +func (rppc *RolePanelPlacedCreate) ExecX(ctx context.Context) { + if err := rppc.Exec(ctx); err != nil { + panic(err) + } +} + +// defaults sets the default values of the builder before save. +func (rppc *RolePanelPlacedCreate) defaults() { + if _, ok := rppc.mutation.ButtonType(); !ok { + v := rolepanelplaced.DefaultButtonType + rppc.mutation.SetButtonType(v) + } + if _, ok := rppc.mutation.ShowName(); !ok { + v := rolepanelplaced.DefaultShowName + rppc.mutation.SetShowName(v) + } + if _, ok := rppc.mutation.FoldingSelectMenu(); !ok { + v := rolepanelplaced.DefaultFoldingSelectMenu + rppc.mutation.SetFoldingSelectMenu(v) + } + if _, ok := rppc.mutation.HideNotice(); !ok { + v := rolepanelplaced.DefaultHideNotice + rppc.mutation.SetHideNotice(v) + } + if _, ok := rppc.mutation.UseDisplayName(); !ok { + v := rolepanelplaced.DefaultUseDisplayName + rppc.mutation.SetUseDisplayName(v) + } + if _, ok := rppc.mutation.CreatedAt(); !ok { + v := rolepanelplaced.DefaultCreatedAt() + rppc.mutation.SetCreatedAt(v) + } + if _, ok := rppc.mutation.Uses(); !ok { + v := rolepanelplaced.DefaultUses + rppc.mutation.SetUses(v) + } + if _, ok := rppc.mutation.ID(); !ok { + v := rolepanelplaced.DefaultID() + rppc.mutation.SetID(v) + } +} + +// check runs all checks and user-defined validators on the builder. +func (rppc *RolePanelPlacedCreate) check() error { + if _, ok := rppc.mutation.ChannelID(); !ok { + return &ValidationError{Name: "channel_id", err: errors.New(`ent: missing required field "RolePanelPlaced.channel_id"`)} + } + if v, ok := rppc.mutation.GetType(); ok { + if err := rolepanelplaced.TypeValidator(v); err != nil { + return &ValidationError{Name: "type", err: fmt.Errorf(`ent: validator failed for field "RolePanelPlaced.type": %w`, err)} + } + } + if _, ok := rppc.mutation.ButtonType(); !ok { + return &ValidationError{Name: "button_type", err: errors.New(`ent: missing required field "RolePanelPlaced.button_type"`)} + } + if v, ok := rppc.mutation.ButtonType(); ok { + if err := rolepanelplaced.ButtonTypeValidator(int(v)); err != nil { + return &ValidationError{Name: "button_type", err: fmt.Errorf(`ent: validator failed for field "RolePanelPlaced.button_type": %w`, err)} + } + } + if _, ok := rppc.mutation.ShowName(); !ok { + return &ValidationError{Name: "show_name", err: errors.New(`ent: missing required field "RolePanelPlaced.show_name"`)} + } + if _, ok := rppc.mutation.FoldingSelectMenu(); !ok { + return &ValidationError{Name: "folding_select_menu", err: errors.New(`ent: missing required field "RolePanelPlaced.folding_select_menu"`)} + } + if _, ok := rppc.mutation.HideNotice(); !ok { + return &ValidationError{Name: "hide_notice", err: errors.New(`ent: missing required field "RolePanelPlaced.hide_notice"`)} + } + if _, ok := rppc.mutation.UseDisplayName(); !ok { + return &ValidationError{Name: "use_display_name", err: errors.New(`ent: missing required field "RolePanelPlaced.use_display_name"`)} + } + if _, ok := rppc.mutation.CreatedAt(); !ok { + return &ValidationError{Name: "created_at", err: errors.New(`ent: missing required field "RolePanelPlaced.created_at"`)} + } + if _, ok := rppc.mutation.Uses(); !ok { + return &ValidationError{Name: "uses", err: errors.New(`ent: missing required field "RolePanelPlaced.uses"`)} + } + if _, ok := rppc.mutation.Name(); !ok { + return &ValidationError{Name: "name", err: errors.New(`ent: missing required field "RolePanelPlaced.name"`)} + } + if v, ok := rppc.mutation.Name(); ok { + if err := rolepanelplaced.NameValidator(v); err != nil { + return &ValidationError{Name: "name", err: fmt.Errorf(`ent: validator failed for field "RolePanelPlaced.name": %w`, err)} + } + } + if _, ok := rppc.mutation.Description(); !ok { + return &ValidationError{Name: "description", err: errors.New(`ent: missing required field "RolePanelPlaced.description"`)} + } + if _, ok := rppc.mutation.GuildID(); !ok { + return &ValidationError{Name: "guild", err: errors.New(`ent: missing required edge "RolePanelPlaced.guild"`)} + } + if _, ok := rppc.mutation.RolePanelID(); !ok { + return &ValidationError{Name: "role_panel", err: errors.New(`ent: missing required edge "RolePanelPlaced.role_panel"`)} + } + return nil +} + +func (rppc *RolePanelPlacedCreate) sqlSave(ctx context.Context) (*RolePanelPlaced, error) { + if err := rppc.check(); err != nil { + return nil, err + } + _node, _spec := rppc.createSpec() + if err := sqlgraph.CreateNode(ctx, rppc.driver, _spec); err != nil { + if sqlgraph.IsConstraintError(err) { + err = &ConstraintError{msg: err.Error(), wrap: err} + } + return nil, err + } + if _spec.ID.Value != nil { + if id, ok := _spec.ID.Value.(*uuid.UUID); ok { + _node.ID = *id + } else if err := _node.ID.Scan(_spec.ID.Value); err != nil { + return nil, err + } + } + rppc.mutation.id = &_node.ID + rppc.mutation.done = true + return _node, nil +} + +func (rppc *RolePanelPlacedCreate) createSpec() (*RolePanelPlaced, *sqlgraph.CreateSpec) { + var ( + _node = &RolePanelPlaced{config: rppc.config} + _spec = sqlgraph.NewCreateSpec(rolepanelplaced.Table, sqlgraph.NewFieldSpec(rolepanelplaced.FieldID, field.TypeUUID)) + ) + if id, ok := rppc.mutation.ID(); ok { + _node.ID = id + _spec.ID.Value = &id + } + if value, ok := rppc.mutation.MessageID(); ok { + _spec.SetField(rolepanelplaced.FieldMessageID, field.TypeUint64, value) + _node.MessageID = &value + } + if value, ok := rppc.mutation.ChannelID(); ok { + _spec.SetField(rolepanelplaced.FieldChannelID, field.TypeUint64, value) + _node.ChannelID = value + } + if value, ok := rppc.mutation.GetType(); ok { + _spec.SetField(rolepanelplaced.FieldType, field.TypeEnum, value) + _node.Type = value + } + if value, ok := rppc.mutation.ButtonType(); ok { + _spec.SetField(rolepanelplaced.FieldButtonType, field.TypeInt, value) + _node.ButtonType = value + } + if value, ok := rppc.mutation.ShowName(); ok { + _spec.SetField(rolepanelplaced.FieldShowName, field.TypeBool, value) + _node.ShowName = value + } + if value, ok := rppc.mutation.FoldingSelectMenu(); ok { + _spec.SetField(rolepanelplaced.FieldFoldingSelectMenu, field.TypeBool, value) + _node.FoldingSelectMenu = value + } + if value, ok := rppc.mutation.HideNotice(); ok { + _spec.SetField(rolepanelplaced.FieldHideNotice, field.TypeBool, value) + _node.HideNotice = value + } + if value, ok := rppc.mutation.UseDisplayName(); ok { + _spec.SetField(rolepanelplaced.FieldUseDisplayName, field.TypeBool, value) + _node.UseDisplayName = value + } + if value, ok := rppc.mutation.CreatedAt(); ok { + _spec.SetField(rolepanelplaced.FieldCreatedAt, field.TypeTime, value) + _node.CreatedAt = value + } + if value, ok := rppc.mutation.Uses(); ok { + _spec.SetField(rolepanelplaced.FieldUses, field.TypeInt, value) + _node.Uses = value + } + if value, ok := rppc.mutation.Name(); ok { + _spec.SetField(rolepanelplaced.FieldName, field.TypeString, value) + _node.Name = value + } + if value, ok := rppc.mutation.Description(); ok { + _spec.SetField(rolepanelplaced.FieldDescription, field.TypeString, value) + _node.Description = value + } + if value, ok := rppc.mutation.Roles(); ok { + _spec.SetField(rolepanelplaced.FieldRoles, field.TypeJSON, value) + _node.Roles = value + } + if value, ok := rppc.mutation.UpdatedAt(); ok { + _spec.SetField(rolepanelplaced.FieldUpdatedAt, field.TypeTime, value) + _node.UpdatedAt = value + } + if nodes := rppc.mutation.GuildIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.M2O, + Inverse: true, + Table: rolepanelplaced.GuildTable, + Columns: []string{rolepanelplaced.GuildColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(guild.FieldID, field.TypeUint64), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _node.guild_role_panel_placements = &nodes[0] + _spec.Edges = append(_spec.Edges, edge) + } + if nodes := rppc.mutation.RolePanelIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.M2O, + Inverse: true, + Table: rolepanelplaced.RolePanelTable, + Columns: []string{rolepanelplaced.RolePanelColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(rolepanel.FieldID, field.TypeUUID), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _node.role_panel_placements = &nodes[0] + _spec.Edges = append(_spec.Edges, edge) + } + return _node, _spec +} + +// RolePanelPlacedCreateBulk is the builder for creating many RolePanelPlaced entities in bulk. +type RolePanelPlacedCreateBulk struct { + config + err error + builders []*RolePanelPlacedCreate +} + +// Save creates the RolePanelPlaced entities in the database. +func (rppcb *RolePanelPlacedCreateBulk) Save(ctx context.Context) ([]*RolePanelPlaced, error) { + if rppcb.err != nil { + return nil, rppcb.err + } + specs := make([]*sqlgraph.CreateSpec, len(rppcb.builders)) + nodes := make([]*RolePanelPlaced, len(rppcb.builders)) + mutators := make([]Mutator, len(rppcb.builders)) + for i := range rppcb.builders { + func(i int, root context.Context) { + builder := rppcb.builders[i] + builder.defaults() + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*RolePanelPlacedMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + if err := builder.check(); err != nil { + return nil, err + } + builder.mutation = mutation + var err error + nodes[i], specs[i] = builder.createSpec() + if i < len(mutators)-1 { + _, err = mutators[i+1].Mutate(root, rppcb.builders[i+1].mutation) + } else { + spec := &sqlgraph.BatchCreateSpec{Nodes: specs} + // Invoke the actual operation on the latest mutation in the chain. + if err = sqlgraph.BatchCreate(ctx, rppcb.driver, spec); err != nil { + if sqlgraph.IsConstraintError(err) { + err = &ConstraintError{msg: err.Error(), wrap: err} + } + } + } + if err != nil { + return nil, err + } + mutation.id = &nodes[i].ID + mutation.done = true + return nodes[i], nil + }) + for i := len(builder.hooks) - 1; i >= 0; i-- { + mut = builder.hooks[i](mut) + } + mutators[i] = mut + }(i, ctx) + } + if len(mutators) > 0 { + if _, err := mutators[0].Mutate(ctx, rppcb.builders[0].mutation); err != nil { + return nil, err + } + } + return nodes, nil +} + +// SaveX is like Save, but panics if an error occurs. +func (rppcb *RolePanelPlacedCreateBulk) SaveX(ctx context.Context) []*RolePanelPlaced { + v, err := rppcb.Save(ctx) + if err != nil { + panic(err) + } + return v +} + +// Exec executes the query. +func (rppcb *RolePanelPlacedCreateBulk) Exec(ctx context.Context) error { + _, err := rppcb.Save(ctx) + return err +} + +// ExecX is like Exec, but panics if an error occurs. +func (rppcb *RolePanelPlacedCreateBulk) ExecX(ctx context.Context) { + if err := rppcb.Exec(ctx); err != nil { + panic(err) + } +} diff --git a/ent/rolepanelplaced_delete.go b/ent/rolepanelplaced_delete.go new file mode 100644 index 00000000..ec9059d1 --- /dev/null +++ b/ent/rolepanelplaced_delete.go @@ -0,0 +1,88 @@ +// Code generated by ent, DO NOT EDIT. + +package ent + +import ( + "context" + + "entgo.io/ent/dialect/sql" + "entgo.io/ent/dialect/sql/sqlgraph" + "entgo.io/ent/schema/field" + "github.com/sabafly/gobot/ent/predicate" + "github.com/sabafly/gobot/ent/rolepanelplaced" +) + +// RolePanelPlacedDelete is the builder for deleting a RolePanelPlaced entity. +type RolePanelPlacedDelete struct { + config + hooks []Hook + mutation *RolePanelPlacedMutation +} + +// Where appends a list predicates to the RolePanelPlacedDelete builder. +func (rppd *RolePanelPlacedDelete) Where(ps ...predicate.RolePanelPlaced) *RolePanelPlacedDelete { + rppd.mutation.Where(ps...) + return rppd +} + +// Exec executes the deletion query and returns how many vertices were deleted. +func (rppd *RolePanelPlacedDelete) Exec(ctx context.Context) (int, error) { + return withHooks(ctx, rppd.sqlExec, rppd.mutation, rppd.hooks) +} + +// ExecX is like Exec, but panics if an error occurs. +func (rppd *RolePanelPlacedDelete) ExecX(ctx context.Context) int { + n, err := rppd.Exec(ctx) + if err != nil { + panic(err) + } + return n +} + +func (rppd *RolePanelPlacedDelete) sqlExec(ctx context.Context) (int, error) { + _spec := sqlgraph.NewDeleteSpec(rolepanelplaced.Table, sqlgraph.NewFieldSpec(rolepanelplaced.FieldID, field.TypeUUID)) + if ps := rppd.mutation.predicates; len(ps) > 0 { + _spec.Predicate = func(selector *sql.Selector) { + for i := range ps { + ps[i](selector) + } + } + } + affected, err := sqlgraph.DeleteNodes(ctx, rppd.driver, _spec) + if err != nil && sqlgraph.IsConstraintError(err) { + err = &ConstraintError{msg: err.Error(), wrap: err} + } + rppd.mutation.done = true + return affected, err +} + +// RolePanelPlacedDeleteOne is the builder for deleting a single RolePanelPlaced entity. +type RolePanelPlacedDeleteOne struct { + rppd *RolePanelPlacedDelete +} + +// Where appends a list predicates to the RolePanelPlacedDelete builder. +func (rppdo *RolePanelPlacedDeleteOne) Where(ps ...predicate.RolePanelPlaced) *RolePanelPlacedDeleteOne { + rppdo.rppd.mutation.Where(ps...) + return rppdo +} + +// Exec executes the deletion query. +func (rppdo *RolePanelPlacedDeleteOne) Exec(ctx context.Context) error { + n, err := rppdo.rppd.Exec(ctx) + switch { + case err != nil: + return err + case n == 0: + return &NotFoundError{rolepanelplaced.Label} + default: + return nil + } +} + +// ExecX is like Exec, but panics if an error occurs. +func (rppdo *RolePanelPlacedDeleteOne) ExecX(ctx context.Context) { + if err := rppdo.Exec(ctx); err != nil { + panic(err) + } +} diff --git a/ent/rolepanelplaced_query.go b/ent/rolepanelplaced_query.go new file mode 100644 index 00000000..3807284b --- /dev/null +++ b/ent/rolepanelplaced_query.go @@ -0,0 +1,690 @@ +// Code generated by ent, DO NOT EDIT. + +package ent + +import ( + "context" + "fmt" + "math" + + "entgo.io/ent/dialect/sql" + "entgo.io/ent/dialect/sql/sqlgraph" + "entgo.io/ent/schema/field" + snowflake "github.com/disgoorg/snowflake/v2" + "github.com/google/uuid" + "github.com/sabafly/gobot/ent/guild" + "github.com/sabafly/gobot/ent/predicate" + "github.com/sabafly/gobot/ent/rolepanel" + "github.com/sabafly/gobot/ent/rolepanelplaced" +) + +// RolePanelPlacedQuery is the builder for querying RolePanelPlaced entities. +type RolePanelPlacedQuery struct { + config + ctx *QueryContext + order []rolepanelplaced.OrderOption + inters []Interceptor + predicates []predicate.RolePanelPlaced + withGuild *GuildQuery + withRolePanel *RolePanelQuery + withFKs bool + // intermediate query (i.e. traversal path). + sql *sql.Selector + path func(context.Context) (*sql.Selector, error) +} + +// Where adds a new predicate for the RolePanelPlacedQuery builder. +func (rppq *RolePanelPlacedQuery) Where(ps ...predicate.RolePanelPlaced) *RolePanelPlacedQuery { + rppq.predicates = append(rppq.predicates, ps...) + return rppq +} + +// Limit the number of records to be returned by this query. +func (rppq *RolePanelPlacedQuery) Limit(limit int) *RolePanelPlacedQuery { + rppq.ctx.Limit = &limit + return rppq +} + +// Offset to start from. +func (rppq *RolePanelPlacedQuery) Offset(offset int) *RolePanelPlacedQuery { + rppq.ctx.Offset = &offset + return rppq +} + +// Unique configures the query builder to filter duplicate records on query. +// By default, unique is set to true, and can be disabled using this method. +func (rppq *RolePanelPlacedQuery) Unique(unique bool) *RolePanelPlacedQuery { + rppq.ctx.Unique = &unique + return rppq +} + +// Order specifies how the records should be ordered. +func (rppq *RolePanelPlacedQuery) Order(o ...rolepanelplaced.OrderOption) *RolePanelPlacedQuery { + rppq.order = append(rppq.order, o...) + return rppq +} + +// QueryGuild chains the current query on the "guild" edge. +func (rppq *RolePanelPlacedQuery) QueryGuild() *GuildQuery { + query := (&GuildClient{config: rppq.config}).Query() + query.path = func(ctx context.Context) (fromU *sql.Selector, err error) { + if err := rppq.prepareQuery(ctx); err != nil { + return nil, err + } + selector := rppq.sqlQuery(ctx) + if err := selector.Err(); err != nil { + return nil, err + } + step := sqlgraph.NewStep( + sqlgraph.From(rolepanelplaced.Table, rolepanelplaced.FieldID, selector), + sqlgraph.To(guild.Table, guild.FieldID), + sqlgraph.Edge(sqlgraph.M2O, true, rolepanelplaced.GuildTable, rolepanelplaced.GuildColumn), + ) + fromU = sqlgraph.SetNeighbors(rppq.driver.Dialect(), step) + return fromU, nil + } + return query +} + +// QueryRolePanel chains the current query on the "role_panel" edge. +func (rppq *RolePanelPlacedQuery) QueryRolePanel() *RolePanelQuery { + query := (&RolePanelClient{config: rppq.config}).Query() + query.path = func(ctx context.Context) (fromU *sql.Selector, err error) { + if err := rppq.prepareQuery(ctx); err != nil { + return nil, err + } + selector := rppq.sqlQuery(ctx) + if err := selector.Err(); err != nil { + return nil, err + } + step := sqlgraph.NewStep( + sqlgraph.From(rolepanelplaced.Table, rolepanelplaced.FieldID, selector), + sqlgraph.To(rolepanel.Table, rolepanel.FieldID), + sqlgraph.Edge(sqlgraph.M2O, true, rolepanelplaced.RolePanelTable, rolepanelplaced.RolePanelColumn), + ) + fromU = sqlgraph.SetNeighbors(rppq.driver.Dialect(), step) + return fromU, nil + } + return query +} + +// First returns the first RolePanelPlaced entity from the query. +// Returns a *NotFoundError when no RolePanelPlaced was found. +func (rppq *RolePanelPlacedQuery) First(ctx context.Context) (*RolePanelPlaced, error) { + nodes, err := rppq.Limit(1).All(setContextOp(ctx, rppq.ctx, "First")) + if err != nil { + return nil, err + } + if len(nodes) == 0 { + return nil, &NotFoundError{rolepanelplaced.Label} + } + return nodes[0], nil +} + +// FirstX is like First, but panics if an error occurs. +func (rppq *RolePanelPlacedQuery) FirstX(ctx context.Context) *RolePanelPlaced { + node, err := rppq.First(ctx) + if err != nil && !IsNotFound(err) { + panic(err) + } + return node +} + +// FirstID returns the first RolePanelPlaced ID from the query. +// Returns a *NotFoundError when no RolePanelPlaced ID was found. +func (rppq *RolePanelPlacedQuery) FirstID(ctx context.Context) (id uuid.UUID, err error) { + var ids []uuid.UUID + if ids, err = rppq.Limit(1).IDs(setContextOp(ctx, rppq.ctx, "FirstID")); err != nil { + return + } + if len(ids) == 0 { + err = &NotFoundError{rolepanelplaced.Label} + return + } + return ids[0], nil +} + +// FirstIDX is like FirstID, but panics if an error occurs. +func (rppq *RolePanelPlacedQuery) FirstIDX(ctx context.Context) uuid.UUID { + id, err := rppq.FirstID(ctx) + if err != nil && !IsNotFound(err) { + panic(err) + } + return id +} + +// Only returns a single RolePanelPlaced entity found by the query, ensuring it only returns one. +// Returns a *NotSingularError when more than one RolePanelPlaced entity is found. +// Returns a *NotFoundError when no RolePanelPlaced entities are found. +func (rppq *RolePanelPlacedQuery) Only(ctx context.Context) (*RolePanelPlaced, error) { + nodes, err := rppq.Limit(2).All(setContextOp(ctx, rppq.ctx, "Only")) + if err != nil { + return nil, err + } + switch len(nodes) { + case 1: + return nodes[0], nil + case 0: + return nil, &NotFoundError{rolepanelplaced.Label} + default: + return nil, &NotSingularError{rolepanelplaced.Label} + } +} + +// OnlyX is like Only, but panics if an error occurs. +func (rppq *RolePanelPlacedQuery) OnlyX(ctx context.Context) *RolePanelPlaced { + node, err := rppq.Only(ctx) + if err != nil { + panic(err) + } + return node +} + +// OnlyID is like Only, but returns the only RolePanelPlaced ID in the query. +// Returns a *NotSingularError when more than one RolePanelPlaced ID is found. +// Returns a *NotFoundError when no entities are found. +func (rppq *RolePanelPlacedQuery) OnlyID(ctx context.Context) (id uuid.UUID, err error) { + var ids []uuid.UUID + if ids, err = rppq.Limit(2).IDs(setContextOp(ctx, rppq.ctx, "OnlyID")); err != nil { + return + } + switch len(ids) { + case 1: + id = ids[0] + case 0: + err = &NotFoundError{rolepanelplaced.Label} + default: + err = &NotSingularError{rolepanelplaced.Label} + } + return +} + +// OnlyIDX is like OnlyID, but panics if an error occurs. +func (rppq *RolePanelPlacedQuery) OnlyIDX(ctx context.Context) uuid.UUID { + id, err := rppq.OnlyID(ctx) + if err != nil { + panic(err) + } + return id +} + +// All executes the query and returns a list of RolePanelPlaceds. +func (rppq *RolePanelPlacedQuery) All(ctx context.Context) ([]*RolePanelPlaced, error) { + ctx = setContextOp(ctx, rppq.ctx, "All") + if err := rppq.prepareQuery(ctx); err != nil { + return nil, err + } + qr := querierAll[[]*RolePanelPlaced, *RolePanelPlacedQuery]() + return withInterceptors[[]*RolePanelPlaced](ctx, rppq, qr, rppq.inters) +} + +// AllX is like All, but panics if an error occurs. +func (rppq *RolePanelPlacedQuery) AllX(ctx context.Context) []*RolePanelPlaced { + nodes, err := rppq.All(ctx) + if err != nil { + panic(err) + } + return nodes +} + +// IDs executes the query and returns a list of RolePanelPlaced IDs. +func (rppq *RolePanelPlacedQuery) IDs(ctx context.Context) (ids []uuid.UUID, err error) { + if rppq.ctx.Unique == nil && rppq.path != nil { + rppq.Unique(true) + } + ctx = setContextOp(ctx, rppq.ctx, "IDs") + if err = rppq.Select(rolepanelplaced.FieldID).Scan(ctx, &ids); err != nil { + return nil, err + } + return ids, nil +} + +// IDsX is like IDs, but panics if an error occurs. +func (rppq *RolePanelPlacedQuery) IDsX(ctx context.Context) []uuid.UUID { + ids, err := rppq.IDs(ctx) + if err != nil { + panic(err) + } + return ids +} + +// Count returns the count of the given query. +func (rppq *RolePanelPlacedQuery) Count(ctx context.Context) (int, error) { + ctx = setContextOp(ctx, rppq.ctx, "Count") + if err := rppq.prepareQuery(ctx); err != nil { + return 0, err + } + return withInterceptors[int](ctx, rppq, querierCount[*RolePanelPlacedQuery](), rppq.inters) +} + +// CountX is like Count, but panics if an error occurs. +func (rppq *RolePanelPlacedQuery) CountX(ctx context.Context) int { + count, err := rppq.Count(ctx) + if err != nil { + panic(err) + } + return count +} + +// Exist returns true if the query has elements in the graph. +func (rppq *RolePanelPlacedQuery) Exist(ctx context.Context) (bool, error) { + ctx = setContextOp(ctx, rppq.ctx, "Exist") + switch _, err := rppq.FirstID(ctx); { + case IsNotFound(err): + return false, nil + case err != nil: + return false, fmt.Errorf("ent: check existence: %w", err) + default: + return true, nil + } +} + +// ExistX is like Exist, but panics if an error occurs. +func (rppq *RolePanelPlacedQuery) ExistX(ctx context.Context) bool { + exist, err := rppq.Exist(ctx) + if err != nil { + panic(err) + } + return exist +} + +// Clone returns a duplicate of the RolePanelPlacedQuery builder, including all associated steps. It can be +// used to prepare common query builders and use them differently after the clone is made. +func (rppq *RolePanelPlacedQuery) Clone() *RolePanelPlacedQuery { + if rppq == nil { + return nil + } + return &RolePanelPlacedQuery{ + config: rppq.config, + ctx: rppq.ctx.Clone(), + order: append([]rolepanelplaced.OrderOption{}, rppq.order...), + inters: append([]Interceptor{}, rppq.inters...), + predicates: append([]predicate.RolePanelPlaced{}, rppq.predicates...), + withGuild: rppq.withGuild.Clone(), + withRolePanel: rppq.withRolePanel.Clone(), + // clone intermediate query. + sql: rppq.sql.Clone(), + path: rppq.path, + } +} + +// WithGuild tells the query-builder to eager-load the nodes that are connected to +// the "guild" edge. The optional arguments are used to configure the query builder of the edge. +func (rppq *RolePanelPlacedQuery) WithGuild(opts ...func(*GuildQuery)) *RolePanelPlacedQuery { + query := (&GuildClient{config: rppq.config}).Query() + for _, opt := range opts { + opt(query) + } + rppq.withGuild = query + return rppq +} + +// WithRolePanel tells the query-builder to eager-load the nodes that are connected to +// the "role_panel" edge. The optional arguments are used to configure the query builder of the edge. +func (rppq *RolePanelPlacedQuery) WithRolePanel(opts ...func(*RolePanelQuery)) *RolePanelPlacedQuery { + query := (&RolePanelClient{config: rppq.config}).Query() + for _, opt := range opts { + opt(query) + } + rppq.withRolePanel = query + return rppq +} + +// GroupBy is used to group vertices by one or more fields/columns. +// It is often used with aggregate functions, like: count, max, mean, min, sum. +// +// Example: +// +// var v []struct { +// MessageID snowflake.ID `json:"message_id,omitempty"` +// Count int `json:"count,omitempty"` +// } +// +// client.RolePanelPlaced.Query(). +// GroupBy(rolepanelplaced.FieldMessageID). +// Aggregate(ent.Count()). +// Scan(ctx, &v) +func (rppq *RolePanelPlacedQuery) GroupBy(field string, fields ...string) *RolePanelPlacedGroupBy { + rppq.ctx.Fields = append([]string{field}, fields...) + grbuild := &RolePanelPlacedGroupBy{build: rppq} + grbuild.flds = &rppq.ctx.Fields + grbuild.label = rolepanelplaced.Label + grbuild.scan = grbuild.Scan + return grbuild +} + +// Select allows the selection one or more fields/columns for the given query, +// instead of selecting all fields in the entity. +// +// Example: +// +// var v []struct { +// MessageID snowflake.ID `json:"message_id,omitempty"` +// } +// +// client.RolePanelPlaced.Query(). +// Select(rolepanelplaced.FieldMessageID). +// Scan(ctx, &v) +func (rppq *RolePanelPlacedQuery) Select(fields ...string) *RolePanelPlacedSelect { + rppq.ctx.Fields = append(rppq.ctx.Fields, fields...) + sbuild := &RolePanelPlacedSelect{RolePanelPlacedQuery: rppq} + sbuild.label = rolepanelplaced.Label + sbuild.flds, sbuild.scan = &rppq.ctx.Fields, sbuild.Scan + return sbuild +} + +// Aggregate returns a RolePanelPlacedSelect configured with the given aggregations. +func (rppq *RolePanelPlacedQuery) Aggregate(fns ...AggregateFunc) *RolePanelPlacedSelect { + return rppq.Select().Aggregate(fns...) +} + +func (rppq *RolePanelPlacedQuery) prepareQuery(ctx context.Context) error { + for _, inter := range rppq.inters { + if inter == nil { + return fmt.Errorf("ent: uninitialized interceptor (forgotten import ent/runtime?)") + } + if trv, ok := inter.(Traverser); ok { + if err := trv.Traverse(ctx, rppq); err != nil { + return err + } + } + } + for _, f := range rppq.ctx.Fields { + if !rolepanelplaced.ValidColumn(f) { + return &ValidationError{Name: f, err: fmt.Errorf("ent: invalid field %q for query", f)} + } + } + if rppq.path != nil { + prev, err := rppq.path(ctx) + if err != nil { + return err + } + rppq.sql = prev + } + return nil +} + +func (rppq *RolePanelPlacedQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*RolePanelPlaced, error) { + var ( + nodes = []*RolePanelPlaced{} + withFKs = rppq.withFKs + _spec = rppq.querySpec() + loadedTypes = [2]bool{ + rppq.withGuild != nil, + rppq.withRolePanel != nil, + } + ) + if rppq.withGuild != nil || rppq.withRolePanel != nil { + withFKs = true + } + if withFKs { + _spec.Node.Columns = append(_spec.Node.Columns, rolepanelplaced.ForeignKeys...) + } + _spec.ScanValues = func(columns []string) ([]any, error) { + return (*RolePanelPlaced).scanValues(nil, columns) + } + _spec.Assign = func(columns []string, values []any) error { + node := &RolePanelPlaced{config: rppq.config} + nodes = append(nodes, node) + node.Edges.loadedTypes = loadedTypes + return node.assignValues(columns, values) + } + for i := range hooks { + hooks[i](ctx, _spec) + } + if err := sqlgraph.QueryNodes(ctx, rppq.driver, _spec); err != nil { + return nil, err + } + if len(nodes) == 0 { + return nodes, nil + } + if query := rppq.withGuild; query != nil { + if err := rppq.loadGuild(ctx, query, nodes, nil, + func(n *RolePanelPlaced, e *Guild) { n.Edges.Guild = e }); err != nil { + return nil, err + } + } + if query := rppq.withRolePanel; query != nil { + if err := rppq.loadRolePanel(ctx, query, nodes, nil, + func(n *RolePanelPlaced, e *RolePanel) { n.Edges.RolePanel = e }); err != nil { + return nil, err + } + } + return nodes, nil +} + +func (rppq *RolePanelPlacedQuery) loadGuild(ctx context.Context, query *GuildQuery, nodes []*RolePanelPlaced, init func(*RolePanelPlaced), assign func(*RolePanelPlaced, *Guild)) error { + ids := make([]snowflake.ID, 0, len(nodes)) + nodeids := make(map[snowflake.ID][]*RolePanelPlaced) + for i := range nodes { + if nodes[i].guild_role_panel_placements == nil { + continue + } + fk := *nodes[i].guild_role_panel_placements + if _, ok := nodeids[fk]; !ok { + ids = append(ids, fk) + } + nodeids[fk] = append(nodeids[fk], nodes[i]) + } + if len(ids) == 0 { + return nil + } + query.Where(guild.IDIn(ids...)) + neighbors, err := query.All(ctx) + if err != nil { + return err + } + for _, n := range neighbors { + nodes, ok := nodeids[n.ID] + if !ok { + return fmt.Errorf(`unexpected foreign-key "guild_role_panel_placements" returned %v`, n.ID) + } + for i := range nodes { + assign(nodes[i], n) + } + } + return nil +} +func (rppq *RolePanelPlacedQuery) loadRolePanel(ctx context.Context, query *RolePanelQuery, nodes []*RolePanelPlaced, init func(*RolePanelPlaced), assign func(*RolePanelPlaced, *RolePanel)) error { + ids := make([]uuid.UUID, 0, len(nodes)) + nodeids := make(map[uuid.UUID][]*RolePanelPlaced) + for i := range nodes { + if nodes[i].role_panel_placements == nil { + continue + } + fk := *nodes[i].role_panel_placements + if _, ok := nodeids[fk]; !ok { + ids = append(ids, fk) + } + nodeids[fk] = append(nodeids[fk], nodes[i]) + } + if len(ids) == 0 { + return nil + } + query.Where(rolepanel.IDIn(ids...)) + neighbors, err := query.All(ctx) + if err != nil { + return err + } + for _, n := range neighbors { + nodes, ok := nodeids[n.ID] + if !ok { + return fmt.Errorf(`unexpected foreign-key "role_panel_placements" returned %v`, n.ID) + } + for i := range nodes { + assign(nodes[i], n) + } + } + return nil +} + +func (rppq *RolePanelPlacedQuery) sqlCount(ctx context.Context) (int, error) { + _spec := rppq.querySpec() + _spec.Node.Columns = rppq.ctx.Fields + if len(rppq.ctx.Fields) > 0 { + _spec.Unique = rppq.ctx.Unique != nil && *rppq.ctx.Unique + } + return sqlgraph.CountNodes(ctx, rppq.driver, _spec) +} + +func (rppq *RolePanelPlacedQuery) querySpec() *sqlgraph.QuerySpec { + _spec := sqlgraph.NewQuerySpec(rolepanelplaced.Table, rolepanelplaced.Columns, sqlgraph.NewFieldSpec(rolepanelplaced.FieldID, field.TypeUUID)) + _spec.From = rppq.sql + if unique := rppq.ctx.Unique; unique != nil { + _spec.Unique = *unique + } else if rppq.path != nil { + _spec.Unique = true + } + if fields := rppq.ctx.Fields; len(fields) > 0 { + _spec.Node.Columns = make([]string, 0, len(fields)) + _spec.Node.Columns = append(_spec.Node.Columns, rolepanelplaced.FieldID) + for i := range fields { + if fields[i] != rolepanelplaced.FieldID { + _spec.Node.Columns = append(_spec.Node.Columns, fields[i]) + } + } + } + if ps := rppq.predicates; len(ps) > 0 { + _spec.Predicate = func(selector *sql.Selector) { + for i := range ps { + ps[i](selector) + } + } + } + if limit := rppq.ctx.Limit; limit != nil { + _spec.Limit = *limit + } + if offset := rppq.ctx.Offset; offset != nil { + _spec.Offset = *offset + } + if ps := rppq.order; len(ps) > 0 { + _spec.Order = func(selector *sql.Selector) { + for i := range ps { + ps[i](selector) + } + } + } + return _spec +} + +func (rppq *RolePanelPlacedQuery) sqlQuery(ctx context.Context) *sql.Selector { + builder := sql.Dialect(rppq.driver.Dialect()) + t1 := builder.Table(rolepanelplaced.Table) + columns := rppq.ctx.Fields + if len(columns) == 0 { + columns = rolepanelplaced.Columns + } + selector := builder.Select(t1.Columns(columns...)...).From(t1) + if rppq.sql != nil { + selector = rppq.sql + selector.Select(selector.Columns(columns...)...) + } + if rppq.ctx.Unique != nil && *rppq.ctx.Unique { + selector.Distinct() + } + for _, p := range rppq.predicates { + p(selector) + } + for _, p := range rppq.order { + p(selector) + } + if offset := rppq.ctx.Offset; offset != nil { + // limit is mandatory for offset clause. We start + // with default value, and override it below if needed. + selector.Offset(*offset).Limit(math.MaxInt32) + } + if limit := rppq.ctx.Limit; limit != nil { + selector.Limit(*limit) + } + return selector +} + +// RolePanelPlacedGroupBy is the group-by builder for RolePanelPlaced entities. +type RolePanelPlacedGroupBy struct { + selector + build *RolePanelPlacedQuery +} + +// Aggregate adds the given aggregation functions to the group-by query. +func (rppgb *RolePanelPlacedGroupBy) Aggregate(fns ...AggregateFunc) *RolePanelPlacedGroupBy { + rppgb.fns = append(rppgb.fns, fns...) + return rppgb +} + +// Scan applies the selector query and scans the result into the given value. +func (rppgb *RolePanelPlacedGroupBy) Scan(ctx context.Context, v any) error { + ctx = setContextOp(ctx, rppgb.build.ctx, "GroupBy") + if err := rppgb.build.prepareQuery(ctx); err != nil { + return err + } + return scanWithInterceptors[*RolePanelPlacedQuery, *RolePanelPlacedGroupBy](ctx, rppgb.build, rppgb, rppgb.build.inters, v) +} + +func (rppgb *RolePanelPlacedGroupBy) sqlScan(ctx context.Context, root *RolePanelPlacedQuery, v any) error { + selector := root.sqlQuery(ctx).Select() + aggregation := make([]string, 0, len(rppgb.fns)) + for _, fn := range rppgb.fns { + aggregation = append(aggregation, fn(selector)) + } + if len(selector.SelectedColumns()) == 0 { + columns := make([]string, 0, len(*rppgb.flds)+len(rppgb.fns)) + for _, f := range *rppgb.flds { + columns = append(columns, selector.C(f)) + } + columns = append(columns, aggregation...) + selector.Select(columns...) + } + selector.GroupBy(selector.Columns(*rppgb.flds...)...) + if err := selector.Err(); err != nil { + return err + } + rows := &sql.Rows{} + query, args := selector.Query() + if err := rppgb.build.driver.Query(ctx, query, args, rows); err != nil { + return err + } + defer rows.Close() + return sql.ScanSlice(rows, v) +} + +// RolePanelPlacedSelect is the builder for selecting fields of RolePanelPlaced entities. +type RolePanelPlacedSelect struct { + *RolePanelPlacedQuery + selector +} + +// Aggregate adds the given aggregation functions to the selector query. +func (rpps *RolePanelPlacedSelect) Aggregate(fns ...AggregateFunc) *RolePanelPlacedSelect { + rpps.fns = append(rpps.fns, fns...) + return rpps +} + +// Scan applies the selector query and scans the result into the given value. +func (rpps *RolePanelPlacedSelect) Scan(ctx context.Context, v any) error { + ctx = setContextOp(ctx, rpps.ctx, "Select") + if err := rpps.prepareQuery(ctx); err != nil { + return err + } + return scanWithInterceptors[*RolePanelPlacedQuery, *RolePanelPlacedSelect](ctx, rpps.RolePanelPlacedQuery, rpps, rpps.inters, v) +} + +func (rpps *RolePanelPlacedSelect) sqlScan(ctx context.Context, root *RolePanelPlacedQuery, v any) error { + selector := root.sqlQuery(ctx) + aggregation := make([]string, 0, len(rpps.fns)) + for _, fn := range rpps.fns { + aggregation = append(aggregation, fn(selector)) + } + switch n := len(*rpps.selector.flds); { + case n == 0 && len(aggregation) > 0: + selector.Select(aggregation...) + case n != 0 && len(aggregation) > 0: + selector.AppendSelect(aggregation...) + } + rows := &sql.Rows{} + query, args := selector.Query() + if err := rpps.driver.Query(ctx, query, args, rows); err != nil { + return err + } + defer rows.Close() + return sql.ScanSlice(rows, v) +} diff --git a/ent/rolepanelplaced_update.go b/ent/rolepanelplaced_update.go new file mode 100644 index 00000000..8a477602 --- /dev/null +++ b/ent/rolepanelplaced_update.go @@ -0,0 +1,1025 @@ +// Code generated by ent, DO NOT EDIT. + +package ent + +import ( + "context" + "errors" + "fmt" + "time" + + "entgo.io/ent/dialect/sql" + "entgo.io/ent/dialect/sql/sqlgraph" + "entgo.io/ent/dialect/sql/sqljson" + "entgo.io/ent/schema/field" + "github.com/disgoorg/disgo/discord" + snowflake "github.com/disgoorg/snowflake/v2" + "github.com/google/uuid" + "github.com/sabafly/gobot/ent/guild" + "github.com/sabafly/gobot/ent/predicate" + "github.com/sabafly/gobot/ent/rolepanel" + "github.com/sabafly/gobot/ent/rolepanelplaced" + "github.com/sabafly/gobot/ent/schema" +) + +// RolePanelPlacedUpdate is the builder for updating RolePanelPlaced entities. +type RolePanelPlacedUpdate struct { + config + hooks []Hook + mutation *RolePanelPlacedMutation +} + +// Where appends a list predicates to the RolePanelPlacedUpdate builder. +func (rppu *RolePanelPlacedUpdate) Where(ps ...predicate.RolePanelPlaced) *RolePanelPlacedUpdate { + rppu.mutation.Where(ps...) + return rppu +} + +// SetMessageID sets the "message_id" field. +func (rppu *RolePanelPlacedUpdate) SetMessageID(s snowflake.ID) *RolePanelPlacedUpdate { + rppu.mutation.ResetMessageID() + rppu.mutation.SetMessageID(s) + return rppu +} + +// SetNillableMessageID sets the "message_id" field if the given value is not nil. +func (rppu *RolePanelPlacedUpdate) SetNillableMessageID(s *snowflake.ID) *RolePanelPlacedUpdate { + if s != nil { + rppu.SetMessageID(*s) + } + return rppu +} + +// AddMessageID adds s to the "message_id" field. +func (rppu *RolePanelPlacedUpdate) AddMessageID(s snowflake.ID) *RolePanelPlacedUpdate { + rppu.mutation.AddMessageID(s) + return rppu +} + +// ClearMessageID clears the value of the "message_id" field. +func (rppu *RolePanelPlacedUpdate) ClearMessageID() *RolePanelPlacedUpdate { + rppu.mutation.ClearMessageID() + return rppu +} + +// SetChannelID sets the "channel_id" field. +func (rppu *RolePanelPlacedUpdate) SetChannelID(s snowflake.ID) *RolePanelPlacedUpdate { + rppu.mutation.ResetChannelID() + rppu.mutation.SetChannelID(s) + return rppu +} + +// SetNillableChannelID sets the "channel_id" field if the given value is not nil. +func (rppu *RolePanelPlacedUpdate) SetNillableChannelID(s *snowflake.ID) *RolePanelPlacedUpdate { + if s != nil { + rppu.SetChannelID(*s) + } + return rppu +} + +// AddChannelID adds s to the "channel_id" field. +func (rppu *RolePanelPlacedUpdate) AddChannelID(s snowflake.ID) *RolePanelPlacedUpdate { + rppu.mutation.AddChannelID(s) + return rppu +} + +// SetType sets the "type" field. +func (rppu *RolePanelPlacedUpdate) SetType(r rolepanelplaced.Type) *RolePanelPlacedUpdate { + rppu.mutation.SetType(r) + return rppu +} + +// SetNillableType sets the "type" field if the given value is not nil. +func (rppu *RolePanelPlacedUpdate) SetNillableType(r *rolepanelplaced.Type) *RolePanelPlacedUpdate { + if r != nil { + rppu.SetType(*r) + } + return rppu +} + +// ClearType clears the value of the "type" field. +func (rppu *RolePanelPlacedUpdate) ClearType() *RolePanelPlacedUpdate { + rppu.mutation.ClearType() + return rppu +} + +// SetButtonType sets the "button_type" field. +func (rppu *RolePanelPlacedUpdate) SetButtonType(ds discord.ButtonStyle) *RolePanelPlacedUpdate { + rppu.mutation.ResetButtonType() + rppu.mutation.SetButtonType(ds) + return rppu +} + +// SetNillableButtonType sets the "button_type" field if the given value is not nil. +func (rppu *RolePanelPlacedUpdate) SetNillableButtonType(ds *discord.ButtonStyle) *RolePanelPlacedUpdate { + if ds != nil { + rppu.SetButtonType(*ds) + } + return rppu +} + +// AddButtonType adds ds to the "button_type" field. +func (rppu *RolePanelPlacedUpdate) AddButtonType(ds discord.ButtonStyle) *RolePanelPlacedUpdate { + rppu.mutation.AddButtonType(ds) + return rppu +} + +// SetShowName sets the "show_name" field. +func (rppu *RolePanelPlacedUpdate) SetShowName(b bool) *RolePanelPlacedUpdate { + rppu.mutation.SetShowName(b) + return rppu +} + +// SetNillableShowName sets the "show_name" field if the given value is not nil. +func (rppu *RolePanelPlacedUpdate) SetNillableShowName(b *bool) *RolePanelPlacedUpdate { + if b != nil { + rppu.SetShowName(*b) + } + return rppu +} + +// SetFoldingSelectMenu sets the "folding_select_menu" field. +func (rppu *RolePanelPlacedUpdate) SetFoldingSelectMenu(b bool) *RolePanelPlacedUpdate { + rppu.mutation.SetFoldingSelectMenu(b) + return rppu +} + +// SetNillableFoldingSelectMenu sets the "folding_select_menu" field if the given value is not nil. +func (rppu *RolePanelPlacedUpdate) SetNillableFoldingSelectMenu(b *bool) *RolePanelPlacedUpdate { + if b != nil { + rppu.SetFoldingSelectMenu(*b) + } + return rppu +} + +// SetHideNotice sets the "hide_notice" field. +func (rppu *RolePanelPlacedUpdate) SetHideNotice(b bool) *RolePanelPlacedUpdate { + rppu.mutation.SetHideNotice(b) + return rppu +} + +// SetNillableHideNotice sets the "hide_notice" field if the given value is not nil. +func (rppu *RolePanelPlacedUpdate) SetNillableHideNotice(b *bool) *RolePanelPlacedUpdate { + if b != nil { + rppu.SetHideNotice(*b) + } + return rppu +} + +// SetUseDisplayName sets the "use_display_name" field. +func (rppu *RolePanelPlacedUpdate) SetUseDisplayName(b bool) *RolePanelPlacedUpdate { + rppu.mutation.SetUseDisplayName(b) + return rppu +} + +// SetNillableUseDisplayName sets the "use_display_name" field if the given value is not nil. +func (rppu *RolePanelPlacedUpdate) SetNillableUseDisplayName(b *bool) *RolePanelPlacedUpdate { + if b != nil { + rppu.SetUseDisplayName(*b) + } + return rppu +} + +// SetUses sets the "uses" field. +func (rppu *RolePanelPlacedUpdate) SetUses(i int) *RolePanelPlacedUpdate { + rppu.mutation.ResetUses() + rppu.mutation.SetUses(i) + return rppu +} + +// SetNillableUses sets the "uses" field if the given value is not nil. +func (rppu *RolePanelPlacedUpdate) SetNillableUses(i *int) *RolePanelPlacedUpdate { + if i != nil { + rppu.SetUses(*i) + } + return rppu +} + +// AddUses adds i to the "uses" field. +func (rppu *RolePanelPlacedUpdate) AddUses(i int) *RolePanelPlacedUpdate { + rppu.mutation.AddUses(i) + return rppu +} + +// SetName sets the "name" field. +func (rppu *RolePanelPlacedUpdate) SetName(s string) *RolePanelPlacedUpdate { + rppu.mutation.SetName(s) + return rppu +} + +// SetNillableName sets the "name" field if the given value is not nil. +func (rppu *RolePanelPlacedUpdate) SetNillableName(s *string) *RolePanelPlacedUpdate { + if s != nil { + rppu.SetName(*s) + } + return rppu +} + +// SetDescription sets the "description" field. +func (rppu *RolePanelPlacedUpdate) SetDescription(s string) *RolePanelPlacedUpdate { + rppu.mutation.SetDescription(s) + return rppu +} + +// SetNillableDescription sets the "description" field if the given value is not nil. +func (rppu *RolePanelPlacedUpdate) SetNillableDescription(s *string) *RolePanelPlacedUpdate { + if s != nil { + rppu.SetDescription(*s) + } + return rppu +} + +// SetRoles sets the "roles" field. +func (rppu *RolePanelPlacedUpdate) SetRoles(s []schema.Role) *RolePanelPlacedUpdate { + rppu.mutation.SetRoles(s) + return rppu +} + +// AppendRoles appends s to the "roles" field. +func (rppu *RolePanelPlacedUpdate) AppendRoles(s []schema.Role) *RolePanelPlacedUpdate { + rppu.mutation.AppendRoles(s) + return rppu +} + +// ClearRoles clears the value of the "roles" field. +func (rppu *RolePanelPlacedUpdate) ClearRoles() *RolePanelPlacedUpdate { + rppu.mutation.ClearRoles() + return rppu +} + +// SetUpdatedAt sets the "updated_at" field. +func (rppu *RolePanelPlacedUpdate) SetUpdatedAt(t time.Time) *RolePanelPlacedUpdate { + rppu.mutation.SetUpdatedAt(t) + return rppu +} + +// SetNillableUpdatedAt sets the "updated_at" field if the given value is not nil. +func (rppu *RolePanelPlacedUpdate) SetNillableUpdatedAt(t *time.Time) *RolePanelPlacedUpdate { + if t != nil { + rppu.SetUpdatedAt(*t) + } + return rppu +} + +// ClearUpdatedAt clears the value of the "updated_at" field. +func (rppu *RolePanelPlacedUpdate) ClearUpdatedAt() *RolePanelPlacedUpdate { + rppu.mutation.ClearUpdatedAt() + return rppu +} + +// SetGuildID sets the "guild" edge to the Guild entity by ID. +func (rppu *RolePanelPlacedUpdate) SetGuildID(id snowflake.ID) *RolePanelPlacedUpdate { + rppu.mutation.SetGuildID(id) + return rppu +} + +// SetGuild sets the "guild" edge to the Guild entity. +func (rppu *RolePanelPlacedUpdate) SetGuild(g *Guild) *RolePanelPlacedUpdate { + return rppu.SetGuildID(g.ID) +} + +// SetRolePanelID sets the "role_panel" edge to the RolePanel entity by ID. +func (rppu *RolePanelPlacedUpdate) SetRolePanelID(id uuid.UUID) *RolePanelPlacedUpdate { + rppu.mutation.SetRolePanelID(id) + return rppu +} + +// SetRolePanel sets the "role_panel" edge to the RolePanel entity. +func (rppu *RolePanelPlacedUpdate) SetRolePanel(r *RolePanel) *RolePanelPlacedUpdate { + return rppu.SetRolePanelID(r.ID) +} + +// Mutation returns the RolePanelPlacedMutation object of the builder. +func (rppu *RolePanelPlacedUpdate) Mutation() *RolePanelPlacedMutation { + return rppu.mutation +} + +// ClearGuild clears the "guild" edge to the Guild entity. +func (rppu *RolePanelPlacedUpdate) ClearGuild() *RolePanelPlacedUpdate { + rppu.mutation.ClearGuild() + return rppu +} + +// ClearRolePanel clears the "role_panel" edge to the RolePanel entity. +func (rppu *RolePanelPlacedUpdate) ClearRolePanel() *RolePanelPlacedUpdate { + rppu.mutation.ClearRolePanel() + return rppu +} + +// Save executes the query and returns the number of nodes affected by the update operation. +func (rppu *RolePanelPlacedUpdate) Save(ctx context.Context) (int, error) { + return withHooks(ctx, rppu.sqlSave, rppu.mutation, rppu.hooks) +} + +// SaveX is like Save, but panics if an error occurs. +func (rppu *RolePanelPlacedUpdate) SaveX(ctx context.Context) int { + affected, err := rppu.Save(ctx) + if err != nil { + panic(err) + } + return affected +} + +// Exec executes the query. +func (rppu *RolePanelPlacedUpdate) Exec(ctx context.Context) error { + _, err := rppu.Save(ctx) + return err +} + +// ExecX is like Exec, but panics if an error occurs. +func (rppu *RolePanelPlacedUpdate) ExecX(ctx context.Context) { + if err := rppu.Exec(ctx); err != nil { + panic(err) + } +} + +// check runs all checks and user-defined validators on the builder. +func (rppu *RolePanelPlacedUpdate) check() error { + if v, ok := rppu.mutation.GetType(); ok { + if err := rolepanelplaced.TypeValidator(v); err != nil { + return &ValidationError{Name: "type", err: fmt.Errorf(`ent: validator failed for field "RolePanelPlaced.type": %w`, err)} + } + } + if v, ok := rppu.mutation.ButtonType(); ok { + if err := rolepanelplaced.ButtonTypeValidator(int(v)); err != nil { + return &ValidationError{Name: "button_type", err: fmt.Errorf(`ent: validator failed for field "RolePanelPlaced.button_type": %w`, err)} + } + } + if v, ok := rppu.mutation.Name(); ok { + if err := rolepanelplaced.NameValidator(v); err != nil { + return &ValidationError{Name: "name", err: fmt.Errorf(`ent: validator failed for field "RolePanelPlaced.name": %w`, err)} + } + } + if _, ok := rppu.mutation.GuildID(); rppu.mutation.GuildCleared() && !ok { + return errors.New(`ent: clearing a required unique edge "RolePanelPlaced.guild"`) + } + if _, ok := rppu.mutation.RolePanelID(); rppu.mutation.RolePanelCleared() && !ok { + return errors.New(`ent: clearing a required unique edge "RolePanelPlaced.role_panel"`) + } + return nil +} + +func (rppu *RolePanelPlacedUpdate) sqlSave(ctx context.Context) (n int, err error) { + if err := rppu.check(); err != nil { + return n, err + } + _spec := sqlgraph.NewUpdateSpec(rolepanelplaced.Table, rolepanelplaced.Columns, sqlgraph.NewFieldSpec(rolepanelplaced.FieldID, field.TypeUUID)) + if ps := rppu.mutation.predicates; len(ps) > 0 { + _spec.Predicate = func(selector *sql.Selector) { + for i := range ps { + ps[i](selector) + } + } + } + if value, ok := rppu.mutation.MessageID(); ok { + _spec.SetField(rolepanelplaced.FieldMessageID, field.TypeUint64, value) + } + if value, ok := rppu.mutation.AddedMessageID(); ok { + _spec.AddField(rolepanelplaced.FieldMessageID, field.TypeUint64, value) + } + if rppu.mutation.MessageIDCleared() { + _spec.ClearField(rolepanelplaced.FieldMessageID, field.TypeUint64) + } + if value, ok := rppu.mutation.ChannelID(); ok { + _spec.SetField(rolepanelplaced.FieldChannelID, field.TypeUint64, value) + } + if value, ok := rppu.mutation.AddedChannelID(); ok { + _spec.AddField(rolepanelplaced.FieldChannelID, field.TypeUint64, value) + } + if value, ok := rppu.mutation.GetType(); ok { + _spec.SetField(rolepanelplaced.FieldType, field.TypeEnum, value) + } + if rppu.mutation.TypeCleared() { + _spec.ClearField(rolepanelplaced.FieldType, field.TypeEnum) + } + if value, ok := rppu.mutation.ButtonType(); ok { + _spec.SetField(rolepanelplaced.FieldButtonType, field.TypeInt, value) + } + if value, ok := rppu.mutation.AddedButtonType(); ok { + _spec.AddField(rolepanelplaced.FieldButtonType, field.TypeInt, value) + } + if value, ok := rppu.mutation.ShowName(); ok { + _spec.SetField(rolepanelplaced.FieldShowName, field.TypeBool, value) + } + if value, ok := rppu.mutation.FoldingSelectMenu(); ok { + _spec.SetField(rolepanelplaced.FieldFoldingSelectMenu, field.TypeBool, value) + } + if value, ok := rppu.mutation.HideNotice(); ok { + _spec.SetField(rolepanelplaced.FieldHideNotice, field.TypeBool, value) + } + if value, ok := rppu.mutation.UseDisplayName(); ok { + _spec.SetField(rolepanelplaced.FieldUseDisplayName, field.TypeBool, value) + } + if value, ok := rppu.mutation.Uses(); ok { + _spec.SetField(rolepanelplaced.FieldUses, field.TypeInt, value) + } + if value, ok := rppu.mutation.AddedUses(); ok { + _spec.AddField(rolepanelplaced.FieldUses, field.TypeInt, value) + } + if value, ok := rppu.mutation.Name(); ok { + _spec.SetField(rolepanelplaced.FieldName, field.TypeString, value) + } + if value, ok := rppu.mutation.Description(); ok { + _spec.SetField(rolepanelplaced.FieldDescription, field.TypeString, value) + } + if value, ok := rppu.mutation.Roles(); ok { + _spec.SetField(rolepanelplaced.FieldRoles, field.TypeJSON, value) + } + if value, ok := rppu.mutation.AppendedRoles(); ok { + _spec.AddModifier(func(u *sql.UpdateBuilder) { + sqljson.Append(u, rolepanelplaced.FieldRoles, value) + }) + } + if rppu.mutation.RolesCleared() { + _spec.ClearField(rolepanelplaced.FieldRoles, field.TypeJSON) + } + if value, ok := rppu.mutation.UpdatedAt(); ok { + _spec.SetField(rolepanelplaced.FieldUpdatedAt, field.TypeTime, value) + } + if rppu.mutation.UpdatedAtCleared() { + _spec.ClearField(rolepanelplaced.FieldUpdatedAt, field.TypeTime) + } + if rppu.mutation.GuildCleared() { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.M2O, + Inverse: true, + Table: rolepanelplaced.GuildTable, + Columns: []string{rolepanelplaced.GuildColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(guild.FieldID, field.TypeUint64), + }, + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := rppu.mutation.GuildIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.M2O, + Inverse: true, + Table: rolepanelplaced.GuildTable, + Columns: []string{rolepanelplaced.GuildColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(guild.FieldID, field.TypeUint64), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Add = append(_spec.Edges.Add, edge) + } + if rppu.mutation.RolePanelCleared() { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.M2O, + Inverse: true, + Table: rolepanelplaced.RolePanelTable, + Columns: []string{rolepanelplaced.RolePanelColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(rolepanel.FieldID, field.TypeUUID), + }, + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := rppu.mutation.RolePanelIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.M2O, + Inverse: true, + Table: rolepanelplaced.RolePanelTable, + Columns: []string{rolepanelplaced.RolePanelColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(rolepanel.FieldID, field.TypeUUID), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Add = append(_spec.Edges.Add, edge) + } + if n, err = sqlgraph.UpdateNodes(ctx, rppu.driver, _spec); err != nil { + if _, ok := err.(*sqlgraph.NotFoundError); ok { + err = &NotFoundError{rolepanelplaced.Label} + } else if sqlgraph.IsConstraintError(err) { + err = &ConstraintError{msg: err.Error(), wrap: err} + } + return 0, err + } + rppu.mutation.done = true + return n, nil +} + +// RolePanelPlacedUpdateOne is the builder for updating a single RolePanelPlaced entity. +type RolePanelPlacedUpdateOne struct { + config + fields []string + hooks []Hook + mutation *RolePanelPlacedMutation +} + +// SetMessageID sets the "message_id" field. +func (rppuo *RolePanelPlacedUpdateOne) SetMessageID(s snowflake.ID) *RolePanelPlacedUpdateOne { + rppuo.mutation.ResetMessageID() + rppuo.mutation.SetMessageID(s) + return rppuo +} + +// SetNillableMessageID sets the "message_id" field if the given value is not nil. +func (rppuo *RolePanelPlacedUpdateOne) SetNillableMessageID(s *snowflake.ID) *RolePanelPlacedUpdateOne { + if s != nil { + rppuo.SetMessageID(*s) + } + return rppuo +} + +// AddMessageID adds s to the "message_id" field. +func (rppuo *RolePanelPlacedUpdateOne) AddMessageID(s snowflake.ID) *RolePanelPlacedUpdateOne { + rppuo.mutation.AddMessageID(s) + return rppuo +} + +// ClearMessageID clears the value of the "message_id" field. +func (rppuo *RolePanelPlacedUpdateOne) ClearMessageID() *RolePanelPlacedUpdateOne { + rppuo.mutation.ClearMessageID() + return rppuo +} + +// SetChannelID sets the "channel_id" field. +func (rppuo *RolePanelPlacedUpdateOne) SetChannelID(s snowflake.ID) *RolePanelPlacedUpdateOne { + rppuo.mutation.ResetChannelID() + rppuo.mutation.SetChannelID(s) + return rppuo +} + +// SetNillableChannelID sets the "channel_id" field if the given value is not nil. +func (rppuo *RolePanelPlacedUpdateOne) SetNillableChannelID(s *snowflake.ID) *RolePanelPlacedUpdateOne { + if s != nil { + rppuo.SetChannelID(*s) + } + return rppuo +} + +// AddChannelID adds s to the "channel_id" field. +func (rppuo *RolePanelPlacedUpdateOne) AddChannelID(s snowflake.ID) *RolePanelPlacedUpdateOne { + rppuo.mutation.AddChannelID(s) + return rppuo +} + +// SetType sets the "type" field. +func (rppuo *RolePanelPlacedUpdateOne) SetType(r rolepanelplaced.Type) *RolePanelPlacedUpdateOne { + rppuo.mutation.SetType(r) + return rppuo +} + +// SetNillableType sets the "type" field if the given value is not nil. +func (rppuo *RolePanelPlacedUpdateOne) SetNillableType(r *rolepanelplaced.Type) *RolePanelPlacedUpdateOne { + if r != nil { + rppuo.SetType(*r) + } + return rppuo +} + +// ClearType clears the value of the "type" field. +func (rppuo *RolePanelPlacedUpdateOne) ClearType() *RolePanelPlacedUpdateOne { + rppuo.mutation.ClearType() + return rppuo +} + +// SetButtonType sets the "button_type" field. +func (rppuo *RolePanelPlacedUpdateOne) SetButtonType(ds discord.ButtonStyle) *RolePanelPlacedUpdateOne { + rppuo.mutation.ResetButtonType() + rppuo.mutation.SetButtonType(ds) + return rppuo +} + +// SetNillableButtonType sets the "button_type" field if the given value is not nil. +func (rppuo *RolePanelPlacedUpdateOne) SetNillableButtonType(ds *discord.ButtonStyle) *RolePanelPlacedUpdateOne { + if ds != nil { + rppuo.SetButtonType(*ds) + } + return rppuo +} + +// AddButtonType adds ds to the "button_type" field. +func (rppuo *RolePanelPlacedUpdateOne) AddButtonType(ds discord.ButtonStyle) *RolePanelPlacedUpdateOne { + rppuo.mutation.AddButtonType(ds) + return rppuo +} + +// SetShowName sets the "show_name" field. +func (rppuo *RolePanelPlacedUpdateOne) SetShowName(b bool) *RolePanelPlacedUpdateOne { + rppuo.mutation.SetShowName(b) + return rppuo +} + +// SetNillableShowName sets the "show_name" field if the given value is not nil. +func (rppuo *RolePanelPlacedUpdateOne) SetNillableShowName(b *bool) *RolePanelPlacedUpdateOne { + if b != nil { + rppuo.SetShowName(*b) + } + return rppuo +} + +// SetFoldingSelectMenu sets the "folding_select_menu" field. +func (rppuo *RolePanelPlacedUpdateOne) SetFoldingSelectMenu(b bool) *RolePanelPlacedUpdateOne { + rppuo.mutation.SetFoldingSelectMenu(b) + return rppuo +} + +// SetNillableFoldingSelectMenu sets the "folding_select_menu" field if the given value is not nil. +func (rppuo *RolePanelPlacedUpdateOne) SetNillableFoldingSelectMenu(b *bool) *RolePanelPlacedUpdateOne { + if b != nil { + rppuo.SetFoldingSelectMenu(*b) + } + return rppuo +} + +// SetHideNotice sets the "hide_notice" field. +func (rppuo *RolePanelPlacedUpdateOne) SetHideNotice(b bool) *RolePanelPlacedUpdateOne { + rppuo.mutation.SetHideNotice(b) + return rppuo +} + +// SetNillableHideNotice sets the "hide_notice" field if the given value is not nil. +func (rppuo *RolePanelPlacedUpdateOne) SetNillableHideNotice(b *bool) *RolePanelPlacedUpdateOne { + if b != nil { + rppuo.SetHideNotice(*b) + } + return rppuo +} + +// SetUseDisplayName sets the "use_display_name" field. +func (rppuo *RolePanelPlacedUpdateOne) SetUseDisplayName(b bool) *RolePanelPlacedUpdateOne { + rppuo.mutation.SetUseDisplayName(b) + return rppuo +} + +// SetNillableUseDisplayName sets the "use_display_name" field if the given value is not nil. +func (rppuo *RolePanelPlacedUpdateOne) SetNillableUseDisplayName(b *bool) *RolePanelPlacedUpdateOne { + if b != nil { + rppuo.SetUseDisplayName(*b) + } + return rppuo +} + +// SetUses sets the "uses" field. +func (rppuo *RolePanelPlacedUpdateOne) SetUses(i int) *RolePanelPlacedUpdateOne { + rppuo.mutation.ResetUses() + rppuo.mutation.SetUses(i) + return rppuo +} + +// SetNillableUses sets the "uses" field if the given value is not nil. +func (rppuo *RolePanelPlacedUpdateOne) SetNillableUses(i *int) *RolePanelPlacedUpdateOne { + if i != nil { + rppuo.SetUses(*i) + } + return rppuo +} + +// AddUses adds i to the "uses" field. +func (rppuo *RolePanelPlacedUpdateOne) AddUses(i int) *RolePanelPlacedUpdateOne { + rppuo.mutation.AddUses(i) + return rppuo +} + +// SetName sets the "name" field. +func (rppuo *RolePanelPlacedUpdateOne) SetName(s string) *RolePanelPlacedUpdateOne { + rppuo.mutation.SetName(s) + return rppuo +} + +// SetNillableName sets the "name" field if the given value is not nil. +func (rppuo *RolePanelPlacedUpdateOne) SetNillableName(s *string) *RolePanelPlacedUpdateOne { + if s != nil { + rppuo.SetName(*s) + } + return rppuo +} + +// SetDescription sets the "description" field. +func (rppuo *RolePanelPlacedUpdateOne) SetDescription(s string) *RolePanelPlacedUpdateOne { + rppuo.mutation.SetDescription(s) + return rppuo +} + +// SetNillableDescription sets the "description" field if the given value is not nil. +func (rppuo *RolePanelPlacedUpdateOne) SetNillableDescription(s *string) *RolePanelPlacedUpdateOne { + if s != nil { + rppuo.SetDescription(*s) + } + return rppuo +} + +// SetRoles sets the "roles" field. +func (rppuo *RolePanelPlacedUpdateOne) SetRoles(s []schema.Role) *RolePanelPlacedUpdateOne { + rppuo.mutation.SetRoles(s) + return rppuo +} + +// AppendRoles appends s to the "roles" field. +func (rppuo *RolePanelPlacedUpdateOne) AppendRoles(s []schema.Role) *RolePanelPlacedUpdateOne { + rppuo.mutation.AppendRoles(s) + return rppuo +} + +// ClearRoles clears the value of the "roles" field. +func (rppuo *RolePanelPlacedUpdateOne) ClearRoles() *RolePanelPlacedUpdateOne { + rppuo.mutation.ClearRoles() + return rppuo +} + +// SetUpdatedAt sets the "updated_at" field. +func (rppuo *RolePanelPlacedUpdateOne) SetUpdatedAt(t time.Time) *RolePanelPlacedUpdateOne { + rppuo.mutation.SetUpdatedAt(t) + return rppuo +} + +// SetNillableUpdatedAt sets the "updated_at" field if the given value is not nil. +func (rppuo *RolePanelPlacedUpdateOne) SetNillableUpdatedAt(t *time.Time) *RolePanelPlacedUpdateOne { + if t != nil { + rppuo.SetUpdatedAt(*t) + } + return rppuo +} + +// ClearUpdatedAt clears the value of the "updated_at" field. +func (rppuo *RolePanelPlacedUpdateOne) ClearUpdatedAt() *RolePanelPlacedUpdateOne { + rppuo.mutation.ClearUpdatedAt() + return rppuo +} + +// SetGuildID sets the "guild" edge to the Guild entity by ID. +func (rppuo *RolePanelPlacedUpdateOne) SetGuildID(id snowflake.ID) *RolePanelPlacedUpdateOne { + rppuo.mutation.SetGuildID(id) + return rppuo +} + +// SetGuild sets the "guild" edge to the Guild entity. +func (rppuo *RolePanelPlacedUpdateOne) SetGuild(g *Guild) *RolePanelPlacedUpdateOne { + return rppuo.SetGuildID(g.ID) +} + +// SetRolePanelID sets the "role_panel" edge to the RolePanel entity by ID. +func (rppuo *RolePanelPlacedUpdateOne) SetRolePanelID(id uuid.UUID) *RolePanelPlacedUpdateOne { + rppuo.mutation.SetRolePanelID(id) + return rppuo +} + +// SetRolePanel sets the "role_panel" edge to the RolePanel entity. +func (rppuo *RolePanelPlacedUpdateOne) SetRolePanel(r *RolePanel) *RolePanelPlacedUpdateOne { + return rppuo.SetRolePanelID(r.ID) +} + +// Mutation returns the RolePanelPlacedMutation object of the builder. +func (rppuo *RolePanelPlacedUpdateOne) Mutation() *RolePanelPlacedMutation { + return rppuo.mutation +} + +// ClearGuild clears the "guild" edge to the Guild entity. +func (rppuo *RolePanelPlacedUpdateOne) ClearGuild() *RolePanelPlacedUpdateOne { + rppuo.mutation.ClearGuild() + return rppuo +} + +// ClearRolePanel clears the "role_panel" edge to the RolePanel entity. +func (rppuo *RolePanelPlacedUpdateOne) ClearRolePanel() *RolePanelPlacedUpdateOne { + rppuo.mutation.ClearRolePanel() + return rppuo +} + +// Where appends a list predicates to the RolePanelPlacedUpdate builder. +func (rppuo *RolePanelPlacedUpdateOne) Where(ps ...predicate.RolePanelPlaced) *RolePanelPlacedUpdateOne { + rppuo.mutation.Where(ps...) + return rppuo +} + +// Select allows selecting one or more fields (columns) of the returned entity. +// The default is selecting all fields defined in the entity schema. +func (rppuo *RolePanelPlacedUpdateOne) Select(field string, fields ...string) *RolePanelPlacedUpdateOne { + rppuo.fields = append([]string{field}, fields...) + return rppuo +} + +// Save executes the query and returns the updated RolePanelPlaced entity. +func (rppuo *RolePanelPlacedUpdateOne) Save(ctx context.Context) (*RolePanelPlaced, error) { + return withHooks(ctx, rppuo.sqlSave, rppuo.mutation, rppuo.hooks) +} + +// SaveX is like Save, but panics if an error occurs. +func (rppuo *RolePanelPlacedUpdateOne) SaveX(ctx context.Context) *RolePanelPlaced { + node, err := rppuo.Save(ctx) + if err != nil { + panic(err) + } + return node +} + +// Exec executes the query on the entity. +func (rppuo *RolePanelPlacedUpdateOne) Exec(ctx context.Context) error { + _, err := rppuo.Save(ctx) + return err +} + +// ExecX is like Exec, but panics if an error occurs. +func (rppuo *RolePanelPlacedUpdateOne) ExecX(ctx context.Context) { + if err := rppuo.Exec(ctx); err != nil { + panic(err) + } +} + +// check runs all checks and user-defined validators on the builder. +func (rppuo *RolePanelPlacedUpdateOne) check() error { + if v, ok := rppuo.mutation.GetType(); ok { + if err := rolepanelplaced.TypeValidator(v); err != nil { + return &ValidationError{Name: "type", err: fmt.Errorf(`ent: validator failed for field "RolePanelPlaced.type": %w`, err)} + } + } + if v, ok := rppuo.mutation.ButtonType(); ok { + if err := rolepanelplaced.ButtonTypeValidator(int(v)); err != nil { + return &ValidationError{Name: "button_type", err: fmt.Errorf(`ent: validator failed for field "RolePanelPlaced.button_type": %w`, err)} + } + } + if v, ok := rppuo.mutation.Name(); ok { + if err := rolepanelplaced.NameValidator(v); err != nil { + return &ValidationError{Name: "name", err: fmt.Errorf(`ent: validator failed for field "RolePanelPlaced.name": %w`, err)} + } + } + if _, ok := rppuo.mutation.GuildID(); rppuo.mutation.GuildCleared() && !ok { + return errors.New(`ent: clearing a required unique edge "RolePanelPlaced.guild"`) + } + if _, ok := rppuo.mutation.RolePanelID(); rppuo.mutation.RolePanelCleared() && !ok { + return errors.New(`ent: clearing a required unique edge "RolePanelPlaced.role_panel"`) + } + return nil +} + +func (rppuo *RolePanelPlacedUpdateOne) sqlSave(ctx context.Context) (_node *RolePanelPlaced, err error) { + if err := rppuo.check(); err != nil { + return _node, err + } + _spec := sqlgraph.NewUpdateSpec(rolepanelplaced.Table, rolepanelplaced.Columns, sqlgraph.NewFieldSpec(rolepanelplaced.FieldID, field.TypeUUID)) + id, ok := rppuo.mutation.ID() + if !ok { + return nil, &ValidationError{Name: "id", err: errors.New(`ent: missing "RolePanelPlaced.id" for update`)} + } + _spec.Node.ID.Value = id + if fields := rppuo.fields; len(fields) > 0 { + _spec.Node.Columns = make([]string, 0, len(fields)) + _spec.Node.Columns = append(_spec.Node.Columns, rolepanelplaced.FieldID) + for _, f := range fields { + if !rolepanelplaced.ValidColumn(f) { + return nil, &ValidationError{Name: f, err: fmt.Errorf("ent: invalid field %q for query", f)} + } + if f != rolepanelplaced.FieldID { + _spec.Node.Columns = append(_spec.Node.Columns, f) + } + } + } + if ps := rppuo.mutation.predicates; len(ps) > 0 { + _spec.Predicate = func(selector *sql.Selector) { + for i := range ps { + ps[i](selector) + } + } + } + if value, ok := rppuo.mutation.MessageID(); ok { + _spec.SetField(rolepanelplaced.FieldMessageID, field.TypeUint64, value) + } + if value, ok := rppuo.mutation.AddedMessageID(); ok { + _spec.AddField(rolepanelplaced.FieldMessageID, field.TypeUint64, value) + } + if rppuo.mutation.MessageIDCleared() { + _spec.ClearField(rolepanelplaced.FieldMessageID, field.TypeUint64) + } + if value, ok := rppuo.mutation.ChannelID(); ok { + _spec.SetField(rolepanelplaced.FieldChannelID, field.TypeUint64, value) + } + if value, ok := rppuo.mutation.AddedChannelID(); ok { + _spec.AddField(rolepanelplaced.FieldChannelID, field.TypeUint64, value) + } + if value, ok := rppuo.mutation.GetType(); ok { + _spec.SetField(rolepanelplaced.FieldType, field.TypeEnum, value) + } + if rppuo.mutation.TypeCleared() { + _spec.ClearField(rolepanelplaced.FieldType, field.TypeEnum) + } + if value, ok := rppuo.mutation.ButtonType(); ok { + _spec.SetField(rolepanelplaced.FieldButtonType, field.TypeInt, value) + } + if value, ok := rppuo.mutation.AddedButtonType(); ok { + _spec.AddField(rolepanelplaced.FieldButtonType, field.TypeInt, value) + } + if value, ok := rppuo.mutation.ShowName(); ok { + _spec.SetField(rolepanelplaced.FieldShowName, field.TypeBool, value) + } + if value, ok := rppuo.mutation.FoldingSelectMenu(); ok { + _spec.SetField(rolepanelplaced.FieldFoldingSelectMenu, field.TypeBool, value) + } + if value, ok := rppuo.mutation.HideNotice(); ok { + _spec.SetField(rolepanelplaced.FieldHideNotice, field.TypeBool, value) + } + if value, ok := rppuo.mutation.UseDisplayName(); ok { + _spec.SetField(rolepanelplaced.FieldUseDisplayName, field.TypeBool, value) + } + if value, ok := rppuo.mutation.Uses(); ok { + _spec.SetField(rolepanelplaced.FieldUses, field.TypeInt, value) + } + if value, ok := rppuo.mutation.AddedUses(); ok { + _spec.AddField(rolepanelplaced.FieldUses, field.TypeInt, value) + } + if value, ok := rppuo.mutation.Name(); ok { + _spec.SetField(rolepanelplaced.FieldName, field.TypeString, value) + } + if value, ok := rppuo.mutation.Description(); ok { + _spec.SetField(rolepanelplaced.FieldDescription, field.TypeString, value) + } + if value, ok := rppuo.mutation.Roles(); ok { + _spec.SetField(rolepanelplaced.FieldRoles, field.TypeJSON, value) + } + if value, ok := rppuo.mutation.AppendedRoles(); ok { + _spec.AddModifier(func(u *sql.UpdateBuilder) { + sqljson.Append(u, rolepanelplaced.FieldRoles, value) + }) + } + if rppuo.mutation.RolesCleared() { + _spec.ClearField(rolepanelplaced.FieldRoles, field.TypeJSON) + } + if value, ok := rppuo.mutation.UpdatedAt(); ok { + _spec.SetField(rolepanelplaced.FieldUpdatedAt, field.TypeTime, value) + } + if rppuo.mutation.UpdatedAtCleared() { + _spec.ClearField(rolepanelplaced.FieldUpdatedAt, field.TypeTime) + } + if rppuo.mutation.GuildCleared() { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.M2O, + Inverse: true, + Table: rolepanelplaced.GuildTable, + Columns: []string{rolepanelplaced.GuildColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(guild.FieldID, field.TypeUint64), + }, + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := rppuo.mutation.GuildIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.M2O, + Inverse: true, + Table: rolepanelplaced.GuildTable, + Columns: []string{rolepanelplaced.GuildColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(guild.FieldID, field.TypeUint64), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Add = append(_spec.Edges.Add, edge) + } + if rppuo.mutation.RolePanelCleared() { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.M2O, + Inverse: true, + Table: rolepanelplaced.RolePanelTable, + Columns: []string{rolepanelplaced.RolePanelColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(rolepanel.FieldID, field.TypeUUID), + }, + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := rppuo.mutation.RolePanelIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.M2O, + Inverse: true, + Table: rolepanelplaced.RolePanelTable, + Columns: []string{rolepanelplaced.RolePanelColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(rolepanel.FieldID, field.TypeUUID), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Add = append(_spec.Edges.Add, edge) + } + _node = &RolePanelPlaced{config: rppuo.config} + _spec.Assign = _node.assignValues + _spec.ScanValues = _node.scanValues + if err = sqlgraph.UpdateNode(ctx, rppuo.driver, _spec); err != nil { + if _, ok := err.(*sqlgraph.NotFoundError); ok { + err = &NotFoundError{rolepanelplaced.Label} + } else if sqlgraph.IsConstraintError(err) { + err = &ConstraintError{msg: err.Error(), wrap: err} + } + return nil, err + } + rppuo.mutation.done = true + return _node, nil +} diff --git a/ent/runtime.go b/ent/runtime.go new file mode 100644 index 00000000..f11bbbc4 --- /dev/null +++ b/ent/runtime.go @@ -0,0 +1,269 @@ +// Code generated by ent, DO NOT EDIT. + +package ent + +import ( + "time" + + "github.com/disgoorg/disgo/discord" + snowflake "github.com/disgoorg/snowflake/v2" + "github.com/google/uuid" + "github.com/sabafly/gobot/ent/guild" + "github.com/sabafly/gobot/ent/member" + "github.com/sabafly/gobot/ent/messagepin" + "github.com/sabafly/gobot/ent/messageremind" + "github.com/sabafly/gobot/ent/rolepanel" + "github.com/sabafly/gobot/ent/rolepaneledit" + "github.com/sabafly/gobot/ent/rolepanelplaced" + "github.com/sabafly/gobot/ent/schema" + "github.com/sabafly/gobot/ent/user" + "github.com/sabafly/gobot/ent/wordsuffix" + "github.com/sabafly/gobot/internal/permissions" + "github.com/sabafly/gobot/internal/xppoint" +) + +// The init function reads all schema descriptors with runtime code +// (default values, validators, hooks and policies) and stitches it +// to their package variables. +func init() { + guildFields := schema.Guild{}.Fields() + _ = guildFields + // guildDescName is the schema descriptor for name field. + guildDescName := guildFields[1].Descriptor() + // guild.NameValidator is a validator for the "name" field. It is called by the builders before save. + guild.NameValidator = guildDescName.Validators[0].(func(string) error) + // guildDescLocale is the schema descriptor for locale field. + guildDescLocale := guildFields[2].Descriptor() + // guild.DefaultLocale holds the default value on creation for the locale field. + guild.DefaultLocale = discord.Locale(guildDescLocale.Default.(string)) + // guild.LocaleValidator is a validator for the "locale" field. It is called by the builders before save. + guild.LocaleValidator = guildDescLocale.Validators[0].(func(string) error) + // guildDescLevelUpMessage is the schema descriptor for level_up_message field. + guildDescLevelUpMessage := guildFields[3].Descriptor() + // guild.DefaultLevelUpMessage holds the default value on creation for the level_up_message field. + guild.DefaultLevelUpMessage = guildDescLevelUpMessage.Default.(string) + // guild.LevelUpMessageValidator is a validator for the "level_up_message" field. It is called by the builders before save. + guild.LevelUpMessageValidator = guildDescLevelUpMessage.Validators[0].(func(string) error) + // guildDescLevelMee6Imported is the schema descriptor for level_mee6_imported field. + guildDescLevelMee6Imported := guildFields[6].Descriptor() + // guild.DefaultLevelMee6Imported holds the default value on creation for the level_mee6_imported field. + guild.DefaultLevelMee6Imported = guildDescLevelMee6Imported.Default.(bool) + // guildDescLevelRole is the schema descriptor for level_role field. + guildDescLevelRole := guildFields[7].Descriptor() + // guild.DefaultLevelRole holds the default value on creation for the level_role field. + guild.DefaultLevelRole = guildDescLevelRole.Default.(map[int]snowflake.ID) + // guildDescPermissions is the schema descriptor for permissions field. + guildDescPermissions := guildFields[8].Descriptor() + // guild.DefaultPermissions holds the default value on creation for the permissions field. + guild.DefaultPermissions = guildDescPermissions.Default.(map[snowflake.ID]permissions.Permission) + // guildDescRemindCount is the schema descriptor for remind_count field. + guildDescRemindCount := guildFields[9].Descriptor() + // guild.DefaultRemindCount holds the default value on creation for the remind_count field. + guild.DefaultRemindCount = guildDescRemindCount.Default.(int) + // guildDescRolePanelEditTimes is the schema descriptor for role_panel_edit_times field. + guildDescRolePanelEditTimes := guildFields[10].Descriptor() + // guild.DefaultRolePanelEditTimes holds the default value on creation for the role_panel_edit_times field. + guild.DefaultRolePanelEditTimes = guildDescRolePanelEditTimes.Default.([]time.Time) + // guildDescBumpEnabled is the schema descriptor for bump_enabled field. + guildDescBumpEnabled := guildFields[11].Descriptor() + // guild.DefaultBumpEnabled holds the default value on creation for the bump_enabled field. + guild.DefaultBumpEnabled = guildDescBumpEnabled.Default.(bool) + // guildDescBumpMessageTitle is the schema descriptor for bump_message_title field. + guildDescBumpMessageTitle := guildFields[12].Descriptor() + // guild.DefaultBumpMessageTitle holds the default value on creation for the bump_message_title field. + guild.DefaultBumpMessageTitle = guildDescBumpMessageTitle.Default.(string) + // guild.BumpMessageTitleValidator is a validator for the "bump_message_title" field. It is called by the builders before save. + guild.BumpMessageTitleValidator = guildDescBumpMessageTitle.Validators[0].(func(string) error) + // guildDescBumpMessage is the schema descriptor for bump_message field. + guildDescBumpMessage := guildFields[13].Descriptor() + // guild.DefaultBumpMessage holds the default value on creation for the bump_message field. + guild.DefaultBumpMessage = guildDescBumpMessage.Default.(string) + // guild.BumpMessageValidator is a validator for the "bump_message" field. It is called by the builders before save. + guild.BumpMessageValidator = guildDescBumpMessage.Validators[0].(func(string) error) + // guildDescBumpRemindMessageTitle is the schema descriptor for bump_remind_message_title field. + guildDescBumpRemindMessageTitle := guildFields[14].Descriptor() + // guild.DefaultBumpRemindMessageTitle holds the default value on creation for the bump_remind_message_title field. + guild.DefaultBumpRemindMessageTitle = guildDescBumpRemindMessageTitle.Default.(string) + // guild.BumpRemindMessageTitleValidator is a validator for the "bump_remind_message_title" field. It is called by the builders before save. + guild.BumpRemindMessageTitleValidator = guildDescBumpRemindMessageTitle.Validators[0].(func(string) error) + // guildDescBumpRemindMessage is the schema descriptor for bump_remind_message field. + guildDescBumpRemindMessage := guildFields[15].Descriptor() + // guild.DefaultBumpRemindMessage holds the default value on creation for the bump_remind_message field. + guild.DefaultBumpRemindMessage = guildDescBumpRemindMessage.Default.(string) + // guild.BumpRemindMessageValidator is a validator for the "bump_remind_message" field. It is called by the builders before save. + guild.BumpRemindMessageValidator = guildDescBumpRemindMessage.Validators[0].(func(string) error) + // guildDescUpEnabled is the schema descriptor for up_enabled field. + guildDescUpEnabled := guildFields[16].Descriptor() + // guild.DefaultUpEnabled holds the default value on creation for the up_enabled field. + guild.DefaultUpEnabled = guildDescUpEnabled.Default.(bool) + // guildDescUpMessageTitle is the schema descriptor for up_message_title field. + guildDescUpMessageTitle := guildFields[17].Descriptor() + // guild.DefaultUpMessageTitle holds the default value on creation for the up_message_title field. + guild.DefaultUpMessageTitle = guildDescUpMessageTitle.Default.(string) + // guild.UpMessageTitleValidator is a validator for the "up_message_title" field. It is called by the builders before save. + guild.UpMessageTitleValidator = guildDescUpMessageTitle.Validators[0].(func(string) error) + // guildDescUpMessage is the schema descriptor for up_message field. + guildDescUpMessage := guildFields[18].Descriptor() + // guild.DefaultUpMessage holds the default value on creation for the up_message field. + guild.DefaultUpMessage = guildDescUpMessage.Default.(string) + // guild.UpMessageValidator is a validator for the "up_message" field. It is called by the builders before save. + guild.UpMessageValidator = guildDescUpMessage.Validators[0].(func(string) error) + // guildDescUpRemindMessageTitle is the schema descriptor for up_remind_message_title field. + guildDescUpRemindMessageTitle := guildFields[19].Descriptor() + // guild.DefaultUpRemindMessageTitle holds the default value on creation for the up_remind_message_title field. + guild.DefaultUpRemindMessageTitle = guildDescUpRemindMessageTitle.Default.(string) + // guild.UpRemindMessageTitleValidator is a validator for the "up_remind_message_title" field. It is called by the builders before save. + guild.UpRemindMessageTitleValidator = guildDescUpRemindMessageTitle.Validators[0].(func(string) error) + // guildDescUpRemindMessage is the schema descriptor for up_remind_message field. + guildDescUpRemindMessage := guildFields[20].Descriptor() + // guild.DefaultUpRemindMessage holds the default value on creation for the up_remind_message field. + guild.DefaultUpRemindMessage = guildDescUpRemindMessage.Default.(string) + // guild.UpRemindMessageValidator is a validator for the "up_remind_message" field. It is called by the builders before save. + guild.UpRemindMessageValidator = guildDescUpRemindMessage.Validators[0].(func(string) error) + memberFields := schema.Member{}.Fields() + _ = memberFields + // memberDescPermission is the schema descriptor for permission field. + memberDescPermission := memberFields[0].Descriptor() + // member.DefaultPermission holds the default value on creation for the permission field. + member.DefaultPermission = memberDescPermission.Default.(permissions.Permission) + // memberDescXp is the schema descriptor for xp field. + memberDescXp := memberFields[1].Descriptor() + // member.DefaultXp holds the default value on creation for the xp field. + member.DefaultXp = xppoint.XP(memberDescXp.Default.(uint64)) + // memberDescMessageCount is the schema descriptor for message_count field. + memberDescMessageCount := memberFields[4].Descriptor() + // member.DefaultMessageCount holds the default value on creation for the message_count field. + member.DefaultMessageCount = memberDescMessageCount.Default.(uint64) + messagepinFields := schema.MessagePin{}.Fields() + _ = messagepinFields + // messagepinDescRateLimit is the schema descriptor for rate_limit field. + messagepinDescRateLimit := messagepinFields[5].Descriptor() + // messagepin.DefaultRateLimit holds the default value on creation for the rate_limit field. + messagepin.DefaultRateLimit = messagepinDescRateLimit.Default.(schema.RateLimit) + // messagepinDescID is the schema descriptor for id field. + messagepinDescID := messagepinFields[0].Descriptor() + // messagepin.DefaultID holds the default value on creation for the id field. + messagepin.DefaultID = messagepinDescID.Default.(func() uuid.UUID) + messageremindFields := schema.MessageRemind{}.Fields() + _ = messageremindFields + // messageremindDescContent is the schema descriptor for content field. + messageremindDescContent := messageremindFields[4].Descriptor() + // messageremind.ContentValidator is a validator for the "content" field. It is called by the builders before save. + messageremind.ContentValidator = messageremindDescContent.Validators[0].(func(string) error) + // messageremindDescName is the schema descriptor for name field. + messageremindDescName := messageremindFields[5].Descriptor() + // messageremind.NameValidator is a validator for the "name" field. It is called by the builders before save. + messageremind.NameValidator = messageremindDescName.Validators[0].(func(string) error) + // messageremindDescID is the schema descriptor for id field. + messageremindDescID := messageremindFields[0].Descriptor() + // messageremind.DefaultID holds the default value on creation for the id field. + messageremind.DefaultID = messageremindDescID.Default.(func() uuid.UUID) + rolepanelFields := schema.RolePanel{}.Fields() + _ = rolepanelFields + // rolepanelDescName is the schema descriptor for name field. + rolepanelDescName := rolepanelFields[1].Descriptor() + // rolepanel.NameValidator is a validator for the "name" field. It is called by the builders before save. + rolepanel.NameValidator = rolepanelDescName.Validators[0].(func(string) error) + // rolepanelDescID is the schema descriptor for id field. + rolepanelDescID := rolepanelFields[0].Descriptor() + // rolepanel.DefaultID holds the default value on creation for the id field. + rolepanel.DefaultID = rolepanelDescID.Default.(func() uuid.UUID) + rolepaneleditFields := schema.RolePanelEdit{}.Fields() + _ = rolepaneleditFields + // rolepaneleditDescModified is the schema descriptor for modified field. + rolepaneleditDescModified := rolepaneleditFields[5].Descriptor() + // rolepaneledit.DefaultModified holds the default value on creation for the modified field. + rolepaneledit.DefaultModified = rolepaneleditDescModified.Default.(bool) + // rolepaneleditDescName is the schema descriptor for name field. + rolepaneleditDescName := rolepaneleditFields[6].Descriptor() + // rolepaneledit.NameValidator is a validator for the "name" field. It is called by the builders before save. + rolepaneledit.NameValidator = rolepaneleditDescName.Validators[0].(func(string) error) + // rolepaneleditDescID is the schema descriptor for id field. + rolepaneleditDescID := rolepaneleditFields[0].Descriptor() + // rolepaneledit.DefaultID holds the default value on creation for the id field. + rolepaneledit.DefaultID = rolepaneleditDescID.Default.(func() uuid.UUID) + rolepanelplacedFields := schema.RolePanelPlaced{}.Fields() + _ = rolepanelplacedFields + // rolepanelplacedDescButtonType is the schema descriptor for button_type field. + rolepanelplacedDescButtonType := rolepanelplacedFields[4].Descriptor() + // rolepanelplaced.DefaultButtonType holds the default value on creation for the button_type field. + rolepanelplaced.DefaultButtonType = discord.ButtonStyle(rolepanelplacedDescButtonType.Default.(int)) + // rolepanelplaced.ButtonTypeValidator is a validator for the "button_type" field. It is called by the builders before save. + rolepanelplaced.ButtonTypeValidator = func() func(int) error { + validators := rolepanelplacedDescButtonType.Validators + fns := [...]func(int) error{ + validators[0].(func(int) error), + validators[1].(func(int) error), + } + return func(button_type int) error { + for _, fn := range fns { + if err := fn(button_type); err != nil { + return err + } + } + return nil + } + }() + // rolepanelplacedDescShowName is the schema descriptor for show_name field. + rolepanelplacedDescShowName := rolepanelplacedFields[5].Descriptor() + // rolepanelplaced.DefaultShowName holds the default value on creation for the show_name field. + rolepanelplaced.DefaultShowName = rolepanelplacedDescShowName.Default.(bool) + // rolepanelplacedDescFoldingSelectMenu is the schema descriptor for folding_select_menu field. + rolepanelplacedDescFoldingSelectMenu := rolepanelplacedFields[6].Descriptor() + // rolepanelplaced.DefaultFoldingSelectMenu holds the default value on creation for the folding_select_menu field. + rolepanelplaced.DefaultFoldingSelectMenu = rolepanelplacedDescFoldingSelectMenu.Default.(bool) + // rolepanelplacedDescHideNotice is the schema descriptor for hide_notice field. + rolepanelplacedDescHideNotice := rolepanelplacedFields[7].Descriptor() + // rolepanelplaced.DefaultHideNotice holds the default value on creation for the hide_notice field. + rolepanelplaced.DefaultHideNotice = rolepanelplacedDescHideNotice.Default.(bool) + // rolepanelplacedDescUseDisplayName is the schema descriptor for use_display_name field. + rolepanelplacedDescUseDisplayName := rolepanelplacedFields[8].Descriptor() + // rolepanelplaced.DefaultUseDisplayName holds the default value on creation for the use_display_name field. + rolepanelplaced.DefaultUseDisplayName = rolepanelplacedDescUseDisplayName.Default.(bool) + // rolepanelplacedDescCreatedAt is the schema descriptor for created_at field. + rolepanelplacedDescCreatedAt := rolepanelplacedFields[9].Descriptor() + // rolepanelplaced.DefaultCreatedAt holds the default value on creation for the created_at field. + rolepanelplaced.DefaultCreatedAt = rolepanelplacedDescCreatedAt.Default.(func() time.Time) + // rolepanelplacedDescUses is the schema descriptor for uses field. + rolepanelplacedDescUses := rolepanelplacedFields[10].Descriptor() + // rolepanelplaced.DefaultUses holds the default value on creation for the uses field. + rolepanelplaced.DefaultUses = rolepanelplacedDescUses.Default.(int) + // rolepanelplacedDescName is the schema descriptor for name field. + rolepanelplacedDescName := rolepanelplacedFields[11].Descriptor() + // rolepanelplaced.NameValidator is a validator for the "name" field. It is called by the builders before save. + rolepanelplaced.NameValidator = rolepanelplacedDescName.Validators[0].(func(string) error) + // rolepanelplacedDescID is the schema descriptor for id field. + rolepanelplacedDescID := rolepanelplacedFields[0].Descriptor() + // rolepanelplaced.DefaultID holds the default value on creation for the id field. + rolepanelplaced.DefaultID = rolepanelplacedDescID.Default.(func() uuid.UUID) + userFields := schema.User{}.Fields() + _ = userFields + // userDescName is the schema descriptor for name field. + userDescName := userFields[1].Descriptor() + // user.NameValidator is a validator for the "name" field. It is called by the builders before save. + user.NameValidator = userDescName.Validators[0].(func(string) error) + // userDescCreatedAt is the schema descriptor for created_at field. + userDescCreatedAt := userFields[2].Descriptor() + // user.DefaultCreatedAt holds the default value on creation for the created_at field. + user.DefaultCreatedAt = userDescCreatedAt.Default.(func() time.Time) + // userDescLocale is the schema descriptor for locale field. + userDescLocale := userFields[3].Descriptor() + // user.DefaultLocale holds the default value on creation for the locale field. + user.DefaultLocale = discord.Locale(userDescLocale.Default.(string)) + // user.LocaleValidator is a validator for the "locale" field. It is called by the builders before save. + user.LocaleValidator = userDescLocale.Validators[0].(func(string) error) + // userDescXp is the schema descriptor for xp field. + userDescXp := userFields[4].Descriptor() + // user.DefaultXp holds the default value on creation for the xp field. + user.DefaultXp = xppoint.XP(userDescXp.Default.(uint64)) + wordsuffixFields := schema.WordSuffix{}.Fields() + _ = wordsuffixFields + // wordsuffixDescSuffix is the schema descriptor for suffix field. + wordsuffixDescSuffix := wordsuffixFields[1].Descriptor() + // wordsuffix.SuffixValidator is a validator for the "suffix" field. It is called by the builders before save. + wordsuffix.SuffixValidator = wordsuffixDescSuffix.Validators[0].(func(string) error) + // wordsuffixDescID is the schema descriptor for id field. + wordsuffixDescID := wordsuffixFields[0].Descriptor() + // wordsuffix.DefaultID holds the default value on creation for the id field. + wordsuffix.DefaultID = wordsuffixDescID.Default.(func() uuid.UUID) +} diff --git a/ent/runtime/runtime.go b/ent/runtime/runtime.go new file mode 100644 index 00000000..ffe89152 --- /dev/null +++ b/ent/runtime/runtime.go @@ -0,0 +1,10 @@ +// Code generated by ent, DO NOT EDIT. + +package runtime + +// The schema-stitching logic is generated in github.com/sabafly/gobot/ent/runtime.go + +const ( + Version = "v0.13.1" // Version of ent codegen. + Sum = "h1:uD8QwN1h6SNphdCCzmkMN3feSUzNnVvV/WIkHKMbzOE=" // Sum of ent codegen. +) diff --git a/ent/schema/guild.go b/ent/schema/guild.go new file mode 100644 index 00000000..9f934a02 --- /dev/null +++ b/ent/schema/guild.go @@ -0,0 +1,109 @@ +package schema + +import ( + "time" + + "entgo.io/ent" + "entgo.io/ent/dialect/entsql" + "entgo.io/ent/schema/edge" + "entgo.io/ent/schema/field" + "github.com/disgoorg/disgo/discord" + "github.com/disgoorg/snowflake/v2" + "github.com/sabafly/gobot/internal/permissions" +) + +// Guild holds the schema definition for the Guild entity. +type Guild struct { + ent.Schema +} + +// Fields of the Guild. +func (Guild) Fields() []ent.Field { + return []ent.Field{ + field.Uint64("id"). + Unique(). + Immutable(). + GoType(snowflake.ID(0)), + field.String("name"). + NotEmpty(), + field.String("locale"). + NotEmpty(). + Default(string(discord.LocaleJapanese)). + GoType(discord.Locale("")), + field.String("level_up_message"). + NotEmpty(). + Default("{user}がレベルアップしたよ🥳\n**{before_level} レベル → {after_level} レベル**"), + field.Uint64("level_up_channel"). + Optional(). + Nillable(). + GoType(snowflake.ID(0)), + field.JSON("level_up_exclude_channel", []snowflake.ID{}). + Optional(), + field.Bool("level_mee6_imported"). + Default(false), + field.JSON("level_role", map[int]snowflake.ID{}). + Default(make(map[int]snowflake.ID)). + Optional(), + field.JSON("permissions", map[snowflake.ID]permissions.Permission{}). + Default(make(map[snowflake.ID]permissions.Permission)), + field.Int("remind_count"). + Default(0), + field.JSON("role_panel_edit_times", []time.Time{}). + Default([]time.Time{}). + Annotations( + entsql.Default(`[]`), + ), + field.Bool("bump_enabled"). + Default(true), + field.String("bump_message_title"). + NotEmpty(). + Default("Bumpを怜知したした"), + field.String("bump_message"). + NotEmpty(). + Default("時間埌に通知したす"), + field.String("bump_remind_message_title"). + NotEmpty(). + Default("Bumpの時間です"), + field.String("bump_remind_message"). + NotEmpty(). + Default("でBumpしたしょう"), + field.Bool("up_enabled"). + Default(true), + field.String("up_message_title"). + NotEmpty(). + Default("UPを怜知したした"), + field.String("up_message"). + NotEmpty(). + Default("時間埌に通知したす"), + field.String("up_remind_message_title"). + NotEmpty(). + Default("UPの時間です"), + field.String("up_remind_message"). + NotEmpty(). + Default("でUPしたしょう"), + field.Uint64("bump_mention"). + Nillable(). + Optional(). + GoType(snowflake.ID(0)), + field.Uint64("up_mention"). + Nillable(). + Optional(). + GoType(snowflake.ID(0)), + } +} + +// Edges of the Guild. +func (Guild) Edges() []ent.Edge { + return []ent.Edge{ + edge.From("owner", User.Type). + Ref("own_guilds"). + Unique(). + Required(), + edge.To("members", Member.Type), + edge.To("message_pins", MessagePin.Type), + edge.To("reminds", MessageRemind.Type), + edge.To("role_panels", RolePanel.Type), + edge.To("role_panel_placements", RolePanelPlaced.Type), + edge.To("role_panel_edits", RolePanelEdit.Type), + } +} diff --git a/ent/schema/member.go b/ent/schema/member.go new file mode 100644 index 00000000..c312d96b --- /dev/null +++ b/ent/schema/member.go @@ -0,0 +1,53 @@ +package schema + +import ( + "entgo.io/ent" + "entgo.io/ent/schema/edge" + "entgo.io/ent/schema/field" + "github.com/disgoorg/snowflake/v2" + "github.com/sabafly/gobot/internal/permissions" + "github.com/sabafly/gobot/internal/xppoint" +) + +// Member holds the schema definition for the Member entity. +type Member struct { + ent.Schema +} + +// Fields of the Member. +func (Member) Fields() []ent.Field { + return []ent.Field{ + field.JSON("permission", permissions.Permission{}). + Default(permissions.Permission{}). + Optional(), + field.Uint64("xp"). + Default(0). + GoType(xppoint.XP(0)), + field.Uint64("user_id"). + Immutable(). + GoType(snowflake.ID(0)), + field.Time("last_xp"). + Optional(), + field.Uint64("message_count"). + Default(0), + field.Uint64("last_notified_level"). + Nillable(). + Optional(), + } +} + +// Edges of the Member. +func (Member) Edges() []ent.Edge { + return []ent.Edge{ + edge.From("guild", Guild.Type). + Ref("members"). + Unique(). + Required(), + edge.From("user", User.Type). + Ref("guilds"). + Field("user_id"). + Immutable(). + Unique(). + Required(), + } +} diff --git a/ent/schema/messagepin.go b/ent/schema/messagepin.go new file mode 100644 index 00000000..49f96337 --- /dev/null +++ b/ent/schema/messagepin.go @@ -0,0 +1,71 @@ +package schema + +import ( + "encoding/json" + "github.com/sabafly/gobot/internal/uuidv7" + "time" + + "entgo.io/ent" + "entgo.io/ent/schema/edge" + "entgo.io/ent/schema/field" + "github.com/disgoorg/disgo/discord" + "github.com/disgoorg/snowflake/v2" +) + +// MessagePin holds the schema definition for the MessagePin entity. +type MessagePin struct { + ent.Schema +} + +// Fields of the MessagePin. +func (MessagePin) Fields() []ent.Field { + return []ent.Field{ + field.UUID("id", uuidv7.New()). + Unique(). + Immutable(). + Default(uuidv7.New), + field.Uint64("channel_id"). + Unique(). + GoType(snowflake.ID(0)), + field.String("content"). + Optional(), + field.JSON("embeds", []discord.Embed{}). + Optional(), + field.Uint64("before_id"). + Optional(). + Nillable(). + GoType(snowflake.ID(0)), + field.JSON("rate_limit", RateLimit{}).Default(RateLimit{limit: []time.Time{}}), + } +} + +type RateLimit struct { + limit []time.Time +} + +func (r RateLimit) MarshalJSON() ([]byte, error) { + return json.Marshal(r.limit) +} + +func (r *RateLimit) UnmarshalJSON(b []byte) error { + return json.Unmarshal(b, &r.limit) +} + +func (r *RateLimit) CheckLimit() bool { + if !((len(r.limit) < 3 || time.Since(r.limit[2]) >= time.Second*5) && (len(r.limit) < 10 || time.Since(r.limit[9]) >= time.Second*30)) { + return false + } + r.limit = append([]time.Time{time.Now()}, r.limit[0:min(10, len(r.limit))]...) + ok := (len(r.limit) < 3 || time.Since(r.limit[2]) >= time.Second*5) && (len(r.limit) < 10 || time.Since(r.limit[9]) >= time.Second*30) + return ok +} + +// Edges of the MessagePin. +func (MessagePin) Edges() []ent.Edge { + return []ent.Edge{ + edge.From("guild", Guild.Type). + Ref("message_pins"). + Required(). + Unique(), + } +} diff --git a/ent/schema/messageremind.go b/ent/schema/messageremind.go new file mode 100644 index 00000000..24051acb --- /dev/null +++ b/ent/schema/messageremind.go @@ -0,0 +1,43 @@ +package schema + +import ( + "entgo.io/ent" + "entgo.io/ent/schema/edge" + "entgo.io/ent/schema/field" + "github.com/disgoorg/snowflake/v2" + "github.com/sabafly/gobot/internal/uuidv7" +) + +// MessageRemind holds the schema definition for the MessageRemind entity. +type MessageRemind struct { + ent.Schema +} + +// Fields of the MessageRemind. +func (MessageRemind) Fields() []ent.Field { + return []ent.Field{ + field.UUID("id", uuidv7.New()). + Unique(). + Immutable(). + Default(uuidv7.New), + field.Uint64("channel_id"). + GoType(snowflake.ID(0)), + field.Uint64("author_id"). + GoType(snowflake.ID(0)), + field.Time("time"), + field.String("content"). + NotEmpty(), + field.String("name"). + NotEmpty(), + } +} + +// Edges of the MessageRemind. +func (MessageRemind) Edges() []ent.Edge { + return []ent.Edge{ + edge.From("guild", Guild.Type). + Ref("reminds"). + Required(). + Unique(), + } +} diff --git a/ent/schema/rolepanel.go b/ent/schema/rolepanel.go new file mode 100644 index 00000000..f593d836 --- /dev/null +++ b/ent/schema/rolepanel.go @@ -0,0 +1,51 @@ +package schema + +import ( + "entgo.io/ent" + "entgo.io/ent/schema/edge" + "entgo.io/ent/schema/field" + "github.com/disgoorg/disgo/discord" + "github.com/disgoorg/snowflake/v2" + "github.com/sabafly/gobot/internal/uuidv7" +) + +// RolePanel holds the schema definition for the RolePanel entity. +type RolePanel struct { + ent.Schema +} + +// Fields of the RolePanel. +func (RolePanel) Fields() []ent.Field { + return []ent.Field{ + field.UUID("id", uuidv7.New()). + Immutable(). + Unique(). + Default(uuidv7.New), + field.String("name"). + NotEmpty(), + field.String("description"), + field.JSON("roles", []Role{}). + Optional(), + field.Time("updated_at").Optional(), + field.Time("applied_at").Optional(), + } +} + +type Role struct { + ID snowflake.ID `json:"id"` + Name string `json:"name"` + Emoji *discord.ComponentEmoji `json:"emoji"` +} + +// Edges of the RolePanel. +func (RolePanel) Edges() []ent.Edge { + return []ent.Edge{ + edge.From("guild", Guild.Type). + Ref("role_panels"). + Required(). + Unique(), + edge.To("placements", RolePanelPlaced.Type), + edge.To("edit", RolePanelEdit.Type). + Unique(), + } +} diff --git a/ent/schema/rolepaneledit.go b/ent/schema/rolepaneledit.go new file mode 100644 index 00000000..72f7f7d9 --- /dev/null +++ b/ent/schema/rolepaneledit.go @@ -0,0 +1,64 @@ +package schema + +import ( + "entgo.io/ent" + "entgo.io/ent/schema/edge" + "entgo.io/ent/schema/field" + "github.com/disgoorg/snowflake/v2" + "github.com/sabafly/gobot/internal/uuidv7" +) + +// RolePanelEdit holds the schema definition for the RolePanelEdit entity. +type RolePanelEdit struct { + ent.Schema +} + +// Fields of the RolePanelEdit. +func (RolePanelEdit) Fields() []ent.Field { + return []ent.Field{ + field.UUID("id", uuidv7.New()). + Immutable(). + Unique(). + Default(uuidv7.New), + field.Uint64("channel_id"). + GoType(snowflake.ID(0)), + field.Uint64("emoji_author"). + Optional(). + Nillable(). + GoType(snowflake.ID(0)), + field.String("token"). + Optional(). + Nillable(), + field.Uint64("selected_role"). + Optional(). + Nillable(). + GoType(snowflake.ID(0)), + field.Bool("modified"). + Default(false), + field.String("name"). + Optional(). + Nillable(). + NotEmpty(), + field.String("description"). + Optional(). + Nillable(), + field.JSON("roles", []Role{}). + Optional(), + } +} + +// Edges of the RolePanelEdit. +func (RolePanelEdit) Edges() []ent.Edge { + return []ent.Edge{ + edge.From("guild", Guild.Type). + Ref("role_panel_edits"). + Required(). + Unique(). + Immutable(), + edge.From("parent", RolePanel.Type). + Ref("edit"). + Required(). + Unique(). + Immutable(), + } +} diff --git a/ent/schema/rolepanelplaced.go b/ent/schema/rolepanelplaced.go new file mode 100644 index 00000000..93f7e80d --- /dev/null +++ b/ent/schema/rolepanelplaced.go @@ -0,0 +1,75 @@ +package schema + +import ( + "github.com/sabafly/gobot/internal/uuidv7" + "time" + + "entgo.io/ent" + "entgo.io/ent/schema/edge" + "entgo.io/ent/schema/field" + "github.com/disgoorg/disgo/discord" + "github.com/disgoorg/snowflake/v2" +) + +// RolePanelPlaced holds the schema definition for the RolePanelPlaced entity. +type RolePanelPlaced struct { + ent.Schema +} + +// Fields of the RolePanelPlaced. +func (RolePanelPlaced) Fields() []ent.Field { + return []ent.Field{ + field.UUID("id", uuidv7.New()). + Immutable(). + Unique(). + Default(uuidv7.New), + field.Uint64("message_id"). + Optional(). + Nillable(). + GoType(snowflake.ID(0)), + field.Uint64("channel_id"). + GoType(snowflake.ID(0)), + field.Enum("type"). + Values("button", "reaction", "select_menu"). + Optional(), + field.Int("button_type"). + Min(int(discord.ButtonStylePrimary)). + Max(int(discord.ButtonStyleDanger)). + Default(int(discord.ButtonStylePrimary)). + GoType(discord.ButtonStyle(0)), + field.Bool("show_name"). + Default(false), + field.Bool("folding_select_menu"). + Default(true), + field.Bool("hide_notice"). + Default(false), + field.Bool("use_display_name"). + Default(false), + field.Time("created_at"). + Immutable(). + Default(time.Now), + field.Int("uses"). + Default(0), + field.String("name"). + NotEmpty(), + field.String("description"), + field.JSON("roles", []Role{}). + Optional(), + field.Time("updated_at"). + Optional(), + } +} + +// Edges of the RolePanelPlaced. +func (RolePanelPlaced) Edges() []ent.Edge { + return []ent.Edge{ + edge.From("guild", Guild.Type). + Ref("role_panel_placements"). + Required(). + Unique(), + edge.From("role_panel", RolePanel.Type). + Ref("placements"). + Required(). + Unique(), + } +} diff --git a/ent/schema/user.go b/ent/schema/user.go new file mode 100644 index 00000000..6b8a51b0 --- /dev/null +++ b/ent/schema/user.go @@ -0,0 +1,48 @@ +package schema + +import ( + "time" + + "entgo.io/ent" + "entgo.io/ent/schema/edge" + "entgo.io/ent/schema/field" + "github.com/disgoorg/disgo/discord" + "github.com/disgoorg/snowflake/v2" + "github.com/sabafly/gobot/internal/xppoint" +) + +// User holds the schema definition for the User entity. +type User struct { + ent.Schema +} + +// Fields of the User. +func (User) Fields() []ent.Field { + return []ent.Field{ + field.Uint64("id"). + Unique(). + Immutable(). + GoType(snowflake.ID(0)), + field.String("name"). + NotEmpty(), + field.Time("created_at"). + Default(time.Now). + Immutable(), + field.String("locale"). + NotEmpty(). + Default(string(discord.LocaleJapanese)). + GoType(discord.Locale("")), + field.Uint64("xp"). + Default(0). + GoType(xppoint.XP(0)), + } +} + +// Edges of the User. +func (User) Edges() []ent.Edge { + return []ent.Edge{ + edge.To("own_guilds", Guild.Type), + edge.To("guilds", Member.Type), + edge.To("word_suffix", WordSuffix.Type), + } +} diff --git a/ent/schema/wordsuffix.go b/ent/schema/wordsuffix.go new file mode 100644 index 00000000..5988699c --- /dev/null +++ b/ent/schema/wordsuffix.go @@ -0,0 +1,47 @@ +package schema + +import ( + "entgo.io/ent" + "entgo.io/ent/schema/edge" + "entgo.io/ent/schema/field" + "github.com/disgoorg/snowflake/v2" + "github.com/sabafly/gobot/internal/uuidv7" +) + +// WordSuffix holds the schema definition for the WordSuffix entity. +type WordSuffix struct { + ent.Schema +} + +// Fields of the WordSuffix. +func (WordSuffix) Fields() []ent.Field { + return []ent.Field{ + field.UUID("id", uuidv7.New()). + Default(uuidv7.New), + field.String("suffix"). + NotEmpty(), + field.Time("expired"). + Optional(). + Nillable(), + field.Uint64("guild_id"). + Optional(). + Nillable(). + GoType(snowflake.ID(0)), + field.Enum("rule"). + Values("webhook", "warn", "delete"). + Default("webhook"), + } +} + +// Edges of the WordSuffix. +func (WordSuffix) Edges() []ent.Edge { + return []ent.Edge{ + edge.To("guild", Guild.Type). + Field("guild_id"). + Unique(), + edge.From("owner", User.Type). + Ref("word_suffix"). + Unique(). + Required(), + } +} diff --git a/ent/tx.go b/ent/tx.go new file mode 100644 index 00000000..37b3a35b --- /dev/null +++ b/ent/tx.go @@ -0,0 +1,234 @@ +// Code generated by ent, DO NOT EDIT. + +package ent + +import ( + "context" + "sync" + + "entgo.io/ent/dialect" +) + +// Tx is a transactional client that is created by calling Client.Tx(). +type Tx struct { + config + // Guild is the client for interacting with the Guild builders. + Guild *GuildClient + // Member is the client for interacting with the Member builders. + Member *MemberClient + // MessagePin is the client for interacting with the MessagePin builders. + MessagePin *MessagePinClient + // MessageRemind is the client for interacting with the MessageRemind builders. + MessageRemind *MessageRemindClient + // RolePanel is the client for interacting with the RolePanel builders. + RolePanel *RolePanelClient + // RolePanelEdit is the client for interacting with the RolePanelEdit builders. + RolePanelEdit *RolePanelEditClient + // RolePanelPlaced is the client for interacting with the RolePanelPlaced builders. + RolePanelPlaced *RolePanelPlacedClient + // User is the client for interacting with the User builders. + User *UserClient + // WordSuffix is the client for interacting with the WordSuffix builders. + WordSuffix *WordSuffixClient + + // lazily loaded. + client *Client + clientOnce sync.Once + // ctx lives for the life of the transaction. It is + // the same context used by the underlying connection. + ctx context.Context +} + +type ( + // Committer is the interface that wraps the Commit method. + Committer interface { + Commit(context.Context, *Tx) error + } + + // The CommitFunc type is an adapter to allow the use of ordinary + // function as a Committer. If f is a function with the appropriate + // signature, CommitFunc(f) is a Committer that calls f. + CommitFunc func(context.Context, *Tx) error + + // CommitHook defines the "commit middleware". A function that gets a Committer + // and returns a Committer. For example: + // + // hook := func(next ent.Committer) ent.Committer { + // return ent.CommitFunc(func(ctx context.Context, tx *ent.Tx) error { + // // Do some stuff before. + // if err := next.Commit(ctx, tx); err != nil { + // return err + // } + // // Do some stuff after. + // return nil + // }) + // } + // + CommitHook func(Committer) Committer +) + +// Commit calls f(ctx, m). +func (f CommitFunc) Commit(ctx context.Context, tx *Tx) error { + return f(ctx, tx) +} + +// Commit commits the transaction. +func (tx *Tx) Commit() error { + txDriver := tx.config.driver.(*txDriver) + var fn Committer = CommitFunc(func(context.Context, *Tx) error { + return txDriver.tx.Commit() + }) + txDriver.mu.Lock() + hooks := append([]CommitHook(nil), txDriver.onCommit...) + txDriver.mu.Unlock() + for i := len(hooks) - 1; i >= 0; i-- { + fn = hooks[i](fn) + } + return fn.Commit(tx.ctx, tx) +} + +// OnCommit adds a hook to call on commit. +func (tx *Tx) OnCommit(f CommitHook) { + txDriver := tx.config.driver.(*txDriver) + txDriver.mu.Lock() + txDriver.onCommit = append(txDriver.onCommit, f) + txDriver.mu.Unlock() +} + +type ( + // Rollbacker is the interface that wraps the Rollback method. + Rollbacker interface { + Rollback(context.Context, *Tx) error + } + + // The RollbackFunc type is an adapter to allow the use of ordinary + // function as a Rollbacker. If f is a function with the appropriate + // signature, RollbackFunc(f) is a Rollbacker that calls f. + RollbackFunc func(context.Context, *Tx) error + + // RollbackHook defines the "rollback middleware". A function that gets a Rollbacker + // and returns a Rollbacker. For example: + // + // hook := func(next ent.Rollbacker) ent.Rollbacker { + // return ent.RollbackFunc(func(ctx context.Context, tx *ent.Tx) error { + // // Do some stuff before. + // if err := next.Rollback(ctx, tx); err != nil { + // return err + // } + // // Do some stuff after. + // return nil + // }) + // } + // + RollbackHook func(Rollbacker) Rollbacker +) + +// Rollback calls f(ctx, m). +func (f RollbackFunc) Rollback(ctx context.Context, tx *Tx) error { + return f(ctx, tx) +} + +// Rollback rollbacks the transaction. +func (tx *Tx) Rollback() error { + txDriver := tx.config.driver.(*txDriver) + var fn Rollbacker = RollbackFunc(func(context.Context, *Tx) error { + return txDriver.tx.Rollback() + }) + txDriver.mu.Lock() + hooks := append([]RollbackHook(nil), txDriver.onRollback...) + txDriver.mu.Unlock() + for i := len(hooks) - 1; i >= 0; i-- { + fn = hooks[i](fn) + } + return fn.Rollback(tx.ctx, tx) +} + +// OnRollback adds a hook to call on rollback. +func (tx *Tx) OnRollback(f RollbackHook) { + txDriver := tx.config.driver.(*txDriver) + txDriver.mu.Lock() + txDriver.onRollback = append(txDriver.onRollback, f) + txDriver.mu.Unlock() +} + +// Client returns a Client that binds to current transaction. +func (tx *Tx) Client() *Client { + tx.clientOnce.Do(func() { + tx.client = &Client{config: tx.config} + tx.client.init() + }) + return tx.client +} + +func (tx *Tx) init() { + tx.Guild = NewGuildClient(tx.config) + tx.Member = NewMemberClient(tx.config) + tx.MessagePin = NewMessagePinClient(tx.config) + tx.MessageRemind = NewMessageRemindClient(tx.config) + tx.RolePanel = NewRolePanelClient(tx.config) + tx.RolePanelEdit = NewRolePanelEditClient(tx.config) + tx.RolePanelPlaced = NewRolePanelPlacedClient(tx.config) + tx.User = NewUserClient(tx.config) + tx.WordSuffix = NewWordSuffixClient(tx.config) +} + +// txDriver wraps the given dialect.Tx with a nop dialect.Driver implementation. +// The idea is to support transactions without adding any extra code to the builders. +// When a builder calls to driver.Tx(), it gets the same dialect.Tx instance. +// Commit and Rollback are nop for the internal builders and the user must call one +// of them in order to commit or rollback the transaction. +// +// If a closed transaction is embedded in one of the generated entities, and the entity +// applies a query, for example: Guild.QueryXXX(), the query will be executed +// through the driver which created this transaction. +// +// Note that txDriver is not goroutine safe. +type txDriver struct { + // the driver we started the transaction from. + drv dialect.Driver + // tx is the underlying transaction. + tx dialect.Tx + // completion hooks. + mu sync.Mutex + onCommit []CommitHook + onRollback []RollbackHook +} + +// newTx creates a new transactional driver. +func newTx(ctx context.Context, drv dialect.Driver) (*txDriver, error) { + tx, err := drv.Tx(ctx) + if err != nil { + return nil, err + } + return &txDriver{tx: tx, drv: drv}, nil +} + +// Tx returns the transaction wrapper (txDriver) to avoid Commit or Rollback calls +// from the internal builders. Should be called only by the internal builders. +func (tx *txDriver) Tx(context.Context) (dialect.Tx, error) { return tx, nil } + +// Dialect returns the dialect of the driver we started the transaction from. +func (tx *txDriver) Dialect() string { return tx.drv.Dialect() } + +// Close is a nop close. +func (*txDriver) Close() error { return nil } + +// Commit is a nop commit for the internal builders. +// User must call `Tx.Commit` in order to commit the transaction. +func (*txDriver) Commit() error { return nil } + +// Rollback is a nop rollback for the internal builders. +// User must call `Tx.Rollback` in order to rollback the transaction. +func (*txDriver) Rollback() error { return nil } + +// Exec calls tx.Exec. +func (tx *txDriver) Exec(ctx context.Context, query string, args, v any) error { + return tx.tx.Exec(ctx, query, args, v) +} + +// Query calls tx.Query. +func (tx *txDriver) Query(ctx context.Context, query string, args, v any) error { + return tx.tx.Query(ctx, query, args, v) +} + +var _ dialect.Driver = (*txDriver)(nil) diff --git a/ent/user.go b/ent/user.go new file mode 100644 index 00000000..72dd2eee --- /dev/null +++ b/ent/user.go @@ -0,0 +1,200 @@ +// Code generated by ent, DO NOT EDIT. + +package ent + +import ( + "fmt" + "strings" + "time" + + "entgo.io/ent" + "entgo.io/ent/dialect/sql" + "github.com/disgoorg/disgo/discord" + snowflake "github.com/disgoorg/snowflake/v2" + "github.com/sabafly/gobot/ent/user" + "github.com/sabafly/gobot/internal/xppoint" +) + +// User is the model entity for the User schema. +type User struct { + config `json:"-"` + // ID of the ent. + ID snowflake.ID `json:"id,omitempty"` + // Name holds the value of the "name" field. + Name string `json:"name,omitempty"` + // CreatedAt holds the value of the "created_at" field. + CreatedAt time.Time `json:"created_at,omitempty"` + // Locale holds the value of the "locale" field. + Locale discord.Locale `json:"locale,omitempty"` + // Xp holds the value of the "xp" field. + Xp xppoint.XP `json:"xp,omitempty"` + // Edges holds the relations/edges for other nodes in the graph. + // The values are being populated by the UserQuery when eager-loading is set. + Edges UserEdges `json:"edges"` + selectValues sql.SelectValues +} + +// UserEdges holds the relations/edges for other nodes in the graph. +type UserEdges struct { + // OwnGuilds holds the value of the own_guilds edge. + OwnGuilds []*Guild `json:"own_guilds,omitempty"` + // Guilds holds the value of the guilds edge. + Guilds []*Member `json:"guilds,omitempty"` + // WordSuffix holds the value of the word_suffix edge. + WordSuffix []*WordSuffix `json:"word_suffix,omitempty"` + // loadedTypes holds the information for reporting if a + // type was loaded (or requested) in eager-loading or not. + loadedTypes [3]bool +} + +// OwnGuildsOrErr returns the OwnGuilds value or an error if the edge +// was not loaded in eager-loading. +func (e UserEdges) OwnGuildsOrErr() ([]*Guild, error) { + if e.loadedTypes[0] { + return e.OwnGuilds, nil + } + return nil, &NotLoadedError{edge: "own_guilds"} +} + +// GuildsOrErr returns the Guilds value or an error if the edge +// was not loaded in eager-loading. +func (e UserEdges) GuildsOrErr() ([]*Member, error) { + if e.loadedTypes[1] { + return e.Guilds, nil + } + return nil, &NotLoadedError{edge: "guilds"} +} + +// WordSuffixOrErr returns the WordSuffix value or an error if the edge +// was not loaded in eager-loading. +func (e UserEdges) WordSuffixOrErr() ([]*WordSuffix, error) { + if e.loadedTypes[2] { + return e.WordSuffix, nil + } + return nil, &NotLoadedError{edge: "word_suffix"} +} + +// scanValues returns the types for scanning values from sql.Rows. +func (*User) scanValues(columns []string) ([]any, error) { + values := make([]any, len(columns)) + for i := range columns { + switch columns[i] { + case user.FieldID, user.FieldXp: + values[i] = new(sql.NullInt64) + case user.FieldName, user.FieldLocale: + values[i] = new(sql.NullString) + case user.FieldCreatedAt: + values[i] = new(sql.NullTime) + default: + values[i] = new(sql.UnknownType) + } + } + return values, nil +} + +// assignValues assigns the values that were returned from sql.Rows (after scanning) +// to the User fields. +func (u *User) assignValues(columns []string, values []any) error { + if m, n := len(values), len(columns); m < n { + return fmt.Errorf("mismatch number of scan values: %d != %d", m, n) + } + for i := range columns { + switch columns[i] { + case user.FieldID: + if value, ok := values[i].(*sql.NullInt64); !ok { + return fmt.Errorf("unexpected type %T for field id", values[i]) + } else if value.Valid { + u.ID = snowflake.ID(value.Int64) + } + case user.FieldName: + if value, ok := values[i].(*sql.NullString); !ok { + return fmt.Errorf("unexpected type %T for field name", values[i]) + } else if value.Valid { + u.Name = value.String + } + case user.FieldCreatedAt: + if value, ok := values[i].(*sql.NullTime); !ok { + return fmt.Errorf("unexpected type %T for field created_at", values[i]) + } else if value.Valid { + u.CreatedAt = value.Time + } + case user.FieldLocale: + if value, ok := values[i].(*sql.NullString); !ok { + return fmt.Errorf("unexpected type %T for field locale", values[i]) + } else if value.Valid { + u.Locale = discord.Locale(value.String) + } + case user.FieldXp: + if value, ok := values[i].(*sql.NullInt64); !ok { + return fmt.Errorf("unexpected type %T for field xp", values[i]) + } else if value.Valid { + u.Xp = xppoint.XP(value.Int64) + } + default: + u.selectValues.Set(columns[i], values[i]) + } + } + return nil +} + +// Value returns the ent.Value that was dynamically selected and assigned to the User. +// This includes values selected through modifiers, order, etc. +func (u *User) Value(name string) (ent.Value, error) { + return u.selectValues.Get(name) +} + +// QueryOwnGuilds queries the "own_guilds" edge of the User entity. +func (u *User) QueryOwnGuilds() *GuildQuery { + return NewUserClient(u.config).QueryOwnGuilds(u) +} + +// QueryGuilds queries the "guilds" edge of the User entity. +func (u *User) QueryGuilds() *MemberQuery { + return NewUserClient(u.config).QueryGuilds(u) +} + +// QueryWordSuffix queries the "word_suffix" edge of the User entity. +func (u *User) QueryWordSuffix() *WordSuffixQuery { + return NewUserClient(u.config).QueryWordSuffix(u) +} + +// Update returns a builder for updating this User. +// Note that you need to call User.Unwrap() before calling this method if this User +// was returned from a transaction, and the transaction was committed or rolled back. +func (u *User) Update() *UserUpdateOne { + return NewUserClient(u.config).UpdateOne(u) +} + +// Unwrap unwraps the User entity that was returned from a transaction after it was closed, +// so that all future queries will be executed through the driver which created the transaction. +func (u *User) Unwrap() *User { + _tx, ok := u.config.driver.(*txDriver) + if !ok { + panic("ent: User is not a transactional entity") + } + u.config.driver = _tx.drv + return u +} + +// String implements the fmt.Stringer. +func (u *User) String() string { + var builder strings.Builder + builder.WriteString("User(") + builder.WriteString(fmt.Sprintf("id=%v, ", u.ID)) + builder.WriteString("name=") + builder.WriteString(u.Name) + builder.WriteString(", ") + builder.WriteString("created_at=") + builder.WriteString(u.CreatedAt.Format(time.ANSIC)) + builder.WriteString(", ") + builder.WriteString("locale=") + builder.WriteString(fmt.Sprintf("%v", u.Locale)) + builder.WriteString(", ") + builder.WriteString("xp=") + builder.WriteString(fmt.Sprintf("%v", u.Xp)) + builder.WriteByte(')') + return builder.String() +} + +// Users is a parsable slice of User. +type Users []*User diff --git a/ent/user/user.go b/ent/user/user.go new file mode 100644 index 00000000..51085436 --- /dev/null +++ b/ent/user/user.go @@ -0,0 +1,179 @@ +// Code generated by ent, DO NOT EDIT. + +package user + +import ( + "time" + + "entgo.io/ent/dialect/sql" + "entgo.io/ent/dialect/sql/sqlgraph" + "github.com/disgoorg/disgo/discord" + "github.com/sabafly/gobot/internal/xppoint" +) + +const ( + // Label holds the string label denoting the user type in the database. + Label = "user" + // FieldID holds the string denoting the id field in the database. + FieldID = "id" + // FieldName holds the string denoting the name field in the database. + FieldName = "name" + // FieldCreatedAt holds the string denoting the created_at field in the database. + FieldCreatedAt = "created_at" + // FieldLocale holds the string denoting the locale field in the database. + FieldLocale = "locale" + // FieldXp holds the string denoting the xp field in the database. + FieldXp = "xp" + // EdgeOwnGuilds holds the string denoting the own_guilds edge name in mutations. + EdgeOwnGuilds = "own_guilds" + // EdgeGuilds holds the string denoting the guilds edge name in mutations. + EdgeGuilds = "guilds" + // EdgeWordSuffix holds the string denoting the word_suffix edge name in mutations. + EdgeWordSuffix = "word_suffix" + // Table holds the table name of the user in the database. + Table = "users" + // OwnGuildsTable is the table that holds the own_guilds relation/edge. + OwnGuildsTable = "guilds" + // OwnGuildsInverseTable is the table name for the Guild entity. + // It exists in this package in order to avoid circular dependency with the "guild" package. + OwnGuildsInverseTable = "guilds" + // OwnGuildsColumn is the table column denoting the own_guilds relation/edge. + OwnGuildsColumn = "user_own_guilds" + // GuildsTable is the table that holds the guilds relation/edge. + GuildsTable = "members" + // GuildsInverseTable is the table name for the Member entity. + // It exists in this package in order to avoid circular dependency with the "member" package. + GuildsInverseTable = "members" + // GuildsColumn is the table column denoting the guilds relation/edge. + GuildsColumn = "user_id" + // WordSuffixTable is the table that holds the word_suffix relation/edge. + WordSuffixTable = "word_suffixes" + // WordSuffixInverseTable is the table name for the WordSuffix entity. + // It exists in this package in order to avoid circular dependency with the "wordsuffix" package. + WordSuffixInverseTable = "word_suffixes" + // WordSuffixColumn is the table column denoting the word_suffix relation/edge. + WordSuffixColumn = "user_word_suffix" +) + +// Columns holds all SQL columns for user fields. +var Columns = []string{ + FieldID, + FieldName, + FieldCreatedAt, + FieldLocale, + FieldXp, +} + +// ValidColumn reports if the column name is valid (part of the table columns). +func ValidColumn(column string) bool { + for i := range Columns { + if column == Columns[i] { + return true + } + } + return false +} + +var ( + // NameValidator is a validator for the "name" field. It is called by the builders before save. + NameValidator func(string) error + // DefaultCreatedAt holds the default value on creation for the "created_at" field. + DefaultCreatedAt func() time.Time + // DefaultLocale holds the default value on creation for the "locale" field. + DefaultLocale discord.Locale + // LocaleValidator is a validator for the "locale" field. It is called by the builders before save. + LocaleValidator func(string) error + // DefaultXp holds the default value on creation for the "xp" field. + DefaultXp xppoint.XP +) + +// OrderOption defines the ordering options for the User queries. +type OrderOption func(*sql.Selector) + +// ByID orders the results by the id field. +func ByID(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldID, opts...).ToFunc() +} + +// ByName orders the results by the name field. +func ByName(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldName, opts...).ToFunc() +} + +// ByCreatedAt orders the results by the created_at field. +func ByCreatedAt(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldCreatedAt, opts...).ToFunc() +} + +// ByLocale orders the results by the locale field. +func ByLocale(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldLocale, opts...).ToFunc() +} + +// ByXp orders the results by the xp field. +func ByXp(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldXp, opts...).ToFunc() +} + +// ByOwnGuildsCount orders the results by own_guilds count. +func ByOwnGuildsCount(opts ...sql.OrderTermOption) OrderOption { + return func(s *sql.Selector) { + sqlgraph.OrderByNeighborsCount(s, newOwnGuildsStep(), opts...) + } +} + +// ByOwnGuilds orders the results by own_guilds terms. +func ByOwnGuilds(term sql.OrderTerm, terms ...sql.OrderTerm) OrderOption { + return func(s *sql.Selector) { + sqlgraph.OrderByNeighborTerms(s, newOwnGuildsStep(), append([]sql.OrderTerm{term}, terms...)...) + } +} + +// ByGuildsCount orders the results by guilds count. +func ByGuildsCount(opts ...sql.OrderTermOption) OrderOption { + return func(s *sql.Selector) { + sqlgraph.OrderByNeighborsCount(s, newGuildsStep(), opts...) + } +} + +// ByGuilds orders the results by guilds terms. +func ByGuilds(term sql.OrderTerm, terms ...sql.OrderTerm) OrderOption { + return func(s *sql.Selector) { + sqlgraph.OrderByNeighborTerms(s, newGuildsStep(), append([]sql.OrderTerm{term}, terms...)...) + } +} + +// ByWordSuffixCount orders the results by word_suffix count. +func ByWordSuffixCount(opts ...sql.OrderTermOption) OrderOption { + return func(s *sql.Selector) { + sqlgraph.OrderByNeighborsCount(s, newWordSuffixStep(), opts...) + } +} + +// ByWordSuffix orders the results by word_suffix terms. +func ByWordSuffix(term sql.OrderTerm, terms ...sql.OrderTerm) OrderOption { + return func(s *sql.Selector) { + sqlgraph.OrderByNeighborTerms(s, newWordSuffixStep(), append([]sql.OrderTerm{term}, terms...)...) + } +} +func newOwnGuildsStep() *sqlgraph.Step { + return sqlgraph.NewStep( + sqlgraph.From(Table, FieldID), + sqlgraph.To(OwnGuildsInverseTable, FieldID), + sqlgraph.Edge(sqlgraph.O2M, false, OwnGuildsTable, OwnGuildsColumn), + ) +} +func newGuildsStep() *sqlgraph.Step { + return sqlgraph.NewStep( + sqlgraph.From(Table, FieldID), + sqlgraph.To(GuildsInverseTable, FieldID), + sqlgraph.Edge(sqlgraph.O2M, false, GuildsTable, GuildsColumn), + ) +} +func newWordSuffixStep() *sqlgraph.Step { + return sqlgraph.NewStep( + sqlgraph.From(Table, FieldID), + sqlgraph.To(WordSuffixInverseTable, FieldID), + sqlgraph.Edge(sqlgraph.O2M, false, WordSuffixTable, WordSuffixColumn), + ) +} diff --git a/ent/user/where.go b/ent/user/where.go new file mode 100644 index 00000000..159eed6b --- /dev/null +++ b/ent/user/where.go @@ -0,0 +1,408 @@ +// Code generated by ent, DO NOT EDIT. + +package user + +import ( + "time" + + "entgo.io/ent/dialect/sql" + "entgo.io/ent/dialect/sql/sqlgraph" + "github.com/disgoorg/disgo/discord" + snowflake "github.com/disgoorg/snowflake/v2" + "github.com/sabafly/gobot/ent/predicate" + "github.com/sabafly/gobot/internal/xppoint" +) + +// ID filters vertices based on their ID field. +func ID(id snowflake.ID) predicate.User { + return predicate.User(sql.FieldEQ(FieldID, id)) +} + +// IDEQ applies the EQ predicate on the ID field. +func IDEQ(id snowflake.ID) predicate.User { + return predicate.User(sql.FieldEQ(FieldID, id)) +} + +// IDNEQ applies the NEQ predicate on the ID field. +func IDNEQ(id snowflake.ID) predicate.User { + return predicate.User(sql.FieldNEQ(FieldID, id)) +} + +// IDIn applies the In predicate on the ID field. +func IDIn(ids ...snowflake.ID) predicate.User { + return predicate.User(sql.FieldIn(FieldID, ids...)) +} + +// IDNotIn applies the NotIn predicate on the ID field. +func IDNotIn(ids ...snowflake.ID) predicate.User { + return predicate.User(sql.FieldNotIn(FieldID, ids...)) +} + +// IDGT applies the GT predicate on the ID field. +func IDGT(id snowflake.ID) predicate.User { + return predicate.User(sql.FieldGT(FieldID, id)) +} + +// IDGTE applies the GTE predicate on the ID field. +func IDGTE(id snowflake.ID) predicate.User { + return predicate.User(sql.FieldGTE(FieldID, id)) +} + +// IDLT applies the LT predicate on the ID field. +func IDLT(id snowflake.ID) predicate.User { + return predicate.User(sql.FieldLT(FieldID, id)) +} + +// IDLTE applies the LTE predicate on the ID field. +func IDLTE(id snowflake.ID) predicate.User { + return predicate.User(sql.FieldLTE(FieldID, id)) +} + +// Name applies equality check predicate on the "name" field. It's identical to NameEQ. +func Name(v string) predicate.User { + return predicate.User(sql.FieldEQ(FieldName, v)) +} + +// CreatedAt applies equality check predicate on the "created_at" field. It's identical to CreatedAtEQ. +func CreatedAt(v time.Time) predicate.User { + return predicate.User(sql.FieldEQ(FieldCreatedAt, v)) +} + +// Locale applies equality check predicate on the "locale" field. It's identical to LocaleEQ. +func Locale(v discord.Locale) predicate.User { + vc := string(v) + return predicate.User(sql.FieldEQ(FieldLocale, vc)) +} + +// Xp applies equality check predicate on the "xp" field. It's identical to XpEQ. +func Xp(v xppoint.XP) predicate.User { + vc := uint64(v) + return predicate.User(sql.FieldEQ(FieldXp, vc)) +} + +// NameEQ applies the EQ predicate on the "name" field. +func NameEQ(v string) predicate.User { + return predicate.User(sql.FieldEQ(FieldName, v)) +} + +// NameNEQ applies the NEQ predicate on the "name" field. +func NameNEQ(v string) predicate.User { + return predicate.User(sql.FieldNEQ(FieldName, v)) +} + +// NameIn applies the In predicate on the "name" field. +func NameIn(vs ...string) predicate.User { + return predicate.User(sql.FieldIn(FieldName, vs...)) +} + +// NameNotIn applies the NotIn predicate on the "name" field. +func NameNotIn(vs ...string) predicate.User { + return predicate.User(sql.FieldNotIn(FieldName, vs...)) +} + +// NameGT applies the GT predicate on the "name" field. +func NameGT(v string) predicate.User { + return predicate.User(sql.FieldGT(FieldName, v)) +} + +// NameGTE applies the GTE predicate on the "name" field. +func NameGTE(v string) predicate.User { + return predicate.User(sql.FieldGTE(FieldName, v)) +} + +// NameLT applies the LT predicate on the "name" field. +func NameLT(v string) predicate.User { + return predicate.User(sql.FieldLT(FieldName, v)) +} + +// NameLTE applies the LTE predicate on the "name" field. +func NameLTE(v string) predicate.User { + return predicate.User(sql.FieldLTE(FieldName, v)) +} + +// NameContains applies the Contains predicate on the "name" field. +func NameContains(v string) predicate.User { + return predicate.User(sql.FieldContains(FieldName, v)) +} + +// NameHasPrefix applies the HasPrefix predicate on the "name" field. +func NameHasPrefix(v string) predicate.User { + return predicate.User(sql.FieldHasPrefix(FieldName, v)) +} + +// NameHasSuffix applies the HasSuffix predicate on the "name" field. +func NameHasSuffix(v string) predicate.User { + return predicate.User(sql.FieldHasSuffix(FieldName, v)) +} + +// NameEqualFold applies the EqualFold predicate on the "name" field. +func NameEqualFold(v string) predicate.User { + return predicate.User(sql.FieldEqualFold(FieldName, v)) +} + +// NameContainsFold applies the ContainsFold predicate on the "name" field. +func NameContainsFold(v string) predicate.User { + return predicate.User(sql.FieldContainsFold(FieldName, v)) +} + +// CreatedAtEQ applies the EQ predicate on the "created_at" field. +func CreatedAtEQ(v time.Time) predicate.User { + return predicate.User(sql.FieldEQ(FieldCreatedAt, v)) +} + +// CreatedAtNEQ applies the NEQ predicate on the "created_at" field. +func CreatedAtNEQ(v time.Time) predicate.User { + return predicate.User(sql.FieldNEQ(FieldCreatedAt, v)) +} + +// CreatedAtIn applies the In predicate on the "created_at" field. +func CreatedAtIn(vs ...time.Time) predicate.User { + return predicate.User(sql.FieldIn(FieldCreatedAt, vs...)) +} + +// CreatedAtNotIn applies the NotIn predicate on the "created_at" field. +func CreatedAtNotIn(vs ...time.Time) predicate.User { + return predicate.User(sql.FieldNotIn(FieldCreatedAt, vs...)) +} + +// CreatedAtGT applies the GT predicate on the "created_at" field. +func CreatedAtGT(v time.Time) predicate.User { + return predicate.User(sql.FieldGT(FieldCreatedAt, v)) +} + +// CreatedAtGTE applies the GTE predicate on the "created_at" field. +func CreatedAtGTE(v time.Time) predicate.User { + return predicate.User(sql.FieldGTE(FieldCreatedAt, v)) +} + +// CreatedAtLT applies the LT predicate on the "created_at" field. +func CreatedAtLT(v time.Time) predicate.User { + return predicate.User(sql.FieldLT(FieldCreatedAt, v)) +} + +// CreatedAtLTE applies the LTE predicate on the "created_at" field. +func CreatedAtLTE(v time.Time) predicate.User { + return predicate.User(sql.FieldLTE(FieldCreatedAt, v)) +} + +// LocaleEQ applies the EQ predicate on the "locale" field. +func LocaleEQ(v discord.Locale) predicate.User { + vc := string(v) + return predicate.User(sql.FieldEQ(FieldLocale, vc)) +} + +// LocaleNEQ applies the NEQ predicate on the "locale" field. +func LocaleNEQ(v discord.Locale) predicate.User { + vc := string(v) + return predicate.User(sql.FieldNEQ(FieldLocale, vc)) +} + +// LocaleIn applies the In predicate on the "locale" field. +func LocaleIn(vs ...discord.Locale) predicate.User { + v := make([]any, len(vs)) + for i := range v { + v[i] = string(vs[i]) + } + return predicate.User(sql.FieldIn(FieldLocale, v...)) +} + +// LocaleNotIn applies the NotIn predicate on the "locale" field. +func LocaleNotIn(vs ...discord.Locale) predicate.User { + v := make([]any, len(vs)) + for i := range v { + v[i] = string(vs[i]) + } + return predicate.User(sql.FieldNotIn(FieldLocale, v...)) +} + +// LocaleGT applies the GT predicate on the "locale" field. +func LocaleGT(v discord.Locale) predicate.User { + vc := string(v) + return predicate.User(sql.FieldGT(FieldLocale, vc)) +} + +// LocaleGTE applies the GTE predicate on the "locale" field. +func LocaleGTE(v discord.Locale) predicate.User { + vc := string(v) + return predicate.User(sql.FieldGTE(FieldLocale, vc)) +} + +// LocaleLT applies the LT predicate on the "locale" field. +func LocaleLT(v discord.Locale) predicate.User { + vc := string(v) + return predicate.User(sql.FieldLT(FieldLocale, vc)) +} + +// LocaleLTE applies the LTE predicate on the "locale" field. +func LocaleLTE(v discord.Locale) predicate.User { + vc := string(v) + return predicate.User(sql.FieldLTE(FieldLocale, vc)) +} + +// LocaleContains applies the Contains predicate on the "locale" field. +func LocaleContains(v discord.Locale) predicate.User { + vc := string(v) + return predicate.User(sql.FieldContains(FieldLocale, vc)) +} + +// LocaleHasPrefix applies the HasPrefix predicate on the "locale" field. +func LocaleHasPrefix(v discord.Locale) predicate.User { + vc := string(v) + return predicate.User(sql.FieldHasPrefix(FieldLocale, vc)) +} + +// LocaleHasSuffix applies the HasSuffix predicate on the "locale" field. +func LocaleHasSuffix(v discord.Locale) predicate.User { + vc := string(v) + return predicate.User(sql.FieldHasSuffix(FieldLocale, vc)) +} + +// LocaleEqualFold applies the EqualFold predicate on the "locale" field. +func LocaleEqualFold(v discord.Locale) predicate.User { + vc := string(v) + return predicate.User(sql.FieldEqualFold(FieldLocale, vc)) +} + +// LocaleContainsFold applies the ContainsFold predicate on the "locale" field. +func LocaleContainsFold(v discord.Locale) predicate.User { + vc := string(v) + return predicate.User(sql.FieldContainsFold(FieldLocale, vc)) +} + +// XpEQ applies the EQ predicate on the "xp" field. +func XpEQ(v xppoint.XP) predicate.User { + vc := uint64(v) + return predicate.User(sql.FieldEQ(FieldXp, vc)) +} + +// XpNEQ applies the NEQ predicate on the "xp" field. +func XpNEQ(v xppoint.XP) predicate.User { + vc := uint64(v) + return predicate.User(sql.FieldNEQ(FieldXp, vc)) +} + +// XpIn applies the In predicate on the "xp" field. +func XpIn(vs ...xppoint.XP) predicate.User { + v := make([]any, len(vs)) + for i := range v { + v[i] = uint64(vs[i]) + } + return predicate.User(sql.FieldIn(FieldXp, v...)) +} + +// XpNotIn applies the NotIn predicate on the "xp" field. +func XpNotIn(vs ...xppoint.XP) predicate.User { + v := make([]any, len(vs)) + for i := range v { + v[i] = uint64(vs[i]) + } + return predicate.User(sql.FieldNotIn(FieldXp, v...)) +} + +// XpGT applies the GT predicate on the "xp" field. +func XpGT(v xppoint.XP) predicate.User { + vc := uint64(v) + return predicate.User(sql.FieldGT(FieldXp, vc)) +} + +// XpGTE applies the GTE predicate on the "xp" field. +func XpGTE(v xppoint.XP) predicate.User { + vc := uint64(v) + return predicate.User(sql.FieldGTE(FieldXp, vc)) +} + +// XpLT applies the LT predicate on the "xp" field. +func XpLT(v xppoint.XP) predicate.User { + vc := uint64(v) + return predicate.User(sql.FieldLT(FieldXp, vc)) +} + +// XpLTE applies the LTE predicate on the "xp" field. +func XpLTE(v xppoint.XP) predicate.User { + vc := uint64(v) + return predicate.User(sql.FieldLTE(FieldXp, vc)) +} + +// HasOwnGuilds applies the HasEdge predicate on the "own_guilds" edge. +func HasOwnGuilds() predicate.User { + return predicate.User(func(s *sql.Selector) { + step := sqlgraph.NewStep( + sqlgraph.From(Table, FieldID), + sqlgraph.Edge(sqlgraph.O2M, false, OwnGuildsTable, OwnGuildsColumn), + ) + sqlgraph.HasNeighbors(s, step) + }) +} + +// HasOwnGuildsWith applies the HasEdge predicate on the "own_guilds" edge with a given conditions (other predicates). +func HasOwnGuildsWith(preds ...predicate.Guild) predicate.User { + return predicate.User(func(s *sql.Selector) { + step := newOwnGuildsStep() + sqlgraph.HasNeighborsWith(s, step, func(s *sql.Selector) { + for _, p := range preds { + p(s) + } + }) + }) +} + +// HasGuilds applies the HasEdge predicate on the "guilds" edge. +func HasGuilds() predicate.User { + return predicate.User(func(s *sql.Selector) { + step := sqlgraph.NewStep( + sqlgraph.From(Table, FieldID), + sqlgraph.Edge(sqlgraph.O2M, false, GuildsTable, GuildsColumn), + ) + sqlgraph.HasNeighbors(s, step) + }) +} + +// HasGuildsWith applies the HasEdge predicate on the "guilds" edge with a given conditions (other predicates). +func HasGuildsWith(preds ...predicate.Member) predicate.User { + return predicate.User(func(s *sql.Selector) { + step := newGuildsStep() + sqlgraph.HasNeighborsWith(s, step, func(s *sql.Selector) { + for _, p := range preds { + p(s) + } + }) + }) +} + +// HasWordSuffix applies the HasEdge predicate on the "word_suffix" edge. +func HasWordSuffix() predicate.User { + return predicate.User(func(s *sql.Selector) { + step := sqlgraph.NewStep( + sqlgraph.From(Table, FieldID), + sqlgraph.Edge(sqlgraph.O2M, false, WordSuffixTable, WordSuffixColumn), + ) + sqlgraph.HasNeighbors(s, step) + }) +} + +// HasWordSuffixWith applies the HasEdge predicate on the "word_suffix" edge with a given conditions (other predicates). +func HasWordSuffixWith(preds ...predicate.WordSuffix) predicate.User { + return predicate.User(func(s *sql.Selector) { + step := newWordSuffixStep() + sqlgraph.HasNeighborsWith(s, step, func(s *sql.Selector) { + for _, p := range preds { + p(s) + } + }) + }) +} + +// And groups predicates with the AND operator between them. +func And(predicates ...predicate.User) predicate.User { + return predicate.User(sql.AndPredicates(predicates...)) +} + +// Or groups predicates with the OR operator between them. +func Or(predicates ...predicate.User) predicate.User { + return predicate.User(sql.OrPredicates(predicates...)) +} + +// Not applies the not operator on the given predicate. +func Not(p predicate.User) predicate.User { + return predicate.User(sql.NotPredicates(p)) +} diff --git a/ent/user_create.go b/ent/user_create.go new file mode 100644 index 00000000..f128730c --- /dev/null +++ b/ent/user_create.go @@ -0,0 +1,387 @@ +// Code generated by ent, DO NOT EDIT. + +package ent + +import ( + "context" + "errors" + "fmt" + "time" + + "entgo.io/ent/dialect/sql/sqlgraph" + "entgo.io/ent/schema/field" + "github.com/disgoorg/disgo/discord" + snowflake "github.com/disgoorg/snowflake/v2" + "github.com/google/uuid" + "github.com/sabafly/gobot/ent/guild" + "github.com/sabafly/gobot/ent/member" + "github.com/sabafly/gobot/ent/user" + "github.com/sabafly/gobot/ent/wordsuffix" + "github.com/sabafly/gobot/internal/xppoint" +) + +// UserCreate is the builder for creating a User entity. +type UserCreate struct { + config + mutation *UserMutation + hooks []Hook +} + +// SetName sets the "name" field. +func (uc *UserCreate) SetName(s string) *UserCreate { + uc.mutation.SetName(s) + return uc +} + +// SetCreatedAt sets the "created_at" field. +func (uc *UserCreate) SetCreatedAt(t time.Time) *UserCreate { + uc.mutation.SetCreatedAt(t) + return uc +} + +// SetNillableCreatedAt sets the "created_at" field if the given value is not nil. +func (uc *UserCreate) SetNillableCreatedAt(t *time.Time) *UserCreate { + if t != nil { + uc.SetCreatedAt(*t) + } + return uc +} + +// SetLocale sets the "locale" field. +func (uc *UserCreate) SetLocale(d discord.Locale) *UserCreate { + uc.mutation.SetLocale(d) + return uc +} + +// SetNillableLocale sets the "locale" field if the given value is not nil. +func (uc *UserCreate) SetNillableLocale(d *discord.Locale) *UserCreate { + if d != nil { + uc.SetLocale(*d) + } + return uc +} + +// SetXp sets the "xp" field. +func (uc *UserCreate) SetXp(x xppoint.XP) *UserCreate { + uc.mutation.SetXp(x) + return uc +} + +// SetNillableXp sets the "xp" field if the given value is not nil. +func (uc *UserCreate) SetNillableXp(x *xppoint.XP) *UserCreate { + if x != nil { + uc.SetXp(*x) + } + return uc +} + +// SetID sets the "id" field. +func (uc *UserCreate) SetID(s snowflake.ID) *UserCreate { + uc.mutation.SetID(s) + return uc +} + +// AddOwnGuildIDs adds the "own_guilds" edge to the Guild entity by IDs. +func (uc *UserCreate) AddOwnGuildIDs(ids ...snowflake.ID) *UserCreate { + uc.mutation.AddOwnGuildIDs(ids...) + return uc +} + +// AddOwnGuilds adds the "own_guilds" edges to the Guild entity. +func (uc *UserCreate) AddOwnGuilds(g ...*Guild) *UserCreate { + ids := make([]snowflake.ID, len(g)) + for i := range g { + ids[i] = g[i].ID + } + return uc.AddOwnGuildIDs(ids...) +} + +// AddGuildIDs adds the "guilds" edge to the Member entity by IDs. +func (uc *UserCreate) AddGuildIDs(ids ...int) *UserCreate { + uc.mutation.AddGuildIDs(ids...) + return uc +} + +// AddGuilds adds the "guilds" edges to the Member entity. +func (uc *UserCreate) AddGuilds(m ...*Member) *UserCreate { + ids := make([]int, len(m)) + for i := range m { + ids[i] = m[i].ID + } + return uc.AddGuildIDs(ids...) +} + +// AddWordSuffixIDs adds the "word_suffix" edge to the WordSuffix entity by IDs. +func (uc *UserCreate) AddWordSuffixIDs(ids ...uuid.UUID) *UserCreate { + uc.mutation.AddWordSuffixIDs(ids...) + return uc +} + +// AddWordSuffix adds the "word_suffix" edges to the WordSuffix entity. +func (uc *UserCreate) AddWordSuffix(w ...*WordSuffix) *UserCreate { + ids := make([]uuid.UUID, len(w)) + for i := range w { + ids[i] = w[i].ID + } + return uc.AddWordSuffixIDs(ids...) +} + +// Mutation returns the UserMutation object of the builder. +func (uc *UserCreate) Mutation() *UserMutation { + return uc.mutation +} + +// Save creates the User in the database. +func (uc *UserCreate) Save(ctx context.Context) (*User, error) { + uc.defaults() + return withHooks(ctx, uc.sqlSave, uc.mutation, uc.hooks) +} + +// SaveX calls Save and panics if Save returns an error. +func (uc *UserCreate) SaveX(ctx context.Context) *User { + v, err := uc.Save(ctx) + if err != nil { + panic(err) + } + return v +} + +// Exec executes the query. +func (uc *UserCreate) Exec(ctx context.Context) error { + _, err := uc.Save(ctx) + return err +} + +// ExecX is like Exec, but panics if an error occurs. +func (uc *UserCreate) ExecX(ctx context.Context) { + if err := uc.Exec(ctx); err != nil { + panic(err) + } +} + +// defaults sets the default values of the builder before save. +func (uc *UserCreate) defaults() { + if _, ok := uc.mutation.CreatedAt(); !ok { + v := user.DefaultCreatedAt() + uc.mutation.SetCreatedAt(v) + } + if _, ok := uc.mutation.Locale(); !ok { + v := user.DefaultLocale + uc.mutation.SetLocale(v) + } + if _, ok := uc.mutation.Xp(); !ok { + v := user.DefaultXp + uc.mutation.SetXp(v) + } +} + +// check runs all checks and user-defined validators on the builder. +func (uc *UserCreate) check() error { + if _, ok := uc.mutation.Name(); !ok { + return &ValidationError{Name: "name", err: errors.New(`ent: missing required field "User.name"`)} + } + if v, ok := uc.mutation.Name(); ok { + if err := user.NameValidator(v); err != nil { + return &ValidationError{Name: "name", err: fmt.Errorf(`ent: validator failed for field "User.name": %w`, err)} + } + } + if _, ok := uc.mutation.CreatedAt(); !ok { + return &ValidationError{Name: "created_at", err: errors.New(`ent: missing required field "User.created_at"`)} + } + if _, ok := uc.mutation.Locale(); !ok { + return &ValidationError{Name: "locale", err: errors.New(`ent: missing required field "User.locale"`)} + } + if v, ok := uc.mutation.Locale(); ok { + if err := user.LocaleValidator(string(v)); err != nil { + return &ValidationError{Name: "locale", err: fmt.Errorf(`ent: validator failed for field "User.locale": %w`, err)} + } + } + if _, ok := uc.mutation.Xp(); !ok { + return &ValidationError{Name: "xp", err: errors.New(`ent: missing required field "User.xp"`)} + } + return nil +} + +func (uc *UserCreate) sqlSave(ctx context.Context) (*User, error) { + if err := uc.check(); err != nil { + return nil, err + } + _node, _spec := uc.createSpec() + if err := sqlgraph.CreateNode(ctx, uc.driver, _spec); err != nil { + if sqlgraph.IsConstraintError(err) { + err = &ConstraintError{msg: err.Error(), wrap: err} + } + return nil, err + } + if _spec.ID.Value != _node.ID { + id := _spec.ID.Value.(int64) + _node.ID = snowflake.ID(id) + } + uc.mutation.id = &_node.ID + uc.mutation.done = true + return _node, nil +} + +func (uc *UserCreate) createSpec() (*User, *sqlgraph.CreateSpec) { + var ( + _node = &User{config: uc.config} + _spec = sqlgraph.NewCreateSpec(user.Table, sqlgraph.NewFieldSpec(user.FieldID, field.TypeUint64)) + ) + if id, ok := uc.mutation.ID(); ok { + _node.ID = id + _spec.ID.Value = id + } + if value, ok := uc.mutation.Name(); ok { + _spec.SetField(user.FieldName, field.TypeString, value) + _node.Name = value + } + if value, ok := uc.mutation.CreatedAt(); ok { + _spec.SetField(user.FieldCreatedAt, field.TypeTime, value) + _node.CreatedAt = value + } + if value, ok := uc.mutation.Locale(); ok { + _spec.SetField(user.FieldLocale, field.TypeString, value) + _node.Locale = value + } + if value, ok := uc.mutation.Xp(); ok { + _spec.SetField(user.FieldXp, field.TypeUint64, value) + _node.Xp = value + } + if nodes := uc.mutation.OwnGuildsIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: false, + Table: user.OwnGuildsTable, + Columns: []string{user.OwnGuildsColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(guild.FieldID, field.TypeUint64), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges = append(_spec.Edges, edge) + } + if nodes := uc.mutation.GuildsIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: false, + Table: user.GuildsTable, + Columns: []string{user.GuildsColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(member.FieldID, field.TypeInt), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges = append(_spec.Edges, edge) + } + if nodes := uc.mutation.WordSuffixIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: false, + Table: user.WordSuffixTable, + Columns: []string{user.WordSuffixColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(wordsuffix.FieldID, field.TypeUUID), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges = append(_spec.Edges, edge) + } + return _node, _spec +} + +// UserCreateBulk is the builder for creating many User entities in bulk. +type UserCreateBulk struct { + config + err error + builders []*UserCreate +} + +// Save creates the User entities in the database. +func (ucb *UserCreateBulk) Save(ctx context.Context) ([]*User, error) { + if ucb.err != nil { + return nil, ucb.err + } + specs := make([]*sqlgraph.CreateSpec, len(ucb.builders)) + nodes := make([]*User, len(ucb.builders)) + mutators := make([]Mutator, len(ucb.builders)) + for i := range ucb.builders { + func(i int, root context.Context) { + builder := ucb.builders[i] + builder.defaults() + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*UserMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + if err := builder.check(); err != nil { + return nil, err + } + builder.mutation = mutation + var err error + nodes[i], specs[i] = builder.createSpec() + if i < len(mutators)-1 { + _, err = mutators[i+1].Mutate(root, ucb.builders[i+1].mutation) + } else { + spec := &sqlgraph.BatchCreateSpec{Nodes: specs} + // Invoke the actual operation on the latest mutation in the chain. + if err = sqlgraph.BatchCreate(ctx, ucb.driver, spec); err != nil { + if sqlgraph.IsConstraintError(err) { + err = &ConstraintError{msg: err.Error(), wrap: err} + } + } + } + if err != nil { + return nil, err + } + mutation.id = &nodes[i].ID + if specs[i].ID.Value != nil && nodes[i].ID == 0 { + id := specs[i].ID.Value.(int64) + nodes[i].ID = snowflake.ID(id) + } + mutation.done = true + return nodes[i], nil + }) + for i := len(builder.hooks) - 1; i >= 0; i-- { + mut = builder.hooks[i](mut) + } + mutators[i] = mut + }(i, ctx) + } + if len(mutators) > 0 { + if _, err := mutators[0].Mutate(ctx, ucb.builders[0].mutation); err != nil { + return nil, err + } + } + return nodes, nil +} + +// SaveX is like Save, but panics if an error occurs. +func (ucb *UserCreateBulk) SaveX(ctx context.Context) []*User { + v, err := ucb.Save(ctx) + if err != nil { + panic(err) + } + return v +} + +// Exec executes the query. +func (ucb *UserCreateBulk) Exec(ctx context.Context) error { + _, err := ucb.Save(ctx) + return err +} + +// ExecX is like Exec, but panics if an error occurs. +func (ucb *UserCreateBulk) ExecX(ctx context.Context) { + if err := ucb.Exec(ctx); err != nil { + panic(err) + } +} diff --git a/ent/user_delete.go b/ent/user_delete.go new file mode 100644 index 00000000..292405b3 --- /dev/null +++ b/ent/user_delete.go @@ -0,0 +1,88 @@ +// Code generated by ent, DO NOT EDIT. + +package ent + +import ( + "context" + + "entgo.io/ent/dialect/sql" + "entgo.io/ent/dialect/sql/sqlgraph" + "entgo.io/ent/schema/field" + "github.com/sabafly/gobot/ent/predicate" + "github.com/sabafly/gobot/ent/user" +) + +// UserDelete is the builder for deleting a User entity. +type UserDelete struct { + config + hooks []Hook + mutation *UserMutation +} + +// Where appends a list predicates to the UserDelete builder. +func (ud *UserDelete) Where(ps ...predicate.User) *UserDelete { + ud.mutation.Where(ps...) + return ud +} + +// Exec executes the deletion query and returns how many vertices were deleted. +func (ud *UserDelete) Exec(ctx context.Context) (int, error) { + return withHooks(ctx, ud.sqlExec, ud.mutation, ud.hooks) +} + +// ExecX is like Exec, but panics if an error occurs. +func (ud *UserDelete) ExecX(ctx context.Context) int { + n, err := ud.Exec(ctx) + if err != nil { + panic(err) + } + return n +} + +func (ud *UserDelete) sqlExec(ctx context.Context) (int, error) { + _spec := sqlgraph.NewDeleteSpec(user.Table, sqlgraph.NewFieldSpec(user.FieldID, field.TypeUint64)) + if ps := ud.mutation.predicates; len(ps) > 0 { + _spec.Predicate = func(selector *sql.Selector) { + for i := range ps { + ps[i](selector) + } + } + } + affected, err := sqlgraph.DeleteNodes(ctx, ud.driver, _spec) + if err != nil && sqlgraph.IsConstraintError(err) { + err = &ConstraintError{msg: err.Error(), wrap: err} + } + ud.mutation.done = true + return affected, err +} + +// UserDeleteOne is the builder for deleting a single User entity. +type UserDeleteOne struct { + ud *UserDelete +} + +// Where appends a list predicates to the UserDelete builder. +func (udo *UserDeleteOne) Where(ps ...predicate.User) *UserDeleteOne { + udo.ud.mutation.Where(ps...) + return udo +} + +// Exec executes the deletion query. +func (udo *UserDeleteOne) Exec(ctx context.Context) error { + n, err := udo.ud.Exec(ctx) + switch { + case err != nil: + return err + case n == 0: + return &NotFoundError{user.Label} + default: + return nil + } +} + +// ExecX is like Exec, but panics if an error occurs. +func (udo *UserDeleteOne) ExecX(ctx context.Context) { + if err := udo.Exec(ctx); err != nil { + panic(err) + } +} diff --git a/ent/user_query.go b/ent/user_query.go new file mode 100644 index 00000000..9403f687 --- /dev/null +++ b/ent/user_query.go @@ -0,0 +1,757 @@ +// Code generated by ent, DO NOT EDIT. + +package ent + +import ( + "context" + "database/sql/driver" + "fmt" + "math" + + "entgo.io/ent/dialect/sql" + "entgo.io/ent/dialect/sql/sqlgraph" + "entgo.io/ent/schema/field" + snowflake "github.com/disgoorg/snowflake/v2" + "github.com/sabafly/gobot/ent/guild" + "github.com/sabafly/gobot/ent/member" + "github.com/sabafly/gobot/ent/predicate" + "github.com/sabafly/gobot/ent/user" + "github.com/sabafly/gobot/ent/wordsuffix" +) + +// UserQuery is the builder for querying User entities. +type UserQuery struct { + config + ctx *QueryContext + order []user.OrderOption + inters []Interceptor + predicates []predicate.User + withOwnGuilds *GuildQuery + withGuilds *MemberQuery + withWordSuffix *WordSuffixQuery + // intermediate query (i.e. traversal path). + sql *sql.Selector + path func(context.Context) (*sql.Selector, error) +} + +// Where adds a new predicate for the UserQuery builder. +func (uq *UserQuery) Where(ps ...predicate.User) *UserQuery { + uq.predicates = append(uq.predicates, ps...) + return uq +} + +// Limit the number of records to be returned by this query. +func (uq *UserQuery) Limit(limit int) *UserQuery { + uq.ctx.Limit = &limit + return uq +} + +// Offset to start from. +func (uq *UserQuery) Offset(offset int) *UserQuery { + uq.ctx.Offset = &offset + return uq +} + +// Unique configures the query builder to filter duplicate records on query. +// By default, unique is set to true, and can be disabled using this method. +func (uq *UserQuery) Unique(unique bool) *UserQuery { + uq.ctx.Unique = &unique + return uq +} + +// Order specifies how the records should be ordered. +func (uq *UserQuery) Order(o ...user.OrderOption) *UserQuery { + uq.order = append(uq.order, o...) + return uq +} + +// QueryOwnGuilds chains the current query on the "own_guilds" edge. +func (uq *UserQuery) QueryOwnGuilds() *GuildQuery { + query := (&GuildClient{config: uq.config}).Query() + query.path = func(ctx context.Context) (fromU *sql.Selector, err error) { + if err := uq.prepareQuery(ctx); err != nil { + return nil, err + } + selector := uq.sqlQuery(ctx) + if err := selector.Err(); err != nil { + return nil, err + } + step := sqlgraph.NewStep( + sqlgraph.From(user.Table, user.FieldID, selector), + sqlgraph.To(guild.Table, guild.FieldID), + sqlgraph.Edge(sqlgraph.O2M, false, user.OwnGuildsTable, user.OwnGuildsColumn), + ) + fromU = sqlgraph.SetNeighbors(uq.driver.Dialect(), step) + return fromU, nil + } + return query +} + +// QueryGuilds chains the current query on the "guilds" edge. +func (uq *UserQuery) QueryGuilds() *MemberQuery { + query := (&MemberClient{config: uq.config}).Query() + query.path = func(ctx context.Context) (fromU *sql.Selector, err error) { + if err := uq.prepareQuery(ctx); err != nil { + return nil, err + } + selector := uq.sqlQuery(ctx) + if err := selector.Err(); err != nil { + return nil, err + } + step := sqlgraph.NewStep( + sqlgraph.From(user.Table, user.FieldID, selector), + sqlgraph.To(member.Table, member.FieldID), + sqlgraph.Edge(sqlgraph.O2M, false, user.GuildsTable, user.GuildsColumn), + ) + fromU = sqlgraph.SetNeighbors(uq.driver.Dialect(), step) + return fromU, nil + } + return query +} + +// QueryWordSuffix chains the current query on the "word_suffix" edge. +func (uq *UserQuery) QueryWordSuffix() *WordSuffixQuery { + query := (&WordSuffixClient{config: uq.config}).Query() + query.path = func(ctx context.Context) (fromU *sql.Selector, err error) { + if err := uq.prepareQuery(ctx); err != nil { + return nil, err + } + selector := uq.sqlQuery(ctx) + if err := selector.Err(); err != nil { + return nil, err + } + step := sqlgraph.NewStep( + sqlgraph.From(user.Table, user.FieldID, selector), + sqlgraph.To(wordsuffix.Table, wordsuffix.FieldID), + sqlgraph.Edge(sqlgraph.O2M, false, user.WordSuffixTable, user.WordSuffixColumn), + ) + fromU = sqlgraph.SetNeighbors(uq.driver.Dialect(), step) + return fromU, nil + } + return query +} + +// First returns the first User entity from the query. +// Returns a *NotFoundError when no User was found. +func (uq *UserQuery) First(ctx context.Context) (*User, error) { + nodes, err := uq.Limit(1).All(setContextOp(ctx, uq.ctx, "First")) + if err != nil { + return nil, err + } + if len(nodes) == 0 { + return nil, &NotFoundError{user.Label} + } + return nodes[0], nil +} + +// FirstX is like First, but panics if an error occurs. +func (uq *UserQuery) FirstX(ctx context.Context) *User { + node, err := uq.First(ctx) + if err != nil && !IsNotFound(err) { + panic(err) + } + return node +} + +// FirstID returns the first User ID from the query. +// Returns a *NotFoundError when no User ID was found. +func (uq *UserQuery) FirstID(ctx context.Context) (id snowflake.ID, err error) { + var ids []snowflake.ID + if ids, err = uq.Limit(1).IDs(setContextOp(ctx, uq.ctx, "FirstID")); err != nil { + return + } + if len(ids) == 0 { + err = &NotFoundError{user.Label} + return + } + return ids[0], nil +} + +// FirstIDX is like FirstID, but panics if an error occurs. +func (uq *UserQuery) FirstIDX(ctx context.Context) snowflake.ID { + id, err := uq.FirstID(ctx) + if err != nil && !IsNotFound(err) { + panic(err) + } + return id +} + +// Only returns a single User entity found by the query, ensuring it only returns one. +// Returns a *NotSingularError when more than one User entity is found. +// Returns a *NotFoundError when no User entities are found. +func (uq *UserQuery) Only(ctx context.Context) (*User, error) { + nodes, err := uq.Limit(2).All(setContextOp(ctx, uq.ctx, "Only")) + if err != nil { + return nil, err + } + switch len(nodes) { + case 1: + return nodes[0], nil + case 0: + return nil, &NotFoundError{user.Label} + default: + return nil, &NotSingularError{user.Label} + } +} + +// OnlyX is like Only, but panics if an error occurs. +func (uq *UserQuery) OnlyX(ctx context.Context) *User { + node, err := uq.Only(ctx) + if err != nil { + panic(err) + } + return node +} + +// OnlyID is like Only, but returns the only User ID in the query. +// Returns a *NotSingularError when more than one User ID is found. +// Returns a *NotFoundError when no entities are found. +func (uq *UserQuery) OnlyID(ctx context.Context) (id snowflake.ID, err error) { + var ids []snowflake.ID + if ids, err = uq.Limit(2).IDs(setContextOp(ctx, uq.ctx, "OnlyID")); err != nil { + return + } + switch len(ids) { + case 1: + id = ids[0] + case 0: + err = &NotFoundError{user.Label} + default: + err = &NotSingularError{user.Label} + } + return +} + +// OnlyIDX is like OnlyID, but panics if an error occurs. +func (uq *UserQuery) OnlyIDX(ctx context.Context) snowflake.ID { + id, err := uq.OnlyID(ctx) + if err != nil { + panic(err) + } + return id +} + +// All executes the query and returns a list of Users. +func (uq *UserQuery) All(ctx context.Context) ([]*User, error) { + ctx = setContextOp(ctx, uq.ctx, "All") + if err := uq.prepareQuery(ctx); err != nil { + return nil, err + } + qr := querierAll[[]*User, *UserQuery]() + return withInterceptors[[]*User](ctx, uq, qr, uq.inters) +} + +// AllX is like All, but panics if an error occurs. +func (uq *UserQuery) AllX(ctx context.Context) []*User { + nodes, err := uq.All(ctx) + if err != nil { + panic(err) + } + return nodes +} + +// IDs executes the query and returns a list of User IDs. +func (uq *UserQuery) IDs(ctx context.Context) (ids []snowflake.ID, err error) { + if uq.ctx.Unique == nil && uq.path != nil { + uq.Unique(true) + } + ctx = setContextOp(ctx, uq.ctx, "IDs") + if err = uq.Select(user.FieldID).Scan(ctx, &ids); err != nil { + return nil, err + } + return ids, nil +} + +// IDsX is like IDs, but panics if an error occurs. +func (uq *UserQuery) IDsX(ctx context.Context) []snowflake.ID { + ids, err := uq.IDs(ctx) + if err != nil { + panic(err) + } + return ids +} + +// Count returns the count of the given query. +func (uq *UserQuery) Count(ctx context.Context) (int, error) { + ctx = setContextOp(ctx, uq.ctx, "Count") + if err := uq.prepareQuery(ctx); err != nil { + return 0, err + } + return withInterceptors[int](ctx, uq, querierCount[*UserQuery](), uq.inters) +} + +// CountX is like Count, but panics if an error occurs. +func (uq *UserQuery) CountX(ctx context.Context) int { + count, err := uq.Count(ctx) + if err != nil { + panic(err) + } + return count +} + +// Exist returns true if the query has elements in the graph. +func (uq *UserQuery) Exist(ctx context.Context) (bool, error) { + ctx = setContextOp(ctx, uq.ctx, "Exist") + switch _, err := uq.FirstID(ctx); { + case IsNotFound(err): + return false, nil + case err != nil: + return false, fmt.Errorf("ent: check existence: %w", err) + default: + return true, nil + } +} + +// ExistX is like Exist, but panics if an error occurs. +func (uq *UserQuery) ExistX(ctx context.Context) bool { + exist, err := uq.Exist(ctx) + if err != nil { + panic(err) + } + return exist +} + +// Clone returns a duplicate of the UserQuery builder, including all associated steps. It can be +// used to prepare common query builders and use them differently after the clone is made. +func (uq *UserQuery) Clone() *UserQuery { + if uq == nil { + return nil + } + return &UserQuery{ + config: uq.config, + ctx: uq.ctx.Clone(), + order: append([]user.OrderOption{}, uq.order...), + inters: append([]Interceptor{}, uq.inters...), + predicates: append([]predicate.User{}, uq.predicates...), + withOwnGuilds: uq.withOwnGuilds.Clone(), + withGuilds: uq.withGuilds.Clone(), + withWordSuffix: uq.withWordSuffix.Clone(), + // clone intermediate query. + sql: uq.sql.Clone(), + path: uq.path, + } +} + +// WithOwnGuilds tells the query-builder to eager-load the nodes that are connected to +// the "own_guilds" edge. The optional arguments are used to configure the query builder of the edge. +func (uq *UserQuery) WithOwnGuilds(opts ...func(*GuildQuery)) *UserQuery { + query := (&GuildClient{config: uq.config}).Query() + for _, opt := range opts { + opt(query) + } + uq.withOwnGuilds = query + return uq +} + +// WithGuilds tells the query-builder to eager-load the nodes that are connected to +// the "guilds" edge. The optional arguments are used to configure the query builder of the edge. +func (uq *UserQuery) WithGuilds(opts ...func(*MemberQuery)) *UserQuery { + query := (&MemberClient{config: uq.config}).Query() + for _, opt := range opts { + opt(query) + } + uq.withGuilds = query + return uq +} + +// WithWordSuffix tells the query-builder to eager-load the nodes that are connected to +// the "word_suffix" edge. The optional arguments are used to configure the query builder of the edge. +func (uq *UserQuery) WithWordSuffix(opts ...func(*WordSuffixQuery)) *UserQuery { + query := (&WordSuffixClient{config: uq.config}).Query() + for _, opt := range opts { + opt(query) + } + uq.withWordSuffix = query + return uq +} + +// GroupBy is used to group vertices by one or more fields/columns. +// It is often used with aggregate functions, like: count, max, mean, min, sum. +// +// Example: +// +// var v []struct { +// Name string `json:"name,omitempty"` +// Count int `json:"count,omitempty"` +// } +// +// client.User.Query(). +// GroupBy(user.FieldName). +// Aggregate(ent.Count()). +// Scan(ctx, &v) +func (uq *UserQuery) GroupBy(field string, fields ...string) *UserGroupBy { + uq.ctx.Fields = append([]string{field}, fields...) + grbuild := &UserGroupBy{build: uq} + grbuild.flds = &uq.ctx.Fields + grbuild.label = user.Label + grbuild.scan = grbuild.Scan + return grbuild +} + +// Select allows the selection one or more fields/columns for the given query, +// instead of selecting all fields in the entity. +// +// Example: +// +// var v []struct { +// Name string `json:"name,omitempty"` +// } +// +// client.User.Query(). +// Select(user.FieldName). +// Scan(ctx, &v) +func (uq *UserQuery) Select(fields ...string) *UserSelect { + uq.ctx.Fields = append(uq.ctx.Fields, fields...) + sbuild := &UserSelect{UserQuery: uq} + sbuild.label = user.Label + sbuild.flds, sbuild.scan = &uq.ctx.Fields, sbuild.Scan + return sbuild +} + +// Aggregate returns a UserSelect configured with the given aggregations. +func (uq *UserQuery) Aggregate(fns ...AggregateFunc) *UserSelect { + return uq.Select().Aggregate(fns...) +} + +func (uq *UserQuery) prepareQuery(ctx context.Context) error { + for _, inter := range uq.inters { + if inter == nil { + return fmt.Errorf("ent: uninitialized interceptor (forgotten import ent/runtime?)") + } + if trv, ok := inter.(Traverser); ok { + if err := trv.Traverse(ctx, uq); err != nil { + return err + } + } + } + for _, f := range uq.ctx.Fields { + if !user.ValidColumn(f) { + return &ValidationError{Name: f, err: fmt.Errorf("ent: invalid field %q for query", f)} + } + } + if uq.path != nil { + prev, err := uq.path(ctx) + if err != nil { + return err + } + uq.sql = prev + } + return nil +} + +func (uq *UserQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*User, error) { + var ( + nodes = []*User{} + _spec = uq.querySpec() + loadedTypes = [3]bool{ + uq.withOwnGuilds != nil, + uq.withGuilds != nil, + uq.withWordSuffix != nil, + } + ) + _spec.ScanValues = func(columns []string) ([]any, error) { + return (*User).scanValues(nil, columns) + } + _spec.Assign = func(columns []string, values []any) error { + node := &User{config: uq.config} + nodes = append(nodes, node) + node.Edges.loadedTypes = loadedTypes + return node.assignValues(columns, values) + } + for i := range hooks { + hooks[i](ctx, _spec) + } + if err := sqlgraph.QueryNodes(ctx, uq.driver, _spec); err != nil { + return nil, err + } + if len(nodes) == 0 { + return nodes, nil + } + if query := uq.withOwnGuilds; query != nil { + if err := uq.loadOwnGuilds(ctx, query, nodes, + func(n *User) { n.Edges.OwnGuilds = []*Guild{} }, + func(n *User, e *Guild) { n.Edges.OwnGuilds = append(n.Edges.OwnGuilds, e) }); err != nil { + return nil, err + } + } + if query := uq.withGuilds; query != nil { + if err := uq.loadGuilds(ctx, query, nodes, + func(n *User) { n.Edges.Guilds = []*Member{} }, + func(n *User, e *Member) { n.Edges.Guilds = append(n.Edges.Guilds, e) }); err != nil { + return nil, err + } + } + if query := uq.withWordSuffix; query != nil { + if err := uq.loadWordSuffix(ctx, query, nodes, + func(n *User) { n.Edges.WordSuffix = []*WordSuffix{} }, + func(n *User, e *WordSuffix) { n.Edges.WordSuffix = append(n.Edges.WordSuffix, e) }); err != nil { + return nil, err + } + } + return nodes, nil +} + +func (uq *UserQuery) loadOwnGuilds(ctx context.Context, query *GuildQuery, nodes []*User, init func(*User), assign func(*User, *Guild)) error { + fks := make([]driver.Value, 0, len(nodes)) + nodeids := make(map[snowflake.ID]*User) + for i := range nodes { + fks = append(fks, nodes[i].ID) + nodeids[nodes[i].ID] = nodes[i] + if init != nil { + init(nodes[i]) + } + } + query.withFKs = true + query.Where(predicate.Guild(func(s *sql.Selector) { + s.Where(sql.InValues(s.C(user.OwnGuildsColumn), fks...)) + })) + neighbors, err := query.All(ctx) + if err != nil { + return err + } + for _, n := range neighbors { + fk := n.user_own_guilds + if fk == nil { + return fmt.Errorf(`foreign-key "user_own_guilds" is nil for node %v`, n.ID) + } + node, ok := nodeids[*fk] + if !ok { + return fmt.Errorf(`unexpected referenced foreign-key "user_own_guilds" returned %v for node %v`, *fk, n.ID) + } + assign(node, n) + } + return nil +} +func (uq *UserQuery) loadGuilds(ctx context.Context, query *MemberQuery, nodes []*User, init func(*User), assign func(*User, *Member)) error { + fks := make([]driver.Value, 0, len(nodes)) + nodeids := make(map[snowflake.ID]*User) + for i := range nodes { + fks = append(fks, nodes[i].ID) + nodeids[nodes[i].ID] = nodes[i] + if init != nil { + init(nodes[i]) + } + } + query.withFKs = true + if len(query.ctx.Fields) > 0 { + query.ctx.AppendFieldOnce(member.FieldUserID) + } + query.Where(predicate.Member(func(s *sql.Selector) { + s.Where(sql.InValues(s.C(user.GuildsColumn), fks...)) + })) + neighbors, err := query.All(ctx) + if err != nil { + return err + } + for _, n := range neighbors { + fk := n.UserID + node, ok := nodeids[fk] + if !ok { + return fmt.Errorf(`unexpected referenced foreign-key "user_id" returned %v for node %v`, fk, n.ID) + } + assign(node, n) + } + return nil +} +func (uq *UserQuery) loadWordSuffix(ctx context.Context, query *WordSuffixQuery, nodes []*User, init func(*User), assign func(*User, *WordSuffix)) error { + fks := make([]driver.Value, 0, len(nodes)) + nodeids := make(map[snowflake.ID]*User) + for i := range nodes { + fks = append(fks, nodes[i].ID) + nodeids[nodes[i].ID] = nodes[i] + if init != nil { + init(nodes[i]) + } + } + query.withFKs = true + query.Where(predicate.WordSuffix(func(s *sql.Selector) { + s.Where(sql.InValues(s.C(user.WordSuffixColumn), fks...)) + })) + neighbors, err := query.All(ctx) + if err != nil { + return err + } + for _, n := range neighbors { + fk := n.user_word_suffix + if fk == nil { + return fmt.Errorf(`foreign-key "user_word_suffix" is nil for node %v`, n.ID) + } + node, ok := nodeids[*fk] + if !ok { + return fmt.Errorf(`unexpected referenced foreign-key "user_word_suffix" returned %v for node %v`, *fk, n.ID) + } + assign(node, n) + } + return nil +} + +func (uq *UserQuery) sqlCount(ctx context.Context) (int, error) { + _spec := uq.querySpec() + _spec.Node.Columns = uq.ctx.Fields + if len(uq.ctx.Fields) > 0 { + _spec.Unique = uq.ctx.Unique != nil && *uq.ctx.Unique + } + return sqlgraph.CountNodes(ctx, uq.driver, _spec) +} + +func (uq *UserQuery) querySpec() *sqlgraph.QuerySpec { + _spec := sqlgraph.NewQuerySpec(user.Table, user.Columns, sqlgraph.NewFieldSpec(user.FieldID, field.TypeUint64)) + _spec.From = uq.sql + if unique := uq.ctx.Unique; unique != nil { + _spec.Unique = *unique + } else if uq.path != nil { + _spec.Unique = true + } + if fields := uq.ctx.Fields; len(fields) > 0 { + _spec.Node.Columns = make([]string, 0, len(fields)) + _spec.Node.Columns = append(_spec.Node.Columns, user.FieldID) + for i := range fields { + if fields[i] != user.FieldID { + _spec.Node.Columns = append(_spec.Node.Columns, fields[i]) + } + } + } + if ps := uq.predicates; len(ps) > 0 { + _spec.Predicate = func(selector *sql.Selector) { + for i := range ps { + ps[i](selector) + } + } + } + if limit := uq.ctx.Limit; limit != nil { + _spec.Limit = *limit + } + if offset := uq.ctx.Offset; offset != nil { + _spec.Offset = *offset + } + if ps := uq.order; len(ps) > 0 { + _spec.Order = func(selector *sql.Selector) { + for i := range ps { + ps[i](selector) + } + } + } + return _spec +} + +func (uq *UserQuery) sqlQuery(ctx context.Context) *sql.Selector { + builder := sql.Dialect(uq.driver.Dialect()) + t1 := builder.Table(user.Table) + columns := uq.ctx.Fields + if len(columns) == 0 { + columns = user.Columns + } + selector := builder.Select(t1.Columns(columns...)...).From(t1) + if uq.sql != nil { + selector = uq.sql + selector.Select(selector.Columns(columns...)...) + } + if uq.ctx.Unique != nil && *uq.ctx.Unique { + selector.Distinct() + } + for _, p := range uq.predicates { + p(selector) + } + for _, p := range uq.order { + p(selector) + } + if offset := uq.ctx.Offset; offset != nil { + // limit is mandatory for offset clause. We start + // with default value, and override it below if needed. + selector.Offset(*offset).Limit(math.MaxInt32) + } + if limit := uq.ctx.Limit; limit != nil { + selector.Limit(*limit) + } + return selector +} + +// UserGroupBy is the group-by builder for User entities. +type UserGroupBy struct { + selector + build *UserQuery +} + +// Aggregate adds the given aggregation functions to the group-by query. +func (ugb *UserGroupBy) Aggregate(fns ...AggregateFunc) *UserGroupBy { + ugb.fns = append(ugb.fns, fns...) + return ugb +} + +// Scan applies the selector query and scans the result into the given value. +func (ugb *UserGroupBy) Scan(ctx context.Context, v any) error { + ctx = setContextOp(ctx, ugb.build.ctx, "GroupBy") + if err := ugb.build.prepareQuery(ctx); err != nil { + return err + } + return scanWithInterceptors[*UserQuery, *UserGroupBy](ctx, ugb.build, ugb, ugb.build.inters, v) +} + +func (ugb *UserGroupBy) sqlScan(ctx context.Context, root *UserQuery, v any) error { + selector := root.sqlQuery(ctx).Select() + aggregation := make([]string, 0, len(ugb.fns)) + for _, fn := range ugb.fns { + aggregation = append(aggregation, fn(selector)) + } + if len(selector.SelectedColumns()) == 0 { + columns := make([]string, 0, len(*ugb.flds)+len(ugb.fns)) + for _, f := range *ugb.flds { + columns = append(columns, selector.C(f)) + } + columns = append(columns, aggregation...) + selector.Select(columns...) + } + selector.GroupBy(selector.Columns(*ugb.flds...)...) + if err := selector.Err(); err != nil { + return err + } + rows := &sql.Rows{} + query, args := selector.Query() + if err := ugb.build.driver.Query(ctx, query, args, rows); err != nil { + return err + } + defer rows.Close() + return sql.ScanSlice(rows, v) +} + +// UserSelect is the builder for selecting fields of User entities. +type UserSelect struct { + *UserQuery + selector +} + +// Aggregate adds the given aggregation functions to the selector query. +func (us *UserSelect) Aggregate(fns ...AggregateFunc) *UserSelect { + us.fns = append(us.fns, fns...) + return us +} + +// Scan applies the selector query and scans the result into the given value. +func (us *UserSelect) Scan(ctx context.Context, v any) error { + ctx = setContextOp(ctx, us.ctx, "Select") + if err := us.prepareQuery(ctx); err != nil { + return err + } + return scanWithInterceptors[*UserQuery, *UserSelect](ctx, us.UserQuery, us, us.inters, v) +} + +func (us *UserSelect) sqlScan(ctx context.Context, root *UserQuery, v any) error { + selector := root.sqlQuery(ctx) + aggregation := make([]string, 0, len(us.fns)) + for _, fn := range us.fns { + aggregation = append(aggregation, fn(selector)) + } + switch n := len(*us.selector.flds); { + case n == 0 && len(aggregation) > 0: + selector.Select(aggregation...) + case n != 0 && len(aggregation) > 0: + selector.AppendSelect(aggregation...) + } + rows := &sql.Rows{} + query, args := selector.Query() + if err := us.driver.Query(ctx, query, args, rows); err != nil { + return err + } + defer rows.Close() + return sql.ScanSlice(rows, v) +} diff --git a/ent/user_update.go b/ent/user_update.go new file mode 100644 index 00000000..b6b7ec12 --- /dev/null +++ b/ent/user_update.go @@ -0,0 +1,826 @@ +// Code generated by ent, DO NOT EDIT. + +package ent + +import ( + "context" + "errors" + "fmt" + + "entgo.io/ent/dialect/sql" + "entgo.io/ent/dialect/sql/sqlgraph" + "entgo.io/ent/schema/field" + "github.com/disgoorg/disgo/discord" + snowflake "github.com/disgoorg/snowflake/v2" + "github.com/google/uuid" + "github.com/sabafly/gobot/ent/guild" + "github.com/sabafly/gobot/ent/member" + "github.com/sabafly/gobot/ent/predicate" + "github.com/sabafly/gobot/ent/user" + "github.com/sabafly/gobot/ent/wordsuffix" + "github.com/sabafly/gobot/internal/xppoint" +) + +// UserUpdate is the builder for updating User entities. +type UserUpdate struct { + config + hooks []Hook + mutation *UserMutation +} + +// Where appends a list predicates to the UserUpdate builder. +func (uu *UserUpdate) Where(ps ...predicate.User) *UserUpdate { + uu.mutation.Where(ps...) + return uu +} + +// SetName sets the "name" field. +func (uu *UserUpdate) SetName(s string) *UserUpdate { + uu.mutation.SetName(s) + return uu +} + +// SetNillableName sets the "name" field if the given value is not nil. +func (uu *UserUpdate) SetNillableName(s *string) *UserUpdate { + if s != nil { + uu.SetName(*s) + } + return uu +} + +// SetLocale sets the "locale" field. +func (uu *UserUpdate) SetLocale(d discord.Locale) *UserUpdate { + uu.mutation.SetLocale(d) + return uu +} + +// SetNillableLocale sets the "locale" field if the given value is not nil. +func (uu *UserUpdate) SetNillableLocale(d *discord.Locale) *UserUpdate { + if d != nil { + uu.SetLocale(*d) + } + return uu +} + +// SetXp sets the "xp" field. +func (uu *UserUpdate) SetXp(x xppoint.XP) *UserUpdate { + uu.mutation.ResetXp() + uu.mutation.SetXp(x) + return uu +} + +// SetNillableXp sets the "xp" field if the given value is not nil. +func (uu *UserUpdate) SetNillableXp(x *xppoint.XP) *UserUpdate { + if x != nil { + uu.SetXp(*x) + } + return uu +} + +// AddXp adds x to the "xp" field. +func (uu *UserUpdate) AddXp(x xppoint.XP) *UserUpdate { + uu.mutation.AddXp(x) + return uu +} + +// AddOwnGuildIDs adds the "own_guilds" edge to the Guild entity by IDs. +func (uu *UserUpdate) AddOwnGuildIDs(ids ...snowflake.ID) *UserUpdate { + uu.mutation.AddOwnGuildIDs(ids...) + return uu +} + +// AddOwnGuilds adds the "own_guilds" edges to the Guild entity. +func (uu *UserUpdate) AddOwnGuilds(g ...*Guild) *UserUpdate { + ids := make([]snowflake.ID, len(g)) + for i := range g { + ids[i] = g[i].ID + } + return uu.AddOwnGuildIDs(ids...) +} + +// AddGuildIDs adds the "guilds" edge to the Member entity by IDs. +func (uu *UserUpdate) AddGuildIDs(ids ...int) *UserUpdate { + uu.mutation.AddGuildIDs(ids...) + return uu +} + +// AddGuilds adds the "guilds" edges to the Member entity. +func (uu *UserUpdate) AddGuilds(m ...*Member) *UserUpdate { + ids := make([]int, len(m)) + for i := range m { + ids[i] = m[i].ID + } + return uu.AddGuildIDs(ids...) +} + +// AddWordSuffixIDs adds the "word_suffix" edge to the WordSuffix entity by IDs. +func (uu *UserUpdate) AddWordSuffixIDs(ids ...uuid.UUID) *UserUpdate { + uu.mutation.AddWordSuffixIDs(ids...) + return uu +} + +// AddWordSuffix adds the "word_suffix" edges to the WordSuffix entity. +func (uu *UserUpdate) AddWordSuffix(w ...*WordSuffix) *UserUpdate { + ids := make([]uuid.UUID, len(w)) + for i := range w { + ids[i] = w[i].ID + } + return uu.AddWordSuffixIDs(ids...) +} + +// Mutation returns the UserMutation object of the builder. +func (uu *UserUpdate) Mutation() *UserMutation { + return uu.mutation +} + +// ClearOwnGuilds clears all "own_guilds" edges to the Guild entity. +func (uu *UserUpdate) ClearOwnGuilds() *UserUpdate { + uu.mutation.ClearOwnGuilds() + return uu +} + +// RemoveOwnGuildIDs removes the "own_guilds" edge to Guild entities by IDs. +func (uu *UserUpdate) RemoveOwnGuildIDs(ids ...snowflake.ID) *UserUpdate { + uu.mutation.RemoveOwnGuildIDs(ids...) + return uu +} + +// RemoveOwnGuilds removes "own_guilds" edges to Guild entities. +func (uu *UserUpdate) RemoveOwnGuilds(g ...*Guild) *UserUpdate { + ids := make([]snowflake.ID, len(g)) + for i := range g { + ids[i] = g[i].ID + } + return uu.RemoveOwnGuildIDs(ids...) +} + +// ClearGuilds clears all "guilds" edges to the Member entity. +func (uu *UserUpdate) ClearGuilds() *UserUpdate { + uu.mutation.ClearGuilds() + return uu +} + +// RemoveGuildIDs removes the "guilds" edge to Member entities by IDs. +func (uu *UserUpdate) RemoveGuildIDs(ids ...int) *UserUpdate { + uu.mutation.RemoveGuildIDs(ids...) + return uu +} + +// RemoveGuilds removes "guilds" edges to Member entities. +func (uu *UserUpdate) RemoveGuilds(m ...*Member) *UserUpdate { + ids := make([]int, len(m)) + for i := range m { + ids[i] = m[i].ID + } + return uu.RemoveGuildIDs(ids...) +} + +// ClearWordSuffix clears all "word_suffix" edges to the WordSuffix entity. +func (uu *UserUpdate) ClearWordSuffix() *UserUpdate { + uu.mutation.ClearWordSuffix() + return uu +} + +// RemoveWordSuffixIDs removes the "word_suffix" edge to WordSuffix entities by IDs. +func (uu *UserUpdate) RemoveWordSuffixIDs(ids ...uuid.UUID) *UserUpdate { + uu.mutation.RemoveWordSuffixIDs(ids...) + return uu +} + +// RemoveWordSuffix removes "word_suffix" edges to WordSuffix entities. +func (uu *UserUpdate) RemoveWordSuffix(w ...*WordSuffix) *UserUpdate { + ids := make([]uuid.UUID, len(w)) + for i := range w { + ids[i] = w[i].ID + } + return uu.RemoveWordSuffixIDs(ids...) +} + +// Save executes the query and returns the number of nodes affected by the update operation. +func (uu *UserUpdate) Save(ctx context.Context) (int, error) { + return withHooks(ctx, uu.sqlSave, uu.mutation, uu.hooks) +} + +// SaveX is like Save, but panics if an error occurs. +func (uu *UserUpdate) SaveX(ctx context.Context) int { + affected, err := uu.Save(ctx) + if err != nil { + panic(err) + } + return affected +} + +// Exec executes the query. +func (uu *UserUpdate) Exec(ctx context.Context) error { + _, err := uu.Save(ctx) + return err +} + +// ExecX is like Exec, but panics if an error occurs. +func (uu *UserUpdate) ExecX(ctx context.Context) { + if err := uu.Exec(ctx); err != nil { + panic(err) + } +} + +// check runs all checks and user-defined validators on the builder. +func (uu *UserUpdate) check() error { + if v, ok := uu.mutation.Name(); ok { + if err := user.NameValidator(v); err != nil { + return &ValidationError{Name: "name", err: fmt.Errorf(`ent: validator failed for field "User.name": %w`, err)} + } + } + if v, ok := uu.mutation.Locale(); ok { + if err := user.LocaleValidator(string(v)); err != nil { + return &ValidationError{Name: "locale", err: fmt.Errorf(`ent: validator failed for field "User.locale": %w`, err)} + } + } + return nil +} + +func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) { + if err := uu.check(); err != nil { + return n, err + } + _spec := sqlgraph.NewUpdateSpec(user.Table, user.Columns, sqlgraph.NewFieldSpec(user.FieldID, field.TypeUint64)) + if ps := uu.mutation.predicates; len(ps) > 0 { + _spec.Predicate = func(selector *sql.Selector) { + for i := range ps { + ps[i](selector) + } + } + } + if value, ok := uu.mutation.Name(); ok { + _spec.SetField(user.FieldName, field.TypeString, value) + } + if value, ok := uu.mutation.Locale(); ok { + _spec.SetField(user.FieldLocale, field.TypeString, value) + } + if value, ok := uu.mutation.Xp(); ok { + _spec.SetField(user.FieldXp, field.TypeUint64, value) + } + if value, ok := uu.mutation.AddedXp(); ok { + _spec.AddField(user.FieldXp, field.TypeUint64, value) + } + if uu.mutation.OwnGuildsCleared() { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: false, + Table: user.OwnGuildsTable, + Columns: []string{user.OwnGuildsColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(guild.FieldID, field.TypeUint64), + }, + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := uu.mutation.RemovedOwnGuildsIDs(); len(nodes) > 0 && !uu.mutation.OwnGuildsCleared() { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: false, + Table: user.OwnGuildsTable, + Columns: []string{user.OwnGuildsColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(guild.FieldID, field.TypeUint64), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := uu.mutation.OwnGuildsIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: false, + Table: user.OwnGuildsTable, + Columns: []string{user.OwnGuildsColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(guild.FieldID, field.TypeUint64), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Add = append(_spec.Edges.Add, edge) + } + if uu.mutation.GuildsCleared() { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: false, + Table: user.GuildsTable, + Columns: []string{user.GuildsColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(member.FieldID, field.TypeInt), + }, + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := uu.mutation.RemovedGuildsIDs(); len(nodes) > 0 && !uu.mutation.GuildsCleared() { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: false, + Table: user.GuildsTable, + Columns: []string{user.GuildsColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(member.FieldID, field.TypeInt), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := uu.mutation.GuildsIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: false, + Table: user.GuildsTable, + Columns: []string{user.GuildsColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(member.FieldID, field.TypeInt), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Add = append(_spec.Edges.Add, edge) + } + if uu.mutation.WordSuffixCleared() { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: false, + Table: user.WordSuffixTable, + Columns: []string{user.WordSuffixColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(wordsuffix.FieldID, field.TypeUUID), + }, + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := uu.mutation.RemovedWordSuffixIDs(); len(nodes) > 0 && !uu.mutation.WordSuffixCleared() { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: false, + Table: user.WordSuffixTable, + Columns: []string{user.WordSuffixColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(wordsuffix.FieldID, field.TypeUUID), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := uu.mutation.WordSuffixIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: false, + Table: user.WordSuffixTable, + Columns: []string{user.WordSuffixColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(wordsuffix.FieldID, field.TypeUUID), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Add = append(_spec.Edges.Add, edge) + } + if n, err = sqlgraph.UpdateNodes(ctx, uu.driver, _spec); err != nil { + if _, ok := err.(*sqlgraph.NotFoundError); ok { + err = &NotFoundError{user.Label} + } else if sqlgraph.IsConstraintError(err) { + err = &ConstraintError{msg: err.Error(), wrap: err} + } + return 0, err + } + uu.mutation.done = true + return n, nil +} + +// UserUpdateOne is the builder for updating a single User entity. +type UserUpdateOne struct { + config + fields []string + hooks []Hook + mutation *UserMutation +} + +// SetName sets the "name" field. +func (uuo *UserUpdateOne) SetName(s string) *UserUpdateOne { + uuo.mutation.SetName(s) + return uuo +} + +// SetNillableName sets the "name" field if the given value is not nil. +func (uuo *UserUpdateOne) SetNillableName(s *string) *UserUpdateOne { + if s != nil { + uuo.SetName(*s) + } + return uuo +} + +// SetLocale sets the "locale" field. +func (uuo *UserUpdateOne) SetLocale(d discord.Locale) *UserUpdateOne { + uuo.mutation.SetLocale(d) + return uuo +} + +// SetNillableLocale sets the "locale" field if the given value is not nil. +func (uuo *UserUpdateOne) SetNillableLocale(d *discord.Locale) *UserUpdateOne { + if d != nil { + uuo.SetLocale(*d) + } + return uuo +} + +// SetXp sets the "xp" field. +func (uuo *UserUpdateOne) SetXp(x xppoint.XP) *UserUpdateOne { + uuo.mutation.ResetXp() + uuo.mutation.SetXp(x) + return uuo +} + +// SetNillableXp sets the "xp" field if the given value is not nil. +func (uuo *UserUpdateOne) SetNillableXp(x *xppoint.XP) *UserUpdateOne { + if x != nil { + uuo.SetXp(*x) + } + return uuo +} + +// AddXp adds x to the "xp" field. +func (uuo *UserUpdateOne) AddXp(x xppoint.XP) *UserUpdateOne { + uuo.mutation.AddXp(x) + return uuo +} + +// AddOwnGuildIDs adds the "own_guilds" edge to the Guild entity by IDs. +func (uuo *UserUpdateOne) AddOwnGuildIDs(ids ...snowflake.ID) *UserUpdateOne { + uuo.mutation.AddOwnGuildIDs(ids...) + return uuo +} + +// AddOwnGuilds adds the "own_guilds" edges to the Guild entity. +func (uuo *UserUpdateOne) AddOwnGuilds(g ...*Guild) *UserUpdateOne { + ids := make([]snowflake.ID, len(g)) + for i := range g { + ids[i] = g[i].ID + } + return uuo.AddOwnGuildIDs(ids...) +} + +// AddGuildIDs adds the "guilds" edge to the Member entity by IDs. +func (uuo *UserUpdateOne) AddGuildIDs(ids ...int) *UserUpdateOne { + uuo.mutation.AddGuildIDs(ids...) + return uuo +} + +// AddGuilds adds the "guilds" edges to the Member entity. +func (uuo *UserUpdateOne) AddGuilds(m ...*Member) *UserUpdateOne { + ids := make([]int, len(m)) + for i := range m { + ids[i] = m[i].ID + } + return uuo.AddGuildIDs(ids...) +} + +// AddWordSuffixIDs adds the "word_suffix" edge to the WordSuffix entity by IDs. +func (uuo *UserUpdateOne) AddWordSuffixIDs(ids ...uuid.UUID) *UserUpdateOne { + uuo.mutation.AddWordSuffixIDs(ids...) + return uuo +} + +// AddWordSuffix adds the "word_suffix" edges to the WordSuffix entity. +func (uuo *UserUpdateOne) AddWordSuffix(w ...*WordSuffix) *UserUpdateOne { + ids := make([]uuid.UUID, len(w)) + for i := range w { + ids[i] = w[i].ID + } + return uuo.AddWordSuffixIDs(ids...) +} + +// Mutation returns the UserMutation object of the builder. +func (uuo *UserUpdateOne) Mutation() *UserMutation { + return uuo.mutation +} + +// ClearOwnGuilds clears all "own_guilds" edges to the Guild entity. +func (uuo *UserUpdateOne) ClearOwnGuilds() *UserUpdateOne { + uuo.mutation.ClearOwnGuilds() + return uuo +} + +// RemoveOwnGuildIDs removes the "own_guilds" edge to Guild entities by IDs. +func (uuo *UserUpdateOne) RemoveOwnGuildIDs(ids ...snowflake.ID) *UserUpdateOne { + uuo.mutation.RemoveOwnGuildIDs(ids...) + return uuo +} + +// RemoveOwnGuilds removes "own_guilds" edges to Guild entities. +func (uuo *UserUpdateOne) RemoveOwnGuilds(g ...*Guild) *UserUpdateOne { + ids := make([]snowflake.ID, len(g)) + for i := range g { + ids[i] = g[i].ID + } + return uuo.RemoveOwnGuildIDs(ids...) +} + +// ClearGuilds clears all "guilds" edges to the Member entity. +func (uuo *UserUpdateOne) ClearGuilds() *UserUpdateOne { + uuo.mutation.ClearGuilds() + return uuo +} + +// RemoveGuildIDs removes the "guilds" edge to Member entities by IDs. +func (uuo *UserUpdateOne) RemoveGuildIDs(ids ...int) *UserUpdateOne { + uuo.mutation.RemoveGuildIDs(ids...) + return uuo +} + +// RemoveGuilds removes "guilds" edges to Member entities. +func (uuo *UserUpdateOne) RemoveGuilds(m ...*Member) *UserUpdateOne { + ids := make([]int, len(m)) + for i := range m { + ids[i] = m[i].ID + } + return uuo.RemoveGuildIDs(ids...) +} + +// ClearWordSuffix clears all "word_suffix" edges to the WordSuffix entity. +func (uuo *UserUpdateOne) ClearWordSuffix() *UserUpdateOne { + uuo.mutation.ClearWordSuffix() + return uuo +} + +// RemoveWordSuffixIDs removes the "word_suffix" edge to WordSuffix entities by IDs. +func (uuo *UserUpdateOne) RemoveWordSuffixIDs(ids ...uuid.UUID) *UserUpdateOne { + uuo.mutation.RemoveWordSuffixIDs(ids...) + return uuo +} + +// RemoveWordSuffix removes "word_suffix" edges to WordSuffix entities. +func (uuo *UserUpdateOne) RemoveWordSuffix(w ...*WordSuffix) *UserUpdateOne { + ids := make([]uuid.UUID, len(w)) + for i := range w { + ids[i] = w[i].ID + } + return uuo.RemoveWordSuffixIDs(ids...) +} + +// Where appends a list predicates to the UserUpdate builder. +func (uuo *UserUpdateOne) Where(ps ...predicate.User) *UserUpdateOne { + uuo.mutation.Where(ps...) + return uuo +} + +// Select allows selecting one or more fields (columns) of the returned entity. +// The default is selecting all fields defined in the entity schema. +func (uuo *UserUpdateOne) Select(field string, fields ...string) *UserUpdateOne { + uuo.fields = append([]string{field}, fields...) + return uuo +} + +// Save executes the query and returns the updated User entity. +func (uuo *UserUpdateOne) Save(ctx context.Context) (*User, error) { + return withHooks(ctx, uuo.sqlSave, uuo.mutation, uuo.hooks) +} + +// SaveX is like Save, but panics if an error occurs. +func (uuo *UserUpdateOne) SaveX(ctx context.Context) *User { + node, err := uuo.Save(ctx) + if err != nil { + panic(err) + } + return node +} + +// Exec executes the query on the entity. +func (uuo *UserUpdateOne) Exec(ctx context.Context) error { + _, err := uuo.Save(ctx) + return err +} + +// ExecX is like Exec, but panics if an error occurs. +func (uuo *UserUpdateOne) ExecX(ctx context.Context) { + if err := uuo.Exec(ctx); err != nil { + panic(err) + } +} + +// check runs all checks and user-defined validators on the builder. +func (uuo *UserUpdateOne) check() error { + if v, ok := uuo.mutation.Name(); ok { + if err := user.NameValidator(v); err != nil { + return &ValidationError{Name: "name", err: fmt.Errorf(`ent: validator failed for field "User.name": %w`, err)} + } + } + if v, ok := uuo.mutation.Locale(); ok { + if err := user.LocaleValidator(string(v)); err != nil { + return &ValidationError{Name: "locale", err: fmt.Errorf(`ent: validator failed for field "User.locale": %w`, err)} + } + } + return nil +} + +func (uuo *UserUpdateOne) sqlSave(ctx context.Context) (_node *User, err error) { + if err := uuo.check(); err != nil { + return _node, err + } + _spec := sqlgraph.NewUpdateSpec(user.Table, user.Columns, sqlgraph.NewFieldSpec(user.FieldID, field.TypeUint64)) + id, ok := uuo.mutation.ID() + if !ok { + return nil, &ValidationError{Name: "id", err: errors.New(`ent: missing "User.id" for update`)} + } + _spec.Node.ID.Value = id + if fields := uuo.fields; len(fields) > 0 { + _spec.Node.Columns = make([]string, 0, len(fields)) + _spec.Node.Columns = append(_spec.Node.Columns, user.FieldID) + for _, f := range fields { + if !user.ValidColumn(f) { + return nil, &ValidationError{Name: f, err: fmt.Errorf("ent: invalid field %q for query", f)} + } + if f != user.FieldID { + _spec.Node.Columns = append(_spec.Node.Columns, f) + } + } + } + if ps := uuo.mutation.predicates; len(ps) > 0 { + _spec.Predicate = func(selector *sql.Selector) { + for i := range ps { + ps[i](selector) + } + } + } + if value, ok := uuo.mutation.Name(); ok { + _spec.SetField(user.FieldName, field.TypeString, value) + } + if value, ok := uuo.mutation.Locale(); ok { + _spec.SetField(user.FieldLocale, field.TypeString, value) + } + if value, ok := uuo.mutation.Xp(); ok { + _spec.SetField(user.FieldXp, field.TypeUint64, value) + } + if value, ok := uuo.mutation.AddedXp(); ok { + _spec.AddField(user.FieldXp, field.TypeUint64, value) + } + if uuo.mutation.OwnGuildsCleared() { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: false, + Table: user.OwnGuildsTable, + Columns: []string{user.OwnGuildsColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(guild.FieldID, field.TypeUint64), + }, + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := uuo.mutation.RemovedOwnGuildsIDs(); len(nodes) > 0 && !uuo.mutation.OwnGuildsCleared() { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: false, + Table: user.OwnGuildsTable, + Columns: []string{user.OwnGuildsColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(guild.FieldID, field.TypeUint64), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := uuo.mutation.OwnGuildsIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: false, + Table: user.OwnGuildsTable, + Columns: []string{user.OwnGuildsColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(guild.FieldID, field.TypeUint64), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Add = append(_spec.Edges.Add, edge) + } + if uuo.mutation.GuildsCleared() { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: false, + Table: user.GuildsTable, + Columns: []string{user.GuildsColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(member.FieldID, field.TypeInt), + }, + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := uuo.mutation.RemovedGuildsIDs(); len(nodes) > 0 && !uuo.mutation.GuildsCleared() { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: false, + Table: user.GuildsTable, + Columns: []string{user.GuildsColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(member.FieldID, field.TypeInt), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := uuo.mutation.GuildsIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: false, + Table: user.GuildsTable, + Columns: []string{user.GuildsColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(member.FieldID, field.TypeInt), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Add = append(_spec.Edges.Add, edge) + } + if uuo.mutation.WordSuffixCleared() { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: false, + Table: user.WordSuffixTable, + Columns: []string{user.WordSuffixColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(wordsuffix.FieldID, field.TypeUUID), + }, + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := uuo.mutation.RemovedWordSuffixIDs(); len(nodes) > 0 && !uuo.mutation.WordSuffixCleared() { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: false, + Table: user.WordSuffixTable, + Columns: []string{user.WordSuffixColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(wordsuffix.FieldID, field.TypeUUID), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := uuo.mutation.WordSuffixIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: false, + Table: user.WordSuffixTable, + Columns: []string{user.WordSuffixColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(wordsuffix.FieldID, field.TypeUUID), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Add = append(_spec.Edges.Add, edge) + } + _node = &User{config: uuo.config} + _spec.Assign = _node.assignValues + _spec.ScanValues = _node.scanValues + if err = sqlgraph.UpdateNode(ctx, uuo.driver, _spec); err != nil { + if _, ok := err.(*sqlgraph.NotFoundError); ok { + err = &NotFoundError{user.Label} + } else if sqlgraph.IsConstraintError(err) { + err = &ConstraintError{msg: err.Error(), wrap: err} + } + return nil, err + } + uuo.mutation.done = true + return _node, nil +} diff --git a/ent/wordsuffix.go b/ent/wordsuffix.go new file mode 100644 index 00000000..2b87c9c2 --- /dev/null +++ b/ent/wordsuffix.go @@ -0,0 +1,207 @@ +// Code generated by ent, DO NOT EDIT. + +package ent + +import ( + "fmt" + "strings" + "time" + + "entgo.io/ent" + "entgo.io/ent/dialect/sql" + snowflake "github.com/disgoorg/snowflake/v2" + "github.com/google/uuid" + "github.com/sabafly/gobot/ent/guild" + "github.com/sabafly/gobot/ent/user" + "github.com/sabafly/gobot/ent/wordsuffix" +) + +// WordSuffix is the model entity for the WordSuffix schema. +type WordSuffix struct { + config `json:"-"` + // ID of the ent. + ID uuid.UUID `json:"id,omitempty"` + // Suffix holds the value of the "suffix" field. + Suffix string `json:"suffix,omitempty"` + // Expired holds the value of the "expired" field. + Expired *time.Time `json:"expired,omitempty"` + // GuildID holds the value of the "guild_id" field. + GuildID *snowflake.ID `json:"guild_id,omitempty"` + // Rule holds the value of the "rule" field. + Rule wordsuffix.Rule `json:"rule,omitempty"` + // Edges holds the relations/edges for other nodes in the graph. + // The values are being populated by the WordSuffixQuery when eager-loading is set. + Edges WordSuffixEdges `json:"edges"` + user_word_suffix *snowflake.ID + selectValues sql.SelectValues +} + +// WordSuffixEdges holds the relations/edges for other nodes in the graph. +type WordSuffixEdges struct { + // Guild holds the value of the guild edge. + Guild *Guild `json:"guild,omitempty"` + // Owner holds the value of the owner edge. + Owner *User `json:"owner,omitempty"` + // loadedTypes holds the information for reporting if a + // type was loaded (or requested) in eager-loading or not. + loadedTypes [2]bool +} + +// GuildOrErr returns the Guild value or an error if the edge +// was not loaded in eager-loading, or loaded but was not found. +func (e WordSuffixEdges) GuildOrErr() (*Guild, error) { + if e.Guild != nil { + return e.Guild, nil + } else if e.loadedTypes[0] { + return nil, &NotFoundError{label: guild.Label} + } + return nil, &NotLoadedError{edge: "guild"} +} + +// OwnerOrErr returns the Owner value or an error if the edge +// was not loaded in eager-loading, or loaded but was not found. +func (e WordSuffixEdges) OwnerOrErr() (*User, error) { + if e.Owner != nil { + return e.Owner, nil + } else if e.loadedTypes[1] { + return nil, &NotFoundError{label: user.Label} + } + return nil, &NotLoadedError{edge: "owner"} +} + +// scanValues returns the types for scanning values from sql.Rows. +func (*WordSuffix) scanValues(columns []string) ([]any, error) { + values := make([]any, len(columns)) + for i := range columns { + switch columns[i] { + case wordsuffix.FieldGuildID: + values[i] = new(sql.NullInt64) + case wordsuffix.FieldSuffix, wordsuffix.FieldRule: + values[i] = new(sql.NullString) + case wordsuffix.FieldExpired: + values[i] = new(sql.NullTime) + case wordsuffix.FieldID: + values[i] = new(uuid.UUID) + case wordsuffix.ForeignKeys[0]: // user_word_suffix + values[i] = new(sql.NullInt64) + default: + values[i] = new(sql.UnknownType) + } + } + return values, nil +} + +// assignValues assigns the values that were returned from sql.Rows (after scanning) +// to the WordSuffix fields. +func (ws *WordSuffix) assignValues(columns []string, values []any) error { + if m, n := len(values), len(columns); m < n { + return fmt.Errorf("mismatch number of scan values: %d != %d", m, n) + } + for i := range columns { + switch columns[i] { + case wordsuffix.FieldID: + if value, ok := values[i].(*uuid.UUID); !ok { + return fmt.Errorf("unexpected type %T for field id", values[i]) + } else if value != nil { + ws.ID = *value + } + case wordsuffix.FieldSuffix: + if value, ok := values[i].(*sql.NullString); !ok { + return fmt.Errorf("unexpected type %T for field suffix", values[i]) + } else if value.Valid { + ws.Suffix = value.String + } + case wordsuffix.FieldExpired: + if value, ok := values[i].(*sql.NullTime); !ok { + return fmt.Errorf("unexpected type %T for field expired", values[i]) + } else if value.Valid { + ws.Expired = new(time.Time) + *ws.Expired = value.Time + } + case wordsuffix.FieldGuildID: + if value, ok := values[i].(*sql.NullInt64); !ok { + return fmt.Errorf("unexpected type %T for field guild_id", values[i]) + } else if value.Valid { + ws.GuildID = new(snowflake.ID) + *ws.GuildID = snowflake.ID(value.Int64) + } + case wordsuffix.FieldRule: + if value, ok := values[i].(*sql.NullString); !ok { + return fmt.Errorf("unexpected type %T for field rule", values[i]) + } else if value.Valid { + ws.Rule = wordsuffix.Rule(value.String) + } + case wordsuffix.ForeignKeys[0]: + if value, ok := values[i].(*sql.NullInt64); !ok { + return fmt.Errorf("unexpected type %T for field user_word_suffix", values[i]) + } else if value.Valid { + ws.user_word_suffix = new(snowflake.ID) + *ws.user_word_suffix = snowflake.ID(value.Int64) + } + default: + ws.selectValues.Set(columns[i], values[i]) + } + } + return nil +} + +// Value returns the ent.Value that was dynamically selected and assigned to the WordSuffix. +// This includes values selected through modifiers, order, etc. +func (ws *WordSuffix) Value(name string) (ent.Value, error) { + return ws.selectValues.Get(name) +} + +// QueryGuild queries the "guild" edge of the WordSuffix entity. +func (ws *WordSuffix) QueryGuild() *GuildQuery { + return NewWordSuffixClient(ws.config).QueryGuild(ws) +} + +// QueryOwner queries the "owner" edge of the WordSuffix entity. +func (ws *WordSuffix) QueryOwner() *UserQuery { + return NewWordSuffixClient(ws.config).QueryOwner(ws) +} + +// Update returns a builder for updating this WordSuffix. +// Note that you need to call WordSuffix.Unwrap() before calling this method if this WordSuffix +// was returned from a transaction, and the transaction was committed or rolled back. +func (ws *WordSuffix) Update() *WordSuffixUpdateOne { + return NewWordSuffixClient(ws.config).UpdateOne(ws) +} + +// Unwrap unwraps the WordSuffix entity that was returned from a transaction after it was closed, +// so that all future queries will be executed through the driver which created the transaction. +func (ws *WordSuffix) Unwrap() *WordSuffix { + _tx, ok := ws.config.driver.(*txDriver) + if !ok { + panic("ent: WordSuffix is not a transactional entity") + } + ws.config.driver = _tx.drv + return ws +} + +// String implements the fmt.Stringer. +func (ws *WordSuffix) String() string { + var builder strings.Builder + builder.WriteString("WordSuffix(") + builder.WriteString(fmt.Sprintf("id=%v, ", ws.ID)) + builder.WriteString("suffix=") + builder.WriteString(ws.Suffix) + builder.WriteString(", ") + if v := ws.Expired; v != nil { + builder.WriteString("expired=") + builder.WriteString(v.Format(time.ANSIC)) + } + builder.WriteString(", ") + if v := ws.GuildID; v != nil { + builder.WriteString("guild_id=") + builder.WriteString(fmt.Sprintf("%v", *v)) + } + builder.WriteString(", ") + builder.WriteString("rule=") + builder.WriteString(fmt.Sprintf("%v", ws.Rule)) + builder.WriteByte(')') + return builder.String() +} + +// WordSuffixes is a parsable slice of WordSuffix. +type WordSuffixes []*WordSuffix diff --git a/ent/wordsuffix/where.go b/ent/wordsuffix/where.go new file mode 100644 index 00000000..9bebcbf2 --- /dev/null +++ b/ent/wordsuffix/where.go @@ -0,0 +1,310 @@ +// Code generated by ent, DO NOT EDIT. + +package wordsuffix + +import ( + "time" + + "entgo.io/ent/dialect/sql" + "entgo.io/ent/dialect/sql/sqlgraph" + snowflake "github.com/disgoorg/snowflake/v2" + "github.com/google/uuid" + "github.com/sabafly/gobot/ent/predicate" +) + +// ID filters vertices based on their ID field. +func ID(id uuid.UUID) predicate.WordSuffix { + return predicate.WordSuffix(sql.FieldEQ(FieldID, id)) +} + +// IDEQ applies the EQ predicate on the ID field. +func IDEQ(id uuid.UUID) predicate.WordSuffix { + return predicate.WordSuffix(sql.FieldEQ(FieldID, id)) +} + +// IDNEQ applies the NEQ predicate on the ID field. +func IDNEQ(id uuid.UUID) predicate.WordSuffix { + return predicate.WordSuffix(sql.FieldNEQ(FieldID, id)) +} + +// IDIn applies the In predicate on the ID field. +func IDIn(ids ...uuid.UUID) predicate.WordSuffix { + return predicate.WordSuffix(sql.FieldIn(FieldID, ids...)) +} + +// IDNotIn applies the NotIn predicate on the ID field. +func IDNotIn(ids ...uuid.UUID) predicate.WordSuffix { + return predicate.WordSuffix(sql.FieldNotIn(FieldID, ids...)) +} + +// IDGT applies the GT predicate on the ID field. +func IDGT(id uuid.UUID) predicate.WordSuffix { + return predicate.WordSuffix(sql.FieldGT(FieldID, id)) +} + +// IDGTE applies the GTE predicate on the ID field. +func IDGTE(id uuid.UUID) predicate.WordSuffix { + return predicate.WordSuffix(sql.FieldGTE(FieldID, id)) +} + +// IDLT applies the LT predicate on the ID field. +func IDLT(id uuid.UUID) predicate.WordSuffix { + return predicate.WordSuffix(sql.FieldLT(FieldID, id)) +} + +// IDLTE applies the LTE predicate on the ID field. +func IDLTE(id uuid.UUID) predicate.WordSuffix { + return predicate.WordSuffix(sql.FieldLTE(FieldID, id)) +} + +// Suffix applies equality check predicate on the "suffix" field. It's identical to SuffixEQ. +func Suffix(v string) predicate.WordSuffix { + return predicate.WordSuffix(sql.FieldEQ(FieldSuffix, v)) +} + +// Expired applies equality check predicate on the "expired" field. It's identical to ExpiredEQ. +func Expired(v time.Time) predicate.WordSuffix { + return predicate.WordSuffix(sql.FieldEQ(FieldExpired, v)) +} + +// GuildID applies equality check predicate on the "guild_id" field. It's identical to GuildIDEQ. +func GuildID(v snowflake.ID) predicate.WordSuffix { + vc := uint64(v) + return predicate.WordSuffix(sql.FieldEQ(FieldGuildID, vc)) +} + +// SuffixEQ applies the EQ predicate on the "suffix" field. +func SuffixEQ(v string) predicate.WordSuffix { + return predicate.WordSuffix(sql.FieldEQ(FieldSuffix, v)) +} + +// SuffixNEQ applies the NEQ predicate on the "suffix" field. +func SuffixNEQ(v string) predicate.WordSuffix { + return predicate.WordSuffix(sql.FieldNEQ(FieldSuffix, v)) +} + +// SuffixIn applies the In predicate on the "suffix" field. +func SuffixIn(vs ...string) predicate.WordSuffix { + return predicate.WordSuffix(sql.FieldIn(FieldSuffix, vs...)) +} + +// SuffixNotIn applies the NotIn predicate on the "suffix" field. +func SuffixNotIn(vs ...string) predicate.WordSuffix { + return predicate.WordSuffix(sql.FieldNotIn(FieldSuffix, vs...)) +} + +// SuffixGT applies the GT predicate on the "suffix" field. +func SuffixGT(v string) predicate.WordSuffix { + return predicate.WordSuffix(sql.FieldGT(FieldSuffix, v)) +} + +// SuffixGTE applies the GTE predicate on the "suffix" field. +func SuffixGTE(v string) predicate.WordSuffix { + return predicate.WordSuffix(sql.FieldGTE(FieldSuffix, v)) +} + +// SuffixLT applies the LT predicate on the "suffix" field. +func SuffixLT(v string) predicate.WordSuffix { + return predicate.WordSuffix(sql.FieldLT(FieldSuffix, v)) +} + +// SuffixLTE applies the LTE predicate on the "suffix" field. +func SuffixLTE(v string) predicate.WordSuffix { + return predicate.WordSuffix(sql.FieldLTE(FieldSuffix, v)) +} + +// SuffixContains applies the Contains predicate on the "suffix" field. +func SuffixContains(v string) predicate.WordSuffix { + return predicate.WordSuffix(sql.FieldContains(FieldSuffix, v)) +} + +// SuffixHasPrefix applies the HasPrefix predicate on the "suffix" field. +func SuffixHasPrefix(v string) predicate.WordSuffix { + return predicate.WordSuffix(sql.FieldHasPrefix(FieldSuffix, v)) +} + +// SuffixHasSuffix applies the HasSuffix predicate on the "suffix" field. +func SuffixHasSuffix(v string) predicate.WordSuffix { + return predicate.WordSuffix(sql.FieldHasSuffix(FieldSuffix, v)) +} + +// SuffixEqualFold applies the EqualFold predicate on the "suffix" field. +func SuffixEqualFold(v string) predicate.WordSuffix { + return predicate.WordSuffix(sql.FieldEqualFold(FieldSuffix, v)) +} + +// SuffixContainsFold applies the ContainsFold predicate on the "suffix" field. +func SuffixContainsFold(v string) predicate.WordSuffix { + return predicate.WordSuffix(sql.FieldContainsFold(FieldSuffix, v)) +} + +// ExpiredEQ applies the EQ predicate on the "expired" field. +func ExpiredEQ(v time.Time) predicate.WordSuffix { + return predicate.WordSuffix(sql.FieldEQ(FieldExpired, v)) +} + +// ExpiredNEQ applies the NEQ predicate on the "expired" field. +func ExpiredNEQ(v time.Time) predicate.WordSuffix { + return predicate.WordSuffix(sql.FieldNEQ(FieldExpired, v)) +} + +// ExpiredIn applies the In predicate on the "expired" field. +func ExpiredIn(vs ...time.Time) predicate.WordSuffix { + return predicate.WordSuffix(sql.FieldIn(FieldExpired, vs...)) +} + +// ExpiredNotIn applies the NotIn predicate on the "expired" field. +func ExpiredNotIn(vs ...time.Time) predicate.WordSuffix { + return predicate.WordSuffix(sql.FieldNotIn(FieldExpired, vs...)) +} + +// ExpiredGT applies the GT predicate on the "expired" field. +func ExpiredGT(v time.Time) predicate.WordSuffix { + return predicate.WordSuffix(sql.FieldGT(FieldExpired, v)) +} + +// ExpiredGTE applies the GTE predicate on the "expired" field. +func ExpiredGTE(v time.Time) predicate.WordSuffix { + return predicate.WordSuffix(sql.FieldGTE(FieldExpired, v)) +} + +// ExpiredLT applies the LT predicate on the "expired" field. +func ExpiredLT(v time.Time) predicate.WordSuffix { + return predicate.WordSuffix(sql.FieldLT(FieldExpired, v)) +} + +// ExpiredLTE applies the LTE predicate on the "expired" field. +func ExpiredLTE(v time.Time) predicate.WordSuffix { + return predicate.WordSuffix(sql.FieldLTE(FieldExpired, v)) +} + +// ExpiredIsNil applies the IsNil predicate on the "expired" field. +func ExpiredIsNil() predicate.WordSuffix { + return predicate.WordSuffix(sql.FieldIsNull(FieldExpired)) +} + +// ExpiredNotNil applies the NotNil predicate on the "expired" field. +func ExpiredNotNil() predicate.WordSuffix { + return predicate.WordSuffix(sql.FieldNotNull(FieldExpired)) +} + +// GuildIDEQ applies the EQ predicate on the "guild_id" field. +func GuildIDEQ(v snowflake.ID) predicate.WordSuffix { + vc := uint64(v) + return predicate.WordSuffix(sql.FieldEQ(FieldGuildID, vc)) +} + +// GuildIDNEQ applies the NEQ predicate on the "guild_id" field. +func GuildIDNEQ(v snowflake.ID) predicate.WordSuffix { + vc := uint64(v) + return predicate.WordSuffix(sql.FieldNEQ(FieldGuildID, vc)) +} + +// GuildIDIn applies the In predicate on the "guild_id" field. +func GuildIDIn(vs ...snowflake.ID) predicate.WordSuffix { + v := make([]any, len(vs)) + for i := range v { + v[i] = uint64(vs[i]) + } + return predicate.WordSuffix(sql.FieldIn(FieldGuildID, v...)) +} + +// GuildIDNotIn applies the NotIn predicate on the "guild_id" field. +func GuildIDNotIn(vs ...snowflake.ID) predicate.WordSuffix { + v := make([]any, len(vs)) + for i := range v { + v[i] = uint64(vs[i]) + } + return predicate.WordSuffix(sql.FieldNotIn(FieldGuildID, v...)) +} + +// GuildIDIsNil applies the IsNil predicate on the "guild_id" field. +func GuildIDIsNil() predicate.WordSuffix { + return predicate.WordSuffix(sql.FieldIsNull(FieldGuildID)) +} + +// GuildIDNotNil applies the NotNil predicate on the "guild_id" field. +func GuildIDNotNil() predicate.WordSuffix { + return predicate.WordSuffix(sql.FieldNotNull(FieldGuildID)) +} + +// RuleEQ applies the EQ predicate on the "rule" field. +func RuleEQ(v Rule) predicate.WordSuffix { + return predicate.WordSuffix(sql.FieldEQ(FieldRule, v)) +} + +// RuleNEQ applies the NEQ predicate on the "rule" field. +func RuleNEQ(v Rule) predicate.WordSuffix { + return predicate.WordSuffix(sql.FieldNEQ(FieldRule, v)) +} + +// RuleIn applies the In predicate on the "rule" field. +func RuleIn(vs ...Rule) predicate.WordSuffix { + return predicate.WordSuffix(sql.FieldIn(FieldRule, vs...)) +} + +// RuleNotIn applies the NotIn predicate on the "rule" field. +func RuleNotIn(vs ...Rule) predicate.WordSuffix { + return predicate.WordSuffix(sql.FieldNotIn(FieldRule, vs...)) +} + +// HasGuild applies the HasEdge predicate on the "guild" edge. +func HasGuild() predicate.WordSuffix { + return predicate.WordSuffix(func(s *sql.Selector) { + step := sqlgraph.NewStep( + sqlgraph.From(Table, FieldID), + sqlgraph.Edge(sqlgraph.M2O, false, GuildTable, GuildColumn), + ) + sqlgraph.HasNeighbors(s, step) + }) +} + +// HasGuildWith applies the HasEdge predicate on the "guild" edge with a given conditions (other predicates). +func HasGuildWith(preds ...predicate.Guild) predicate.WordSuffix { + return predicate.WordSuffix(func(s *sql.Selector) { + step := newGuildStep() + sqlgraph.HasNeighborsWith(s, step, func(s *sql.Selector) { + for _, p := range preds { + p(s) + } + }) + }) +} + +// HasOwner applies the HasEdge predicate on the "owner" edge. +func HasOwner() predicate.WordSuffix { + return predicate.WordSuffix(func(s *sql.Selector) { + step := sqlgraph.NewStep( + sqlgraph.From(Table, FieldID), + sqlgraph.Edge(sqlgraph.M2O, true, OwnerTable, OwnerColumn), + ) + sqlgraph.HasNeighbors(s, step) + }) +} + +// HasOwnerWith applies the HasEdge predicate on the "owner" edge with a given conditions (other predicates). +func HasOwnerWith(preds ...predicate.User) predicate.WordSuffix { + return predicate.WordSuffix(func(s *sql.Selector) { + step := newOwnerStep() + sqlgraph.HasNeighborsWith(s, step, func(s *sql.Selector) { + for _, p := range preds { + p(s) + } + }) + }) +} + +// And groups predicates with the AND operator between them. +func And(predicates ...predicate.WordSuffix) predicate.WordSuffix { + return predicate.WordSuffix(sql.AndPredicates(predicates...)) +} + +// Or groups predicates with the OR operator between them. +func Or(predicates ...predicate.WordSuffix) predicate.WordSuffix { + return predicate.WordSuffix(sql.OrPredicates(predicates...)) +} + +// Not applies the not operator on the given predicate. +func Not(p predicate.WordSuffix) predicate.WordSuffix { + return predicate.WordSuffix(sql.NotPredicates(p)) +} diff --git a/ent/wordsuffix/wordsuffix.go b/ent/wordsuffix/wordsuffix.go new file mode 100644 index 00000000..0313a6de --- /dev/null +++ b/ent/wordsuffix/wordsuffix.go @@ -0,0 +1,166 @@ +// Code generated by ent, DO NOT EDIT. + +package wordsuffix + +import ( + "fmt" + + "entgo.io/ent/dialect/sql" + "entgo.io/ent/dialect/sql/sqlgraph" + "github.com/google/uuid" +) + +const ( + // Label holds the string label denoting the wordsuffix type in the database. + Label = "word_suffix" + // FieldID holds the string denoting the id field in the database. + FieldID = "id" + // FieldSuffix holds the string denoting the suffix field in the database. + FieldSuffix = "suffix" + // FieldExpired holds the string denoting the expired field in the database. + FieldExpired = "expired" + // FieldGuildID holds the string denoting the guild_id field in the database. + FieldGuildID = "guild_id" + // FieldRule holds the string denoting the rule field in the database. + FieldRule = "rule" + // EdgeGuild holds the string denoting the guild edge name in mutations. + EdgeGuild = "guild" + // EdgeOwner holds the string denoting the owner edge name in mutations. + EdgeOwner = "owner" + // Table holds the table name of the wordsuffix in the database. + Table = "word_suffixes" + // GuildTable is the table that holds the guild relation/edge. + GuildTable = "word_suffixes" + // GuildInverseTable is the table name for the Guild entity. + // It exists in this package in order to avoid circular dependency with the "guild" package. + GuildInverseTable = "guilds" + // GuildColumn is the table column denoting the guild relation/edge. + GuildColumn = "guild_id" + // OwnerTable is the table that holds the owner relation/edge. + OwnerTable = "word_suffixes" + // OwnerInverseTable is the table name for the User entity. + // It exists in this package in order to avoid circular dependency with the "user" package. + OwnerInverseTable = "users" + // OwnerColumn is the table column denoting the owner relation/edge. + OwnerColumn = "user_word_suffix" +) + +// Columns holds all SQL columns for wordsuffix fields. +var Columns = []string{ + FieldID, + FieldSuffix, + FieldExpired, + FieldGuildID, + FieldRule, +} + +// ForeignKeys holds the SQL foreign-keys that are owned by the "word_suffixes" +// table and are not defined as standalone fields in the schema. +var ForeignKeys = []string{ + "user_word_suffix", +} + +// ValidColumn reports if the column name is valid (part of the table columns). +func ValidColumn(column string) bool { + for i := range Columns { + if column == Columns[i] { + return true + } + } + for i := range ForeignKeys { + if column == ForeignKeys[i] { + return true + } + } + return false +} + +var ( + // SuffixValidator is a validator for the "suffix" field. It is called by the builders before save. + SuffixValidator func(string) error + // DefaultID holds the default value on creation for the "id" field. + DefaultID func() uuid.UUID +) + +// Rule defines the type for the "rule" enum field. +type Rule string + +// RuleWebhook is the default value of the Rule enum. +const DefaultRule = RuleWebhook + +// Rule values. +const ( + RuleWebhook Rule = "webhook" + RuleWarn Rule = "warn" + RuleDelete Rule = "delete" +) + +func (r Rule) String() string { + return string(r) +} + +// RuleValidator is a validator for the "rule" field enum values. It is called by the builders before save. +func RuleValidator(r Rule) error { + switch r { + case RuleWebhook, RuleWarn, RuleDelete: + return nil + default: + return fmt.Errorf("wordsuffix: invalid enum value for rule field: %q", r) + } +} + +// OrderOption defines the ordering options for the WordSuffix queries. +type OrderOption func(*sql.Selector) + +// ByID orders the results by the id field. +func ByID(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldID, opts...).ToFunc() +} + +// BySuffix orders the results by the suffix field. +func BySuffix(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldSuffix, opts...).ToFunc() +} + +// ByExpired orders the results by the expired field. +func ByExpired(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldExpired, opts...).ToFunc() +} + +// ByGuildID orders the results by the guild_id field. +func ByGuildID(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldGuildID, opts...).ToFunc() +} + +// ByRule orders the results by the rule field. +func ByRule(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldRule, opts...).ToFunc() +} + +// ByGuildField orders the results by guild field. +func ByGuildField(field string, opts ...sql.OrderTermOption) OrderOption { + return func(s *sql.Selector) { + sqlgraph.OrderByNeighborTerms(s, newGuildStep(), sql.OrderByField(field, opts...)) + } +} + +// ByOwnerField orders the results by owner field. +func ByOwnerField(field string, opts ...sql.OrderTermOption) OrderOption { + return func(s *sql.Selector) { + sqlgraph.OrderByNeighborTerms(s, newOwnerStep(), sql.OrderByField(field, opts...)) + } +} +func newGuildStep() *sqlgraph.Step { + return sqlgraph.NewStep( + sqlgraph.From(Table, FieldID), + sqlgraph.To(GuildInverseTable, FieldID), + sqlgraph.Edge(sqlgraph.M2O, false, GuildTable, GuildColumn), + ) +} +func newOwnerStep() *sqlgraph.Step { + return sqlgraph.NewStep( + sqlgraph.From(Table, FieldID), + sqlgraph.To(OwnerInverseTable, FieldID), + sqlgraph.Edge(sqlgraph.M2O, true, OwnerTable, OwnerColumn), + ) +} diff --git a/ent/wordsuffix_create.go b/ent/wordsuffix_create.go new file mode 100644 index 00000000..e3df5761 --- /dev/null +++ b/ent/wordsuffix_create.go @@ -0,0 +1,337 @@ +// Code generated by ent, DO NOT EDIT. + +package ent + +import ( + "context" + "errors" + "fmt" + "time" + + "entgo.io/ent/dialect/sql/sqlgraph" + "entgo.io/ent/schema/field" + snowflake "github.com/disgoorg/snowflake/v2" + "github.com/google/uuid" + "github.com/sabafly/gobot/ent/guild" + "github.com/sabafly/gobot/ent/user" + "github.com/sabafly/gobot/ent/wordsuffix" +) + +// WordSuffixCreate is the builder for creating a WordSuffix entity. +type WordSuffixCreate struct { + config + mutation *WordSuffixMutation + hooks []Hook +} + +// SetSuffix sets the "suffix" field. +func (wsc *WordSuffixCreate) SetSuffix(s string) *WordSuffixCreate { + wsc.mutation.SetSuffix(s) + return wsc +} + +// SetExpired sets the "expired" field. +func (wsc *WordSuffixCreate) SetExpired(t time.Time) *WordSuffixCreate { + wsc.mutation.SetExpired(t) + return wsc +} + +// SetNillableExpired sets the "expired" field if the given value is not nil. +func (wsc *WordSuffixCreate) SetNillableExpired(t *time.Time) *WordSuffixCreate { + if t != nil { + wsc.SetExpired(*t) + } + return wsc +} + +// SetGuildID sets the "guild_id" field. +func (wsc *WordSuffixCreate) SetGuildID(s snowflake.ID) *WordSuffixCreate { + wsc.mutation.SetGuildID(s) + return wsc +} + +// SetNillableGuildID sets the "guild_id" field if the given value is not nil. +func (wsc *WordSuffixCreate) SetNillableGuildID(s *snowflake.ID) *WordSuffixCreate { + if s != nil { + wsc.SetGuildID(*s) + } + return wsc +} + +// SetRule sets the "rule" field. +func (wsc *WordSuffixCreate) SetRule(w wordsuffix.Rule) *WordSuffixCreate { + wsc.mutation.SetRule(w) + return wsc +} + +// SetNillableRule sets the "rule" field if the given value is not nil. +func (wsc *WordSuffixCreate) SetNillableRule(w *wordsuffix.Rule) *WordSuffixCreate { + if w != nil { + wsc.SetRule(*w) + } + return wsc +} + +// SetID sets the "id" field. +func (wsc *WordSuffixCreate) SetID(u uuid.UUID) *WordSuffixCreate { + wsc.mutation.SetID(u) + return wsc +} + +// SetNillableID sets the "id" field if the given value is not nil. +func (wsc *WordSuffixCreate) SetNillableID(u *uuid.UUID) *WordSuffixCreate { + if u != nil { + wsc.SetID(*u) + } + return wsc +} + +// SetGuild sets the "guild" edge to the Guild entity. +func (wsc *WordSuffixCreate) SetGuild(g *Guild) *WordSuffixCreate { + return wsc.SetGuildID(g.ID) +} + +// SetOwnerID sets the "owner" edge to the User entity by ID. +func (wsc *WordSuffixCreate) SetOwnerID(id snowflake.ID) *WordSuffixCreate { + wsc.mutation.SetOwnerID(id) + return wsc +} + +// SetOwner sets the "owner" edge to the User entity. +func (wsc *WordSuffixCreate) SetOwner(u *User) *WordSuffixCreate { + return wsc.SetOwnerID(u.ID) +} + +// Mutation returns the WordSuffixMutation object of the builder. +func (wsc *WordSuffixCreate) Mutation() *WordSuffixMutation { + return wsc.mutation +} + +// Save creates the WordSuffix in the database. +func (wsc *WordSuffixCreate) Save(ctx context.Context) (*WordSuffix, error) { + wsc.defaults() + return withHooks(ctx, wsc.sqlSave, wsc.mutation, wsc.hooks) +} + +// SaveX calls Save and panics if Save returns an error. +func (wsc *WordSuffixCreate) SaveX(ctx context.Context) *WordSuffix { + v, err := wsc.Save(ctx) + if err != nil { + panic(err) + } + return v +} + +// Exec executes the query. +func (wsc *WordSuffixCreate) Exec(ctx context.Context) error { + _, err := wsc.Save(ctx) + return err +} + +// ExecX is like Exec, but panics if an error occurs. +func (wsc *WordSuffixCreate) ExecX(ctx context.Context) { + if err := wsc.Exec(ctx); err != nil { + panic(err) + } +} + +// defaults sets the default values of the builder before save. +func (wsc *WordSuffixCreate) defaults() { + if _, ok := wsc.mutation.Rule(); !ok { + v := wordsuffix.DefaultRule + wsc.mutation.SetRule(v) + } + if _, ok := wsc.mutation.ID(); !ok { + v := wordsuffix.DefaultID() + wsc.mutation.SetID(v) + } +} + +// check runs all checks and user-defined validators on the builder. +func (wsc *WordSuffixCreate) check() error { + if _, ok := wsc.mutation.Suffix(); !ok { + return &ValidationError{Name: "suffix", err: errors.New(`ent: missing required field "WordSuffix.suffix"`)} + } + if v, ok := wsc.mutation.Suffix(); ok { + if err := wordsuffix.SuffixValidator(v); err != nil { + return &ValidationError{Name: "suffix", err: fmt.Errorf(`ent: validator failed for field "WordSuffix.suffix": %w`, err)} + } + } + if _, ok := wsc.mutation.Rule(); !ok { + return &ValidationError{Name: "rule", err: errors.New(`ent: missing required field "WordSuffix.rule"`)} + } + if v, ok := wsc.mutation.Rule(); ok { + if err := wordsuffix.RuleValidator(v); err != nil { + return &ValidationError{Name: "rule", err: fmt.Errorf(`ent: validator failed for field "WordSuffix.rule": %w`, err)} + } + } + if _, ok := wsc.mutation.OwnerID(); !ok { + return &ValidationError{Name: "owner", err: errors.New(`ent: missing required edge "WordSuffix.owner"`)} + } + return nil +} + +func (wsc *WordSuffixCreate) sqlSave(ctx context.Context) (*WordSuffix, error) { + if err := wsc.check(); err != nil { + return nil, err + } + _node, _spec := wsc.createSpec() + if err := sqlgraph.CreateNode(ctx, wsc.driver, _spec); err != nil { + if sqlgraph.IsConstraintError(err) { + err = &ConstraintError{msg: err.Error(), wrap: err} + } + return nil, err + } + if _spec.ID.Value != nil { + if id, ok := _spec.ID.Value.(*uuid.UUID); ok { + _node.ID = *id + } else if err := _node.ID.Scan(_spec.ID.Value); err != nil { + return nil, err + } + } + wsc.mutation.id = &_node.ID + wsc.mutation.done = true + return _node, nil +} + +func (wsc *WordSuffixCreate) createSpec() (*WordSuffix, *sqlgraph.CreateSpec) { + var ( + _node = &WordSuffix{config: wsc.config} + _spec = sqlgraph.NewCreateSpec(wordsuffix.Table, sqlgraph.NewFieldSpec(wordsuffix.FieldID, field.TypeUUID)) + ) + if id, ok := wsc.mutation.ID(); ok { + _node.ID = id + _spec.ID.Value = &id + } + if value, ok := wsc.mutation.Suffix(); ok { + _spec.SetField(wordsuffix.FieldSuffix, field.TypeString, value) + _node.Suffix = value + } + if value, ok := wsc.mutation.Expired(); ok { + _spec.SetField(wordsuffix.FieldExpired, field.TypeTime, value) + _node.Expired = &value + } + if value, ok := wsc.mutation.Rule(); ok { + _spec.SetField(wordsuffix.FieldRule, field.TypeEnum, value) + _node.Rule = value + } + if nodes := wsc.mutation.GuildIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.M2O, + Inverse: false, + Table: wordsuffix.GuildTable, + Columns: []string{wordsuffix.GuildColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(guild.FieldID, field.TypeUint64), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _node.GuildID = &nodes[0] + _spec.Edges = append(_spec.Edges, edge) + } + if nodes := wsc.mutation.OwnerIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.M2O, + Inverse: true, + Table: wordsuffix.OwnerTable, + Columns: []string{wordsuffix.OwnerColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(user.FieldID, field.TypeUint64), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _node.user_word_suffix = &nodes[0] + _spec.Edges = append(_spec.Edges, edge) + } + return _node, _spec +} + +// WordSuffixCreateBulk is the builder for creating many WordSuffix entities in bulk. +type WordSuffixCreateBulk struct { + config + err error + builders []*WordSuffixCreate +} + +// Save creates the WordSuffix entities in the database. +func (wscb *WordSuffixCreateBulk) Save(ctx context.Context) ([]*WordSuffix, error) { + if wscb.err != nil { + return nil, wscb.err + } + specs := make([]*sqlgraph.CreateSpec, len(wscb.builders)) + nodes := make([]*WordSuffix, len(wscb.builders)) + mutators := make([]Mutator, len(wscb.builders)) + for i := range wscb.builders { + func(i int, root context.Context) { + builder := wscb.builders[i] + builder.defaults() + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*WordSuffixMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + if err := builder.check(); err != nil { + return nil, err + } + builder.mutation = mutation + var err error + nodes[i], specs[i] = builder.createSpec() + if i < len(mutators)-1 { + _, err = mutators[i+1].Mutate(root, wscb.builders[i+1].mutation) + } else { + spec := &sqlgraph.BatchCreateSpec{Nodes: specs} + // Invoke the actual operation on the latest mutation in the chain. + if err = sqlgraph.BatchCreate(ctx, wscb.driver, spec); err != nil { + if sqlgraph.IsConstraintError(err) { + err = &ConstraintError{msg: err.Error(), wrap: err} + } + } + } + if err != nil { + return nil, err + } + mutation.id = &nodes[i].ID + mutation.done = true + return nodes[i], nil + }) + for i := len(builder.hooks) - 1; i >= 0; i-- { + mut = builder.hooks[i](mut) + } + mutators[i] = mut + }(i, ctx) + } + if len(mutators) > 0 { + if _, err := mutators[0].Mutate(ctx, wscb.builders[0].mutation); err != nil { + return nil, err + } + } + return nodes, nil +} + +// SaveX is like Save, but panics if an error occurs. +func (wscb *WordSuffixCreateBulk) SaveX(ctx context.Context) []*WordSuffix { + v, err := wscb.Save(ctx) + if err != nil { + panic(err) + } + return v +} + +// Exec executes the query. +func (wscb *WordSuffixCreateBulk) Exec(ctx context.Context) error { + _, err := wscb.Save(ctx) + return err +} + +// ExecX is like Exec, but panics if an error occurs. +func (wscb *WordSuffixCreateBulk) ExecX(ctx context.Context) { + if err := wscb.Exec(ctx); err != nil { + panic(err) + } +} diff --git a/ent/wordsuffix_delete.go b/ent/wordsuffix_delete.go new file mode 100644 index 00000000..99a292dd --- /dev/null +++ b/ent/wordsuffix_delete.go @@ -0,0 +1,88 @@ +// Code generated by ent, DO NOT EDIT. + +package ent + +import ( + "context" + + "entgo.io/ent/dialect/sql" + "entgo.io/ent/dialect/sql/sqlgraph" + "entgo.io/ent/schema/field" + "github.com/sabafly/gobot/ent/predicate" + "github.com/sabafly/gobot/ent/wordsuffix" +) + +// WordSuffixDelete is the builder for deleting a WordSuffix entity. +type WordSuffixDelete struct { + config + hooks []Hook + mutation *WordSuffixMutation +} + +// Where appends a list predicates to the WordSuffixDelete builder. +func (wsd *WordSuffixDelete) Where(ps ...predicate.WordSuffix) *WordSuffixDelete { + wsd.mutation.Where(ps...) + return wsd +} + +// Exec executes the deletion query and returns how many vertices were deleted. +func (wsd *WordSuffixDelete) Exec(ctx context.Context) (int, error) { + return withHooks(ctx, wsd.sqlExec, wsd.mutation, wsd.hooks) +} + +// ExecX is like Exec, but panics if an error occurs. +func (wsd *WordSuffixDelete) ExecX(ctx context.Context) int { + n, err := wsd.Exec(ctx) + if err != nil { + panic(err) + } + return n +} + +func (wsd *WordSuffixDelete) sqlExec(ctx context.Context) (int, error) { + _spec := sqlgraph.NewDeleteSpec(wordsuffix.Table, sqlgraph.NewFieldSpec(wordsuffix.FieldID, field.TypeUUID)) + if ps := wsd.mutation.predicates; len(ps) > 0 { + _spec.Predicate = func(selector *sql.Selector) { + for i := range ps { + ps[i](selector) + } + } + } + affected, err := sqlgraph.DeleteNodes(ctx, wsd.driver, _spec) + if err != nil && sqlgraph.IsConstraintError(err) { + err = &ConstraintError{msg: err.Error(), wrap: err} + } + wsd.mutation.done = true + return affected, err +} + +// WordSuffixDeleteOne is the builder for deleting a single WordSuffix entity. +type WordSuffixDeleteOne struct { + wsd *WordSuffixDelete +} + +// Where appends a list predicates to the WordSuffixDelete builder. +func (wsdo *WordSuffixDeleteOne) Where(ps ...predicate.WordSuffix) *WordSuffixDeleteOne { + wsdo.wsd.mutation.Where(ps...) + return wsdo +} + +// Exec executes the deletion query. +func (wsdo *WordSuffixDeleteOne) Exec(ctx context.Context) error { + n, err := wsdo.wsd.Exec(ctx) + switch { + case err != nil: + return err + case n == 0: + return &NotFoundError{wordsuffix.Label} + default: + return nil + } +} + +// ExecX is like Exec, but panics if an error occurs. +func (wsdo *WordSuffixDeleteOne) ExecX(ctx context.Context) { + if err := wsdo.Exec(ctx); err != nil { + panic(err) + } +} diff --git a/ent/wordsuffix_query.go b/ent/wordsuffix_query.go new file mode 100644 index 00000000..1fdeeee2 --- /dev/null +++ b/ent/wordsuffix_query.go @@ -0,0 +1,693 @@ +// Code generated by ent, DO NOT EDIT. + +package ent + +import ( + "context" + "fmt" + "math" + + "entgo.io/ent/dialect/sql" + "entgo.io/ent/dialect/sql/sqlgraph" + "entgo.io/ent/schema/field" + snowflake "github.com/disgoorg/snowflake/v2" + "github.com/google/uuid" + "github.com/sabafly/gobot/ent/guild" + "github.com/sabafly/gobot/ent/predicate" + "github.com/sabafly/gobot/ent/user" + "github.com/sabafly/gobot/ent/wordsuffix" +) + +// WordSuffixQuery is the builder for querying WordSuffix entities. +type WordSuffixQuery struct { + config + ctx *QueryContext + order []wordsuffix.OrderOption + inters []Interceptor + predicates []predicate.WordSuffix + withGuild *GuildQuery + withOwner *UserQuery + withFKs bool + // intermediate query (i.e. traversal path). + sql *sql.Selector + path func(context.Context) (*sql.Selector, error) +} + +// Where adds a new predicate for the WordSuffixQuery builder. +func (wsq *WordSuffixQuery) Where(ps ...predicate.WordSuffix) *WordSuffixQuery { + wsq.predicates = append(wsq.predicates, ps...) + return wsq +} + +// Limit the number of records to be returned by this query. +func (wsq *WordSuffixQuery) Limit(limit int) *WordSuffixQuery { + wsq.ctx.Limit = &limit + return wsq +} + +// Offset to start from. +func (wsq *WordSuffixQuery) Offset(offset int) *WordSuffixQuery { + wsq.ctx.Offset = &offset + return wsq +} + +// Unique configures the query builder to filter duplicate records on query. +// By default, unique is set to true, and can be disabled using this method. +func (wsq *WordSuffixQuery) Unique(unique bool) *WordSuffixQuery { + wsq.ctx.Unique = &unique + return wsq +} + +// Order specifies how the records should be ordered. +func (wsq *WordSuffixQuery) Order(o ...wordsuffix.OrderOption) *WordSuffixQuery { + wsq.order = append(wsq.order, o...) + return wsq +} + +// QueryGuild chains the current query on the "guild" edge. +func (wsq *WordSuffixQuery) QueryGuild() *GuildQuery { + query := (&GuildClient{config: wsq.config}).Query() + query.path = func(ctx context.Context) (fromU *sql.Selector, err error) { + if err := wsq.prepareQuery(ctx); err != nil { + return nil, err + } + selector := wsq.sqlQuery(ctx) + if err := selector.Err(); err != nil { + return nil, err + } + step := sqlgraph.NewStep( + sqlgraph.From(wordsuffix.Table, wordsuffix.FieldID, selector), + sqlgraph.To(guild.Table, guild.FieldID), + sqlgraph.Edge(sqlgraph.M2O, false, wordsuffix.GuildTable, wordsuffix.GuildColumn), + ) + fromU = sqlgraph.SetNeighbors(wsq.driver.Dialect(), step) + return fromU, nil + } + return query +} + +// QueryOwner chains the current query on the "owner" edge. +func (wsq *WordSuffixQuery) QueryOwner() *UserQuery { + query := (&UserClient{config: wsq.config}).Query() + query.path = func(ctx context.Context) (fromU *sql.Selector, err error) { + if err := wsq.prepareQuery(ctx); err != nil { + return nil, err + } + selector := wsq.sqlQuery(ctx) + if err := selector.Err(); err != nil { + return nil, err + } + step := sqlgraph.NewStep( + sqlgraph.From(wordsuffix.Table, wordsuffix.FieldID, selector), + sqlgraph.To(user.Table, user.FieldID), + sqlgraph.Edge(sqlgraph.M2O, true, wordsuffix.OwnerTable, wordsuffix.OwnerColumn), + ) + fromU = sqlgraph.SetNeighbors(wsq.driver.Dialect(), step) + return fromU, nil + } + return query +} + +// First returns the first WordSuffix entity from the query. +// Returns a *NotFoundError when no WordSuffix was found. +func (wsq *WordSuffixQuery) First(ctx context.Context) (*WordSuffix, error) { + nodes, err := wsq.Limit(1).All(setContextOp(ctx, wsq.ctx, "First")) + if err != nil { + return nil, err + } + if len(nodes) == 0 { + return nil, &NotFoundError{wordsuffix.Label} + } + return nodes[0], nil +} + +// FirstX is like First, but panics if an error occurs. +func (wsq *WordSuffixQuery) FirstX(ctx context.Context) *WordSuffix { + node, err := wsq.First(ctx) + if err != nil && !IsNotFound(err) { + panic(err) + } + return node +} + +// FirstID returns the first WordSuffix ID from the query. +// Returns a *NotFoundError when no WordSuffix ID was found. +func (wsq *WordSuffixQuery) FirstID(ctx context.Context) (id uuid.UUID, err error) { + var ids []uuid.UUID + if ids, err = wsq.Limit(1).IDs(setContextOp(ctx, wsq.ctx, "FirstID")); err != nil { + return + } + if len(ids) == 0 { + err = &NotFoundError{wordsuffix.Label} + return + } + return ids[0], nil +} + +// FirstIDX is like FirstID, but panics if an error occurs. +func (wsq *WordSuffixQuery) FirstIDX(ctx context.Context) uuid.UUID { + id, err := wsq.FirstID(ctx) + if err != nil && !IsNotFound(err) { + panic(err) + } + return id +} + +// Only returns a single WordSuffix entity found by the query, ensuring it only returns one. +// Returns a *NotSingularError when more than one WordSuffix entity is found. +// Returns a *NotFoundError when no WordSuffix entities are found. +func (wsq *WordSuffixQuery) Only(ctx context.Context) (*WordSuffix, error) { + nodes, err := wsq.Limit(2).All(setContextOp(ctx, wsq.ctx, "Only")) + if err != nil { + return nil, err + } + switch len(nodes) { + case 1: + return nodes[0], nil + case 0: + return nil, &NotFoundError{wordsuffix.Label} + default: + return nil, &NotSingularError{wordsuffix.Label} + } +} + +// OnlyX is like Only, but panics if an error occurs. +func (wsq *WordSuffixQuery) OnlyX(ctx context.Context) *WordSuffix { + node, err := wsq.Only(ctx) + if err != nil { + panic(err) + } + return node +} + +// OnlyID is like Only, but returns the only WordSuffix ID in the query. +// Returns a *NotSingularError when more than one WordSuffix ID is found. +// Returns a *NotFoundError when no entities are found. +func (wsq *WordSuffixQuery) OnlyID(ctx context.Context) (id uuid.UUID, err error) { + var ids []uuid.UUID + if ids, err = wsq.Limit(2).IDs(setContextOp(ctx, wsq.ctx, "OnlyID")); err != nil { + return + } + switch len(ids) { + case 1: + id = ids[0] + case 0: + err = &NotFoundError{wordsuffix.Label} + default: + err = &NotSingularError{wordsuffix.Label} + } + return +} + +// OnlyIDX is like OnlyID, but panics if an error occurs. +func (wsq *WordSuffixQuery) OnlyIDX(ctx context.Context) uuid.UUID { + id, err := wsq.OnlyID(ctx) + if err != nil { + panic(err) + } + return id +} + +// All executes the query and returns a list of WordSuffixes. +func (wsq *WordSuffixQuery) All(ctx context.Context) ([]*WordSuffix, error) { + ctx = setContextOp(ctx, wsq.ctx, "All") + if err := wsq.prepareQuery(ctx); err != nil { + return nil, err + } + qr := querierAll[[]*WordSuffix, *WordSuffixQuery]() + return withInterceptors[[]*WordSuffix](ctx, wsq, qr, wsq.inters) +} + +// AllX is like All, but panics if an error occurs. +func (wsq *WordSuffixQuery) AllX(ctx context.Context) []*WordSuffix { + nodes, err := wsq.All(ctx) + if err != nil { + panic(err) + } + return nodes +} + +// IDs executes the query and returns a list of WordSuffix IDs. +func (wsq *WordSuffixQuery) IDs(ctx context.Context) (ids []uuid.UUID, err error) { + if wsq.ctx.Unique == nil && wsq.path != nil { + wsq.Unique(true) + } + ctx = setContextOp(ctx, wsq.ctx, "IDs") + if err = wsq.Select(wordsuffix.FieldID).Scan(ctx, &ids); err != nil { + return nil, err + } + return ids, nil +} + +// IDsX is like IDs, but panics if an error occurs. +func (wsq *WordSuffixQuery) IDsX(ctx context.Context) []uuid.UUID { + ids, err := wsq.IDs(ctx) + if err != nil { + panic(err) + } + return ids +} + +// Count returns the count of the given query. +func (wsq *WordSuffixQuery) Count(ctx context.Context) (int, error) { + ctx = setContextOp(ctx, wsq.ctx, "Count") + if err := wsq.prepareQuery(ctx); err != nil { + return 0, err + } + return withInterceptors[int](ctx, wsq, querierCount[*WordSuffixQuery](), wsq.inters) +} + +// CountX is like Count, but panics if an error occurs. +func (wsq *WordSuffixQuery) CountX(ctx context.Context) int { + count, err := wsq.Count(ctx) + if err != nil { + panic(err) + } + return count +} + +// Exist returns true if the query has elements in the graph. +func (wsq *WordSuffixQuery) Exist(ctx context.Context) (bool, error) { + ctx = setContextOp(ctx, wsq.ctx, "Exist") + switch _, err := wsq.FirstID(ctx); { + case IsNotFound(err): + return false, nil + case err != nil: + return false, fmt.Errorf("ent: check existence: %w", err) + default: + return true, nil + } +} + +// ExistX is like Exist, but panics if an error occurs. +func (wsq *WordSuffixQuery) ExistX(ctx context.Context) bool { + exist, err := wsq.Exist(ctx) + if err != nil { + panic(err) + } + return exist +} + +// Clone returns a duplicate of the WordSuffixQuery builder, including all associated steps. It can be +// used to prepare common query builders and use them differently after the clone is made. +func (wsq *WordSuffixQuery) Clone() *WordSuffixQuery { + if wsq == nil { + return nil + } + return &WordSuffixQuery{ + config: wsq.config, + ctx: wsq.ctx.Clone(), + order: append([]wordsuffix.OrderOption{}, wsq.order...), + inters: append([]Interceptor{}, wsq.inters...), + predicates: append([]predicate.WordSuffix{}, wsq.predicates...), + withGuild: wsq.withGuild.Clone(), + withOwner: wsq.withOwner.Clone(), + // clone intermediate query. + sql: wsq.sql.Clone(), + path: wsq.path, + } +} + +// WithGuild tells the query-builder to eager-load the nodes that are connected to +// the "guild" edge. The optional arguments are used to configure the query builder of the edge. +func (wsq *WordSuffixQuery) WithGuild(opts ...func(*GuildQuery)) *WordSuffixQuery { + query := (&GuildClient{config: wsq.config}).Query() + for _, opt := range opts { + opt(query) + } + wsq.withGuild = query + return wsq +} + +// WithOwner tells the query-builder to eager-load the nodes that are connected to +// the "owner" edge. The optional arguments are used to configure the query builder of the edge. +func (wsq *WordSuffixQuery) WithOwner(opts ...func(*UserQuery)) *WordSuffixQuery { + query := (&UserClient{config: wsq.config}).Query() + for _, opt := range opts { + opt(query) + } + wsq.withOwner = query + return wsq +} + +// GroupBy is used to group vertices by one or more fields/columns. +// It is often used with aggregate functions, like: count, max, mean, min, sum. +// +// Example: +// +// var v []struct { +// Suffix string `json:"suffix,omitempty"` +// Count int `json:"count,omitempty"` +// } +// +// client.WordSuffix.Query(). +// GroupBy(wordsuffix.FieldSuffix). +// Aggregate(ent.Count()). +// Scan(ctx, &v) +func (wsq *WordSuffixQuery) GroupBy(field string, fields ...string) *WordSuffixGroupBy { + wsq.ctx.Fields = append([]string{field}, fields...) + grbuild := &WordSuffixGroupBy{build: wsq} + grbuild.flds = &wsq.ctx.Fields + grbuild.label = wordsuffix.Label + grbuild.scan = grbuild.Scan + return grbuild +} + +// Select allows the selection one or more fields/columns for the given query, +// instead of selecting all fields in the entity. +// +// Example: +// +// var v []struct { +// Suffix string `json:"suffix,omitempty"` +// } +// +// client.WordSuffix.Query(). +// Select(wordsuffix.FieldSuffix). +// Scan(ctx, &v) +func (wsq *WordSuffixQuery) Select(fields ...string) *WordSuffixSelect { + wsq.ctx.Fields = append(wsq.ctx.Fields, fields...) + sbuild := &WordSuffixSelect{WordSuffixQuery: wsq} + sbuild.label = wordsuffix.Label + sbuild.flds, sbuild.scan = &wsq.ctx.Fields, sbuild.Scan + return sbuild +} + +// Aggregate returns a WordSuffixSelect configured with the given aggregations. +func (wsq *WordSuffixQuery) Aggregate(fns ...AggregateFunc) *WordSuffixSelect { + return wsq.Select().Aggregate(fns...) +} + +func (wsq *WordSuffixQuery) prepareQuery(ctx context.Context) error { + for _, inter := range wsq.inters { + if inter == nil { + return fmt.Errorf("ent: uninitialized interceptor (forgotten import ent/runtime?)") + } + if trv, ok := inter.(Traverser); ok { + if err := trv.Traverse(ctx, wsq); err != nil { + return err + } + } + } + for _, f := range wsq.ctx.Fields { + if !wordsuffix.ValidColumn(f) { + return &ValidationError{Name: f, err: fmt.Errorf("ent: invalid field %q for query", f)} + } + } + if wsq.path != nil { + prev, err := wsq.path(ctx) + if err != nil { + return err + } + wsq.sql = prev + } + return nil +} + +func (wsq *WordSuffixQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*WordSuffix, error) { + var ( + nodes = []*WordSuffix{} + withFKs = wsq.withFKs + _spec = wsq.querySpec() + loadedTypes = [2]bool{ + wsq.withGuild != nil, + wsq.withOwner != nil, + } + ) + if wsq.withOwner != nil { + withFKs = true + } + if withFKs { + _spec.Node.Columns = append(_spec.Node.Columns, wordsuffix.ForeignKeys...) + } + _spec.ScanValues = func(columns []string) ([]any, error) { + return (*WordSuffix).scanValues(nil, columns) + } + _spec.Assign = func(columns []string, values []any) error { + node := &WordSuffix{config: wsq.config} + nodes = append(nodes, node) + node.Edges.loadedTypes = loadedTypes + return node.assignValues(columns, values) + } + for i := range hooks { + hooks[i](ctx, _spec) + } + if err := sqlgraph.QueryNodes(ctx, wsq.driver, _spec); err != nil { + return nil, err + } + if len(nodes) == 0 { + return nodes, nil + } + if query := wsq.withGuild; query != nil { + if err := wsq.loadGuild(ctx, query, nodes, nil, + func(n *WordSuffix, e *Guild) { n.Edges.Guild = e }); err != nil { + return nil, err + } + } + if query := wsq.withOwner; query != nil { + if err := wsq.loadOwner(ctx, query, nodes, nil, + func(n *WordSuffix, e *User) { n.Edges.Owner = e }); err != nil { + return nil, err + } + } + return nodes, nil +} + +func (wsq *WordSuffixQuery) loadGuild(ctx context.Context, query *GuildQuery, nodes []*WordSuffix, init func(*WordSuffix), assign func(*WordSuffix, *Guild)) error { + ids := make([]snowflake.ID, 0, len(nodes)) + nodeids := make(map[snowflake.ID][]*WordSuffix) + for i := range nodes { + if nodes[i].GuildID == nil { + continue + } + fk := *nodes[i].GuildID + if _, ok := nodeids[fk]; !ok { + ids = append(ids, fk) + } + nodeids[fk] = append(nodeids[fk], nodes[i]) + } + if len(ids) == 0 { + return nil + } + query.Where(guild.IDIn(ids...)) + neighbors, err := query.All(ctx) + if err != nil { + return err + } + for _, n := range neighbors { + nodes, ok := nodeids[n.ID] + if !ok { + return fmt.Errorf(`unexpected foreign-key "guild_id" returned %v`, n.ID) + } + for i := range nodes { + assign(nodes[i], n) + } + } + return nil +} +func (wsq *WordSuffixQuery) loadOwner(ctx context.Context, query *UserQuery, nodes []*WordSuffix, init func(*WordSuffix), assign func(*WordSuffix, *User)) error { + ids := make([]snowflake.ID, 0, len(nodes)) + nodeids := make(map[snowflake.ID][]*WordSuffix) + for i := range nodes { + if nodes[i].user_word_suffix == nil { + continue + } + fk := *nodes[i].user_word_suffix + if _, ok := nodeids[fk]; !ok { + ids = append(ids, fk) + } + nodeids[fk] = append(nodeids[fk], nodes[i]) + } + if len(ids) == 0 { + return nil + } + query.Where(user.IDIn(ids...)) + neighbors, err := query.All(ctx) + if err != nil { + return err + } + for _, n := range neighbors { + nodes, ok := nodeids[n.ID] + if !ok { + return fmt.Errorf(`unexpected foreign-key "user_word_suffix" returned %v`, n.ID) + } + for i := range nodes { + assign(nodes[i], n) + } + } + return nil +} + +func (wsq *WordSuffixQuery) sqlCount(ctx context.Context) (int, error) { + _spec := wsq.querySpec() + _spec.Node.Columns = wsq.ctx.Fields + if len(wsq.ctx.Fields) > 0 { + _spec.Unique = wsq.ctx.Unique != nil && *wsq.ctx.Unique + } + return sqlgraph.CountNodes(ctx, wsq.driver, _spec) +} + +func (wsq *WordSuffixQuery) querySpec() *sqlgraph.QuerySpec { + _spec := sqlgraph.NewQuerySpec(wordsuffix.Table, wordsuffix.Columns, sqlgraph.NewFieldSpec(wordsuffix.FieldID, field.TypeUUID)) + _spec.From = wsq.sql + if unique := wsq.ctx.Unique; unique != nil { + _spec.Unique = *unique + } else if wsq.path != nil { + _spec.Unique = true + } + if fields := wsq.ctx.Fields; len(fields) > 0 { + _spec.Node.Columns = make([]string, 0, len(fields)) + _spec.Node.Columns = append(_spec.Node.Columns, wordsuffix.FieldID) + for i := range fields { + if fields[i] != wordsuffix.FieldID { + _spec.Node.Columns = append(_spec.Node.Columns, fields[i]) + } + } + if wsq.withGuild != nil { + _spec.Node.AddColumnOnce(wordsuffix.FieldGuildID) + } + } + if ps := wsq.predicates; len(ps) > 0 { + _spec.Predicate = func(selector *sql.Selector) { + for i := range ps { + ps[i](selector) + } + } + } + if limit := wsq.ctx.Limit; limit != nil { + _spec.Limit = *limit + } + if offset := wsq.ctx.Offset; offset != nil { + _spec.Offset = *offset + } + if ps := wsq.order; len(ps) > 0 { + _spec.Order = func(selector *sql.Selector) { + for i := range ps { + ps[i](selector) + } + } + } + return _spec +} + +func (wsq *WordSuffixQuery) sqlQuery(ctx context.Context) *sql.Selector { + builder := sql.Dialect(wsq.driver.Dialect()) + t1 := builder.Table(wordsuffix.Table) + columns := wsq.ctx.Fields + if len(columns) == 0 { + columns = wordsuffix.Columns + } + selector := builder.Select(t1.Columns(columns...)...).From(t1) + if wsq.sql != nil { + selector = wsq.sql + selector.Select(selector.Columns(columns...)...) + } + if wsq.ctx.Unique != nil && *wsq.ctx.Unique { + selector.Distinct() + } + for _, p := range wsq.predicates { + p(selector) + } + for _, p := range wsq.order { + p(selector) + } + if offset := wsq.ctx.Offset; offset != nil { + // limit is mandatory for offset clause. We start + // with default value, and override it below if needed. + selector.Offset(*offset).Limit(math.MaxInt32) + } + if limit := wsq.ctx.Limit; limit != nil { + selector.Limit(*limit) + } + return selector +} + +// WordSuffixGroupBy is the group-by builder for WordSuffix entities. +type WordSuffixGroupBy struct { + selector + build *WordSuffixQuery +} + +// Aggregate adds the given aggregation functions to the group-by query. +func (wsgb *WordSuffixGroupBy) Aggregate(fns ...AggregateFunc) *WordSuffixGroupBy { + wsgb.fns = append(wsgb.fns, fns...) + return wsgb +} + +// Scan applies the selector query and scans the result into the given value. +func (wsgb *WordSuffixGroupBy) Scan(ctx context.Context, v any) error { + ctx = setContextOp(ctx, wsgb.build.ctx, "GroupBy") + if err := wsgb.build.prepareQuery(ctx); err != nil { + return err + } + return scanWithInterceptors[*WordSuffixQuery, *WordSuffixGroupBy](ctx, wsgb.build, wsgb, wsgb.build.inters, v) +} + +func (wsgb *WordSuffixGroupBy) sqlScan(ctx context.Context, root *WordSuffixQuery, v any) error { + selector := root.sqlQuery(ctx).Select() + aggregation := make([]string, 0, len(wsgb.fns)) + for _, fn := range wsgb.fns { + aggregation = append(aggregation, fn(selector)) + } + if len(selector.SelectedColumns()) == 0 { + columns := make([]string, 0, len(*wsgb.flds)+len(wsgb.fns)) + for _, f := range *wsgb.flds { + columns = append(columns, selector.C(f)) + } + columns = append(columns, aggregation...) + selector.Select(columns...) + } + selector.GroupBy(selector.Columns(*wsgb.flds...)...) + if err := selector.Err(); err != nil { + return err + } + rows := &sql.Rows{} + query, args := selector.Query() + if err := wsgb.build.driver.Query(ctx, query, args, rows); err != nil { + return err + } + defer rows.Close() + return sql.ScanSlice(rows, v) +} + +// WordSuffixSelect is the builder for selecting fields of WordSuffix entities. +type WordSuffixSelect struct { + *WordSuffixQuery + selector +} + +// Aggregate adds the given aggregation functions to the selector query. +func (wss *WordSuffixSelect) Aggregate(fns ...AggregateFunc) *WordSuffixSelect { + wss.fns = append(wss.fns, fns...) + return wss +} + +// Scan applies the selector query and scans the result into the given value. +func (wss *WordSuffixSelect) Scan(ctx context.Context, v any) error { + ctx = setContextOp(ctx, wss.ctx, "Select") + if err := wss.prepareQuery(ctx); err != nil { + return err + } + return scanWithInterceptors[*WordSuffixQuery, *WordSuffixSelect](ctx, wss.WordSuffixQuery, wss, wss.inters, v) +} + +func (wss *WordSuffixSelect) sqlScan(ctx context.Context, root *WordSuffixQuery, v any) error { + selector := root.sqlQuery(ctx) + aggregation := make([]string, 0, len(wss.fns)) + for _, fn := range wss.fns { + aggregation = append(aggregation, fn(selector)) + } + switch n := len(*wss.selector.flds); { + case n == 0 && len(aggregation) > 0: + selector.Select(aggregation...) + case n != 0 && len(aggregation) > 0: + selector.AppendSelect(aggregation...) + } + rows := &sql.Rows{} + query, args := selector.Query() + if err := wss.driver.Query(ctx, query, args, rows); err != nil { + return err + } + defer rows.Close() + return sql.ScanSlice(rows, v) +} diff --git a/ent/wordsuffix_update.go b/ent/wordsuffix_update.go new file mode 100644 index 00000000..85eedca5 --- /dev/null +++ b/ent/wordsuffix_update.go @@ -0,0 +1,553 @@ +// Code generated by ent, DO NOT EDIT. + +package ent + +import ( + "context" + "errors" + "fmt" + "time" + + "entgo.io/ent/dialect/sql" + "entgo.io/ent/dialect/sql/sqlgraph" + "entgo.io/ent/schema/field" + snowflake "github.com/disgoorg/snowflake/v2" + "github.com/sabafly/gobot/ent/guild" + "github.com/sabafly/gobot/ent/predicate" + "github.com/sabafly/gobot/ent/user" + "github.com/sabafly/gobot/ent/wordsuffix" +) + +// WordSuffixUpdate is the builder for updating WordSuffix entities. +type WordSuffixUpdate struct { + config + hooks []Hook + mutation *WordSuffixMutation +} + +// Where appends a list predicates to the WordSuffixUpdate builder. +func (wsu *WordSuffixUpdate) Where(ps ...predicate.WordSuffix) *WordSuffixUpdate { + wsu.mutation.Where(ps...) + return wsu +} + +// SetSuffix sets the "suffix" field. +func (wsu *WordSuffixUpdate) SetSuffix(s string) *WordSuffixUpdate { + wsu.mutation.SetSuffix(s) + return wsu +} + +// SetNillableSuffix sets the "suffix" field if the given value is not nil. +func (wsu *WordSuffixUpdate) SetNillableSuffix(s *string) *WordSuffixUpdate { + if s != nil { + wsu.SetSuffix(*s) + } + return wsu +} + +// SetExpired sets the "expired" field. +func (wsu *WordSuffixUpdate) SetExpired(t time.Time) *WordSuffixUpdate { + wsu.mutation.SetExpired(t) + return wsu +} + +// SetNillableExpired sets the "expired" field if the given value is not nil. +func (wsu *WordSuffixUpdate) SetNillableExpired(t *time.Time) *WordSuffixUpdate { + if t != nil { + wsu.SetExpired(*t) + } + return wsu +} + +// ClearExpired clears the value of the "expired" field. +func (wsu *WordSuffixUpdate) ClearExpired() *WordSuffixUpdate { + wsu.mutation.ClearExpired() + return wsu +} + +// SetGuildID sets the "guild_id" field. +func (wsu *WordSuffixUpdate) SetGuildID(s snowflake.ID) *WordSuffixUpdate { + wsu.mutation.SetGuildID(s) + return wsu +} + +// SetNillableGuildID sets the "guild_id" field if the given value is not nil. +func (wsu *WordSuffixUpdate) SetNillableGuildID(s *snowflake.ID) *WordSuffixUpdate { + if s != nil { + wsu.SetGuildID(*s) + } + return wsu +} + +// ClearGuildID clears the value of the "guild_id" field. +func (wsu *WordSuffixUpdate) ClearGuildID() *WordSuffixUpdate { + wsu.mutation.ClearGuildID() + return wsu +} + +// SetRule sets the "rule" field. +func (wsu *WordSuffixUpdate) SetRule(w wordsuffix.Rule) *WordSuffixUpdate { + wsu.mutation.SetRule(w) + return wsu +} + +// SetNillableRule sets the "rule" field if the given value is not nil. +func (wsu *WordSuffixUpdate) SetNillableRule(w *wordsuffix.Rule) *WordSuffixUpdate { + if w != nil { + wsu.SetRule(*w) + } + return wsu +} + +// SetGuild sets the "guild" edge to the Guild entity. +func (wsu *WordSuffixUpdate) SetGuild(g *Guild) *WordSuffixUpdate { + return wsu.SetGuildID(g.ID) +} + +// SetOwnerID sets the "owner" edge to the User entity by ID. +func (wsu *WordSuffixUpdate) SetOwnerID(id snowflake.ID) *WordSuffixUpdate { + wsu.mutation.SetOwnerID(id) + return wsu +} + +// SetOwner sets the "owner" edge to the User entity. +func (wsu *WordSuffixUpdate) SetOwner(u *User) *WordSuffixUpdate { + return wsu.SetOwnerID(u.ID) +} + +// Mutation returns the WordSuffixMutation object of the builder. +func (wsu *WordSuffixUpdate) Mutation() *WordSuffixMutation { + return wsu.mutation +} + +// ClearGuild clears the "guild" edge to the Guild entity. +func (wsu *WordSuffixUpdate) ClearGuild() *WordSuffixUpdate { + wsu.mutation.ClearGuild() + return wsu +} + +// ClearOwner clears the "owner" edge to the User entity. +func (wsu *WordSuffixUpdate) ClearOwner() *WordSuffixUpdate { + wsu.mutation.ClearOwner() + return wsu +} + +// Save executes the query and returns the number of nodes affected by the update operation. +func (wsu *WordSuffixUpdate) Save(ctx context.Context) (int, error) { + return withHooks(ctx, wsu.sqlSave, wsu.mutation, wsu.hooks) +} + +// SaveX is like Save, but panics if an error occurs. +func (wsu *WordSuffixUpdate) SaveX(ctx context.Context) int { + affected, err := wsu.Save(ctx) + if err != nil { + panic(err) + } + return affected +} + +// Exec executes the query. +func (wsu *WordSuffixUpdate) Exec(ctx context.Context) error { + _, err := wsu.Save(ctx) + return err +} + +// ExecX is like Exec, but panics if an error occurs. +func (wsu *WordSuffixUpdate) ExecX(ctx context.Context) { + if err := wsu.Exec(ctx); err != nil { + panic(err) + } +} + +// check runs all checks and user-defined validators on the builder. +func (wsu *WordSuffixUpdate) check() error { + if v, ok := wsu.mutation.Suffix(); ok { + if err := wordsuffix.SuffixValidator(v); err != nil { + return &ValidationError{Name: "suffix", err: fmt.Errorf(`ent: validator failed for field "WordSuffix.suffix": %w`, err)} + } + } + if v, ok := wsu.mutation.Rule(); ok { + if err := wordsuffix.RuleValidator(v); err != nil { + return &ValidationError{Name: "rule", err: fmt.Errorf(`ent: validator failed for field "WordSuffix.rule": %w`, err)} + } + } + if _, ok := wsu.mutation.OwnerID(); wsu.mutation.OwnerCleared() && !ok { + return errors.New(`ent: clearing a required unique edge "WordSuffix.owner"`) + } + return nil +} + +func (wsu *WordSuffixUpdate) sqlSave(ctx context.Context) (n int, err error) { + if err := wsu.check(); err != nil { + return n, err + } + _spec := sqlgraph.NewUpdateSpec(wordsuffix.Table, wordsuffix.Columns, sqlgraph.NewFieldSpec(wordsuffix.FieldID, field.TypeUUID)) + if ps := wsu.mutation.predicates; len(ps) > 0 { + _spec.Predicate = func(selector *sql.Selector) { + for i := range ps { + ps[i](selector) + } + } + } + if value, ok := wsu.mutation.Suffix(); ok { + _spec.SetField(wordsuffix.FieldSuffix, field.TypeString, value) + } + if value, ok := wsu.mutation.Expired(); ok { + _spec.SetField(wordsuffix.FieldExpired, field.TypeTime, value) + } + if wsu.mutation.ExpiredCleared() { + _spec.ClearField(wordsuffix.FieldExpired, field.TypeTime) + } + if value, ok := wsu.mutation.Rule(); ok { + _spec.SetField(wordsuffix.FieldRule, field.TypeEnum, value) + } + if wsu.mutation.GuildCleared() { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.M2O, + Inverse: false, + Table: wordsuffix.GuildTable, + Columns: []string{wordsuffix.GuildColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(guild.FieldID, field.TypeUint64), + }, + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := wsu.mutation.GuildIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.M2O, + Inverse: false, + Table: wordsuffix.GuildTable, + Columns: []string{wordsuffix.GuildColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(guild.FieldID, field.TypeUint64), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Add = append(_spec.Edges.Add, edge) + } + if wsu.mutation.OwnerCleared() { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.M2O, + Inverse: true, + Table: wordsuffix.OwnerTable, + Columns: []string{wordsuffix.OwnerColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(user.FieldID, field.TypeUint64), + }, + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := wsu.mutation.OwnerIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.M2O, + Inverse: true, + Table: wordsuffix.OwnerTable, + Columns: []string{wordsuffix.OwnerColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(user.FieldID, field.TypeUint64), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Add = append(_spec.Edges.Add, edge) + } + if n, err = sqlgraph.UpdateNodes(ctx, wsu.driver, _spec); err != nil { + if _, ok := err.(*sqlgraph.NotFoundError); ok { + err = &NotFoundError{wordsuffix.Label} + } else if sqlgraph.IsConstraintError(err) { + err = &ConstraintError{msg: err.Error(), wrap: err} + } + return 0, err + } + wsu.mutation.done = true + return n, nil +} + +// WordSuffixUpdateOne is the builder for updating a single WordSuffix entity. +type WordSuffixUpdateOne struct { + config + fields []string + hooks []Hook + mutation *WordSuffixMutation +} + +// SetSuffix sets the "suffix" field. +func (wsuo *WordSuffixUpdateOne) SetSuffix(s string) *WordSuffixUpdateOne { + wsuo.mutation.SetSuffix(s) + return wsuo +} + +// SetNillableSuffix sets the "suffix" field if the given value is not nil. +func (wsuo *WordSuffixUpdateOne) SetNillableSuffix(s *string) *WordSuffixUpdateOne { + if s != nil { + wsuo.SetSuffix(*s) + } + return wsuo +} + +// SetExpired sets the "expired" field. +func (wsuo *WordSuffixUpdateOne) SetExpired(t time.Time) *WordSuffixUpdateOne { + wsuo.mutation.SetExpired(t) + return wsuo +} + +// SetNillableExpired sets the "expired" field if the given value is not nil. +func (wsuo *WordSuffixUpdateOne) SetNillableExpired(t *time.Time) *WordSuffixUpdateOne { + if t != nil { + wsuo.SetExpired(*t) + } + return wsuo +} + +// ClearExpired clears the value of the "expired" field. +func (wsuo *WordSuffixUpdateOne) ClearExpired() *WordSuffixUpdateOne { + wsuo.mutation.ClearExpired() + return wsuo +} + +// SetGuildID sets the "guild_id" field. +func (wsuo *WordSuffixUpdateOne) SetGuildID(s snowflake.ID) *WordSuffixUpdateOne { + wsuo.mutation.SetGuildID(s) + return wsuo +} + +// SetNillableGuildID sets the "guild_id" field if the given value is not nil. +func (wsuo *WordSuffixUpdateOne) SetNillableGuildID(s *snowflake.ID) *WordSuffixUpdateOne { + if s != nil { + wsuo.SetGuildID(*s) + } + return wsuo +} + +// ClearGuildID clears the value of the "guild_id" field. +func (wsuo *WordSuffixUpdateOne) ClearGuildID() *WordSuffixUpdateOne { + wsuo.mutation.ClearGuildID() + return wsuo +} + +// SetRule sets the "rule" field. +func (wsuo *WordSuffixUpdateOne) SetRule(w wordsuffix.Rule) *WordSuffixUpdateOne { + wsuo.mutation.SetRule(w) + return wsuo +} + +// SetNillableRule sets the "rule" field if the given value is not nil. +func (wsuo *WordSuffixUpdateOne) SetNillableRule(w *wordsuffix.Rule) *WordSuffixUpdateOne { + if w != nil { + wsuo.SetRule(*w) + } + return wsuo +} + +// SetGuild sets the "guild" edge to the Guild entity. +func (wsuo *WordSuffixUpdateOne) SetGuild(g *Guild) *WordSuffixUpdateOne { + return wsuo.SetGuildID(g.ID) +} + +// SetOwnerID sets the "owner" edge to the User entity by ID. +func (wsuo *WordSuffixUpdateOne) SetOwnerID(id snowflake.ID) *WordSuffixUpdateOne { + wsuo.mutation.SetOwnerID(id) + return wsuo +} + +// SetOwner sets the "owner" edge to the User entity. +func (wsuo *WordSuffixUpdateOne) SetOwner(u *User) *WordSuffixUpdateOne { + return wsuo.SetOwnerID(u.ID) +} + +// Mutation returns the WordSuffixMutation object of the builder. +func (wsuo *WordSuffixUpdateOne) Mutation() *WordSuffixMutation { + return wsuo.mutation +} + +// ClearGuild clears the "guild" edge to the Guild entity. +func (wsuo *WordSuffixUpdateOne) ClearGuild() *WordSuffixUpdateOne { + wsuo.mutation.ClearGuild() + return wsuo +} + +// ClearOwner clears the "owner" edge to the User entity. +func (wsuo *WordSuffixUpdateOne) ClearOwner() *WordSuffixUpdateOne { + wsuo.mutation.ClearOwner() + return wsuo +} + +// Where appends a list predicates to the WordSuffixUpdate builder. +func (wsuo *WordSuffixUpdateOne) Where(ps ...predicate.WordSuffix) *WordSuffixUpdateOne { + wsuo.mutation.Where(ps...) + return wsuo +} + +// Select allows selecting one or more fields (columns) of the returned entity. +// The default is selecting all fields defined in the entity schema. +func (wsuo *WordSuffixUpdateOne) Select(field string, fields ...string) *WordSuffixUpdateOne { + wsuo.fields = append([]string{field}, fields...) + return wsuo +} + +// Save executes the query and returns the updated WordSuffix entity. +func (wsuo *WordSuffixUpdateOne) Save(ctx context.Context) (*WordSuffix, error) { + return withHooks(ctx, wsuo.sqlSave, wsuo.mutation, wsuo.hooks) +} + +// SaveX is like Save, but panics if an error occurs. +func (wsuo *WordSuffixUpdateOne) SaveX(ctx context.Context) *WordSuffix { + node, err := wsuo.Save(ctx) + if err != nil { + panic(err) + } + return node +} + +// Exec executes the query on the entity. +func (wsuo *WordSuffixUpdateOne) Exec(ctx context.Context) error { + _, err := wsuo.Save(ctx) + return err +} + +// ExecX is like Exec, but panics if an error occurs. +func (wsuo *WordSuffixUpdateOne) ExecX(ctx context.Context) { + if err := wsuo.Exec(ctx); err != nil { + panic(err) + } +} + +// check runs all checks and user-defined validators on the builder. +func (wsuo *WordSuffixUpdateOne) check() error { + if v, ok := wsuo.mutation.Suffix(); ok { + if err := wordsuffix.SuffixValidator(v); err != nil { + return &ValidationError{Name: "suffix", err: fmt.Errorf(`ent: validator failed for field "WordSuffix.suffix": %w`, err)} + } + } + if v, ok := wsuo.mutation.Rule(); ok { + if err := wordsuffix.RuleValidator(v); err != nil { + return &ValidationError{Name: "rule", err: fmt.Errorf(`ent: validator failed for field "WordSuffix.rule": %w`, err)} + } + } + if _, ok := wsuo.mutation.OwnerID(); wsuo.mutation.OwnerCleared() && !ok { + return errors.New(`ent: clearing a required unique edge "WordSuffix.owner"`) + } + return nil +} + +func (wsuo *WordSuffixUpdateOne) sqlSave(ctx context.Context) (_node *WordSuffix, err error) { + if err := wsuo.check(); err != nil { + return _node, err + } + _spec := sqlgraph.NewUpdateSpec(wordsuffix.Table, wordsuffix.Columns, sqlgraph.NewFieldSpec(wordsuffix.FieldID, field.TypeUUID)) + id, ok := wsuo.mutation.ID() + if !ok { + return nil, &ValidationError{Name: "id", err: errors.New(`ent: missing "WordSuffix.id" for update`)} + } + _spec.Node.ID.Value = id + if fields := wsuo.fields; len(fields) > 0 { + _spec.Node.Columns = make([]string, 0, len(fields)) + _spec.Node.Columns = append(_spec.Node.Columns, wordsuffix.FieldID) + for _, f := range fields { + if !wordsuffix.ValidColumn(f) { + return nil, &ValidationError{Name: f, err: fmt.Errorf("ent: invalid field %q for query", f)} + } + if f != wordsuffix.FieldID { + _spec.Node.Columns = append(_spec.Node.Columns, f) + } + } + } + if ps := wsuo.mutation.predicates; len(ps) > 0 { + _spec.Predicate = func(selector *sql.Selector) { + for i := range ps { + ps[i](selector) + } + } + } + if value, ok := wsuo.mutation.Suffix(); ok { + _spec.SetField(wordsuffix.FieldSuffix, field.TypeString, value) + } + if value, ok := wsuo.mutation.Expired(); ok { + _spec.SetField(wordsuffix.FieldExpired, field.TypeTime, value) + } + if wsuo.mutation.ExpiredCleared() { + _spec.ClearField(wordsuffix.FieldExpired, field.TypeTime) + } + if value, ok := wsuo.mutation.Rule(); ok { + _spec.SetField(wordsuffix.FieldRule, field.TypeEnum, value) + } + if wsuo.mutation.GuildCleared() { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.M2O, + Inverse: false, + Table: wordsuffix.GuildTable, + Columns: []string{wordsuffix.GuildColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(guild.FieldID, field.TypeUint64), + }, + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := wsuo.mutation.GuildIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.M2O, + Inverse: false, + Table: wordsuffix.GuildTable, + Columns: []string{wordsuffix.GuildColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(guild.FieldID, field.TypeUint64), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Add = append(_spec.Edges.Add, edge) + } + if wsuo.mutation.OwnerCleared() { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.M2O, + Inverse: true, + Table: wordsuffix.OwnerTable, + Columns: []string{wordsuffix.OwnerColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(user.FieldID, field.TypeUint64), + }, + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := wsuo.mutation.OwnerIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.M2O, + Inverse: true, + Table: wordsuffix.OwnerTable, + Columns: []string{wordsuffix.OwnerColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(user.FieldID, field.TypeUint64), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Add = append(_spec.Edges.Add, edge) + } + _node = &WordSuffix{config: wsuo.config} + _spec.Assign = _node.assignValues + _spec.ScanValues = _node.scanValues + if err = sqlgraph.UpdateNode(ctx, wsuo.driver, _spec); err != nil { + if _, ok := err.(*sqlgraph.NotFoundError); ok { + err = &NotFoundError{wordsuffix.Label} + } else if sqlgraph.IsConstraintError(err) { + err = &ConstraintError{msg: err.Error(), wrap: err} + } + return nil, err + } + wsuo.mutation.done = true + return _node, nil +} diff --git a/go.mod b/go.mod index 4385fa68..3aff5c06 100644 --- a/go.mod +++ b/go.mod @@ -1,47 +1,60 @@ module github.com/sabafly/gobot -go 1.21 +go 1.22.0 require ( - github.com/Tnze/go-mc v1.19.4 - github.com/disgoorg/dislog v1.1.0 + entgo.io/ent v0.13.1 + github.com/disgoorg/disgo v0.18.2 github.com/disgoorg/json v1.1.0 github.com/disgoorg/snowflake/v2 v2.0.1 - github.com/dustin/go-humanize v1.0.1 - github.com/go-redis/redis/v8 v8.11.5 - github.com/google/uuid v1.3.0 - github.com/mattn/go-colorable v0.1.13 - github.com/pelletier/go-toml/v2 v2.0.9 - github.com/sabafly/disgo v0.5.0 - github.com/sabafly/sabafly-lib/v2 v2.6.6 - github.com/shirou/gopsutil/v3 v3.23.7 - github.com/sirupsen/logrus v1.9.3 - github.com/spf13/cobra v1.7.0 - github.com/xrjr/mcutils v1.5.1 + github.com/forPelevin/gomoji v1.2.0 + github.com/go-sql-driver/mysql v1.8.1 + github.com/google/uuid v1.6.0 + github.com/joho/godotenv v1.5.1 + github.com/markusmobius/go-dateparser v1.2.1 + github.com/nicksnyder/go-i18n/v2 v2.4.0 + github.com/pelletier/go-toml/v2 v2.2.1 + github.com/redis/go-redis/v9 v9.5.1 + github.com/spf13/cobra v1.8.0 + github.com/tj/go-naturaldate v1.3.0 + golang.org/x/exp v0.0.0-20240416160154-fe59bbe5cc7f + golang.org/x/text v0.14.0 gopkg.in/yaml.v2 v2.4.0 ) require ( - github.com/cespare/xxhash/v2 v2.2.0 // indirect + ariga.io/atlas v0.21.1 // indirect + filippo.io/edwards25519 v1.1.0 // indirect + github.com/agext/levenshtein v1.2.3 // indirect + github.com/apparentlymart/go-textseg/v15 v15.0.0 // indirect + github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect - github.com/disgoorg/disgo v0.16.8 // indirect - github.com/disgoorg/log v1.2.1 // indirect - github.com/forPelevin/gomoji v1.1.8 // indirect - github.com/go-ole/go-ole v1.3.0 // indirect - github.com/gorilla/websocket v1.5.0 // indirect + github.com/elliotchance/pie/v2 v2.8.0 // indirect + github.com/go-openapi/inflect v0.21.0 // indirect + github.com/google/go-cmp v0.6.0 // indirect + github.com/gorilla/websocket v1.5.1 // indirect + github.com/hablullah/go-hijri v1.0.2 // indirect + github.com/hablullah/go-juliandays v1.0.0 // indirect + github.com/hashicorp/hcl/v2 v2.20.1 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect - github.com/lufia/plan9stats v0.0.0-20230326075908-cb1d2100619a // indirect - github.com/mattn/go-isatty v0.0.19 // indirect - github.com/nicksnyder/go-i18n/v2 v2.2.1 // indirect - github.com/power-devops/perfstat v0.0.0-20221212215047-62379fc7944b // indirect - github.com/rivo/uniseg v0.4.4 // indirect - github.com/sasha-s/go-csync v0.0.0-20210812194225-61421b77c44b // indirect + github.com/jalaali/go-jalaali v0.0.0-20210801064154-80525e88d958 // indirect + github.com/kr/pretty v0.3.1 // indirect + github.com/magefile/mage v1.15.0 // indirect + github.com/mitchellh/go-wordwrap v1.0.1 // indirect + github.com/rivo/uniseg v0.4.7 // indirect + github.com/rogpeppe/go-internal v1.12.0 // indirect + github.com/sasha-s/go-csync v0.0.0-20240107134140-fcbab37b09ad // indirect github.com/spf13/pflag v1.0.5 // indirect - github.com/tklauser/go-sysconf v0.3.12 // indirect - github.com/tklauser/numcpus v0.6.1 // indirect - github.com/yusufpapurcu/wmi v1.2.3 // indirect - golang.org/x/crypto v0.12.0 // indirect - golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63 // indirect - golang.org/x/sys v0.11.0 // indirect - golang.org/x/text v0.12.0 // indirect + github.com/tetratelabs/wazero v1.7.1 // indirect + github.com/wasilibs/go-re2 v1.5.2 // indirect + github.com/zclconf/go-cty v1.14.4 // indirect + golang.org/x/crypto v0.22.0 // indirect + golang.org/x/mod v0.17.0 // indirect + golang.org/x/net v0.24.0 // indirect + golang.org/x/sync v0.7.0 // indirect + golang.org/x/sys v0.19.0 // indirect + golang.org/x/tools v0.20.0 // indirect + gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect ) + +replace github.com/disgoorg/disgo => github.com/sabafly/sabafly-disgo v0.13.13-0.20240420164318-79cb68abab87 diff --git a/go.sum b/go.sum index 315f18ac..af7376d3 100644 --- a/go.sum +++ b/go.sum @@ -1,158 +1,144 @@ -github.com/BurntSushi/toml v1.0.0 h1:dtDWrepsVPfW9H/4y7dDgFc2MBUSeJhlaDtK13CxFlU= -github.com/BurntSushi/toml v1.0.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= -github.com/Tnze/go-mc v1.19.4 h1:9qtxH+xRJWswOYnlf/dsFY4EI2f5jsFhtqTYOObaGIE= -github.com/Tnze/go-mc v1.19.4/go.mod h1:c1znJQglgqa1Jjs3Dr29woN/msguiJrlNtWXhKedh2U= -github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= -github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +ariga.io/atlas v0.21.1 h1:Eg9XYhKTH3UHoqP7tKMWFV+Z5JnpVOJCgO3MHrUtKmk= +ariga.io/atlas v0.21.1/go.mod h1:VPlcXdd4w2KqKnH54yEZcry79UAhpaWaxEsmn5JRNoE= +entgo.io/ent v0.13.1 h1:uD8QwN1h6SNphdCCzmkMN3feSUzNnVvV/WIkHKMbzOE= +entgo.io/ent v0.13.1/go.mod h1:qCEmo+biw3ccBn9OyL4ZK5dfpwg++l1Gxwac5B1206A= +filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= +filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= +github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8= +github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= +github.com/DATA-DOG/go-sqlmock v1.5.0 h1:Shsta01QNfFxHCfpW6YH2STWB0MudeXXEWMr20OEh60= +github.com/DATA-DOG/go-sqlmock v1.5.0/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= +github.com/agext/levenshtein v1.2.3 h1:YB2fHEn0UJagG8T1rrWknE3ZQzWM06O8AMAatNn7lmo= +github.com/agext/levenshtein v1.2.3/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558= +github.com/apparentlymart/go-textseg/v15 v15.0.0 h1:uYvfpb3DyLSCGWnctWKGj857c6ew1u1fNQOlOtuGxQY= +github.com/apparentlymart/go-textseg/v15 v15.0.0/go.mod h1:K8XmNZdhEBkdlyDdvbmmsvpAG721bKi0joRfFdHIWJ4= +github.com/bsm/ginkgo/v2 v2.12.0 h1:Ny8MWAHyOepLGlLKYmXG4IEkioBysk6GpaRTLC8zwWs= +github.com/bsm/ginkgo/v2 v2.12.0/go.mod h1:SwYbGRRDovPVboqFv0tPTcG1sN61LM1Z4ARdbAV9g4c= +github.com/bsm/gomega v1.27.10 h1:yeMWxP2pV2fG3FgAODIY8EiRE3dy0aeFYt4l7wh6yKA= +github.com/bsm/gomega v1.27.10/go.mod h1:JyEr/xRbxbtgWNi8tIEVPUYZ5Dzef52k01W3YH0H+O0= +github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= +github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= -github.com/disgoorg/disgo v0.16.8 h1:tvUeX+3Iu8U6koDc8RAgcQadRciWJwsI95Y7edHqq2g= -github.com/disgoorg/disgo v0.16.8/go.mod h1:5fsaUpfu6Yv0p+PfmsAeQkV395KQskVu/d1bdq8vsNI= -github.com/disgoorg/dislog v1.1.0 h1:BhFzCyBL1Fo9JQ+Mze411JBRf9Epqp2jJYHcSoQSSj4= -github.com/disgoorg/dislog v1.1.0/go.mod h1:MO9pSb/rIpiMXpMOX6yIbjiry0Vw0FUCmA7KP0cTlnY= github.com/disgoorg/json v1.1.0 h1:7xigHvomlVA9PQw9bMGO02PHGJJPqvX5AnwlYg/Tnys= github.com/disgoorg/json v1.1.0/go.mod h1:BHDwdde0rpQFDVsRLKhma6Y7fTbQKub/zdGO5O9NqqA= -github.com/disgoorg/log v1.2.1 h1:kZYAWkUBcGy4LbZcgYtgYu49xNVLy+xG5Uq3yz5VVQs= -github.com/disgoorg/log v1.2.1/go.mod h1:hhQWYTFTnIGzAuFPZyXJEi11IBm9wq+/TVZt/FEwX0o= github.com/disgoorg/snowflake/v2 v2.0.1 h1:CuUxGLwggUxEswZOmZ+mZ5i0xSumQdXW9tXW7uGqe+0= github.com/disgoorg/snowflake/v2 v2.0.1/go.mod h1:SPU9c2CNn5DSyb86QcKtdZgix9osEtKrHLW4rMhfLCs= -github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= -github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= -github.com/forPelevin/gomoji v1.1.8 h1:JElzDdt0TyiUlecy6PfITDL6eGvIaxqYH1V52zrd0qQ= -github.com/forPelevin/gomoji v1.1.8/go.mod h1:8+Z3KNGkdslmeGZBC3tCrwMrcPy5GRzAD+gL9NAwMXg= -github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= -github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= -github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= -github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE= -github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78= -github.com/go-redis/redis/v8 v8.11.5 h1:AcZZR7igkdvfVmQTPnu9WE37LRrO/YrBH5zWyjDC0oI= -github.com/go-redis/redis/v8 v8.11.5/go.mod h1:gREzHqY1hg6oD9ngVRbLStwAWKhA0FEgq8Jd4h5lpwo= -github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= -github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= -github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= -github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/elliotchance/pie/v2 v2.8.0 h1://QS43W8sEha8XV/fjngO5iMudN3XARJV5cpBayAcVY= +github.com/elliotchance/pie/v2 v2.8.0/go.mod h1:18t0dgGFH006g4eVdDtWfgFZPQEgl10IoEO8YWEq3Og= +github.com/forPelevin/gomoji v1.2.0 h1:9k4WVSSkE1ARO/BWywxgEUBvR/jMnao6EZzrql5nxJ8= +github.com/forPelevin/gomoji v1.2.0/go.mod h1:8+Z3KNGkdslmeGZBC3tCrwMrcPy5GRzAD+gL9NAwMXg= +github.com/go-openapi/inflect v0.21.0 h1:FoBjBTQEcbg2cJUWX6uwL9OyIW8eqc9k4KhN4lfbeYk= +github.com/go-openapi/inflect v0.21.0/go.mod h1:INezMuUu7SJQc2AyR3WO0DqqYUJSj8Kb4hBd7WtjlAw= +github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y= +github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg= +github.com/go-test/deep v1.0.3 h1:ZrJSEWsXzPOxaZnFteGEfooLba+ju3FYIbOrS+rQd68= +github.com/go-test/deep v1.0.3/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY= +github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY= +github.com/hablullah/go-hijri v1.0.2 h1:drT/MZpSZJQXo7jftf5fthArShcaMtsal0Zf/dnmp6k= +github.com/hablullah/go-hijri v1.0.2/go.mod h1:OS5qyYLDjORXzK4O1adFw9Q5WfhOcMdAKglDkcTxgWQ= +github.com/hablullah/go-juliandays v1.0.0 h1:A8YM7wIj16SzlKT0SRJc9CD29iiaUzpBLzh5hr0/5p0= +github.com/hablullah/go-juliandays v1.0.0/go.mod h1:0JOYq4oFOuDja+oospuc61YoX+uNEn7Z6uHYTbBzdGc= +github.com/hashicorp/hcl/v2 v2.20.1 h1:M6hgdyz7HYt1UN9e61j+qKJBqR3orTWbI1HKBJEdxtc= +github.com/hashicorp/hcl/v2 v2.20.1/go.mod h1:TZDqQ4kNKCbh1iJp99FdPiUaVDDUPivbqxZulxDYqL4= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= -github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I= -github.com/lufia/plan9stats v0.0.0-20230326075908-cb1d2100619a h1:N9zuLhTvBSRt0gWSiJswwQ2HqDmtX/ZCDJURnKUt1Ik= -github.com/lufia/plan9stats v0.0.0-20230326075908-cb1d2100619a/go.mod h1:JKx41uQRwqlTZabZc+kILPrO/3jlKnQ2Z8b7YiVw5cE= -github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= -github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= -github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= -github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= -github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= -github.com/nicksnyder/go-i18n/v2 v2.2.1 h1:aOzRCdwsJuoExfZhoiXHy4bjruwCMdt5otbYojM/PaA= -github.com/nicksnyder/go-i18n/v2 v2.2.1/go.mod h1:fF2++lPHlo+/kPaj3nB0uxtPwzlPm+BlgwGX7MkeGj0= -github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= -github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= -github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= -github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= -github.com/onsi/gomega v1.18.1 h1:M1GfJqGRrBrrGGsbxzV5dqM2U2ApXefZCQpkukxYRLE= -github.com/onsi/gomega v1.18.1/go.mod h1:0q+aL8jAiMXy9hbwj2mr5GziHiwhAIQpFmmtT5hitRs= -github.com/pelletier/go-toml/v2 v2.0.9 h1:uH2qQXheeefCCkuBBSLi7jCiSmj3VRh2+Goq2N7Xxu0= -github.com/pelletier/go-toml/v2 v2.0.9/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc= +github.com/jalaali/go-jalaali v0.0.0-20210801064154-80525e88d958 h1:qxLoi6CAcXVzjfvu+KXIXJOAsQB62LXjsfbOaErsVzE= +github.com/jalaali/go-jalaali v0.0.0-20210801064154-80525e88d958/go.mod h1:Wqfu7mjUHj9WDzSSPI5KfBclTTEnLveRUFr/ujWnTgE= +github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= +github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/magefile/mage v1.15.0 h1:BvGheCMAsG3bWUDbZ8AyXXpCNwU9u5CB6sM+HNb9HYg= +github.com/magefile/mage v1.15.0/go.mod h1:z5UZb/iS3GoOSn0JgWuiw7dxlurVYTu+/jHXqQg881A= +github.com/markusmobius/go-dateparser v1.2.1 h1:mYRRdu3TzpAeE6fSl2Gn3arfxEtoTRvFOKlumlVsUtg= +github.com/markusmobius/go-dateparser v1.2.1/go.mod h1:5xYsZ1h7iB3sE1BSu8bkjYpbFST7EU1/AFxcyO3mgYg= +github.com/mattn/go-sqlite3 v1.14.16 h1:yOQRA0RpS5PFz/oikGwBEqvAWhWg5ufRz4ETLjwpU1Y= +github.com/mattn/go-sqlite3 v1.14.16/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg= +github.com/mitchellh/go-wordwrap v1.0.1 h1:TLuKupo69TCn6TQSyGxwI1EblZZEsQ0vMlAFQflz0v0= +github.com/mitchellh/go-wordwrap v1.0.1/go.mod h1:R62XHJLzvMFRBbcrT7m7WgmE1eOyTSsCt+hzestvNj0= +github.com/nicksnyder/go-i18n/v2 v2.4.0 h1:3IcvPOAvnCKwNm0TB0dLDTuawWEj+ax/RERNC+diLMM= +github.com/nicksnyder/go-i18n/v2 v2.4.0/go.mod h1:nxYSZE9M0bf3Y70gPQjN9ha7XNHX7gMc814+6wVyEI4= +github.com/pelletier/go-toml/v2 v2.2.1 h1:9TA9+T8+8CUCO2+WYnDLCgrYi9+omqKXyjDtosvtEhg= +github.com/pelletier/go-toml/v2 v2.2.1/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs= +github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE= -github.com/power-devops/perfstat v0.0.0-20221212215047-62379fc7944b h1:0LFwY6Q3gMACTjAbMZBjXAqTOzOwFaj2Ld6cjeQ7Rig= -github.com/power-devops/perfstat v0.0.0-20221212215047-62379fc7944b/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE= -github.com/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis= -github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= +github.com/redis/go-redis/v9 v9.5.1 h1:H1X4D3yHPaYrkL5X06Wh6xNVM/pX0Ft4RV0vMGvLBh8= +github.com/redis/go-redis/v9 v9.5.1/go.mod h1:hdY0cQFCN4fnSYT6TkisLufl/4W5UIXyv0b/CLO2V2M= +github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= +github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= +github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= +github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= +github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/sabafly/disgo v0.5.0 h1:pwUJb991m+7B8fxVpfujpThZSgzeaipu/wBElQK7dmo= -github.com/sabafly/disgo v0.5.0/go.mod h1:qhKFp2bKcueqnGIOQkXmHBVjSQ1taA1wdwba3+mlJEI= -github.com/sabafly/sabafly-lib/v2 v2.6.4 h1:CkQpglvWzu8j6VYUb8fUGI9bIiAyGHVI5+W6gWQf7N0= -github.com/sabafly/sabafly-lib/v2 v2.6.4/go.mod h1:6LwbMUGyrdlfa7q6Zg01zAekcjW0oI5B9hTFOV+DsLI= -github.com/sabafly/sabafly-lib/v2 v2.6.5 h1:n1YQglyPJrGlHFMh6tll3eyvfrYuBayEYETlnvFl8fs= -github.com/sabafly/sabafly-lib/v2 v2.6.5/go.mod h1:6LwbMUGyrdlfa7q6Zg01zAekcjW0oI5B9hTFOV+DsLI= -github.com/sabafly/sabafly-lib/v2 v2.6.6 h1:LUDUXUV9pRGG3y29iSVvn7erTvNmLcdzKJV1XvTsZKg= -github.com/sabafly/sabafly-lib/v2 v2.6.6/go.mod h1:6LwbMUGyrdlfa7q6Zg01zAekcjW0oI5B9hTFOV+DsLI= -github.com/sasha-s/go-csync v0.0.0-20210812194225-61421b77c44b h1:qYTY2tN72LhgDj2rtWG+LI6TXFl2ygFQQ4YezfVaGQE= -github.com/sasha-s/go-csync v0.0.0-20210812194225-61421b77c44b/go.mod h1:/pA7k3zsXKdjjAiUhB5CjuKib9KJGCaLvZwtxGC8U0s= -github.com/shirou/gopsutil/v3 v3.23.7 h1:C+fHO8hfIppoJ1WdsVm1RoI0RwXoNdfTK7yWXV0wVj4= -github.com/shirou/gopsutil/v3 v3.23.7/go.mod h1:c4gnmoRC0hQuaLqvxnx1//VXQ0Ms/X9UnJF8pddY5z4= -github.com/shoenig/go-m1cpu v0.1.6/go.mod h1:1JJMcUBvfNwpq05QDQVAnx3gUHr9IYF7GNg9SUEw2VQ= -github.com/shoenig/test v0.6.4/go.mod h1:byHiCGXqrVaflBLAMq/srcZIHynQPQgeyvkvXnjqq0k= -github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= -github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= -github.com/spf13/cobra v1.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I= -github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0= +github.com/sabafly/sabafly-disgo v0.13.13-0.20240420164318-79cb68abab87 h1:ZKY3LQly4Ilw5nZBFHaY2R6PIjB9Bo2dMf8WU41bFbo= +github.com/sabafly/sabafly-disgo v0.13.13-0.20240420164318-79cb68abab87/go.mod h1:X5jvExDOODIxL7W11X1/PPeUUoKg7/utfpQv7EG3YyE= +github.com/sasha-s/go-csync v0.0.0-20240107134140-fcbab37b09ad h1:qIQkSlF5vAUHxEmTbaqt1hkJ/t6skqEGYiMag343ucI= +github.com/sasha-s/go-csync v0.0.0-20240107134140-fcbab37b09ad/go.mod h1:/pA7k3zsXKdjjAiUhB5CjuKib9KJGCaLvZwtxGC8U0s= +github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0= +github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= -github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= -github.com/tklauser/go-sysconf v0.3.11/go.mod h1:GqXfhXY3kiPa0nAXPDIQIWzJbMCB7AmcWpGR8lSZfqI= -github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU= -github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI= -github.com/tklauser/numcpus v0.6.0/go.mod h1:FEZLMke0lhOUG6w2JadTzp0a+Nl8PF/GFkQ5UVIcaL4= -github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+Fk= -github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY= -github.com/xrjr/mcutils v1.5.1 h1:E4ScafEH+joxWVgRCGpJBJfxWX/vaNJDcoS40V91rVo= -github.com/xrjr/mcutils v1.5.1/go.mod h1:43n8cyMIHYjiRM2LFZLVH5Ppz2+RvWppz6OgkLP8Lsk= -github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= -github.com/yusufpapurcu/wmi v1.2.3 h1:E1ctvB7uKFMOJw3fdOW32DwGE9I7t++CRUEMKvFoFiw= -github.com/yusufpapurcu/wmi v1.2.3/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.12.0 h1:tFM/ta59kqch6LlvYnPa0yx5a83cL2nHflFhYKvv9Yk= -golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw= -golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63 h1:m64FZMko/V45gv0bNmrNYoDEq8U5YUhetc9cBWKS1TQ= -golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63/go.mod h1:0v4NqG35kSWCMzLaMeX+IQrlSnVE/bqGSyC2cz/9Le8= -golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.14.0 h1:BONx9s002vGdD9umnlX1Po8vOZmrgH34qlHcD1MfK14= -golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI= -golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM= -golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.12.0 h1:k+n5B8goJNdU7hSvEtMUz3d1Q6D/XW4COJSJR6fN0mc= -golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/tetratelabs/wazero v1.7.1 h1:QtSfd6KLc41DIMpDYlJdoMc6k7QTN246DM2+n2Y/Dx8= +github.com/tetratelabs/wazero v1.7.1/go.mod h1:ytl6Zuh20R/eROuyDaGPkp82O9C/DJfXAwJfQ3X6/7Y= +github.com/tj/assert v0.0.0-20190920132354-ee03d75cd160 h1:NSWpaDaurcAJY7PkL8Xt0PhZE7qpvbZl5ljd8r6U0bI= +github.com/tj/assert v0.0.0-20190920132354-ee03d75cd160/go.mod h1:mZ9/Rh9oLWpLLDRpvE+3b7gP/C2YyLFYxNmcLnPTMe0= +github.com/tj/go-naturaldate v1.3.0 h1:OgJIPkR/Jk4bFMBLbxZ8w+QUxwjqSvzd9x+yXocY4RI= +github.com/tj/go-naturaldate v1.3.0/go.mod h1:rpUbjivDKiS1BlfMGc2qUKNZ/yxgthOfmytQs8d8hKk= +github.com/wasilibs/go-re2 v1.5.2 h1:fDO2TJrRzRrv3jD0gzOvmZ2UM4Yt9YXOEdLrlNc/Ies= +github.com/wasilibs/go-re2 v1.5.2/go.mod h1:UqqxQ1O99boQUm1r61H/IYGiGQOS/P88K7hU5nLNkEg= +github.com/wasilibs/nottinygc v0.4.0 h1:h1TJMihMC4neN6Zq+WKpLxgd9xCFMw7O9ETLwY2exJQ= +github.com/wasilibs/nottinygc v0.4.0/go.mod h1:oDcIotskuYNMpqMF23l7Z8uzD4TC0WXHK8jetlB3HIo= +github.com/zclconf/go-cty v1.14.4 h1:uXXczd9QDGsgu0i/QFR/hzI5NYCHLf6NQw/atrbnhq8= +github.com/zclconf/go-cty v1.14.4/go.mod h1:VvMs5i0vgZdhYawQNq5kePSpLAoz8u1xvZgrPIxfnZE= +github.com/zclconf/go-cty-debug v0.0.0-20191215020915-b22d67c1ba0b h1:FosyBZYxY34Wul7O/MSKey3txpPYyCqVO5ZyceuQJEI= +github.com/zclconf/go-cty-debug v0.0.0-20191215020915-b22d67c1ba0b/go.mod h1:ZRKQfBXbGkpdV6QMzT3rU1kSTAnfu1dO8dPKjYprgj8= +golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30= +golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M= +golang.org/x/exp v0.0.0-20240416160154-fe59bbe5cc7f h1:99ci1mjWVBWwJiEKYY6jWa4d2nTQVIEhZIptnrVb1XY= +golang.org/x/exp v0.0.0-20240416160154-fe59bbe5cc7f/go.mod h1:/lliqkxwWAhPjf5oSOIJup2XcqJaw8RGS6k3TGEc7GI= +golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA= +golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w= +golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8= +golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= +golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o= +golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= +golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/tools v0.20.0 h1:hz/CVckiOxybQvFw6h7b/q80NTr9IUQb4s1IIzW7KNY= +golang.org/x/tools v0.20.0/go.mod h1:WvitBU7JJf6A4jOdg4S1tviW9bhUxkgeCui/0JHctQg= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= -gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= -gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/internal/builtin/buildtin.go b/internal/builtin/buildtin.go new file mode 100644 index 00000000..9ed28749 --- /dev/null +++ b/internal/builtin/buildtin.go @@ -0,0 +1,46 @@ +package builtin + +func Or[T any](ok bool, a, b T) T { + if ok { + return a + } + return b +} + +func Ptr[T any](v T) *T { return &v } + +func RequireNonNil[T any](v *T) T { + if v == nil { + panic("unexpected nil") + } + return *v +} + +func NonNil[T any](v *T) T { + if v != nil { + return *v + } + var zero T + return zero +} + +func NonNilMap[T map[K]V, K comparable, V any](v T) T { + if v != nil { + return v + } + return make(T) +} + +func Must[T any](v T, err error) T { + if err != nil { + panic(err) + } + return v +} + +func NonNilOrDefault[T any](v *T, def T) T { + if v != nil { + return *v + } + return def +} diff --git a/internal/discordutil/emoji.go b/internal/discordutil/emoji.go new file mode 100644 index 00000000..921739a4 --- /dev/null +++ b/internal/discordutil/emoji.go @@ -0,0 +1,75 @@ +package discordutil + +import ( + "fmt" + "strings" + + "github.com/disgoorg/disgo/discord" + "github.com/disgoorg/snowflake/v2" + "github.com/sabafly/gobot/internal/emoji" +) + +func ParseCustomEmojis(str string) []discord.Emoji { + emojis := emoji.DiscordEmoji.FindAllString(str, -1) + toReturn := make([]discord.Emoji, len(emojis)) + if len(emojis) < 1 { + return toReturn + } + for i, em := range emojis { + parts := strings.Split(em, ":") + toReturn[i] = discord.Emoji{ + ID: snowflake.MustParse(parts[2]), + Name: parts[1], + Animated: strings.HasPrefix(em, "", e.Name, e.ID) + } + return fmt.Sprintf("<:%s:%d>", e.Name, e.ID) +} + +func ReactionComponentEmoji(e discord.ComponentEmoji) string { + var zeroID snowflake.ID + if e.ID == zeroID { + return e.Name + } + return fmt.Sprintf("%s:%d", e.Name, e.ID) +} + +// Number2Emoji は1から始たる +func Number2Emoji(n int) string { + return Index2Emoji(n - 1) +} + +// Index2Emoji は0から始たる +func Index2Emoji(n int) string { + return string(rune('🇊' + n)) +} diff --git a/internal/discordutil/message.go b/internal/discordutil/message.go new file mode 100644 index 00000000..6b5793ff --- /dev/null +++ b/internal/discordutil/message.go @@ -0,0 +1,13 @@ +package discordutil + +import ( + "time" + + "github.com/disgoorg/disgo/bot" + "github.com/disgoorg/snowflake/v2" +) + +func DeleteMessageAfter(client bot.Client, channelID, messageID snowflake.ID, after time.Duration) error { + time.Sleep(after) + return client.Rest().DeleteMessage(channelID, messageID) +} diff --git a/internal/discordutil/role.go b/internal/discordutil/role.go new file mode 100644 index 00000000..f8ff8a21 --- /dev/null +++ b/internal/discordutil/role.go @@ -0,0 +1,16 @@ +package discordutil + +import ( + "github.com/disgoorg/disgo/discord" + "slices" +) + +func GetHighestRole(roles []discord.Role) *discord.Role { + slices.SortStableFunc(roles, func(a, b discord.Role) int { + return a.Compare(b) + }) + if len(roles) < 1 { + return nil + } + return &roles[0] +} diff --git a/internal/embeds/embed.go b/internal/embeds/embed.go new file mode 100644 index 00000000..7bb9a1ce --- /dev/null +++ b/internal/embeds/embed.go @@ -0,0 +1,50 @@ +package embeds + +import ( + "time" + + "github.com/disgoorg/disgo/discord" +) + +var ( + Color = 0x00AED9 + BotName = "gobot" +) + +func SetEmbedProperties(embed discord.Embed) discord.Embed { + now := time.Now() + if embed.Color == 0 { + embed.Color = Color + } + if embed.Footer == nil { + embed.Footer = &discord.EmbedFooter{} + } + if embed.Footer.Text == "" { + embed.Footer.Text = BotName + } + if embed.Timestamp == nil { + embed.Timestamp = &now + } + return embed +} + +func SetEmbedsProperties(embeds []discord.Embed) []discord.Embed { + now := time.Now() + for i := range embeds { + if embeds[i].Color == 0 { + embeds[i].Color = Color + } + if i == len(embeds)-1 { + if embeds[i].Footer == nil { + embeds[i].Footer = &discord.EmbedFooter{} + } + if embeds[i].Footer.Text == "" { + embeds[i].Footer.Text = BotName + } + if embeds[i].Timestamp == nil { + embeds[i].Timestamp = &now + } + } + } + return embeds +} diff --git a/internal/emoji/emoji.go b/internal/emoji/emoji.go new file mode 100644 index 00000000..5ed3591f --- /dev/null +++ b/internal/emoji/emoji.go @@ -0,0 +1,24 @@ +package emoji + +import ( + "regexp" + + "github.com/forPelevin/gomoji" +) + +func MatchString(str string) bool { + return DiscordEmoji.MatchString(str) || gomoji.ContainsEmoji(str) +} + +func FindAllString(str string) []string { + s := []string{} + emojis := gomoji.CollectAll(str) + for _, e := range emojis { + s = append(s, e.Character) + } + discord_emojis := DiscordEmoji.FindAllString(str, -1) + s = append(s, discord_emojis...) + return s +} + +var DiscordEmoji = regexp.MustCompile("") diff --git a/internal/emoji/registry.go b/internal/emoji/registry.go new file mode 100644 index 00000000..cdba8907 --- /dev/null +++ b/internal/emoji/registry.go @@ -0,0 +1,42 @@ +package emoji + +import "github.com/disgoorg/disgo/discord" + +var ( + Reaction = &discord.ComponentEmoji{ + ID: 1141985795641716736, + Name: "reaction", + } + SelectMenu = &discord.ComponentEmoji{ + ID: 1141991243832901704, + Name: "select_menu", + } + Button = &discord.ComponentEmoji{ + ID: 1141991285281001553, + Name: "button", + } + GreenButton = &discord.ComponentEmoji{ + ID: 1142333937180483687, + Name: "green_button", + } + BlueButton = &discord.ComponentEmoji{ + ID: 1142333868490367037, + Name: "blue_button", + } + RedButton = &discord.ComponentEmoji{ + ID: 1142334020403871745, + Name: "red_button", + } + GrayButton = &discord.ComponentEmoji{ + ID: 1142333913906298960, + Name: "gray_button", + } + On = &discord.ComponentEmoji{ + ID: 1142095470227890279, + Name: "on", + } + Off = &discord.ComponentEmoji{ + ID: 1142110196462788779, + Name: "off", + } +) diff --git a/internal/errors/errors.go b/internal/errors/errors.go new file mode 100644 index 00000000..04f32fd3 --- /dev/null +++ b/internal/errors/errors.go @@ -0,0 +1,74 @@ +package errors + +import ( + "errors" + + "github.com/disgoorg/disgo/discord" + "github.com/disgoorg/disgo/rest" + "github.com/sabafly/gobot/internal/embeds" + "github.com/sabafly/gobot/internal/translate" +) + +var ( + As = errors.As + Is = errors.Is + Join = errors.Join + New = errors.New + Unwrap = errors.Unwrap +) + +type ( + config struct { + desc *string + } + + Option func(*config) +) + +func (c *config) options(opts ...Option) { + for _, opt := range opts { + opt(c) + } +} + +func WithDescription(s string) Option { + return func(c *config) { + c.desc = &s + } +} + +func ErrorMessage( + key string, + event interface { + RespondMessage(messageBuilder discord.MessageBuilder, opts ...rest.RequestOpt) error + Locale() discord.Locale + }, + opts ...Option, +) error { + cfg := config{} + cfg.options(opts...) + + var desc string + if cfg.desc != nil { + desc = *cfg.desc + } else { + d, err := translate.Localize(event.Locale(), key+".description", nil, 0) + if err == nil { + desc = d + } + } + + return event.RespondMessage( + discord.NewMessageBuilder(). + SetEmbeds( + embeds.SetEmbedProperties( + discord.NewEmbedBuilder(). + SetTitlef("❗ %s", translate.Message(event.Locale(), key)). + SetDescription(desc). + SetColor(0xff2121). + Build(), + ), + ). + SetFlags(discord.MessageFlagEphemeral), + ) +} diff --git a/internal/errors/trace.go b/internal/errors/trace.go new file mode 100644 index 00000000..8c5c282d --- /dev/null +++ b/internal/errors/trace.go @@ -0,0 +1,89 @@ +package errors + +import ( + "errors" + "fmt" + "github.com/google/uuid" + "github.com/sabafly/gobot/internal/uuidv7" + "log/slog" + "runtime" + "runtime/debug" + + "github.com/disgoorg/disgo/rest" +) + +type Error interface { + error + File() string + Stack() string + ID() uuid.UUID +} + +type errorImpl struct { + err error + file string + stack string + id uuid.UUID +} + +var _ Error = (*errorImpl)(nil) + +func (e errorImpl) Error() string { return e.err.Error() } +func (e errorImpl) File() string { return e.file } +func (e errorImpl) Stack() string { return e.stack } +func (e errorImpl) ID() uuid.UUID { return e.id } + +func NewError(err error) Error { + if err == nil { + return nil + } + return newError(err, 2) +} + +func newError(err error, skip int) *errorImpl { + pc := make([]uintptr, 10) // at least 1 entry needed + runtime.Callers(skip, pc) + f := runtime.FuncForPC(pc[0]) + file, line := f.FileLine(pc[0]) + // TODO: なんかこうトラックIDずか蚀っおいい感じに管理したい  + + // トラッキング + id := uuidv7.New() + + slog.Error("゚ラヌが生成されたした", "err", err, "file", fmt.Sprintf("%s:%d", file, line), "filename", f.Name()) + e := Unwrap(err) + if e == nil { + e = err + } + var restErr rest.Error + if errors.As(e, &restErr) { + slog.Error("request info", "err", fmt.Errorf("%w\nurl: %s\nrq: %s\nrs: %s\nhd: %v", restErr, restErr.Request.URL, string(restErr.RqBody), string(restErr.RsBody), restErr.Response.Header)) + } + return &errorImpl{ + err: err, + file: fmt.Sprintf("%s:%d %s\n", file, line, f.Name()), + stack: string(debug.Stack()), + id: id, + } +} + +type ErrorWithMessage interface { + Key() string +} + +type errorWithMessageImpl struct { + *errorImpl + key string +} + +func (e errorWithMessageImpl) Key() string { return e.key } + +func NewErrorWithMessage(err error, key string) Error { + if err == nil { + return nil + } + return &errorWithMessageImpl{ + errorImpl: newError(err, 3), + key: key, + } +} diff --git a/internal/flags/flags.go b/internal/flags/flags.go new file mode 100644 index 00000000..b7899cb9 --- /dev/null +++ b/internal/flags/flags.go @@ -0,0 +1,39 @@ +package flags + +import "golang.org/x/exp/constraints" + +// Add allows you to add multiple bits together, producing a new bit +func Add[T constraints.Integer](f T, bits ...T) T { + for _, bit := range bits { + f |= bit + } + return f +} + +// Remove allows you to subtract multiple bits from the first, producing a new bit +func Remove[T constraints.Integer](f T, bits ...T) T { + for _, bit := range bits { + f &^= bit + } + return f +} + +// Has will ensure that the bit includes all the bits entered +func Has[T constraints.Integer](f T, bits ...T) bool { + for _, bit := range bits { + if (f & bit) != bit { + return false + } + } + return true +} + +// Missing will check whether the bit is missing any one of the bits +func Missing[T constraints.Integer](f T, bits ...T) bool { + for _, bit := range bits { + if (f & bit) != bit { + return true + } + } + return false +} diff --git a/internal/parse/time.go b/internal/parse/time.go new file mode 100644 index 00000000..a801b94e --- /dev/null +++ b/internal/parse/time.go @@ -0,0 +1,27 @@ +package parse + +import ( + "time" + + "github.com/markusmobius/go-dateparser" + "github.com/sabafly/gobot/internal/errors" + "github.com/tj/go-naturaldate" +) + +func TimeFuture(str string) (time.Time, error) { + if d, err := time.ParseDuration(str); err == nil { + return time.Now().Local().Add(d), nil + } + if t, err := time.Parse("2006-01-02 15:04:05 MST", str+" JST"); err == nil { + return t.Local(), nil + } + if t, err := naturaldate.Parse(str, time.Now().Local(), naturaldate.WithDirection(naturaldate.Future)); err == nil { + return t.Local(), nil + } + if t, err := dateparser.Parse(&dateparser.Configuration{ + CurrentTime: time.Now().Local(), + }, str); err == nil { + return t.Time.Local(), nil + } + return time.Time{}, errors.New("invalid format") +} diff --git a/internal/permissions/permission.go b/internal/permissions/permission.go new file mode 100644 index 00000000..58dff9c0 --- /dev/null +++ b/internal/permissions/permission.go @@ -0,0 +1,78 @@ +package permissions + +import ( + "encoding/json" + "fmt" + "strings" +) + +func (p *Permission) UnmarshalJSON(b []byte) error { + return json.Unmarshal(b, &p.m) +} + +func (p Permission) MarshalJSON() ([]byte, error) { + return json.Marshal(p.m) +} + +type Permission struct{ m map[string]bool } + +func (p Permission) String() string { + b := strings.Builder{} + for k, v := range p.m { + b.WriteString(fmt.Sprintf("%s: %t\n", k, v)) + } + return b.String() +} + +func (p *Permission) Set(perm string, enabled bool) { + if p.m == nil { + p.m = make(map[string]bool) + } + perm = strings.TrimPrefix(perm, ".") + perm = strings.TrimSuffix(perm, ".*") + p.m[perm] = enabled +} + +func (p Permission) UnSet(perm string) { + if p.m == nil { + p.m = make(map[string]bool) + } + perm = strings.TrimPrefix(perm, ".") + perm = strings.TrimSuffix(perm, ".*") + delete(p.m, perm) +} + +func (p Permission) Enabled(perm string) bool { + if p.m == nil { + return false + } + perms := strings.Split(perm, ".") + var pc string + r := p.m["*"] + for _, v := range perms { + pc += v + if a, ok := p.m[pc]; ok { + r = a + } + pc += "." + } + return r +} + +func (p Permission) Disabled(perm string) bool { + if p.m == nil { + return false + } + perms := strings.Split(perm, ".") + var pc string + a, ok := p.m["*"] + r := ok && !a + for _, v := range perms { + pc += v + if a, ok := p.m[pc]; ok { + r = !a + } + pc += "." + } + return r +} diff --git a/internal/ratelimit/ratelimit.go b/internal/ratelimit/ratelimit.go new file mode 100644 index 00000000..6dfcbb21 --- /dev/null +++ b/internal/ratelimit/ratelimit.go @@ -0,0 +1,27 @@ +package ratelimit + +import ( + "time" +) + +type Rule struct { + Limit int + Unit time.Duration +} + +// CheckLimit はセヌフならtrueを返す +func CheckLimit(t []time.Time, r []Rule) ([]time.Time, bool) { + m := 0 + for _, v := range r { + if !check(t, v.Limit, v.Unit) { + return t, false + } + m = max(v.Limit, m) + } + t = append([]time.Time{time.Now()}, (t)[0:min(m, len(t))]...) + return t, true +} + +func check(times []time.Time, limit int, unit time.Duration) bool { + return len(times) < limit || time.Since(times[limit-1]) >= unit +} diff --git a/internal/smap/sortmap.go b/internal/smap/sortmap.go new file mode 100644 index 00000000..72115d75 --- /dev/null +++ b/internal/smap/sortmap.go @@ -0,0 +1,34 @@ +package smap + +import ( + "slices" + + "golang.org/x/exp/maps" +) + +func MakeSortMap[M map[K]V, K comparable, V any](m map[K]V) SortMap[M, K, V] { + return SortMap[M, K, V]{ + m: m, + } +} + +type SortMap[M map[K]V, K comparable, V any] struct { + m M +} + +func (m SortMap[M, K, V]) SortKey(f func(a, b K) int) ([]K, []V) { + k := maps.Keys(m.m) + slices.SortStableFunc(k, f) + v := make([]V, len(k)) + for i, k := range k { + v[i] = m.m[k] + } + return k, v +} + +func (m SortMap[M, K, V]) Range(s func(a, b K) int, f func(k K, v V)) { + k, v := m.SortKey(s) + for i, k := range k { + f(k, v[i]) + } +} diff --git a/internal/smap/syncmap.go b/internal/smap/syncmap.go new file mode 100644 index 00000000..6a6cc60b --- /dev/null +++ b/internal/smap/syncmap.go @@ -0,0 +1,51 @@ +package smap + +import "sync" + +type SyncedMap[K, V any] struct { + m sync.Map +} + +func (s *SyncedMap[K, V]) Delete(key K) { + s.m.Delete(key) +} + +func (s *SyncedMap[K, V]) Load(key K) (V, bool) { + v, ok := s.m.Load(key) + if !ok { + var zero V + return zero, false + } + r, ok := v.(V) + return r, ok +} + +func (s *SyncedMap[K, V]) LoadAndDelete(key K) (V, bool) { + v, ok := s.m.LoadAndDelete(key) + if !ok { + var zero V + return zero, false + } + r, ok := v.(V) + return r, ok +} + +func (s *SyncedMap[K, V]) LoadOrStore(key K, value V) (V, bool) { + v, ok := s.m.LoadOrStore(key, value) + return v.(V), ok +} + +func (s *SyncedMap[K, V]) Range(f func(k K, v V) bool) { + s.m.Range(func(key, value any) bool { + return f(key.(K), value.(V)) + }) +} + +func (s *SyncedMap[K, V]) Store(key K, value V) { + s.m.Store(key, value) +} + +func (s *SyncedMap[K, V]) Swap(key K, value V) (V, bool) { + pr, loaded := s.m.Swap(key, value) + return pr.(V), loaded +} diff --git a/internal/translate/translate.go b/internal/translate/translate.go new file mode 100644 index 00000000..9e8a4b8e --- /dev/null +++ b/internal/translate/translate.go @@ -0,0 +1,202 @@ +/* + Copyright (C) 2022-2023 sabafly + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ +package translate + +import ( + "encoding/json" + "os" + "strings" + + "github.com/disgoorg/disgo/discord" + "github.com/nicksnyder/go-i18n/v2/i18n" + "github.com/pelletier/go-toml/v2" + "golang.org/x/text/language" + "gopkg.in/yaml.v2" +) + +var ( + defaultLang = language.Japanese + bundle = i18n.NewBundle(defaultLang) + defaultLocalizer = i18n.NewLocalizer(bundle) +) + +func SetDefaultLanguage(lang language.Tag) { + defaultLang = lang +} + +type Cfg struct { + Fallback string + FallbackLanguage discord.Locale + TemplateData any + PluralCount int +} + +type Option func(*Cfg) + +func WithFallback(fallback string) Option { + return func(c *Cfg) { + c.Fallback = fallback + } +} + +func WithFallBackLanguage(lang discord.Locale) Option { + return func(c *Cfg) { + c.FallbackLanguage = lang + } +} + +func WithTemplate(data any) Option { + return func(c *Cfg) { + c.TemplateData = data + } +} + +func WithPluralCount(count int) Option { + return func(c *Cfg) { + c.PluralCount = count + } +} + +func LoadDir(dir string) (*i18n.Bundle, error) { + bundle = i18n.NewBundle(defaultLang) + bundle.RegisterUnmarshalFunc("yaml", yaml.Unmarshal) + bundle.RegisterUnmarshalFunc("json", json.Unmarshal) + bundle.RegisterUnmarshalFunc("toml", toml.Unmarshal) + fd, err := os.ReadDir(dir) + if err != nil { + return nil, err + } + for _, de := range fd { + _, err := bundle.LoadMessageFile(dir + "/" + de.Name()) + if err != nil { + return nil, err + } + } + defaultLocalizer = i18n.NewLocalizer(bundle, locales...) + return bundle, nil +} + +var ( + locales = []string{ + "en-US", + "en-GB", + "bg", + "zh-CN", + "zh-TW", + "hr", + "cs", + "da", + "nl", + "fi", + "fr", + "de", + "el", + "hi", + "hu", + "id", + "it", + "ja", + "ko", + "lt", + "no", + "pl", + "pt-BR", + "ro", + "ru", + "es-ES", + "sv-SE", + "th", + "tr", + "uk", + "vi", + } +) + +func Localize(locale discord.Locale, messageID string, template any, count int) (string, error) { + return i18n.NewLocalizer(bundle, locale.Code()).Localize(&i18n.LocalizeConfig{ + MessageID: messageID, + TemplateData: template, + PluralCount: count, + }) +} + +func Message(locale discord.Locale, messageID string, opts ...Option) (res string) { + opt := new(Cfg) + opt.FallbackLanguage = discord.LocaleJapanese + for _, o := range opts { + o(opt) + } + res, err := Localize(locale, messageID, opt.TemplateData, opt.PluralCount) + if err == nil { + return res + } + alt, err := defaultLocalizer.Localize(&i18n.LocalizeConfig{ + MessageID: messageID, + TemplateData: opt.TemplateData, + PluralCount: opt.PluralCount, + }) + if err == nil { + return alt + } + res = messageID + if opt.Fallback != "" { + res = opt.Fallback + } + return res +} + +func MessageMap(key string, replace bool, opts ...Option) map[discord.Locale]string { + res := map[discord.Locale]string{ + discord.LocaleEnglishUS: Message(discord.LocaleEnglishUS, key, opts...), + discord.LocaleEnglishGB: Message(discord.LocaleEnglishGB, key, opts...), + discord.LocaleBulgarian: Message(discord.LocaleBulgarian, key, opts...), + discord.LocaleChineseCN: Message(discord.LocaleChineseCN, key, opts...), + discord.LocaleChineseTW: Message(discord.LocaleChineseTW, key, opts...), + discord.LocaleCroatian: Message(discord.LocaleCroatian, key, opts...), + discord.LocaleCzech: Message(discord.LocaleCzech, key, opts...), + discord.LocaleDanish: Message(discord.LocaleDanish, key, opts...), + discord.LocaleDutch: Message(discord.LocaleDutch, key, opts...), + discord.LocaleFinnish: Message(discord.LocaleFinnish, key, opts...), + discord.LocaleFrench: Message(discord.LocaleFrench, key, opts...), + discord.LocaleGerman: Message(discord.LocaleGerman, key, opts...), + discord.LocaleGreek: Message(discord.LocaleGreek, key, opts...), + discord.LocaleHindi: Message(discord.LocaleHindi, key, opts...), + discord.LocaleHungarian: Message(discord.LocaleHungarian, key, opts...), + discord.LocaleIndonesian: Message(discord.LocaleIndonesian, key, opts...), + discord.LocaleItalian: Message(discord.LocaleItalian, key, opts...), + discord.LocaleJapanese: Message(discord.LocaleJapanese, key, opts...), + discord.LocaleKorean: Message(discord.LocaleKorean, key, opts...), + discord.LocaleLithuanian: Message(discord.LocaleLithuanian, key, opts...), + discord.LocaleNorwegian: Message(discord.LocaleNorwegian, key, opts...), + discord.LocalePolish: Message(discord.LocalePolish, key, opts...), + discord.LocalePortugueseBR: Message(discord.LocalePortugueseBR, key, opts...), + discord.LocaleRomanian: Message(discord.LocaleRomanian, key, opts...), + discord.LocaleRussian: Message(discord.LocaleRussian, key, opts...), + discord.LocaleSpanishES: Message(discord.LocaleSpanishES, key, opts...), + discord.LocaleSwedish: Message(discord.LocaleSwedish, key, opts...), + discord.LocaleThai: Message(discord.LocaleThai, key, opts...), + discord.LocaleTurkish: Message(discord.LocaleTurkish, key, opts...), + discord.LocaleUkrainian: Message(discord.LocaleUkrainian, key, opts...), + discord.LocaleVietnamese: Message(discord.LocaleVietnamese, key, opts...), + } + if replace { + for l, v := range res { + res[l] = strings.ReplaceAll(v, " ", "-") + } + } + return res +} diff --git a/internal/uuidv7/uuid.go b/internal/uuidv7/uuid.go new file mode 100644 index 00000000..5825bfe3 --- /dev/null +++ b/internal/uuidv7/uuid.go @@ -0,0 +1,10 @@ +package uuidv7 + +import ( + "github.com/google/uuid" +) + +// New returns a new uuid.UUID v7 +func New() uuid.UUID { + return uuid.Must(uuid.NewV7()) +} diff --git a/internal/xppoint/xp.go b/internal/xppoint/xp.go new file mode 100644 index 00000000..68b8c023 --- /dev/null +++ b/internal/xppoint/xp.go @@ -0,0 +1,99 @@ +package xppoint + +import ( + "math/big" +) + +type XP uint64 + +func (xp XP) Level() uint64 { + return level(uint64(xp)) +} + +func (xp *XP) Add(n uint64) { + *xp += XP(n) +} + +const multiplier = 25 + +func RequiredPoint(level uint64) uint64 { + // 0から始たる + // 次のレベルに経隓倀がどれだけいるか + // + // level=0 -> 1レベルに䞊がるたでの経隓倀 + n := level + var x uint64 + switch { + case level < 16: + x = 2*n + 7 + case level < 31: + x = 5*n - 38 + case 31 <= level: + x = 9*n - 158 + } + x *= multiplier + return x +} + +func TotalPoint(level uint64) uint64 { + // 次の方皋匏を䜿甚しお、レベルに到達するたでにどれだけの経隓倀が収集されたかを決定できたす。 + f := (&big.Float{}).SetUint64(level) + x := big.NewFloat(0) + switch { + case level <= 16: // level^2 + 6 × level + x.Add((&big.Float{}).Mul(f, f), (&big.Float{}).Mul(big.NewFloat(6), f)) + case level <= 31: // 2.5 × level^2 – 40.5 × level + 360 + x.Add( + (&big.Float{}).Mul(big.NewFloat(2.5), (&big.Float{}).Mul(f, f)), + (&big.Float{}).Mul(big.NewFloat(-40.5), f), + ).Add(x, big.NewFloat(360)) + case 32 <= level: // 4.5 × level^2 – 162.5 × level + 2220 + x.Add( + (&big.Float{}).Mul(big.NewFloat(4.5), (&big.Float{}).Mul(f, f)), + (&big.Float{}).Mul(big.NewFloat(-162.5), f), + ).Add(x, big.NewFloat(2220)) + } + x.Mul(x, big.NewFloat(multiplier)) + u, _ := x.Uint64() + return u +} + +func level(points uint64) uint64 { + points /= multiplier + f := (&big.Float{}).SetUint64(points) + x := big.NewFloat(0) + switch { + case points <= 352: + x.Add( + (&big.Float{}).Sqrt((&big.Float{}).Add(f, big.NewFloat(9))), + big.NewFloat(-3), + ) + case points <= 1507: + x.Add( + big.NewFloat(81.0/10.0), + (&big.Float{}).Sqrt( + (&big.Float{}).Mul( + big.NewFloat(2.0/5.0), + (&big.Float{}).Add( + f, + big.NewFloat(-7839.0/40.0)), + ), + ), + ) + case 1508 <= points: + x.Add( + big.NewFloat(325.0/18.0), + (&big.Float{}).Sqrt( + (&big.Float{}).Mul( + big.NewFloat(2.0/9.0), + (&big.Float{}).Add( + f, + big.NewFloat(-54215.0/72.0), + ), + ), + ), + ) + } + i, _ := x.Uint64() + return i +} diff --git a/internal/xppoint/xp_test.go b/internal/xppoint/xp_test.go new file mode 100644 index 00000000..e5ad2a8f --- /dev/null +++ b/internal/xppoint/xp_test.go @@ -0,0 +1,25 @@ +package xppoint_test + +import ( + "testing" + + "github.com/sabafly/gobot/internal/xppoint" + "golang.org/x/exp/slog" +) + +func TestXPSum(t *testing.T) { + for i := 0; i < 1000; i++ { + tp := xppoint.TotalPoint(uint64(i)) + xp := xppoint.XP(tp) + if xp.Level() != uint64(i) { + slog.Warn("failed 1", "xp", xp, "i", i, "level", xp.Level()) + t.Fail() + } + rp := xppoint.RequiredPoint(uint64(i)) + xp.Add(rp) + if xp.Level() != uint64(i)+1 { + slog.Warn("failed 2", "xp", xp, "i", i, "level", xp.Level()) + t.Fail() + } + } +} diff --git a/lang/ja.yaml b/lang/ja.yaml index 5945acce..0357daca 100644 --- a/lang/ja.yaml +++ b/lang/ja.yaml @@ -1,378 +1,616 @@ -error_occurred_embed_message: "゚ラヌが発生したした" -command_user_info_status: "ステヌタス" -command_user_info_time: "メンバヌになった日" -command_user_info_time_created: "アカりント" -command_user_info_time_joined: "ギルド" -command_user_info_avatar: "アバタヌURL" -command_user_info_role: "ロヌル" -command_user_info_color: "カラヌコヌド" -command_user_info_nick: "ニックネヌム" -command_user_info_messages_statics: "メッセヌゞ統蚈" -online_status: "ステヌタス" -client_web: "ブラりザ" -client_desktop: "デスクトップ" -client_mobile: "モバむル" +about_command_description: ボットの情報を衚瀺する +activity_competing_name: "{{.Name}}の詊合䞭" activity_game_name: "{{.Name}}をプレむ䞭" -activity_streaming_name: "[{{.Details}}]({{.URL}})を配信䞭" activity_listening_name: "{{.Name}}を再生䞭" +activity_party_format: ({{.PartySize}}/{{.PartyMax}}) +activity_streaming_name: "[{{.Details}}]({{.URL}})を配信䞭" activity_watching_name: "{{.Name}}を芖聎䞭" -activity_competing_name: "{{.Name}}の詊合䞭" -activity_party_format: "({{.PartySize}}/{{.PartyMax}})" -error_not_found: "404 䞍明なリク゚スト" -day: "日" -hour: "時間" -minute: "分" -seconds: "秒" -all_time: "党期間" -channel: "チャンネル" -command_text_feature_add_message_select_target: "察象ずなる{{.Target}}を遞んで䞋さい" -error_invalid_command_argument_title: "コマンド匕数゚ラヌ" -error_invalid_command_argument_message: "コマンドの匕数が正しく指定されおいたせん" -error_already_deleted_title: "削陀倱敗" +all_time: 党期間 +april: 4月 +august: 8月 +channel: チャンネル +client_desktop: デスクトップ +client_mobile: モバむル +client_web: ブラりザ +command_config_bump_message_modal_text_0_label: 応答メッセヌゞのタむトル +command_config_bump_message_modal_text_1_label: 応答メッセヌゞの本文 +command_config_bump_message_modal_text_2_label: 催促メッセヌゞのタむトル +command_config_bump_message_modal_text_3_label: 催促メッセヌゞの本文 +command_level_move_result_embed_title: 経隓倀を移動したした +command_level_rank_result_embed_title: グロヌバル +command_level_reset_result_embed_title: レベルをリセットしたした +command_message_create_modal_action_row_0_placeholder: メッセヌゞの内容 +command_message_pin_create_modal_action_row_0_label: 内容 +command_message_pin_create_modal_title: 固定メッセヌゞを䜜成 +command_message_pin_create_pinned_message: ピン留め +command_text_feature_add_message_select_target: 察象ずなる{{.Target}}を遞んで䞋さい +command_text_ping_response_embed_title: ポング +command_text_poll_create_embed_component_edit_choice_placeholder: 遞択肢のプロパティ +command_text_poll_create_embed_component_edit_choice_response_field_emoji_name: 絵文字 +command_text_poll_create_embed_component_edit_choice_response_message_title: 遞択肢の詳现 +command_text_poll_create_embed_component_edit_settings_response_message_title: 珟圚の蚭定 +command_text_poll_create_embed_component_edit_settings_response_select_menu_placeholder: 線集する蚭定を遞択 +command_text_poll_create_embed_create_description: パネルを送信するチャンネルを遞んで䞋さい +command_text_poll_create_embed_create_title: 投祚パネルを䜜成 +command_text_poll_create_embed_field_choices: 祚数 +command_text_poll_create_embed_field_description: 詳现 +command_text_poll_create_embed_field_time_limit: 期限 +command_text_poll_create_embed_field_title: タむトル +command_text_poll_create_embed_message_title: 投祚を䜜成 +command_text_poll_create_modal_add_choice_component_description_label: 詳现 +command_text_poll_create_modal_add_choice_component_description_placeholder: 遞択肢の詳现 (任意) +command_text_poll_create_modal_add_choice_component_name_label: 名前 +command_text_poll_create_modal_add_choice_component_name_placeholder: 遞択肢の名前 +command_text_poll_create_modal_add_choice_component_response_title: 远加したした +command_text_poll_create_modal_add_choice_title: 遞択肢を远加 +command_text_poll_create_modal_change_choice_emoji_description: このチャンネルに絵文字を送信しおください +command_text_poll_create_modal_change_choice_emoji_title: 絵文字を線集 +command_text_poll_create_modal_change_choice_info_component_response_title: 倉曎したした +command_text_poll_create_modal_change_choice_info_title: 遞択肢を線集 +command_text_poll_create_modal_change_poll_info_modal_component_description: 詳现 +command_text_poll_create_modal_change_poll_info_modal_component_description_placeholder: 投祚の詳现な説明 +command_text_poll_create_modal_change_poll_info_modal_component_title: タむトル +command_text_poll_create_modal_change_poll_info_modal_component_title_placeholder: 投祚のタむトル +command_text_poll_create_modal_change_poll_info_modal_title: 投祚の名前を倉曎 +command_text_poll_settings_show_type_after_vote: 投祚枈み +command_text_poll_settings_show_type_always: オン +command_text_poll_settings_show_type_never: オフ +command_text_poll_settings_type_can_change_target: 投祚先を埌から倉曎するこずを蚱可する +command_text_poll_settings_type_show_count: 祚数を衚瀺する +command_text_poll_settings_type_show_total_count: 投祚の総数を衚瀺する +command_text_poll_settings_type_show_user: 投祚しおいるナヌザヌを衚瀺する +command_text_poll_settings_type_show_user_in_result: 投祚しおいるナヌザヌを投祚結果で衚瀺する +command_text_role_panel_create_add_role_menu_embed_description: パネルに䜿甚するロヌルを遞択しおください +command_text_role_panel_create_add_role_menu_embed_title: ロヌルを遞択 +command_text_role_panel_create_base_menu_embed_field_description_name: 説明 +command_text_role_panel_create_base_menu_embed_field_name_name: パネルの名前 +command_text_role_panel_create_base_menu_embed_title: 圹職パネルを䜜成 +command_text_role_panel_create_build_message_component_button_use_label: 䜿甚 +command_text_role_panel_create_edit_panel_config_fields_max_name: 最倧 +command_text_role_panel_create_edit_panel_config_fields_min_name: 最小 +command_text_role_panel_create_edit_panel_config_modal_components_value_label: 倀 +command_text_role_panel_create_edit_panel_config_modal_components_value_placeholder: 数倀 +command_text_role_panel_create_edit_panel_config_modal_title: 倀を入力 +command_text_role_panel_create_edit_panel_config_title: パネルの蚭定 +command_text_role_panel_create_edit_panel_create_add_list_embed_description: 圹職パネルのリストに登録したした +command_text_role_panel_create_edit_panel_create_add_list_embed_title: リストに远加 +command_text_role_panel_create_edit_panel_create_components_add_list_label: パネル䞀芧に远加 +command_text_role_panel_create_edit_panel_create_components_send_channel_label: チャンネルにメッセヌゞを䜜成 +command_text_role_panel_create_edit_panel_create_embed_description: 䜜成するパネルの䜜成先を遞んでください +command_text_role_panel_create_edit_panel_create_embed_title: パネルを䜜成 +command_text_role_panel_create_edit_panel_create_send_channel_embed_description: パネルを送信するチャンネルを遞択しおください +command_text_role_panel_create_edit_panel_create_send_channel_embed_title: チャンネルを遞択 +command_text_role_panel_create_edit_panel_info_modal_component_description_label: 詳现 +command_text_role_panel_create_edit_panel_info_modal_component_name_label: 名前 +command_text_role_panel_create_edit_panel_info_modal_title: パネルを線集 +command_text_role_panel_create_edit_role_emoji_embed_description: このチャンネルに絵文字を送信しおください +command_text_role_panel_create_edit_role_emoji_embed_title: 絵文字を倉曎 +command_text_role_panel_create_edit_role_info_modal_component_description_label: 詳现 +command_text_role_panel_create_edit_role_info_modal_component_name_label: 衚瀺名 +command_text_role_panel_create_edit_role_info_modal_title: ロヌルを線集 +command_text_role_panel_create_edit_role_menu_embed_fields_description: 説明 +command_text_role_panel_create_edit_role_menu_embed_fields_display_name: 衚瀺名 +command_text_role_panel_create_edit_role_menu_embed_fields_emoji: 絵文字 +command_text_role_panel_create_edit_role_menu_embed_fields_role: ロヌル +command_text_role_panel_create_edit_role_menu_embed_title: ロヌルを線集する +command_text_role_panel_delete_embed_description: 遞択したパネルを削陀したした +command_text_role_panel_delete_embed_title: 完了 +command_text_role_panel_get_role_embed_field_added_name: 远加 +command_text_role_panel_get_role_embed_field_already_name: 既存 +command_text_role_panel_get_role_embed_field_removed_name: 解陀 +command_text_role_panel_role_create_modal_component_description_label: 説明 +command_text_role_panel_role_create_modal_component_name_label: 名前 +command_text_role_panel_role_create_modal_title: 䜜成するパネルの情報 +command_text_role_panel_use_embed_description: ほしいロヌルを党お遞択しおください +command_text_role_panel_use_embed_title: ロヌルを遞択 +command_user_info_avatar: アバタヌURL +command_user_info_color: カラヌコヌド +command_user_info_messages_statics: メッセヌゞ統蚈 +command_user_info_nick: ニックネヌム +command_user_info_role: ロヌル +command_user_info_status: ステヌタス +command_user_info_time: メンバヌになった日 +command_user_info_time_created: アカりント +command_user_info_time_joined: ギルド +config_bump_mention_command_description: Bump通知の際にメンションするロヌルを蚭定する +config_bump_mention_command_role_option_description: メンションするロヌル +config_bump_message_changed: Bump通知のメッセヌゞを倉曎したした +config_bump_message_command_description: Bump通知のメッセヌゞを線集する +config_bump_off_command_description: Bump通知を無効化する +config_bump_off_description: Bump通知を無効化したした +config_bump_on_command_description: Bump通知を有効化する +config_bump_on_description: Bump通知を有効化したした +config_bump_up_mention_none: メンション先は蚭定されおいたせん +config_bump_up_mention_remove: メンション先を {{.Mention}} から解陀したした +config_bump_up_mention_set: メンション先を {{.Mention}} に蚭定したした +config_changed: 蚭定を倉曎したした +config_import_mee6_result_unauthorized: "mee6リヌダヌボヌドがパブリックではありたせん。\r[蚭定](https://mee6.xyz/en/dashboard/{{.GuildID}}/leaderboard)からリヌダヌボヌドを公開しおください。" +config_level_exclude_add: "{{.Mention}} をレベル機胜の察象から陀倖したす" +config_level_exclude_add_command_channel_option_description: 䟋倖にするチャンネル +config_level_exclude_add_command_description: レベルアップの察象倖にするチャンネルを远加したす +config_level_exclude_remove: "{{.Mention}} はレベル機胜の察象になりたす" +config_level_exclude_remove_command_channel_option_description: 䟋倖から倖すチャンネル +config_level_exclude_remove_command_description: レベルアップの察象倖からチャンネルを取り陀く +config_level_import_mee6_command_description: mee6から経隓倀を匕き継ぎたす ⚠ 党員のレベルがリセットされたす ⚠ +config_level_notice_channel_command_channel_option_description: 通知を送信するチャンネル +config_level_notice_channel_command_description: レベルアップ通知を送信するチャンネルを蚭定する +config_level_notice_channel_remove: レベル通知はメッセヌゞが送られたチャンネルに送信したす +config_level_notice_channel_set: レベル通知を {{.Mention}} に送信したす +config_level_notice_message_changed: レベルアップ通知のメッセヌゞを倉曎したした +config_level_notice_message_command_description: レベルアップ通知のメッセヌゞを線集する +config_up_mention_command_description: UP通知の際にメンションするロヌルを蚭定する +config_up_mention_command_role_option_description: メンションするロヌル +config_up_message_changed: UP通知のメッセヌゞを倉曎したした +config_up_message_command_description: UP通知のメッセヌゞを線集する +config_up_off_description: UP通知を無効したした +config_up_off_message_description: UP通知を無効化する +config_up_on_command_description: UP通知を有効化する +config_up_on_description: UP通知を有効化したした +day: 日 +december: 12月 +embed_dialog_base_menu_title: 埋め蟌みクリ゚ヌタヌ +embed_dialog_button_to_title_description_menu: タむトル・本文 +embed_dialog_set_desc_modal_0_text_input_label: 本文 +embed_dialog_set_desc_modal_title: 本文を蚭定 +embed_dialog_set_title_modal_0_text_input_label: タむトル +embed_dialog_set_title_modal_title: タむトルを蚭定 +embed_dialog_title_description_menu_button_set_description_label: 本文を蚭定 +embed_dialog_title_description_menu_button_set_title_label: タむトルを蚭定 +embed_dialog_title_description_menu_fields_0_title: タむトル +embed_dialog_title_description_menu_fields_1_title: 本文 +embed_dialog_title_description_menu_title: 項目 +error_add_role_failed_message: 圹職の順䜍等を確認しおください +error_add_role_failed_title: 圹職の远加に倱敗したした error_already_deleted_message: "削陀に倱敗したした\rすでに削陀されおいる可胜性がありたす" -error_create_failed_title: "䜜成倱敗" +error_already_deleted_title: 削陀倱敗 +error_bot_member_not_found_message: ボットを招埅しなおしお䞋さい +error_bot_member_not_found_title: ボットが正しく招埅されおいたせん +error_busy_message: もう䞀床やり盎しおください +error_busy_title: ちょっず忙しいです +error_cant_edit_same_time_message: "同時に線集するこずはできたせん\rセッションを終了しおからやり盎しおください" +error_cant_edit_same_time_title: 同時に線集できたせん +error_convert_failed_no_role_message: 有効な圹職がありたせん +error_convert_failed_no_role_title: 匕継ぎに倱敗したした error_create_failed_message: "䜜成に倱敗したした\rすでに䜜成されおいる可胜性がありたす" -command_text_ping_response_embed_title: "ポング" -command_text_poll_create_embed_message_title: "投祚を䜜成" -command_text_poll_create_embed_field_title: "タむトル" -command_text_poll_create_embed_field_description: "詳现" -command_text_poll_create_embed_field_time_limit: "期限" -command_text_poll_create_embed_field_choices: "祚数" -max: "最倧" -min: "最小" -command_text_poll_create_modal_add_choice_title: "遞択肢を远加" -command_text_poll_create_modal_add_choice_component_name_label: "名前" -command_text_poll_create_modal_add_choice_component_name_placeholder: "遞択肢の名前" -command_text_poll_create_modal_add_choice_component_description_label: "詳现" -command_text_poll_create_modal_add_choice_component_description_placeholder: "遞択肢の詳现 (任意)" -command_text_poll_create_modal_add_choice_component_response_title: "远加したした" -command_text_poll_create_embed_component_edit_choice_placeholder: "遞択肢のプロパティ" -command_text_poll_create_embed_component_edit_choice_response_message_title: "遞択肢の詳现" -command_text_poll_create_embed_component_edit_choice_response_field_emoji_name: "絵文字" -command_text_poll_create_modal_change_choice_info_title: "遞択肢を線集" -command_text_poll_create_modal_change_choice_info_component_response_title: "倉曎したした" -command_text_poll_create_modal_change_choice_emoji_title: "絵文字を線集" -command_text_poll_create_modal_change_choice_emoji_description: "このチャンネルに絵文字を送信しおください" -command_text_poll_create_embed_component_edit_settings_response_message_title: "珟圚の蚭定" -command_text_poll_create_embed_component_edit_settings_response_select_menu_placeholder: "線集する蚭定を遞択" -command_text_poll_settings_type_show_user: "投祚しおいるナヌザヌを衚瀺する" -command_text_poll_settings_type_show_count: "祚数を衚瀺する" -command_text_poll_settings_type_show_total_count: "投祚の総数を衚瀺する" -command_text_poll_settings_type_show_user_in_result: "投祚しおいるナヌザヌを投祚結果で衚瀺する" -command_text_poll_settings_type_can_change_target: "投祚先を埌から倉曎するこずを蚱可する" -command_text_poll_settings_show_type_always: "オン" -command_text_poll_settings_show_type_never: "オフ" -command_text_poll_settings_show_type_after_vote: "投祚枈み" -command_text_poll_create_embed_create_title: "投祚パネルを䜜成" -command_text_poll_create_embed_create_description: "パネルを送信するチャンネルを遞んで䞋さい" -poll_choices_title: "遞択肢䞀芧" -poll_embed_field_end_at: "終了日時" -poll_embed_field_number_of_votes: "祚数" -poll_embed_field_ex_total_votes: "环蚈祚数" -poll_component_button_vote_label: "投祚する" -poll_component_button_see_info_label: "投祚状況" -poll_component_button_see_result_label: "結果を芋る" -poll_component_button_vote_response_already_voted: "すでに投祚しおいたす" -poll_component_button_vote_response_already_voted_field_votes_name: "投祚先" -poll_component_select_menu_vote_do_response_title: "投祚完了" -poll_component_cannot_use_this: "䜿甚できたせん" -poll_component_see_info_response_embed_title: "{{.Name}}の詳现" -poll_component_voter: "投祚者" -poll_message_result_title: "{{.Rank}}䜍" -poll_message_result_description: "{{.Count}}祚" -poll_message_result_embed_title: "投祚結果" -joined_people: "参加人数" -people: "{{.Count}}人" -command_text_poll_create_modal_change_poll_info_modal_title: "投祚の名前を倉曎" -command_text_poll_create_modal_change_poll_info_modal_component_title: "タむトル" -command_text_poll_create_modal_change_poll_info_modal_component_title_placeholder: "投祚のタむトル" -command_text_poll_create_modal_change_poll_info_modal_component_description: "詳现" -command_text_poll_create_modal_change_poll_info_modal_component_description_placeholder: "投祚の詳现な説明" -command_text_role_panel_role_create_modal_title: "䜜成するパネルの情報" -command_text_role_panel_role_create_modal_component_name_label: "名前" -command_text_role_panel_role_create_modal_component_description_label: "説明" -command_text_role_panel_create_base_menu_embed_title: "圹職パネルを䜜成" -command_text_role_panel_create_base_menu_embed_field_name_name: "パネルの名前" -command_text_role_panel_create_base_menu_embed_field_description_name: "説明" -command_text_role_panel_create_edit_role_menu_embed_title: "ロヌルを線集する" -command_text_role_panel_create_edit_role_menu_embed_fields_display_name: "衚瀺名" -command_text_role_panel_create_edit_role_menu_embed_fields_description: "説明" -command_text_role_panel_create_edit_role_menu_embed_fields_emoji: "絵文字" -command_text_role_panel_create_add_role_menu_embed_title: "ロヌルを遞択" -command_text_role_panel_create_add_role_menu_embed_description: "パネルに䜿甚するロヌルを遞択しおください" -error_bot_member_not_found_title: "ボットが正しく招埅されおいたせん" -error_bot_member_not_found_message: "ボットを招埅しなおしお䞋さい" -command_text_role_panel_create_edit_role_info_modal_title: "ロヌルを線集" -command_text_role_panel_create_edit_role_info_modal_component_name_label: "衚瀺名" -command_text_role_panel_create_edit_role_info_modal_component_description_label: "詳现" -command_text_role_panel_create_edit_role_emoji_embed_title: "絵文字を倉曎" -command_text_role_panel_create_edit_role_emoji_embed_description: "このチャンネルに絵文字を送信しおください" -command_text_role_panel_create_edit_role_menu_embed_fields_role: "ロヌル" -command_text_role_panel_create_edit_panel_info_modal_title: "パネルを線集" -command_text_role_panel_create_edit_panel_info_modal_component_name_label: "名前" -command_text_role_panel_create_edit_panel_info_modal_component_description_label: "詳现" -command_text_role_panel_create_edit_panel_config_title: "パネルの蚭定" -command_text_role_panel_create_edit_panel_config_fields_max_name: "最倧" -command_text_role_panel_create_edit_panel_config_fields_min_name: "最小" -role: - one: "ロヌル" - other: "ロヌル" -command_text_role_panel_create_edit_panel_config_modal_title: "倀を入力" -command_text_role_panel_create_edit_panel_config_modal_components_value_label: "倀" -command_text_role_panel_create_edit_panel_config_modal_components_value_placeholder: "数倀" -error_out_of_range_select_menu_title: "無効な数倀" -error_out_of_range_select_menu_message: "1以䞊25以䞋の範囲内である必芁がありたす" -command_text_role_panel_create_edit_panel_create_embed_title: "パネルを䜜成" -command_text_role_panel_create_edit_panel_create_embed_description: "䜜成するパネルの䜜成先を遞んでください" -command_text_role_panel_create_edit_panel_create_components_send_channel_label: "チャンネルにメッセヌゞを䜜成" -command_text_role_panel_create_edit_panel_create_components_add_list_label: "パネル䞀芧に远加" -command_text_role_panel_create_build_message_component_button_use_label: "䜿甚" -command_text_role_panel_create_edit_panel_create_send_channel_embed_title: "チャンネルを遞択" -command_text_role_panel_create_edit_panel_create_send_channel_embed_description: "パネルを送信するチャンネルを遞択しおください" -role_panel: "圹職パネル" -command_text_role_panel_use_embed_title: "ロヌルを遞択" -command_text_role_panel_use_embed_description: "ほしいロヌルを党お遞択しおください" -command_text_role_panel_get_role_embed_field_added_name: "远加" -command_text_role_panel_get_role_embed_field_already_name: "既存" -command_text_role_panel_get_role_embed_field_removed_name: "解陀" -command_text_role_panel_create_edit_panel_create_add_list_embed_title: "リストに远加" -command_text_role_panel_create_edit_panel_create_add_list_embed_description: "圹職パネルのリストに登録したした" -error_guild_max_count_limit_has_reached_title: "最倧数に達しおいたす" -error_guild_max_count_limit_has_reached_message: "このギルドは個数制限に達しおいたす。 どれかを削陀しおからやり盎しおください。" -error_has_no_data_title: "デヌタがありたせん" -error_has_no_data_message: "少なくずも䞀぀はある必芁がありたす" -command_text_role_panel_delete_embed_title: "完了" -command_text_role_panel_delete_embed_description: "遞択したパネルを削陀したした" -error_has_no_panel_title: "パネルが登録されおいたせん" -error_has_no_panel_message: "パネル䞀芧にパネルを登録しおください" -error_timeout_title: "タむムアりト" -error_timeout_message: "有効期限が切れおいたす。最初からやり盎しおください。" -error_no_permission_title: "暩限が䞍足しおいたす" -error_no_permission_message: "{{.Name}}の暩限が必芁です" -command_message_pin_create_modal_title: "固定メッセヌゞを䜜成" -command_message_pin_create_modal_action_row_0_label: "内容" -command_message_create_modal_action_row_0_placeholder: "メッセヌゞの内容" -command_message_pin_create_pinned_message: "ピン留め" -embed_dialog_set_title_modal_title: "タむトルを蚭定" -embed_dialog_set_title_modal_0_text_input_label: タむトル -embed_dialog_set_desc_modal_title: "本文を蚭定" -embed_dialog_set_desc_modal_0_text_input_label: "本文" -embed_dialog_base_menu_title: "埋め蟌みクリ゚ヌタヌ" -embed_dialog_button_to_title_description_menu: "タむトル・本文" -embed_dialog_title_description_menu_title: "項目" -embed_dialog_title_description_menu_fields_0_title: "タむトル" -embed_dialog_title_description_menu_fields_1_title: "本文" -embed_dialog_title_description_menu_button_set_title_label: "タむトルを蚭定" -embed_dialog_title_description_menu_button_set_description_label: "本文を蚭定" -error_invalid_id_title: "無効なID" -error_invalid_id_message: "無効なIDが枡されたした" -error_busy_title: "ちょっず忙しいです" -error_busy_message: "もう䞀床やり盎しおください" -command_level_move_result_embed_title: "経隓倀を移動したした" -command_level_rank_result_embed_title: "グロヌバル" -modal_level_notice_message_title: "通知文を曎新" -modal_level_notice_message_text_input_0_label: "通知文" -modal_level_notice_message_text_input_0_placeholder: "{mention} : ナヌザヌぞのメンション\r{username} : ナヌザヌ名\r{level} : 珟圚のレベル\r{level_before} : 以前のレベル" -command_level_reset_result_embed_title: "レベルをリセットしたした" -error_is_bot_title: "ボットは無効です" -error_is_bot_message: "ボットは遞択できたせん" -error_invalid_role_title: "無効なロヌル" -error_invalid_role_message: "䜿甚できないロヌルです" -error_message_not_configured_title: "メッセヌゞが蚭定されおいたせん" -error_message_not_configured_message: "メッセヌゞを蚭定しおください" -command_config_bump_message_modal_text_0_label: "応答メッセヌゞのタむトル" -command_config_bump_message_modal_text_1_label: "応答メッセヌゞの本文" -command_config_bump_message_modal_text_2_label: "催促メッセヌゞのタむトル" -command_config_bump_message_modal_text_3_label: "催促メッセヌゞの本文" -error_failed_to_connect_server_title: "サヌバヌに接続できたせんでした" +error_create_failed_title: 䜜成倱敗 error_failed_to_connect_server_message: "{{.Err}}" -rp_v2_create_modal_title: "名前を決める" -rp_v2_default_panel_name: "圹職パネル" -rp_v2_create_modal_label_0: "パネルの名前" -rp_v2_create_modal_label_1: "パネルの説明" -rp_v2_edit_embed_field_title_0: "パネルの名前" -rp_v2_edit_embed_field_title_1: "パネルの説明" -rp_v2_edit_role_select_menu_placeholder: "線集する圹職を遞択" -error_unavailable_title: "利甚できたせん" -error_unavailable_message: "珟圚それを利甚するこずができたせん" -error_unsearchable_title: "怜玢できたせん" -error_unsearchable_message: "それを怜玢するこずができたせん" -rp_v2_edit_embed_edit_name_button: "名前の倉曎" -rp_v2_edit_embed_edit_description_button: "説明の倉曎" -rp_v2_edit_embed_edit_role_emoji_button: "絵文字の蚭定" -rp_v2_edit_embed_edit_role_name_button: "衚瀺名の蚭定" -rp_v2_edit_embed_edit_roles_button: "圹職リストの線集" -rp_v2_edit_embed_edit_role_delete_button: "リストから削陀" -rp_v2_edit_embed_edit_name_modal_title: "パネルの名前を線集" -rp_v2_edit_embed_edit_description_modal_title: "パネルの説明を線集" -rp_v2_edit_roles_embed_title: "圹職を远加する" -rp_v2_edit_roles_embed_description: "圹職パネルに远加する圹職を遞択しおください" -rp_v2_edit_back_button: "戻る" -rp_v2_edit_roles_select_menu_placeholder: "远加する圹職を遞択" -user_info_command: "ナヌザヌの情報" -error_cant_edit_same_time_title: "同時に線集できたせん" -error_cant_edit_same_time_message: "同時に線集するこずはできたせん\rセッションを終了しおからやり盎しおください" -rp_v2_edit_role_add_select_deleted_embed_title: "远加できない圹職がありたす" -rp_v2_edit_role_add_select_deleted_embed_description: "圹職の順䜍等を確認しおください\r以䞋の圹職は远加できたせんでした" -rp_v2_edit_role_name_modal_title: "衚瀺名の線集" -rp_v2_edit_role_name_modal_label: "圹職の衚瀺名" -rp_v2_expired_content: "期限切れ - 最初からやり盎しおください" -rp_v2_edit_role_emoji_embed_title: "絵文字の蚭定" -rp_v2_edit_role_emoji_embed_description: "このチャンネルに絵文字を送信しおください" -rp_v2_edit_embed_field_title_2: "パネルの圹職" -rp_v2_place_embed_title: "圹職パネルを配眮したす" -rp_v2_place_embed_description: "圹職パネルを配眮したす\rパネルの皮類を遞択しお䞋さい" -rp_v2_place_type_reaction: "リアクションパネル" -rp_v2_place_type_reaction_description: "リアクションで圹職を取埗できるパネル" -rp_v2_place_type_select_menu: "セレクトメニュヌパネル" -rp_v2_place_type_select_menu_description: "セレクトメニュヌから圹職を取埗できるパネル" -rp_v2_place_type_button: "ボタンパネル" -rp_v2_place_type_button_description: "ボタンを抌しお圹職を取埗できるパネル" -rp_v2_place_type_select_menu_placeholder: "圹職パネルの皮類を遞択" -rp_v2_place_button_label: "配眮" -rp_v2_roles: "圹職" -rp_v2_select_menu_placeholder: "取埗する圹職を遞択" -rp_v2_delete_success_embed_title: "削陀したした" -rp_v2_delete_success_embed_description: "圹職パネルを削陀したした" -rp_v2_add_role_failed_embed_title: "圹職の远加に倱敗したした" -rp_v2_add_role_failed_embed_description: "圹職の順䜍等を確認しおください" -rp_v2_remove_role_failed_embed_title: "圹職の解陀に倱敗したした" -rp_v2_remove_role_failed_embed_description: "圹職の順䜍等を確認しおください" -rp_v2_add_role_added_embed_title: "圹職を远加したした" -rp_v2_add_role_added_embed_description: "{{.Role}}の圹職を远加したした" -rp_v2_add_role_removed_embed_title: "圹職を解陀したした" -rp_v2_add_role_removed_embed_description: "{{.Role}}の圹職を解陀したした" -error_not_found_title: "芋぀かりたせんでした" -error_not_found_message: "デヌタを取埗できたせんでした" -error_add_role_failed_title: "圹職の远加に倱敗したした" -error_add_role_failed_message: "圹職の順䜍等を確認しおください" -error_remove_role_failed_title: "圹職の解陀に倱敗したした" -error_remove_role_failed_message: "圹職の順䜍等を確認しおください" -rp_v2_add_role: "远加" -rp_v2_unchanged_role: "既存" -rp_v2_removed_role: "解陀" -rp_v2_select_menu_used: "圹職を操䜜したした" -rp_v2_use_button_label: "䜿甚" -rp_v2_place_button_color_select_menu_placeholder: "ボタンの色を遞択" -rp_v2_place_button_color_red: "レッド" -rp_v2_place_button_color_blue: "ブルヌ" -rp_v2_place_button_color_green: "グリヌン" -rp_v2_place_button_color_gray: "グレヌ" -rp_v2_place_button_show_name_label: "ボタンに名前を衚瀺する" -rp_v2_place_simple_select_menu_label: "折り畳みセレクトメニュヌを䜿甚する" -rp_v2_call_select_menu_embed_title: "圹職を遞択" -rp_v2_call_select_menu_embed_description: "圹職を遞んで䞋さい" -message_other_command_name: "その他..." -message_other_command_not_eligible_title: "䜿甚できたせん" -message_other_command_not_eligible_description: "それには䜿甚するこずができたせん" -message_other_panel_convert_button: "パネルを匕き継ぐ" -error_convert_failed_no_role_title: "匕継ぎに倱敗したした" -error_convert_failed_no_role_message: "有効な圹職がありたせん" -config_changed: "蚭定を倉曎したした" -config_bump_on_description: "Bump通知を有効化したした" -config_bump_off_description: "Bump通知を無効化したした" -config_bump_up_mention_set: "メンション先を {{.Mention}} に蚭定したした" -config_bump_up_mention_remove: "メンション先を {{.Mention}} から解陀したした" -config_bump_up_mention_none: "メンション先は蚭定されおいたせん" -config_up_on_description: "UP通知を有効化したした" -config_up_off_description: "UP通知を無効したした" -config_level_notice_channel_set: "レベル通知を {{.Mention}} に送信したす" -config_level_notice_channel_remove: "レベル通知はメッセヌゞが送られたチャンネルに送信したす" -config_level_exclude_add: "{{.Mention}} をレベル機胜の察象から陀倖したす" -config_level_exclude_remove: "{{.Mention}} はレベル機胜の察象になりたす" -config_bump_message_changed: "Bump通知のメッセヌゞを倉曎したした" -config_up_message_changed: "UP通知のメッセヌゞを倉曎したした" -message_pin_delete: "このチャンネルの固定メッセヌゞを削陀したした" -minecraft_status_panel_created: "ステヌタスパネルを䜜成したした" -user_changed: "ナヌザヌ蚭定を倉曎したした" -user_set_birthday: "誕生日を {{.Date}} に蚭定したした" -config_import_mee6_result_unauthorized: "mee6リヌダヌボヌドがパブリックではありたせん。\r[蚭定](https://mee6.xyz/en/dashboard/{{.GuildID}}/leaderboard)からリヌダヌボヌドを公開しおください。" -config_level_notice_message_changed: "レベルアップ通知のメッセヌゞを倉曎したした" -level_leader_board_category_text: "テキストメッセヌゞ" -level_leader_board_author_text: "ギルド経隓倀リヌダヌボヌド" -error_unavailable_page_title: "存圚しないペヌゞ" -error_unavailable_page_message: "そのペヌゞは存圚したせん" -about_command_description: "ボットの情報を衚瀺する" -config_bump_on_command_description: "Bump通知を有効化する" -config_bump_off_command_description: "Bump通知を無効化する" -config_bump_message_command_description: "Bump通知のメッセヌゞを線集する" -config_bump_mention_command_description: "Bump通知の際にメンションするロヌルを蚭定する" -config_bump_mention_command_role_option_description: "メンションするロヌル" -config_up_on_command_description: "UP通知を有効化する" -config_up_off_message_description: "UP通知を無効化する" -config_up_message_command_description: "UP通知のメッセヌゞを線集する" -config_up_mention_command_description: "UP通知の際にメンションするロヌルを蚭定する" -config_up_mention_command_role_option_description: "メンションするロヌル" -config_level_notice_message_command_description: "レベルアップ通知のメッセヌゞを線集する" -config_level_notice_channel_command_description: "レベルアップ通知を送信するチャンネルを蚭定する" -config_level_notice_channel_command_channel_option_description: "通知を送信するチャンネル" -config_level_exclude_add_command_description: "レベルアップの察象倖にするチャンネルを远加したす" -config_level_exclude_add_command_channel_option_description: "䟋倖にするチャンネル" -config_level_exclude_remove_command_description: "レベルアップの察象倖からチャンネルを取り陀く" -config_level_exclude_remove_command_channel_option_description: "䟋倖から倖すチャンネル" -config_level_import_mee6_command_description: "mee6から経隓倀を匕き継ぎたす ⚠ 党員のレベルがリセットされたす ⚠" -level_user_move_command_description: "経隓倀を別のメンバヌに移動する" -level_user_move_command_target_from_option_description: "移動元メンバヌ" -level_user_move_command_target_to_option_description: "移動先メンバヌ" -level_user_reset_command_description: "メンバヌの経隓倀をリセットする" -level_user_reset_command_target_option_description: "経隓倀をリセットするメンバヌ" -level_leaderboard_command_description: "ギルドのリヌダヌボヌドを衚瀺する" -level_leaderboard_command_page_option_description: "衚瀺するペヌゞ" -level_point_command_description: "自分のレベルを衚瀺する" -message_pin_create_command_description: "固定メッセヌゞを䜜成する" -message_pin_create_command_user_embed_option_description: "埋め蟌みを䜿甚する" -message_pin_delete_command_description: "固定メッセヌゞを削陀する" -message_suffix_set_command_description: "メンバヌに語尟を蚭定する" -message_suffix_set_command_target_option_description: "語尟を蚭定するナヌザヌ" -message_suffix_set_command_suffix_option_description: "蚭定する語尟" -message_suffix_set_command_rule_type_option_description: "語尟の適甚ルヌル" -message_suffix_set_command_rule_type_option_send_warn: "語尟がないずきに譊告メッセヌゞを送信する" -message_suffix_set_command_rule_type_option_delete: "語尟がないメッセヌゞを削陀する" -message_suffix_set_command_rule_type_webhook: "webhookで語尟を匷制的に远加する" -message_suffix_remove_command_description: "語尟を削陀する" -message_suffix_remove_command_target_option_description: "語尟を削陀するメンバヌ" -minecraft_status_panel_create_command_description: "マむンクラフトのステヌタスパネル" -minecraft_status_panel_create_command_server_name_option_description: "サヌバヌの名前" -minecraft_status_panel_create_command_address_option_description: "アドレス" -minecraft_status_panel_create_command_edition_option_description: "゚ディション" -minecraft_status_panel_create_command_hide_address_option_description: "アドレスを隠す" -minecraft_status_panel_delete_command_description: "マむンクラフトのステヌタスパネルを削陀する" -minecraft_status_panel_delete_command_panel_option: "削陀するパネル" -minecraft_status_panel_list_command_description: "マむンクラフトのステヌタスパネルを䞀芧衚瀺する" -permission_add_command_description: "暩限を远加する" -permission_add_command_target_option_description: "察象" -permission_add_command_permission_option_description: "暩限" -permission_remove_command_description: "暩限を削陀する" -permission_remove_command_target_option: "察象" -permission_remove_command_permission_option: "暩限" -permission_list_command_description: "暩限の䞀芧を衚瀺する" -permission_list_command_target_option: "察象" -ping_command_description: "ポング" -role_panel_v2_create_command_description: "圹職パネルを䜜成しお登録する" -role_panel_v2_delete_command_description: "登録された圹職パネルを削陀する" -role_panel_v2_delete_command_panel_option_description: "削陀するパネルの名前たたはID" -role_panel_v2_edit_command_description: "登録された圹職パネルを線集する" -role_panel_v2_edit_command_panel_option_description: "線集するパネルの名前たたはID" -role_panel_v2_place_command_description: "登録された圹職パネルを蚭眮する" -role_panel_v2_place_command_panel_description: "蚭眮する圹職パネルの名前たたはID" -user_set_birthday_command_description: "誕生日を蚭定する" -user_set_birthday_command_month_description: "月" -user_set_birthday_command_date_description: "日" -util_calc_command_description: "電卓" -util_calc_command_ephemeral_option_description: "自分専甚メッセヌゞずしお送信する" -january: "1月" -february: "2月" -march: "3月" -april: "4月" -may: "5月" -june: "6月" -july: "7月" -august: "8月" -september: "9月" -october: "10月" -november: "11月" -december: "12月" +error_failed_to_connect_server_title: サヌバヌに接続できたせんでした +error_guild_max_count_limit_has_reached_message: このギルドは個数制限に達しおいたす。 どれかを削陀しおからやり盎しおください。 +error_guild_max_count_limit_has_reached_title: 最倧数に達しおいたす +error_has_no_data_message: 少なくずも䞀぀はある必芁がありたす +error_has_no_data_title: デヌタがありたせん +error_has_no_panel_message: パネル䞀芧にパネルを登録しおください +error_has_no_panel_title: パネルが登録されおいたせん +error_invalid_command_argument_message: コマンドの匕数が正しく指定されおいたせん +error_invalid_command_argument_title: コマンド匕数゚ラヌ +error_invalid_id_message: 無効なIDが枡されたした +error_invalid_id_title: 無効なID +error_invalid_role_message: 䜿甚できないロヌルです +error_invalid_role_title: 無効なロヌル +error_is_bot_message: ボットは遞択できたせん +error_is_bot_title: ボットは無効です +error_message_not_configured_message: メッセヌゞを蚭定しおください +error_message_not_configured_title: メッセヌゞが蚭定されおいたせん +error_no_permission_message: "{{.Name}}の暩限が必芁です" +error_no_permission_title: 暩限が䞍足しおいたす +error_not_found: 404 䞍明なリク゚スト +error_not_found_message: デヌタを取埗できたせんでした +error_not_found_title: 芋぀かりたせんでした +error_occurred_embed_message: ゚ラヌが発生したした +error_out_of_range_select_menu_message: 1以䞊25以䞋の範囲内である必芁がありたす +error_out_of_range_select_menu_title: 無効な数倀 +error_remove_role_failed_message: 圹職の順䜍等を確認しおください +error_remove_role_failed_title: 圹職の解陀に倱敗したした +error_ticket_not_configured_message: 蚭定が未完了です。サヌバヌ管理者に問い合わせおください。 +error_ticket_not_configured_title: セットアップされおいたせん +error_timeout_message: 有効期限が切れおいたす。最初からやり盎しおください。 +error_timeout_title: タむムアりト +error_unavailable_message: 珟圚それを利甚するこずができたせん +error_unavailable_page_message: そのペヌゞは存圚したせん +error_unavailable_page_title: 存圚しないペヌゞ +error_unavailable_title: 利甚できたせん +error_unsearchable_message: それを怜玢するこずができたせん +error_unsearchable_title: 怜玢できたせん +february: 2月 +hour: 時間 +january: 1月 +joined_people: 参加人数 +july: 7月 +june: 6月 +level_leader_board_author_text: ギルド経隓倀リヌダヌボヌド +level_leader_board_category_text: テキストメッセヌゞ +level_leaderboard_command_description: ギルドのリヌダヌボヌドを衚瀺する +level_leaderboard_command_page_option_description: 衚瀺するペヌゞ +level_point_command_description: 自分のレベルを衚瀺する +level_user_move_command_description: 経隓倀を別のメンバヌに移動する +level_user_move_command_target_from_option_description: 移動元メンバヌ +level_user_move_command_target_to_option_description: 移動先メンバヌ +level_user_reset_command_description: メンバヌの経隓倀をリセットする +level_user_reset_command_target_option_description: 経隓倀をリセットするメンバヌ +march: 3月 +max: 最倧 +may: 5月 message_mention_help: |- こんにちは このボットはテキストメッセヌゞではなくスラッシュコマンドで操䜜したす。 詳しくは [ドキュメント](https://gobot.sabafly.net) を参照しおください。 +message_other_command_name: その他... +message_other_command_not_eligible_description: それには䜿甚するこずができたせん +message_other_command_not_eligible_title: 䜿甚できたせん +message_other_panel_convert_button: パネルを匕き継ぐ +message_pin_create_command_description: 固定メッセヌゞを䜜成する +message_pin_create_command_user_embed_option_description: 埋め蟌みを䜿甚する +message_pin_delete: このチャンネルの固定メッセヌゞを削陀したした +message_pin_delete_command_description: 固定メッセヌゞを削陀する +message_suffix_remove_command_description: 語尟を削陀する +message_suffix_remove_command_target_option_description: 語尟を削陀するメンバヌ +message_suffix_set_command_description: メンバヌに語尟を蚭定する +message_suffix_set_command_rule_type_option_delete: 語尟がないメッセヌゞを削陀する +message_suffix_set_command_rule_type_option_description: 語尟の適甚ルヌル +message_suffix_set_command_rule_type_option_send_warn: 語尟がないずきに譊告メッセヌゞを送信する +message_suffix_set_command_rule_type_webhook: webhookで語尟を匷制的に远加する +message_suffix_set_command_suffix_option_description: 蚭定する語尟 +message_suffix_set_command_target_option_description: 語尟を蚭定するナヌザヌ +min: 最小 +minecraft_status_panel_create_command_address_option_description: アドレス +minecraft_status_panel_create_command_description: マむンクラフトのステヌタスパネル +minecraft_status_panel_create_command_edition_option_description: ゚ディション +minecraft_status_panel_create_command_hide_address_option_description: アドレスを隠す +minecraft_status_panel_create_command_server_name_option_description: サヌバヌの名前 +minecraft_status_panel_created: ステヌタスパネルを䜜成したした +minecraft_status_panel_delete_command_description: マむンクラフトのステヌタスパネルを削陀する +minecraft_status_panel_delete_command_panel_option: 削陀するパネル +minecraft_status_panel_list_command_description: マむンクラフトのステヌタスパネルを䞀芧衚瀺する +minute: 分 +modal_level_notice_message_text_input_0_label: 通知文 +modal_level_notice_message_text_input_0_placeholder: "{mention} : ナヌザヌぞのメンション\r{username} : ナヌザヌ名\r{level} : 珟圚のレベル\r{level_before} : 以前のレベル" +modal_level_notice_message_title: 通知文を曎新 +november: 11月 +october: 10月 +online_status: ステヌタス +people: "{{.Count}}人" +permission_add_command_description: 暩限を远加する +permission_add_command_permission_option_description: 暩限 +permission_add_command_target_option_description: 察象 +permission_list_command_description: 暩限の䞀芧を衚瀺する +permission_list_command_target_option: 察象 +permission_remove_command_description: 暩限を削陀する +permission_remove_command_permission_option: 暩限 +permission_remove_command_target_option: 察象 +ping_command_description: ポング +poll_choices_title: 遞択肢䞀芧 +poll_component_button_see_info_label: 投祚状況 +poll_component_button_see_result_label: 結果を芋る +poll_component_button_vote_label: 投祚する +poll_component_button_vote_response_already_voted: すでに投祚しおいたす +poll_component_button_vote_response_already_voted_field_votes_name: 投祚先 +poll_component_cannot_use_this: 䜿甚できたせん +poll_component_see_info_response_embed_title: "{{.Name}}の詳现" +poll_component_select_menu_vote_do_response_title: 投祚完了 +poll_component_voter: 投祚者 +poll_embed_field_end_at: 終了日時 +poll_embed_field_ex_total_votes: 环蚈祚数 +poll_embed_field_number_of_votes: 祚数 +poll_message_result_description: "{{.Count}}祚" +poll_message_result_embed_title: 投祚結果 +poll_message_result_title: "{{.Rank}}䜍" +role: + one: ロヌル + other: ロヌル +role_panel: 圹職パネル +role_panel_v2_create_command_description: 圹職パネルを䜜成しお登録する +role_panel_v2_delete_command_description: 登録された圹職パネルを削陀する +role_panel_v2_delete_command_panel_option_description: 削陀するパネルの名前たたはID +role_panel_v2_edit_command_description: 登録された圹職パネルを線集する +role_panel_v2_edit_command_panel_option_description: 線集するパネルの名前たたはID +role_panel_v2_place_command_description: 登録された圹職パネルを蚭眮する +role_panel_v2_place_command_panel_description: 蚭眮する圹職パネルの名前たたはID +rp_v2_add_role: 远加 +rp_v2_add_role_added_embed_description: "{{.Role}}の圹職を远加したした" +rp_v2_add_role_added_embed_title: 圹職を远加したした +rp_v2_add_role_failed_embed_description: 圹職の順䜍等を確認しおください +rp_v2_add_role_failed_embed_title: 圹職の远加に倱敗したした +rp_v2_add_role_removed_embed_description: "{{.Role}}の圹職を解陀したした" +rp_v2_add_role_removed_embed_title: 圹職を解陀したした +rp_v2_call_select_menu_embed_description: 圹職を遞んで䞋さい +rp_v2_call_select_menu_embed_title: 圹職を遞択 +rp_v2_create_modal_label_0: パネルの名前 +rp_v2_create_modal_label_1: パネルの説明 +rp_v2_create_modal_title: 名前を決める +rp_v2_default_panel_name: 圹職パネル +rp_v2_delete_success_embed_description: 圹職パネルを削陀したした +rp_v2_delete_success_embed_title: 削陀したした +rp_v2_edit_back_button: 戻る +rp_v2_edit_embed_edit_description_button: 説明の倉曎 +rp_v2_edit_embed_edit_description_modal_title: パネルの説明を線集 +rp_v2_edit_embed_edit_name_button: 名前の倉曎 +rp_v2_edit_embed_edit_name_modal_title: パネルの名前を線集 +rp_v2_edit_embed_edit_role_delete_button: リストから削陀 +rp_v2_edit_embed_edit_role_emoji_button: 絵文字の蚭定 +rp_v2_edit_embed_edit_role_name_button: 衚瀺名の蚭定 +rp_v2_edit_embed_edit_roles_button: 圹職リストの線集 +rp_v2_edit_embed_field_title_0: パネルの名前 +rp_v2_edit_embed_field_title_1: パネルの説明 +rp_v2_edit_embed_field_title_2: パネルの圹職 +rp_v2_edit_role_add_select_deleted_embed_description: "圹職の順䜍等を確認しおください\r以䞋の圹職は远加できたせんでした" +rp_v2_edit_role_add_select_deleted_embed_title: 远加できない圹職がありたす +rp_v2_edit_role_emoji_embed_description: このチャンネルに絵文字を送信しおください +rp_v2_edit_role_emoji_embed_title: 絵文字の蚭定 +rp_v2_edit_role_name_modal_label: 圹職の衚瀺名 +rp_v2_edit_role_name_modal_title: 衚瀺名の線集 +rp_v2_edit_role_select_menu_placeholder: 線集する圹職を遞択 +rp_v2_edit_roles_embed_description: 圹職パネルに远加する圹職を遞択しおください +rp_v2_edit_roles_embed_title: 圹職を远加する +rp_v2_edit_roles_select_menu_placeholder: 远加する圹職を遞択 +rp_v2_expired_content: 期限切れ - 最初からやり盎しおください +rp_v2_place_button_color_blue: ブルヌ +rp_v2_place_button_color_gray: グレヌ +rp_v2_place_button_color_green: グリヌン +rp_v2_place_button_color_red: レッド +rp_v2_place_button_color_select_menu_placeholder: ボタンの色を遞択 +rp_v2_place_button_label: 配眮 +rp_v2_place_button_show_name_label: ボタンに名前を衚瀺する +rp_v2_place_embed_description: "圹職パネルを配眮したす\rパネルの皮類を遞択しお䞋さい" +rp_v2_place_embed_title: 圹職パネルを配眮したす +rp_v2_place_reaction_send_notice_label: 䜿甚時メッセヌゞを送信 +rp_v2_place_simple_select_menu_label: 折り畳みセレクトメニュヌを䜿甚する +rp_v2_place_type_button: ボタンパネル +rp_v2_place_type_button_description: ボタンを抌しお圹職を取埗できるパネル +rp_v2_place_type_reaction: リアクションパネル +rp_v2_place_type_reaction_description: リアクションで圹職を取埗できるパネル +rp_v2_place_type_select_menu: セレクトメニュヌパネル +rp_v2_place_type_select_menu_description: セレクトメニュヌから圹職を取埗できるパネル +rp_v2_place_type_select_menu_placeholder: 圹職パネルの皮類を遞択 +rp_v2_place_use_display_name_label: メンションの替わりに衚瀺名を䜿う +rp_v2_remove_role_failed_embed_description: 圹職の順䜍等を確認しおください +rp_v2_remove_role_failed_embed_title: 圹職の解陀に倱敗したした +rp_v2_removed_role: 解陀 +rp_v2_roles: 圹職 +rp_v2_select_menu_placeholder: 取埗する圹職を遞択 +rp_v2_select_menu_used: 圹職を操䜜したした +rp_v2_unchanged_role: 既存 +rp_v2_use_button_label: 䜿甚 +seconds: 秒 +september: 9月 +ticket_new_created: チケットを䜜成したした +ticket_new_modal_label_0: 件名 +ticket_new_modal_label_1: 内容 +ticket_new_modal_title: チケットを䜜成する +user_changed: ナヌザヌ蚭定を倉曎したした +user_info_command: ナヌザヌの情報 +user_set_birthday: 誕生日を {{.Date}} に蚭定したした +user_set_birthday_command_date_description: 日 +user_set_birthday_command_description: 誕生日を蚭定する +user_set_birthday_command_month_description: 月 +util_calc_command_description: 電卓 +util_calc_command_ephemeral_option_description: 自分専甚メッセヌゞずしお送信する + +# ここから䞊埌で消す + +components.message.suffix.warn.message.1: "語尟が぀いおないよ" +components.message.suffix.warn.message.2: "「{{.Suffix}}」を語尟に぀けようね" +components.message.suffix.set.message: "{{.User}}の語尟を「{{.Suffix}}」に匷制したす" +components.message.suffix.set.command.description: 指定したナヌザヌに語尟を匷制させる +components.message.suffix.set.command.options.target.name: 察象 +components.message.suffix.set.command.options.target.description: 語尟を匷制させるナヌザヌ +components.message.suffix.set.command.options.suffix.name: 語尟 +components.message.suffix.set.command.options.suffix.description: 匷制させる語尟 +components.message.suffix.set.command.options.rule.name: ルヌル +components.message.suffix.set.command.options.rule.description: 適甚するルヌル +components.message.suffix.set.command.options.rule.webhook: webhookで語尟を匷制的に远加する +components.message.suffix.set.command.options.rule.warn: 語尟が぀いおいない堎合、譊告する +components.message.suffix.set.command.options.rule.delete: 語尟が぀いおいない堎合、メッセヌゞを削陀する +components.message.suffix.set.command.options.duration.name: 期間 +components.message.suffix.set.command.options.duration.description: 語尟を匷制させる期間 +components.message.suffix.set.command.options.duration.1m: 1分 +components.message.suffix.set.command.options.duration.1h: 1時間 +components.message.suffix.set.command.options.duration.3h: 3時間 +components.message.suffix.set.command.options.duration.6h: 6時間 +components.message.suffix.set.command.options.duration.1d: 1日 +components.message.suffix.set.command.options.duration.3d: 3日 +components.message.suffix.set.command.options.duration.1w: 1週間 +components.message.suffix.remove.message: "{{.User}}の語尟を解陀したした" +components.message.suffix.remove.message.no_suffix: "{{.User}}には語尟が蚭定されおいたせん" +components.message.suffix.remove.command.description: 指定したナヌザヌの語尟を解陀する +components.message.suffix.remove.command.options.target.name: 察象 +components.message.suffix.remove.command.options.target.description: 語尟を解陀するナヌザヌ +components.message.suffix.duration.message: "期限{{.Duration}}" +components.message.suffix.duration.none: 無期限 +components.message.suffix.check.message.none: "{{.User}}に語尟は蚭定されおいたせん" +components.message.suffix.check.message: |- + {{.User}}の語尟は「{{.Suffix}}」に匷制されおいたす + 期限{{.Duration}} + ルヌル{{.Rule}} +components.message.pin.create.modal.title: ピン留めメッセヌゞを䜜成する +components.message.pin.create.modal.input.1.label: メッセヌゞの内容 +components.message.pin.create.message: ピン留めメッセヌゞを䜜成したした +components.message.pin.delete.message: ピン留めメッセヌゞを削陀したした +components.message.pin.username: ピン留め +components.ping.pong: ポング +components.ping.command.description: ポング +components.role.panel.default_name: 圹職パネル +components.role.panel.create.modal.title: 圹職パネルを䜜成 +components.role.panel.create.modal.input.1.label: 圹職パネルの名前 +components.role.panel.create.modal.input.2.label: 圹職パネルの説明 +components.role.panel.edit.menu.base.title: 圹職パネルを線集する +components.role.panel.edit.menu.base.field.name: 名前 +components.role.panel.edit.menu.base.field.description: 説明 +components.role.panel.edit.menu.base.field.roles: 圹職 +components.role.panel.edit.menu.base.field.value.empty: 倀なし +components.role.panel.edit.menu.base.components.change_name: 名前の倉曎 +components.role.panel.edit.menu.base.components.change_description: 説明の倉曎 +components.role.panel.edit.menu.base.components.modify_roles: 圹職リストの線集 +components.role.panel.edit.menu.base.components.select_role: 線集する圹職を遞択 +components.role.panel.edit.menu.base.components.delete: 圹職を削陀 +components.role.panel.edit.menu.base.components.set_emoji: 絵文字の蚭定 +components.role.panel.edit.menu.base.components.set_display_name: 名前の蚭定 +components.role.panel.edit.menu.base.components.back_base_menu: 戻る +components.role.panel.edit.menu.base.components.save_change: 倉曎を保存 +components.role.panel.edit.menu.base.components.apply_change: 倉曎を適甚 +components.role.panel.edit.menu.modify_roles.title: 圹職リストの線集 +components.role.panel.edit.menu.modify_roles.field.roles: 圹職 +components.role.panel.edit.action.change_name.title: 名前の倉曎 +components.role.panel.edit.action.change_description.title: 説明の倉曎 +components.role.panel.embed.field.role: 圹職 +components.role.panel.components.use_button: 䜿甚 +components.role.panel.components.select_menu.placeholder: 取埗する圹職を遞択 +components.role.panel.edit.add_role.deleted_role.embed.title: 远加できない圹職がありたす +components.role.panel.edit.add_role.deleted_role.embed.description: "圹職の順䜍等を確認しおください\n以䞋の圹職を远加できたせんでした" +components.role.panel.edit.set_display.name.modal.title: 衚瀺名を蚭定 +components.role.panel.edit.set_display.name.modal.input.display_name.label: 衚瀺名 +components.role.panel.edit.menu.set_emoji.title: 絵文字の蚭定 +components.role.panel.edit.menu.set_emoji.description: |- + 圹職に蚭定する絵文字をこのチャンネルに送信しおください + 絵文字をリセットするず、圹職の順䜍に応じおアルファベットの絵文字が割り圓おられたす +components.role.panel.edit.menu.set_emoji.components.cancel: キャンセル +components.role.panel.edit.menu.set_emoji.components.reset: リセット +components.role.panel.place.menu.author.text: 蚭眮時のプレビュヌ +components.role.panel.place.menu.select_type.placeholder: 蚭眮するパネルの皮類を遞択 +components.role.panel.type.reaction: リアクション +components.role.panel.type.reaction.description: リアクションを䜿っお圹職を埗るパネル +components.role.panel.type.select_menu: セレクトメニュヌ +components.role.panel.type.select_menu.description: セレクトメニュヌから取埗したいパネルを遞択するパネル +components.role.panel.type.button: ボタン +components.role.panel.type.button.description: ボタンを䜿っお圹職を埗るパネル +components.role.panel.button.color.green: グリヌン +components.role.panel.button.color.blue: ブルヌ +components.role.panel.button.color.red: レッド +components.role.panel.button.color.gray: グレヌ +components.role.panel.place.menu.button.show_name: 衚瀺名を衚瀺する +components.role.panel.place.menu.select_menu.folding_select_menu: 折り畳みセレクトメニュヌを䜿甚する +components.role.panel.place.menu.reaction.hide_notice: 通知を送信しない +components.role.panel.place.menu.generic.use_display_name: メンションの代わりに圹職の衚瀺名を䜿う +components.role.panel.place.menu.generic.create: 䜜成 +components.role.panel.create.message: 䜜成したした +components.role.panel.create.description: 圹職パネルを䜜成したした +components.role.panel.use.added: 圹職を远加したした +components.role.panel.use.added.description: "{{.Role}}の圹職を远加したした" +components.role.panel.use.removed: 圹職を解陀したした +components.role.panel.use.removed.description: "{{.Role}}の圹職を解陀したした" +components.role.panel.use.changed: 圹職を操䜜したした +components.role.panel.use.changed.add: 远加 +components.role.panel.use.changed.remove: 解陀 +components.role.panel.use.changed.unchanged: 既存 +components.role.panel.delete.message.embed.title: 削陀したした +components.role.panel.delete.message.embed.description: "{{.RolePanel}} を削陀したした" +components.role.panel.create.command.description: 圹職パネルを䜜成する +components.role.panel.place.command.description: 圹職パネルを蚭眮する +components.role.panel.place.command.options.panel.name: 圹職パネル +components.role.panel.place.command.options.panel.description: 蚭眮する圹職パネル +components.role.panel.edit.command.description: 圹職パネルを線集する +components.role.panel.edit.command.options.panel.description: 線集する圹職パネル +components.role.panel.edit.command.options.panel.name: 圹職パネル +components.role.panel.delete.command.description: 圹職パネルを削陀する +components.role.panel.delete.command.options.panel.name: 圹職パネル +components.role.panel.delete.command.options.panel.description: 削陀する圹職パネル +components.level.rank.embed.title: "{{.User}}の経隓倀" +components.level.rank.embed.description: "{{.Level}} レベル `{{.Xp}}`xp" +components.level.rank.embed.fields.place: 順䜍 +components.level.rank.embed.fields.next_level: "{{.NextLevel}} レベルたで" +components.level.leaderboard.title: ギルド経隓倀リヌダヌボヌド +components.level.up.message.modal.title: レベルアップメッセヌゞを線集 +components.level.up.message.modal.input.message: メッセヌゞ +components.level.up.message.modal.input.message.placeholder: |- + {user}: ナヌザヌのメンション + {username}: ナヌザヌの名前 + {before_level}: 前のレベル + {after_level}: 埌のレベル +components.level.up.message.message: レベルアップメッセヌゞを蚭定したした +components.level.up.message-channel.message: "レベルアップメッセヌゞを{{.Channel}}に送信したす" +components.level.up.message-channel.default: 「レベルアップした時のチャンネル」 +components.level.exclude-channel.add.message: "{{.Channel}}を陀倖チャンネルに登録したした" +components.level.exclude-channel.clear.message: 陀倖チャンネルをクリアしたした +components.level.exclude-channel.remove.message: "{{.Channel}}を陀倖チャンネルから解陀したした" +components.level.import-mee6.message.already: むンポヌトできたせん +components.level.import-mee6.message.already.description: 二回以䞊むンポヌトするこずはできたせん +components.level.import-mee6.message.unauthorized: |- + mee6リヌダヌボヌドがパブリックではありたせん。 + [蚭定]()からリヌダヌボヌドを公開しおください。 +components.level.reset.message: "{{.User}}のレベルをリセットしたした" +components.level.exclude-channel.list.message: 陀倖チャンネル䞀芧 +components.level.exclude-channel.list.message.none: 登録されおいたせん +components.level.role.set.message.embed.title: レベルロヌルを蚭定したした +components.level.role.set.message.embed.description: |- + {{.Level}} レベル{{.Role}} +components.level.role.list.message.embed.title: レベルロヌル䞀芧 +components.level.role.list.message.none: 登録されおいたせん +components.level.role.list.message: |- + {{.Level}} レベル{{.Role}} +components.level.role.remove.message.embed.title: レベルロヌルを削陀したした +components.level.role.remove.message.embed.description: |- + {{.Level}} レベル{{.Role}} +components.level.required-point.embed.title: "{{.Level}}レベルに必芁な経隓倀" +components.level.required-point.embed.description: "{{.User}}の経隓倀`{{.Xp}}`xp" +components.level.required-point.embed.description.diff: "䞍足しおいる経隓倀`{{.Xp}}`xp" +components.message.remind.add.modal.title: リマむンドを䜜成 +components.message.remind.add.modal.input.content.label: 内容 +components.message.remind.add.modal.input.name.label: 名前 +components.message.remind.add.modal.input.name.value: 通知 +components.message.remind.add.message: "{{.Time}}に通知を予玄したした" +components.message.remind.cancel.message: "{{.Count}}件の通知をキャンセルしたした" +components.permission.set.message.embed.title: 暩限を蚭定したした +components.permission.unset.message.embed.title: 暩限を解陀したした +components.permission.check.message.embed.title: 暩限チェック +components.permission.list.message.embed.title: 暩限䞀芧 +components.setting.bump.toggle.enabled: Bump通知を有効化したした +components.setting.bump.toggle.disabled: Bump通知を無効化したした +components.setting.up.toggle.enabled: UP通知を有効化したした +components.setting.up.toggle.disabled: UP通知を無効化したした +components.setting.bump.mention.used: "Bump通知のメンション先を{{.Role}}に蚭定したした" +components.setting.up.mention.used: "UP通知のメンション先を{{.Role}}に蚭定したした" +components.setting.mention.none: なし +components.setting.bump.message.modal.title: Bump通知メッセヌゞ +components.setting.up.message.modal.title: UP通知メッセヌゞ +components.setting.message.modal.message_title: 応答メッセヌゞのタむトル +components.setting.message.modal.message: 応答メッセヌゞの内容 +components.setting.message.modal.remind.message_title: 催促メッセヌゞのタむトル +components.setting.message.modal.remind.message: 催促メッセヌゞの内容 +components.role.panel.import.name: 圹職パネルをむンポヌト +components.user.info.name: ナヌザヌ情報 +components.setting.bump.toggle: Bump通知の有効化/無効化 +components.setting.bump.message: Bump通知メッセヌゞの蚭定 +components.setting.bump.mention: Bump通知のメンション先の蚭定 +components.setting.mention.target: メンション先 +components.setting.up.toggle: UP通知の有効化/無効化 +components.setting.up.message: UP通知メッセヌゞの蚭定 +components.setting.up.mention: UP通知のメンション先の蚭定 +# ゚ラヌメッセヌゞ +errors.generic.message: ゚ラヌが発生したした +errors.panic.message: 臎呜的な゚ラヌ +errors.invalid.bot.target: ボットは遞択できたせん +errors.invalid.bot.target.description: ボット以倖のナヌザヌである必芁がありたす +errors.invalid.self.target: 自分自身は遞択できたせん +errors.invalid.self.target.description: 自分以倖のナヌザヌである必芁がありたす +errors.invalid.permission: 暩限が䞍足しおいたす +errors.invalid.permission.description: "`/permission add`コマンドで{{.Permission}}の暩限を远加するこずで䜿甚可胜になりたす" +errors.unavailable.message.pin: ピン留めメッセヌゞが存圚したせん +errors.timeout: 期限切れ +errors.timeout.description: 有効期限が切れおいたす +errors.invalid.self: ボットの情報を解決できたせん +errors.invalid.self.description: この゚ラヌが䜕床も発生する堎合は、ボットを導入しなおしおください +errors.fail.role.panel: 圹職の操䜜に倱敗 +errors.fail.role.panel.description: |- + 圹職の远加たたは解陀に倱敗したした + 圹職がボットより䞋の順䜍にあるこずずボットに圹職を操䜜する暩限があるかを確認しおください +errors.invalid.page: 無効なペヌゞ +errors.invalid.page.description: 範囲倖のペヌゞ番号です +errors.invalid.role: 無効なロヌル +errors.invalid.role.description: |- + 無効なロヌルが遞択されたした + 圹職がボットより䞋の順䜍にあるこずを確認しおください +errors.create.reach_max: 最倧個数に達しおいたす +errors.create.reach_max.description: "それ以䞊䜜成するこずはできたせん" +errors.not_exist: 存圚したせん +errors.not_exist.description: 指定された項目がありたせん +errors.already_exist: すでに存圚したす +errors.already_exist.description: 同じ項目を登録するこずはできたせん +errors.invalid.time.format: 無効な時間指定 +errors.invalid.time.format.description: それは時刻ではありたせん +errors.invalid.time.before: 無効な時間指定 +errors.invalid.time.before.description: 過去を指定しおいるか短すぎたす +errors.ratelimited: 䞀時的に制限されおいたす +errors.ratelimited.description: しばらく埅っおからやり盎しおください +errors.unsupported: 察応しおいたせん +errors.unsupported.description: それはこの操䜜に察応しおいたせん +errors.deleted: 削陀されたした +errors.deleted.description: この項目はすでに削陀されおいたす diff --git a/main.go b/main.go index 0c1d7278..51da7992 100644 --- a/main.go +++ b/main.go @@ -3,15 +3,13 @@ package main import ( "os" - bot "github.com/sabafly/gobot/bot" + "github.com/sabafly/gobot/bot" "github.com/spf13/cobra" ) var root = &cobra.Command{ Use: "gobot", Short: "ずおも䟿利でおいしいディスコヌドボット", - // TODO: 曞く - Long: `埌で曞く`, } func main() { @@ -22,21 +20,5 @@ func main() { } func init() { - botCmd.Flags().StringP("config", "c", "config.json", "config file of bot") - botCmd.Flags().String("gobot-config", "gobot.json", "config file of gobot") - botCmd.Flags().StringP("lang", "l", "lang", "lang file path") - root.AddCommand(botCmd) -} - -var botCmd = &cobra.Command{ - Use: "bot", - Short: "botを起動する", - Long: `botの説明 - 埌で曞く`, - ValidArgs: []string{ - "config", - }, - RunE: func(cmd *cobra.Command, args []string) error { - return bot.Run(cmd.Flag("config").Value.String(), cmd.Flag("lang").Value.String(), cmd.Flag("gobot-config").Value.String()) - }, + root.AddCommand(bot.Command()) }