Compare commits
46 Commits
@ -0,0 +1,56 @@
|
||||
name: Build Container
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
tags:
|
||||
- "v*"
|
||||
schedule:
|
||||
# daily builds to always include patches in the docker image
|
||||
- cron: '0 4 * * *'
|
||||
|
||||
env:
|
||||
CARGO_TERM_COLOR: always
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Set up toolchain
|
||||
uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
toolchain: stable
|
||||
override: true
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v1
|
||||
- name: Cache Docker layers
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: /var/lib/containers/
|
||||
key: ${{ runner.os }}-podman-${{ hashFiles('Cargo.lock') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-podman-
|
||||
- name: Build
|
||||
id: build-image
|
||||
uses: redhat-actions/buildah-build@v2
|
||||
with:
|
||||
context: .
|
||||
layers: true
|
||||
containerfiles: ./Containerfile
|
||||
platforms: ${{github.event.inputs.platforms}}
|
||||
image: trivernis/tobi
|
||||
- name: Login to DockerHub
|
||||
uses: redhat-actions/podman-login@v1
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
registry: docker.io
|
||||
- name: Push
|
||||
uses: redhat-actions/push-to-registry@v2
|
||||
with:
|
||||
image: ${{ steps.build-image.outputs.image }}
|
||||
tags: ${{ steps.build-image.outputs.tags }}
|
||||
registry: docker.io
|
@ -1,47 +0,0 @@
|
||||
name: Build Docker Container
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
branches: [ main, actions ]
|
||||
|
||||
env:
|
||||
CARGO_TERM_COLOR: always
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Set up toolchain
|
||||
uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
toolchain: stable
|
||||
override: true
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v1
|
||||
- name: Cache Docker layers
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: /tmp/.buildx-cache
|
||||
key: ${{ runner.os }}-buildx-${{ hashFiles('Cargo.lock') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-buildx-
|
||||
- name: Login to DockerHub
|
||||
uses: docker/login-action@v1
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
- name: Build and push
|
||||
uses: docker/build-push-action@v2
|
||||
with:
|
||||
context: .
|
||||
file: ./Dockerfile
|
||||
platforms: ${{github.event.inputs.platforms}}
|
||||
push: true
|
||||
cache-from: type=local,src=/tmp/.buildx-cache
|
||||
cache-to: type=local,dest=/tmp/.buildx-cache
|
||||
tags: |
|
||||
trivernis/tobi:latest
|
@ -0,0 +1,39 @@
|
||||
version: 1
|
||||
when:
|
||||
- event: [pull_request]
|
||||
- event: push
|
||||
branch:
|
||||
- ${CI_REPO_DEFAULT_BRANCH}
|
||||
- release/*
|
||||
- fix/*
|
||||
steps:
|
||||
test:
|
||||
image: rust:alpine
|
||||
commands:
|
||||
- apk add --no-cache --force-overwrite \
|
||||
build-base \
|
||||
openssl-dev \
|
||||
libopusenc-dev \
|
||||
libpq-dev \
|
||||
curl \
|
||||
bash
|
||||
- rustup default stable
|
||||
- rustup component add clippy --toolchain stable-x86_64-unknown-linux-musl
|
||||
- cargo clippy
|
||||
- cargo test --verbose --package bot-coreutils
|
||||
- cargo test --verbose --package bot-database
|
||||
- cargo test --verbose
|
||||
|
||||
build:
|
||||
image: rust:alpine
|
||||
commands:
|
||||
- apk add --no-cache --force-overwrite \
|
||||
build-base \
|
||||
openssl-dev \
|
||||
libopusenc-dev \
|
||||
libpq-dev \
|
||||
curl \
|
||||
bash
|
||||
- cargo build
|
||||
when:
|
||||
- event: [pull_request]
|
@ -0,0 +1,20 @@
|
||||
version: 1
|
||||
when:
|
||||
- event: [tag]
|
||||
branch:
|
||||
- ${CI_REPO_DEFAULT_BRANCH}
|
||||
steps:
|
||||
build:
|
||||
image: woodpeckerci/plugin-docker-buildx
|
||||
secrets: [forgejo_token]
|
||||
settings:
|
||||
dockerfile: Containerfile
|
||||
tag: ${CI_COMMIT_TAG##v}
|
||||
repo: git.trivernis.net/trivernis/2b-rs
|
||||
registry: git.trivernis.net
|
||||
platforms: linux/amd64
|
||||
username:
|
||||
from_secret: forgejo_id
|
||||
password:
|
||||
from_secret: forgejo_token
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,45 @@
|
||||
ARG BASE_IMAGE=docker.io/alpine:edge
|
||||
|
||||
FROM ${BASE_IMAGE} AS build_base
|
||||
RUN apk update
|
||||
RUN apk add --no-cache --force-overwrite \
|
||||
build-base \
|
||||
openssl-dev \
|
||||
libopusenc-dev \
|
||||
libpq-dev \
|
||||
curl \
|
||||
bash
|
||||
RUN curl https://sh.rustup.rs -sSf | bash -s -- -y
|
||||
ENV PATH="/root/.cargo/bin:${PATH}"
|
||||
RUN rm -rf /var/lib/{cache,log}/ /var/cache
|
||||
|
||||
FROM build_base AS builder
|
||||
ENV RUSTFLAGS="-C target-feature=-crt-static"
|
||||
WORKDIR /usr/src
|
||||
RUN cargo new tobi
|
||||
WORKDIR /usr/src/tobi
|
||||
COPY Cargo.toml Cargo.lock ./
|
||||
COPY src ./src
|
||||
COPY bot-coreutils ./bot-coreutils
|
||||
COPY bot-database ./bot-database
|
||||
RUN cargo build --release
|
||||
RUN mkdir /tmp/tobi
|
||||
RUN cp target/release/tobi-rs /tmp/tobi/
|
||||
|
||||
FROM ${BASE_IMAGE} AS runtime-base
|
||||
RUN apk update
|
||||
RUN apk add --no-cache --force-overwrite \
|
||||
openssl \
|
||||
libopusenc \
|
||||
libpq \
|
||||
python3 \
|
||||
py3-pip \
|
||||
qalc \
|
||||
ffmpeg \
|
||||
bash
|
||||
RUN pip3 install yt-dlp --break-system-packages
|
||||
RUN rm -rf /var/lib/{cache,log}/ /var/cache
|
||||
|
||||
FROM runtime-base
|
||||
COPY --from=builder /tmp/tobi/tobi-rs .
|
||||
ENTRYPOINT ["/tobi-rs"]
|
@ -1,33 +0,0 @@
|
||||
# syntax=docker/dockerfile:1.0-experimental
|
||||
FROM rust:slim-bullseye AS builder
|
||||
RUN apt-get update
|
||||
RUN apt-get install -y build-essential libssl-dev libopus-dev libpq-dev pkg-config
|
||||
WORKDIR /usr/src
|
||||
RUN USER=root cargo new tobi
|
||||
WORKDIR /usr/src/tobi
|
||||
COPY Cargo.toml Cargo.lock ./
|
||||
COPY src ./src
|
||||
COPY bot-coreutils ./bot-coreutils
|
||||
COPY bot-database ./bot-database
|
||||
RUN --mount=type=cache,target=/usr/local/cargo/registry \
|
||||
--mount=type=cache,target=target \
|
||||
cargo build --release
|
||||
RUN mkdir /tmp/tobi
|
||||
RUN --mount=type=cache,target=target cp target/release/tobi-rs /tmp/tobi/
|
||||
|
||||
FROM bitnami/minideb:bullseye AS qalculate-builder
|
||||
RUN mkdir /tmp/qalculate
|
||||
WORKDIR /tmp/qalculate
|
||||
RUN install_packages ca-certificates wget xz-utils
|
||||
RUN wget https://github.com/Qalculate/qalculate-gtk/releases/download/v3.18.0/qalculate-3.18.0-x86_64.tar.xz -O qalculate.tar.xz
|
||||
RUN tar xf qalculate.tar.xz
|
||||
RUN cp qalculate-3.18.0/* /tmp/qalculate
|
||||
|
||||
FROM bitnami/minideb:bullseye
|
||||
RUN apt update
|
||||
RUN apt install openssl libopus0 ffmpeg python3 python3-pip libpq5 pkg-config -y
|
||||
COPY --from=qalculate-builder /tmp/qalculate/* /usr/bin/
|
||||
COPY --from=builder /tmp/tobi/tobi-rs .
|
||||
RUN pip3 install youtube-dl
|
||||
RUN rm -rf /var/lib/{apt,dpkg,cache,log}/
|
||||
ENTRYPOINT ["/tobi-rs"]
|
@ -1,313 +0,0 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
|
||||
|
||||
[[package]]
|
||||
name = "bot-coreutils"
|
||||
version = "0.1.1"
|
||||
dependencies = [
|
||||
"log",
|
||||
"mime_guess",
|
||||
"rand",
|
||||
"tokio",
|
||||
"url",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bytes"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "form_urlencoded"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5fc25a87fa4fd2094bffb06925852034d90a17f0d1e05197d4956d3555752191"
|
||||
dependencies = [
|
||||
"matches",
|
||||
"percent-encoding",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"wasi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "idna"
|
||||
version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8"
|
||||
dependencies = [
|
||||
"matches",
|
||||
"unicode-bidi",
|
||||
"unicode-normalization",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.108"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8521a1b57e76b1ec69af7599e75e38e7b7fad6610f037db8c79b127201b5d119"
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "matches"
|
||||
version = "0.1.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f"
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a"
|
||||
|
||||
[[package]]
|
||||
name = "mime"
|
||||
version = "0.3.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d"
|
||||
|
||||
[[package]]
|
||||
name = "mime_guess"
|
||||
version = "2.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2684d4c2e97d99848d30b324b00c8fcc7e5c897b7cbb5819b09e7c90e8baf212"
|
||||
dependencies = [
|
||||
"mime",
|
||||
"unicase",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "mio"
|
||||
version = "0.7.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8067b404fe97c70829f082dec8bcf4f71225d7eaea1d8645349cb76fa06205cc"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"log",
|
||||
"miow",
|
||||
"ntapi",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "miow"
|
||||
version = "0.3.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b9f1c5b025cda876f66ef43a113f91ebc9f4ccef34843000e0adf6ebbab84e21"
|
||||
dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ntapi"
|
||||
version = "0.3.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3f6bb902e437b6d86e03cce10a7e2af662292c5dfef23b65899ea3ac9354ad44"
|
||||
dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "692fcb63b64b1758029e0a96ee63e049ce8c5948587f2f7208df04625e5f6b56"
|
||||
|
||||
[[package]]
|
||||
name = "percent-encoding"
|
||||
version = "2.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e"
|
||||
|
||||
[[package]]
|
||||
name = "pin-project-lite"
|
||||
version = "0.2.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8d31d11c69a6b52a174b42bdc0c30e5e11670f90788b2c471c31c1d17d449443"
|
||||
|
||||
[[package]]
|
||||
name = "ppv-lite86"
|
||||
version = "0.2.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ed0cfbc8191465bed66e1718596ee0b0b35d5ee1f41c5df2189d0fe8bde535ba"
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.8.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2e7573632e6454cf6b99d7aac4ccca54be06da05aca2ef7423d22d27d4d4bcd8"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"rand_chacha",
|
||||
"rand_core",
|
||||
"rand_hc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_chacha"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
|
||||
dependencies = [
|
||||
"ppv-lite86",
|
||||
"rand_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_core"
|
||||
version = "0.6.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7"
|
||||
dependencies = [
|
||||
"getrandom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_hc"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d51e9f596de227fda2ea6c84607f5558e196eeaf43c986b724ba4fb8fdf497e7"
|
||||
dependencies = [
|
||||
"rand_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "signal-hook-registry"
|
||||
version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e51e73328dc4ac0c7ccbda3a494dfa03df1de2f46018127f60c693f2648455b0"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tinyvec"
|
||||
version = "1.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2c1c1d5a42b6245520c249549ec267180beaffcc0615401ac8e31853d4b6d8d2"
|
||||
dependencies = [
|
||||
"tinyvec_macros",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tinyvec_macros"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c"
|
||||
|
||||
[[package]]
|
||||
name = "tokio"
|
||||
version = "1.14.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "70e992e41e0d2fb9f755b37446f20900f64446ef54874f40a60c78f021ac6144"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"bytes",
|
||||
"libc",
|
||||
"memchr",
|
||||
"mio",
|
||||
"once_cell",
|
||||
"pin-project-lite",
|
||||
"signal-hook-registry",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicase"
|
||||
version = "2.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "50f37be617794602aabbeee0be4f259dc1778fabe05e2d67ee8f79326d5cb4f6"
|
||||
dependencies = [
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-bidi"
|
||||
version = "0.3.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1a01404663e3db436ed2746d9fefef640d868edae3cceb81c3b8d5732fda678f"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-normalization"
|
||||
version = "0.1.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d54590932941a9e9266f0832deed84ebe1bf2e4c9e4a3554d393d18f5e854bf9"
|
||||
dependencies = [
|
||||
"tinyvec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "url"
|
||||
version = "2.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a507c383b2d33b5fc35d1861e77e6b383d158b2da5e14fe51b83dfedf6fd578c"
|
||||
dependencies = [
|
||||
"form_urlencoded",
|
||||
"idna",
|
||||
"matches",
|
||||
"percent-encoding",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "version_check"
|
||||
version = "0.9.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe"
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.10.2+wasi-snapshot-preview1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6"
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
|
||||
dependencies = [
|
||||
"winapi-i686-pc-windows-gnu",
|
||||
"winapi-x86_64-pc-windows-gnu",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-i686-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||
|
||||
[[package]]
|
||||
name = "winapi-x86_64-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
@ -1,469 +0,0 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "async-trait"
|
||||
version = "0.1.51"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "44318e776df68115a881de9a8fd1b9e53368d7a4a5ce4cc48517da3393233a5e"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "1.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||
|
||||
[[package]]
|
||||
name = "bot-database"
|
||||
version = "0.6.0"
|
||||
dependencies = [
|
||||
"chrono",
|
||||
"diesel",
|
||||
"diesel_migrations",
|
||||
"dotenv",
|
||||
"log",
|
||||
"r2d2",
|
||||
"thiserror",
|
||||
"tokio-diesel",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "byteorder"
|
||||
version = "1.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "chrono"
|
||||
version = "0.4.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"num-integer",
|
||||
"num-traits",
|
||||
"time",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "diesel"
|
||||
version = "1.4.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b28135ecf6b7d446b43e27e225622a038cc4e2930a1022f51cdb97ada19b8e4d"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"byteorder",
|
||||
"chrono",
|
||||
"diesel_derives",
|
||||
"pq-sys",
|
||||
"r2d2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "diesel_derives"
|
||||
version = "1.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "45f5098f628d02a7a0f68ddba586fb61e80edec3bdc1be3b921f4ceec60858d3"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "diesel_migrations"
|
||||
version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bf3cde8413353dc7f5d72fa8ce0b99a560a359d2c5ef1e5817ca731cd9008f4c"
|
||||
dependencies = [
|
||||
"migrations_internals",
|
||||
"migrations_macros",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dotenv"
|
||||
version = "0.15.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "77c90badedccf4105eca100756a0b1289e191f6fcbdadd3cee1d2f614f97da8f"
|
||||
|
||||
[[package]]
|
||||
name = "futures"
|
||||
version = "0.3.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8cd0210d8c325c245ff06fd95a3b13689a1a276ac8cfa8e8720cb840bfb84b9e"
|
||||
dependencies = [
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
"futures-io",
|
||||
"futures-sink",
|
||||
"futures-task",
|
||||
"futures-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-channel"
|
||||
version = "0.3.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7fc8cd39e3dbf865f7340dce6a2d401d24fd37c6fe6c4f0ee0de8bfca2252d27"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-sink",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-core"
|
||||
version = "0.3.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "629316e42fe7c2a0b9a65b47d159ceaa5453ab14e8f0a3c5eedbb8cd55b4a445"
|
||||
|
||||
[[package]]
|
||||
name = "futures-io"
|
||||
version = "0.3.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e481354db6b5c353246ccf6a728b0c5511d752c08da7260546fc0933869daa11"
|
||||
|
||||
[[package]]
|
||||
name = "futures-sink"
|
||||
version = "0.3.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "996c6442437b62d21a32cd9906f9c41e7dc1e19a9579843fad948696769305af"
|
||||
|
||||
[[package]]
|
||||
name = "futures-task"
|
||||
version = "0.3.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dabf1872aaab32c886832f2276d2f5399887e2bd613698a02359e4ea83f8de12"
|
||||
|
||||
[[package]]
|
||||
name = "futures-util"
|
||||
version = "0.3.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "41d22213122356472061ac0f1ab2cee28d2bac8491410fd68c2af53d1cedb83e"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-sink",
|
||||
"futures-task",
|
||||
"pin-project-lite",
|
||||
"pin-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
version = "0.1.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "instant"
|
||||
version = "0.1.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.108"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8521a1b57e76b1ec69af7599e75e38e7b7fad6610f037db8c79b127201b5d119"
|
||||
|
||||
[[package]]
|
||||
name = "lock_api"
|
||||
version = "0.4.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "712a4d093c9976e24e7dbca41db895dabcbac38eb5f4045393d17a95bdfb1109"
|
||||
dependencies = [
|
||||
"scopeguard",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "migrations_internals"
|
||||
version = "1.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2b4fc84e4af020b837029e017966f86a1c2d5e83e64b589963d5047525995860"
|
||||
dependencies = [
|
||||
"diesel",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "migrations_macros"
|
||||
version = "1.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9753f12909fd8d923f75ae5c3258cae1ed3c8ec052e1b38c93c21a6d157f789c"
|
||||
dependencies = [
|
||||
"migrations_internals",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-integer"
|
||||
version = "0.1.44"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-traits"
|
||||
version = "0.2.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num_cpus"
|
||||
version = "1.13.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3"
|
||||
dependencies = [
|
||||
"hermit-abi",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "parking_lot"
|
||||
version = "0.11.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99"
|
||||
dependencies = [
|
||||
"instant",
|
||||
"lock_api",
|
||||
"parking_lot_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "parking_lot_core"
|
||||
version = "0.8.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d76e8e1493bcac0d2766c42737f34458f1c8c50c0d23bcb24ea953affb273216"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"instant",
|
||||
"libc",
|
||||
"redox_syscall",
|
||||
"smallvec",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pin-project-lite"
|
||||
version = "0.2.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8d31d11c69a6b52a174b42bdc0c30e5e11670f90788b2c471c31c1d17d449443"
|
||||
|
||||
[[package]]
|
||||
name = "pin-utils"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
|
||||
|
||||
[[package]]
|
||||
name = "pq-sys"
|
||||
version = "0.4.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6ac25eee5a0582f45a67e837e350d784e7003bd29a5f460796772061ca49ffda"
|
||||
dependencies = [
|
||||
"vcpkg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.32"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ba508cc11742c0dc5c1659771673afbab7a0efab23aa17e854cbab0837ed0b43"
|
||||
dependencies = [
|
||||
"unicode-xid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "38bc8cc6a5f2e3655e0899c1b848643b2562f853f114bfec7be120678e3ace05"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "r2d2"
|
||||
version = "0.8.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "545c5bc2b880973c9c10e4067418407a0ccaa3091781d1671d46eb35107cb26f"
|
||||
dependencies = [
|
||||
"log",
|
||||
"parking_lot",
|
||||
"scheduled-thread-pool",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.2.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8383f39639269cde97d255a32bdb68c047337295414940c68bdd30c2e13203ff"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "scheduled-thread-pool"
|
||||
version = "0.2.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dc6f74fd1204073fa02d5d5d68bec8021be4c38690b61264b2fdb48083d0e7d7"
|
||||
dependencies = [
|
||||
"parking_lot",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "scopeguard"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
|
||||
|
||||
[[package]]
|
||||
name = "smallvec"
|
||||
version = "1.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1ecab6c735a6bb4139c0caafd0cc3635748bbb3acf4550e8138122099251f309"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.82"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8daf5dd0bb60cbd4137b1b587d2fc0ae729bc07cf01cd70b36a1ed5ade3b9d59"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-xid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.30"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "854babe52e4df1653706b98fcfc05843010039b406875930a70e4d9644e5c417"
|
||||
dependencies = [
|
||||
"thiserror-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "1.0.30"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "aa32fd3f627f367fe16f893e2597ae3c05020f8bba2666a4e6ea73d377e5714b"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "time"
|
||||
version = "0.1.44"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"wasi",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio"
|
||||
version = "1.14.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "70e992e41e0d2fb9f755b37446f20900f64446ef54874f40a60c78f021ac6144"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"num_cpus",
|
||||
"pin-project-lite",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio-diesel"
|
||||
version = "0.3.0"
|
||||
source = "git+https://github.com/Trivernis/tokio-diesel#f4af42558246ab323600622ba8d08803d3c18842"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"diesel",
|
||||
"futures",
|
||||
"r2d2",
|
||||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-xid"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
|
||||
|
||||
[[package]]
|
||||
name = "vcpkg"
|
||||
version = "0.2.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.10.0+wasi-snapshot-preview1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f"
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
|
||||
dependencies = [
|
||||
"winapi-i686-pc-windows-gnu",
|
||||
"winapi-x86_64-pc-windows-gnu",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-i686-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||
|
||||
[[package]]
|
||||
name = "winapi-x86_64-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
@ -1,5 +0,0 @@
|
||||
# For documentation on how to configure this file,
|
||||
# see diesel.rs/guides/configuring-diesel-cli
|
||||
|
||||
[print_schema]
|
||||
file = "src/schema.rs"
|
@ -0,0 +1,13 @@
|
||||
[package]
|
||||
name = "migration"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
publish = false
|
||||
|
||||
[lib]
|
||||
name = "migration"
|
||||
path = "src/lib.rs"
|
||||
|
||||
[dependencies]
|
||||
sea-orm-migration = "0.9.3"
|
||||
tokio = { version = "1.21.2", features = ["rt", "net", "tracing"] }
|
@ -0,0 +1,37 @@
|
||||
# Running Migrator CLI
|
||||
|
||||
- Apply all pending migrations
|
||||
```sh
|
||||
cargo run
|
||||
```
|
||||
```sh
|
||||
cargo run -- up
|
||||
```
|
||||
- Apply first 10 pending migrations
|
||||
```sh
|
||||
cargo run -- up -n 10
|
||||
```
|
||||
- Rollback last applied migrations
|
||||
```sh
|
||||
cargo run -- down
|
||||
```
|
||||
- Rollback last 10 applied migrations
|
||||
```sh
|
||||
cargo run -- down -n 10
|
||||
```
|
||||
- Drop all tables from the database, then reapply all migrations
|
||||
```sh
|
||||
cargo run -- fresh
|
||||
```
|
||||
- Rollback all applied migrations, then reapply all migrations
|
||||
```sh
|
||||
cargo run -- refresh
|
||||
```
|
||||
- Rollback all applied migrations
|
||||
```sh
|
||||
cargo run -- reset
|
||||
```
|
||||
- Check the status of all migrations
|
||||
```sh
|
||||
cargo run -- status
|
||||
```
|
@ -0,0 +1,16 @@
|
||||
pub use sea_orm_migration::prelude::*;
|
||||
|
||||
mod m20220029_164527_change_timestamp_format;
|
||||
mod m20220101_000001_create_table;
|
||||
|
||||
pub struct Migrator;
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl MigratorTrait for Migrator {
|
||||
fn migrations() -> Vec<Box<dyn MigrationTrait>> {
|
||||
vec![
|
||||
Box::new(m20220101_000001_create_table::Migration),
|
||||
Box::new(m20220029_164527_change_timestamp_format::Migration),
|
||||
]
|
||||
}
|
||||
}
|
@ -0,0 +1,82 @@
|
||||
use crate::{DbErr, Table};
|
||||
use sea_orm_migration::prelude::*;
|
||||
|
||||
#[derive(Iden)]
|
||||
pub enum Statistics {
|
||||
Table,
|
||||
ExecutedAt,
|
||||
}
|
||||
|
||||
#[derive(Iden)]
|
||||
pub enum EphemeralMessages {
|
||||
Table,
|
||||
Timeout,
|
||||
}
|
||||
|
||||
pub struct Migration;
|
||||
|
||||
impl MigrationName for Migration {
|
||||
fn name(&self) -> &str {
|
||||
"m20220029_164527_change_timestamp_format"
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl MigrationTrait for Migration {
|
||||
async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {
|
||||
manager
|
||||
.alter_table(
|
||||
Table::alter()
|
||||
.table(Statistics::Table)
|
||||
.modify_column(
|
||||
ColumnDef::new(Statistics::ExecutedAt)
|
||||
.timestamp_with_time_zone()
|
||||
.not_null(),
|
||||
)
|
||||
.to_owned(),
|
||||
)
|
||||
.await?;
|
||||
manager
|
||||
.alter_table(
|
||||
Table::alter()
|
||||
.table(EphemeralMessages::Table)
|
||||
.modify_column(
|
||||
ColumnDef::new(EphemeralMessages::Timeout)
|
||||
.timestamp_with_time_zone()
|
||||
.not_null(),
|
||||
)
|
||||
.to_owned(),
|
||||
)
|
||||
.await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {
|
||||
manager
|
||||
.alter_table(
|
||||
Table::alter()
|
||||
.table(Statistics::Table)
|
||||
.modify_column(
|
||||
ColumnDef::new(Statistics::ExecutedAt)
|
||||
.timestamp()
|
||||
.not_null(),
|
||||
)
|
||||
.to_owned(),
|
||||
)
|
||||
.await?;
|
||||
manager
|
||||
.alter_table(
|
||||
Table::alter()
|
||||
.table(EphemeralMessages::Table)
|
||||
.modify_column(
|
||||
ColumnDef::new(EphemeralMessages::Timeout)
|
||||
.timestamp()
|
||||
.not_null(),
|
||||
)
|
||||
.to_owned(),
|
||||
)
|
||||
.await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
@ -0,0 +1,287 @@
|
||||
use sea_orm_migration::prelude::*;
|
||||
|
||||
pub struct Migration;
|
||||
|
||||
#[derive(Iden)]
|
||||
pub enum EphemeralMessages {
|
||||
Table,
|
||||
ChannelId,
|
||||
MessageId,
|
||||
Timeout,
|
||||
}
|
||||
|
||||
#[derive(Iden)]
|
||||
pub enum GuildPlaylists {
|
||||
Table,
|
||||
GuildId,
|
||||
Name,
|
||||
Url,
|
||||
}
|
||||
|
||||
#[derive(Iden)]
|
||||
pub enum GuildSettings {
|
||||
Table,
|
||||
GuildId,
|
||||
Key,
|
||||
Value,
|
||||
}
|
||||
|
||||
#[derive(Iden)]
|
||||
pub enum Media {
|
||||
Table,
|
||||
Id,
|
||||
Category,
|
||||
Name,
|
||||
Url,
|
||||
}
|
||||
|
||||
#[derive(Iden)]
|
||||
pub enum Statistics {
|
||||
Table,
|
||||
Id,
|
||||
Version,
|
||||
Command,
|
||||
ExecutedAt,
|
||||
Success,
|
||||
ErrorMsg,
|
||||
}
|
||||
|
||||
#[derive(Iden)]
|
||||
pub enum YoutubeSongs {
|
||||
Table,
|
||||
Id,
|
||||
SpotifyId,
|
||||
Artist,
|
||||
Title,
|
||||
Album,
|
||||
Url,
|
||||
Score,
|
||||
}
|
||||
|
||||
impl MigrationName for Migration {
|
||||
fn name(&self) -> &str {
|
||||
"m20220101_000001_create_table"
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl MigrationTrait for Migration {
|
||||
async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {
|
||||
manager.create_table(ephemeral_messages()).await?;
|
||||
manager.create_table(guild_playlists()).await?;
|
||||
manager.create_table(guild_settings()).await?;
|
||||
manager.create_table(media()).await?;
|
||||
manager.create_table(statistics()).await?;
|
||||
manager.create_table(youtube_songs()).await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {
|
||||
manager
|
||||
.drop_table(Table::drop().table(EphemeralMessages::Table).to_owned())
|
||||
.await?;
|
||||
manager
|
||||
.drop_table(Table::drop().table(GuildPlaylists::Table).to_owned())
|
||||
.await?;
|
||||
manager
|
||||
.drop_table(Table::drop().table(GuildSettings::Table).to_owned())
|
||||
.await?;
|
||||
manager
|
||||
.drop_table(Table::drop().table(Media::Table).to_owned())
|
||||
.await?;
|
||||
manager
|
||||
.drop_table(Table::drop().table(Statistics::Table).to_owned())
|
||||
.await?;
|
||||
manager
|
||||
.drop_table(Table::drop().table(YoutubeSongs::Table).to_owned())
|
||||
.await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
fn ephemeral_messages() -> TableCreateStatement {
|
||||
Table::create()
|
||||
.table(EphemeralMessages::Table)
|
||||
.if_not_exists()
|
||||
.col(
|
||||
ColumnDef::new(EphemeralMessages::ChannelId)
|
||||
.big_integer()
|
||||
.not_null(),
|
||||
)
|
||||
.col(
|
||||
ColumnDef::new(EphemeralMessages::MessageId)
|
||||
.big_integer()
|
||||
.not_null(),
|
||||
)
|
||||
.col(
|
||||
ColumnDef::new(EphemeralMessages::Timeout)
|
||||
.timestamp()
|
||||
.not_null(),
|
||||
)
|
||||
.primary_key(
|
||||
Index::create()
|
||||
.col(EphemeralMessages::ChannelId)
|
||||
.col(EphemeralMessages::MessageId),
|
||||
)
|
||||
.to_owned()
|
||||
}
|
||||
|
||||
fn guild_playlists() -> TableCreateStatement {
|
||||
Table::create()
|
||||
.table(GuildPlaylists::Table)
|
||||
.if_not_exists()
|
||||
.col(
|
||||
ColumnDef::new(GuildPlaylists::GuildId)
|
||||
.big_integer()
|
||||
.not_null(),
|
||||
)
|
||||
.col(
|
||||
ColumnDef::new(GuildPlaylists::Name)
|
||||
.string_len(255)
|
||||
.not_null(),
|
||||
)
|
||||
.col(
|
||||
ColumnDef::new(GuildPlaylists::Url)
|
||||
.string_len(1204)
|
||||
.not_null(),
|
||||
)
|
||||
.primary_key(
|
||||
Index::create()
|
||||
.col(GuildPlaylists::GuildId)
|
||||
.col(GuildPlaylists::Name),
|
||||
)
|
||||
.to_owned()
|
||||
}
|
||||
|
||||
fn guild_settings() -> TableCreateStatement {
|
||||
Table::create()
|
||||
.table(GuildSettings::Table)
|
||||
.if_not_exists()
|
||||
.col(
|
||||
ColumnDef::new(GuildSettings::GuildId)
|
||||
.big_integer()
|
||||
.not_null(),
|
||||
)
|
||||
.col(
|
||||
ColumnDef::new(GuildSettings::Key)
|
||||
.string_len(255)
|
||||
.not_null(),
|
||||
)
|
||||
.col(
|
||||
ColumnDef::new(GuildSettings::Value)
|
||||
.string_len(1024)
|
||||
.not_null(),
|
||||
)
|
||||
.primary_key(
|
||||
Index::create()
|
||||
.col(GuildSettings::GuildId)
|
||||
.col(GuildSettings::Key),
|
||||
)
|
||||
.to_owned()
|
||||
}
|
||||
|
||||
fn media() -> TableCreateStatement {
|
||||
Table::create()
|
||||
.table(Media::Table)
|
||||
.if_not_exists()
|
||||
.col(
|
||||
ColumnDef::new(Media::Id)
|
||||
.big_integer()
|
||||
.auto_increment()
|
||||
.not_null()
|
||||
.primary_key(),
|
||||
)
|
||||
.col(ColumnDef::new(Media::Category).string_len(128))
|
||||
.col(ColumnDef::new(Media::Name).string_len(128))
|
||||
.col(ColumnDef::new(Media::Url).string_len(128))
|
||||
.index(
|
||||
Index::create()
|
||||
.unique()
|
||||
.col(Media::Category)
|
||||
.col(Media::Name),
|
||||
)
|
||||
.to_owned()
|
||||
}
|
||||
|
||||
fn statistics() -> TableCreateStatement {
|
||||
Table::create()
|
||||
.table(Statistics::Table)
|
||||
.if_not_exists()
|
||||
.col(
|
||||
ColumnDef::new(Statistics::Id)
|
||||
.big_integer()
|
||||
.auto_increment()
|
||||
.primary_key(),
|
||||
)
|
||||
.col(
|
||||
ColumnDef::new(Statistics::Version)
|
||||
.string_len(32)
|
||||
.not_null(),
|
||||
)
|
||||
.col(
|
||||
ColumnDef::new(Statistics::Command)
|
||||
.string_len(255)
|
||||
.not_null(),
|
||||
)
|
||||
.col(
|
||||
ColumnDef::new(Statistics::ExecutedAt)
|
||||
.timestamp()
|
||||
.not_null(),
|
||||
)
|
||||
.col(
|
||||
ColumnDef::new(Statistics::Success)
|
||||
.boolean()
|
||||
.not_null()
|
||||
.default(true),
|
||||
)
|
||||
.col(ColumnDef::new(Statistics::ErrorMsg).string())
|
||||
.to_owned()
|
||||
}
|
||||
|
||||
fn youtube_songs() -> TableCreateStatement {
|
||||
Table::create()
|
||||
.table(YoutubeSongs::Table)
|
||||
.if_not_exists()
|
||||
.col(
|
||||
ColumnDef::new(YoutubeSongs::Id)
|
||||
.big_integer()
|
||||
.primary_key()
|
||||
.auto_increment(),
|
||||
)
|
||||
.col(
|
||||
ColumnDef::new(YoutubeSongs::SpotifyId)
|
||||
.string_len(255)
|
||||
.not_null(),
|
||||
)
|
||||
.col(
|
||||
ColumnDef::new(YoutubeSongs::Artist)
|
||||
.string_len(128)
|
||||
.not_null(),
|
||||
)
|
||||
.col(
|
||||
ColumnDef::new(YoutubeSongs::Title)
|
||||
.string_len(255)
|
||||
.not_null(),
|
||||
)
|
||||
.col(
|
||||
ColumnDef::new(YoutubeSongs::Album)
|
||||
.string_len(255)
|
||||
.not_null(),
|
||||
)
|
||||
.col(ColumnDef::new(YoutubeSongs::Url).string_len(128).not_null())
|
||||
.col(
|
||||
ColumnDef::new(YoutubeSongs::Score)
|
||||
.integer()
|
||||
.default(0)
|
||||
.not_null(),
|
||||
)
|
||||
.index(
|
||||
Index::create()
|
||||
.unique()
|
||||
.col(YoutubeSongs::SpotifyId)
|
||||
.col(YoutubeSongs::Url),
|
||||
)
|
||||
.to_owned()
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
use migration::Migrator;
|
||||
use sea_orm_migration::prelude::*;
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
cli::run_cli(Migrator).await;
|
||||
}
|
@ -1,6 +0,0 @@
|
||||
-- This file was automatically created by Diesel to setup helper functions
|
||||
-- and other internal bookkeeping. This file is safe to edit, any future
|
||||
-- changes will be added to existing projects as new migrations.
|
||||
|
||||
DROP FUNCTION IF EXISTS diesel_manage_updated_at(_tbl regclass);
|
||||
DROP FUNCTION IF EXISTS diesel_set_updated_at();
|
@ -1,36 +0,0 @@
|
||||
-- This file was automatically created by Diesel to setup helper functions
|
||||
-- and other internal bookkeeping. This file is safe to edit, any future
|
||||
-- changes will be added to existing projects as new migrations.
|
||||
|
||||
|
||||
|
||||
|
||||
-- Sets up a trigger for the given table to automatically set a column called
|
||||
-- `updated_at` whenever the row is modified (unless `updated_at` was included
|
||||
-- in the modified columns)
|
||||
--
|
||||
-- # Example
|
||||
--
|
||||
-- ```sql
|
||||
-- CREATE TABLE users (id SERIAL PRIMARY KEY, updated_at TIMESTAMP NOT NULL DEFAULT NOW());
|
||||
--
|
||||
-- SELECT diesel_manage_updated_at('users');
|
||||
-- ```
|
||||
CREATE OR REPLACE FUNCTION diesel_manage_updated_at(_tbl regclass) RETURNS VOID AS $$
|
||||
BEGIN
|
||||
EXECUTE format('CREATE TRIGGER set_updated_at BEFORE UPDATE ON %s
|
||||
FOR EACH ROW EXECUTE PROCEDURE diesel_set_updated_at()', _tbl);
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
|
||||
CREATE OR REPLACE FUNCTION diesel_set_updated_at() RETURNS trigger AS $$
|
||||
BEGIN
|
||||
IF (
|
||||
NEW IS DISTINCT FROM OLD AND
|
||||
NEW.updated_at IS NOT DISTINCT FROM OLD.updated_at
|
||||
) THEN
|
||||
NEW.updated_at := current_timestamp;
|
||||
END IF;
|
||||
RETURN NEW;
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
@ -1,2 +0,0 @@
|
||||
-- This file should undo anything in `up.sql`
|
||||
DROP TABLE guild_settings;
|
@ -1,6 +0,0 @@
|
||||
CREATE TABLE guild_settings (
|
||||
guild_id BIGINT NOT NULL,
|
||||
key VARCHAR(255) NOT NULL,
|
||||
value VARCHAR(1024),
|
||||
PRIMARY KEY (guild_id, key)
|
||||
);
|
@ -1,2 +0,0 @@
|
||||
-- This file should undo anything in `up.sql`
|
||||
DROP TABLE guild_playlists;
|
@ -1,7 +0,0 @@
|
||||
-- Your SQL goes here
|
||||
CREATE TABLE guild_playlists (
|
||||
guild_id BIGINT NOT NULL,
|
||||
name VARCHAR(255) NOT NULL,
|
||||
url VARCHAR(1024) NOT NULL,
|
||||
PRIMARY KEY (guild_id, name)
|
||||
)
|
@ -1,2 +0,0 @@
|
||||
-- This file should undo anything in `up.sql`
|
||||
DROP TABLE gifs;
|
@ -1,8 +0,0 @@
|
||||
-- Your SQL goes here
|
||||
CREATE TABLE gifs (
|
||||
id BIGSERIAL PRIMARY KEY ,
|
||||
category VARCHAR(128),
|
||||
name VARCHAR(128),
|
||||
url VARCHAR(128) NOT NULL,
|
||||
UNIQUE (category, name)
|
||||
)
|
@ -1,2 +0,0 @@
|
||||
-- This file should undo anything in `up.sql`
|
||||
DROP TABLE statistics;
|
@ -1,9 +0,0 @@
|
||||
-- Your SQL goes here
|
||||
CREATE TABLE statistics (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
version VARCHAR(32) NOT NULL,
|
||||
command VARCHAR(255) NOT NULL,
|
||||
executed_at TIMESTAMP NOT NULL,
|
||||
success BOOLEAN NOT NULL DEFAULT TRUE,
|
||||
error_msg TEXT
|
||||
)
|
@ -1,2 +0,0 @@
|
||||
-- This file should undo anything in `up.sql`
|
||||
DROP TABLE youtube_songs;
|
@ -1,11 +0,0 @@
|
||||
-- Your SQL goes here
|
||||
CREATE TABLE youtube_songs (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
spotify_id VARCHAR(255) NOT NULL,
|
||||
artist VARCHAR(128) NOT NULL,
|
||||
title VARCHAR(255) NOT NULL,
|
||||
album VARCHAR(255) NOT NULL,
|
||||
url VARCHAR(128) NOT NULL,
|
||||
score INTEGER DEFAULT 0 NOT NULL,
|
||||
UNIQUE (spotify_id, url)
|
||||
)
|
@ -1,2 +0,0 @@
|
||||
-- This file should undo anything in `up.sql`
|
||||
DROP TABLE ephemeral_messages;
|
@ -1,7 +0,0 @@
|
||||
-- Your SQL goes here
|
||||
CREATE TABLE ephemeral_messages (
|
||||
channel_id BIGINT NOT NULL,
|
||||
message_id BIGINT NOT NULL,
|
||||
timeout TIMESTAMP NOT NULL,
|
||||
PRIMARY KEY (channel_id, message_id)
|
||||
)
|
@ -1,2 +0,0 @@
|
||||
-- This file should undo anything in `up.sql`
|
||||
ALTER TABLE media RENAME TO gifs;
|
@ -1,2 +0,0 @@
|
||||
-- Your SQL goes here
|
||||
ALTER TABLE gifs RENAME TO media;
|
@ -1,50 +1,49 @@
|
||||
use crate::entity::statistics;
|
||||
use crate::error::DatabaseResult;
|
||||
use sea_orm::prelude::*;
|
||||
use sea_orm::ActiveValue::Set;
|
||||
use sea_orm::{FromQueryResult, QuerySelect};
|
||||
use std::time::SystemTime;
|
||||
|
||||
use diesel::dsl::count;
|
||||
use diesel::insert_into;
|
||||
use diesel::prelude::*;
|
||||
use tokio_diesel::*;
|
||||
|
||||
use crate::error::DatabaseResult;
|
||||
use crate::models::*;
|
||||
use crate::schema::*;
|
||||
use crate::Database;
|
||||
#[derive(FromQueryResult)]
|
||||
struct CommandCount {
|
||||
count: i64,
|
||||
}
|
||||
|
||||
impl Database {
|
||||
impl super::BotDatabase {
|
||||
/// Adds a command statistic to the database
|
||||
#[tracing::instrument(level = "debug", skip(self))]
|
||||
pub async fn add_statistic(
|
||||
&self,
|
||||
version: &str,
|
||||
command: &str,
|
||||
version: String,
|
||||
command: String,
|
||||
executed_at: SystemTime,
|
||||
success: bool,
|
||||
error_msg: Option<String>,
|
||||
) -> DatabaseResult<()> {
|
||||
use statistics::dsl;
|
||||
log::trace!("Adding statistic to database");
|
||||
insert_into(dsl::statistics)
|
||||
.values(StatisticInsert {
|
||||
version: version.to_string(),
|
||||
command: command.to_string(),
|
||||
executed_at,
|
||||
success,
|
||||
error_msg,
|
||||
})
|
||||
.execute_async(&self.pool)
|
||||
.await?;
|
||||
let model = statistics::ActiveModel {
|
||||
version: Set(version),
|
||||
command: Set(command),
|
||||
executed_at: Set(DateTimeLocal::from(executed_at).into()),
|
||||
success: Set(success),
|
||||
error_msg: Set(error_msg),
|
||||
..Default::default()
|
||||
};
|
||||
model.insert(&self.db).await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Returns the total number of commands executed
|
||||
#[tracing::instrument(level = "debug", skip(self))]
|
||||
pub async fn get_total_commands_statistic(&self) -> DatabaseResult<u64> {
|
||||
use statistics::dsl;
|
||||
log::trace!("Querying total number of commands");
|
||||
let total_count: i64 = dsl::statistics
|
||||
.select(count(dsl::id))
|
||||
.first_async::<i64>(&self.pool)
|
||||
let total_count: Option<CommandCount> = statistics::Entity::find()
|
||||
.select_only()
|
||||
.column_as(statistics::Column::Id.count(), "count")
|
||||
.into_model::<CommandCount>()
|
||||
.one(&self.db)
|
||||
.await?;
|
||||
|
||||
Ok(total_count as u64)
|
||||
Ok(total_count.unwrap().count as u64)
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,24 @@
|
||||
//! SeaORM Entity. Generated by sea-orm-codegen 0.7.0
|
||||
|
||||
use sea_orm::entity::prelude::*;
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, DeriveEntityModel)]
|
||||
#[sea_orm(table_name = "ephemeral_messages")]
|
||||
pub struct Model {
|
||||
#[sea_orm(primary_key, auto_increment = false)]
|
||||
pub channel_id: i64,
|
||||
#[sea_orm(primary_key, auto_increment = false)]
|
||||
pub message_id: i64,
|
||||
pub timeout: DateTimeWithTimeZone,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, EnumIter)]
|
||||
pub enum Relation {}
|
||||
|
||||
impl RelationTrait for Relation {
|
||||
fn def(&self) -> RelationDef {
|
||||
panic!("No RelationDef")
|
||||
}
|
||||
}
|
||||
|
||||
impl ActiveModelBehavior for ActiveModel {}
|
@ -0,0 +1,24 @@
|
||||
//! SeaORM Entity. Generated by sea-orm-codegen 0.7.0
|
||||
|
||||
use sea_orm::entity::prelude::*;
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, DeriveEntityModel)]
|
||||
#[sea_orm(table_name = "guild_playlists")]
|
||||
pub struct Model {
|
||||
#[sea_orm(primary_key, auto_increment = false)]
|
||||
pub guild_id: i64,
|
||||
#[sea_orm(primary_key, auto_increment = false)]
|
||||
pub name: String,
|
||||
pub url: String,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, EnumIter)]
|
||||
pub enum Relation {}
|
||||
|
||||
impl RelationTrait for Relation {
|
||||
fn def(&self) -> RelationDef {
|
||||
panic!("No RelationDef")
|
||||
}
|
||||
}
|
||||
|
||||
impl ActiveModelBehavior for ActiveModel {}
|
@ -0,0 +1,24 @@
|
||||
//! SeaORM Entity. Generated by sea-orm-codegen 0.7.0
|
||||
|
||||
use sea_orm::entity::prelude::*;
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, DeriveEntityModel)]
|
||||
#[sea_orm(table_name = "guild_settings")]
|
||||
pub struct Model {
|
||||
#[sea_orm(primary_key, auto_increment = false)]
|
||||
pub guild_id: i64,
|
||||
#[sea_orm(primary_key, auto_increment = false)]
|
||||
pub key: String,
|
||||
pub value: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, EnumIter)]
|
||||
pub enum Relation {}
|
||||
|
||||
impl RelationTrait for Relation {
|
||||
fn def(&self) -> RelationDef {
|
||||
panic!("No RelationDef")
|
||||
}
|
||||
}
|
||||
|
||||
impl ActiveModelBehavior for ActiveModel {}
|
@ -0,0 +1,24 @@
|
||||
//! SeaORM Entity. Generated by sea-orm-codegen 0.7.0
|
||||
|
||||
use sea_orm::entity::prelude::*;
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, DeriveEntityModel)]
|
||||
#[sea_orm(table_name = "media")]
|
||||
pub struct Model {
|
||||
#[sea_orm(primary_key)]
|
||||
pub id: i64,
|
||||
pub category: Option<String>,
|
||||
pub name: Option<String>,
|
||||
pub url: String,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, EnumIter)]
|
||||
pub enum Relation {}
|
||||
|
||||
impl RelationTrait for Relation {
|
||||
fn def(&self) -> RelationDef {
|
||||
panic!("No RelationDef")
|
||||
}
|
||||
}
|
||||
|
||||
impl ActiveModelBehavior for ActiveModel {}
|
@ -0,0 +1,10 @@
|
||||
//! SeaORM Entity. Generated by sea-orm-codegen 0.7.0
|
||||
|
||||
pub mod prelude;
|
||||
|
||||
pub mod ephemeral_messages;
|
||||
pub mod guild_playlists;
|
||||
pub mod guild_settings;
|
||||
pub mod media;
|
||||
pub mod statistics;
|
||||
pub mod youtube_songs;
|
@ -0,0 +1,8 @@
|
||||
//! SeaORM Entity. Generated by sea-orm-codegen 0.7.0
|
||||
|
||||
pub use super::ephemeral_messages::Entity as EphemeralMessages;
|
||||
pub use super::guild_playlists::Entity as GuildPlaylists;
|
||||
pub use super::guild_settings::Entity as GuildSettings;
|
||||
pub use super::media::Entity as Media;
|
||||
pub use super::statistics::Entity as Statistics;
|
||||
pub use super::youtube_songs::Entity as YoutubeSongs;
|
@ -0,0 +1,27 @@
|
||||
//! SeaORM Entity. Generated by sea-orm-codegen 0.7.0
|
||||
|
||||
use sea_orm::entity::prelude::*;
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, DeriveEntityModel)]
|
||||
#[sea_orm(table_name = "statistics")]
|
||||
pub struct Model {
|
||||
#[sea_orm(primary_key)]
|
||||
pub id: i64,
|
||||
pub version: String,
|
||||
pub command: String,
|
||||
pub executed_at: DateTimeWithTimeZone,
|
||||
pub success: bool,
|
||||
#[sea_orm(column_type = "Text", nullable)]
|
||||
pub error_msg: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, EnumIter)]
|
||||
pub enum Relation {}
|
||||
|
||||
impl RelationTrait for Relation {
|
||||
fn def(&self) -> RelationDef {
|
||||
panic!("No RelationDef")
|
||||
}
|
||||
}
|
||||
|
||||
impl ActiveModelBehavior for ActiveModel {}
|
@ -0,0 +1,27 @@
|
||||
//! SeaORM Entity. Generated by sea-orm-codegen 0.7.0
|
||||
|
||||
use sea_orm::entity::prelude::*;
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, DeriveEntityModel)]
|
||||
#[sea_orm(table_name = "youtube_songs")]
|
||||
pub struct Model {
|
||||
#[sea_orm(primary_key)]
|
||||
pub id: i64,
|
||||
pub spotify_id: String,
|
||||
pub artist: String,
|
||||
pub title: String,
|
||||
pub album: String,
|
||||
pub url: String,
|
||||
pub score: i32,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, EnumIter)]
|
||||
pub enum Relation {}
|
||||
|
||||
impl RelationTrait for Relation {
|
||||
fn def(&self) -> RelationDef {
|
||||
panic!("No RelationDef")
|
||||
}
|
||||
}
|
||||
|
||||
impl ActiveModelBehavior for ActiveModel {}
|
@ -1,47 +1,31 @@
|
||||
#[macro_use]
|
||||
extern crate diesel;
|
||||
|
||||
#[macro_use]
|
||||
extern crate diesel_migrations;
|
||||
|
||||
use crate::error::{DatabaseError, DatabaseResult};
|
||||
use diesel::prelude::*;
|
||||
use diesel::r2d2::{ConnectionManager, ManageConnection, Pool};
|
||||
use crate::error::DatabaseResult;
|
||||
use std::env;
|
||||
|
||||
pub mod database;
|
||||
pub mod entity;
|
||||
pub mod error;
|
||||
pub mod models;
|
||||
pub mod schema;
|
||||
|
||||
pub static VERSION: &str = env!("CARGO_PKG_VERSION");
|
||||
pub use database::Database;
|
||||
|
||||
type PoolConnection = Pool<ConnectionManager<PgConnection>>;
|
||||
pub use database::BotDatabase as Database;
|
||||
use migration::MigratorTrait;
|
||||
use sea_orm::{ConnectOptions, Database as SeaDatabase, DatabaseConnection};
|
||||
|
||||
embed_migrations!("../bot-database/migrations");
|
||||
|
||||
fn get_connection() -> DatabaseResult<PoolConnection> {
|
||||
#[tracing::instrument]
|
||||
async fn get_connection() -> DatabaseResult<DatabaseConnection> {
|
||||
let database_url = env::var("DATABASE_URL").expect("No DATABASE_URL in path");
|
||||
log::debug!("Establishing database connection...");
|
||||
let manager = ConnectionManager::<PgConnection>::new(database_url);
|
||||
log::trace!("Connecting...");
|
||||
manager
|
||||
.connect()
|
||||
.map_err(|e| DatabaseError::Msg(format!("{:?}", e)))?;
|
||||
log::trace!("Creating pool...");
|
||||
let pool = Pool::builder().max_size(16).build(manager)?;
|
||||
log::trace!("Getting one connection to run migrations...");
|
||||
let connection = pool.get()?;
|
||||
log::debug!("Running migrations...");
|
||||
embedded_migrations::run(&connection)?;
|
||||
log::debug!("Migrations finished");
|
||||
log::info!("Database connection initialized");
|
||||
|
||||
Ok(pool)
|
||||
tracing::debug!("Establishing database connection...");
|
||||
let opt = ConnectOptions::new(database_url);
|
||||
let db = SeaDatabase::connect(opt).await?;
|
||||
tracing::debug!("Running migrations...");
|
||||
migration::Migrator::up(&db, None).await?;
|
||||
tracing::debug!("Migrations finished");
|
||||
tracing::info!("Database connection initialized");
|
||||
|
||||
Ok(db)
|
||||
}
|
||||
|
||||
pub fn get_database() -> DatabaseResult<Database> {
|
||||
let conn = get_connection()?;
|
||||
pub async fn get_database() -> DatabaseResult<Database> {
|
||||
let conn = get_connection().await?;
|
||||
Ok(Database::new(conn))
|
||||
}
|
||||
|
@ -1,94 +1,8 @@
|
||||
use crate::schema::*;
|
||||
use std::time::SystemTime;
|
||||
|
||||
#[derive(Queryable, Debug)]
|
||||
pub struct GuildSetting {
|
||||
pub guild_id: i64,
|
||||
pub key: String,
|
||||
pub value: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Insertable, Debug)]
|
||||
#[table_name = "guild_settings"]
|
||||
pub struct GuildSettingInsert {
|
||||
pub guild_id: i64,
|
||||
pub key: String,
|
||||
pub value: String,
|
||||
}
|
||||
|
||||
#[derive(Queryable, Debug)]
|
||||
pub struct GuildPlaylist {
|
||||
pub guild_id: i64,
|
||||
pub name: String,
|
||||
pub url: String,
|
||||
}
|
||||
|
||||
#[derive(Insertable, Debug)]
|
||||
#[table_name = "guild_playlists"]
|
||||
pub struct GuildPlaylistInsert {
|
||||
pub guild_id: i64,
|
||||
pub name: String,
|
||||
pub url: String,
|
||||
}
|
||||
|
||||
#[derive(Queryable, Debug, Clone)]
|
||||
pub struct Media {
|
||||
pub id: i64,
|
||||
pub category: Option<String>,
|
||||
pub name: Option<String>,
|
||||
pub url: String,
|
||||
}
|
||||
|
||||
#[derive(Insertable, Debug)]
|
||||
#[table_name = "media"]
|
||||
pub struct MediaInsert {
|
||||
pub category: Option<String>,
|
||||
pub name: Option<String>,
|
||||
pub url: String,
|
||||
}
|
||||
|
||||
#[derive(Insertable, Debug)]
|
||||
#[table_name = "statistics"]
|
||||
pub struct StatisticInsert {
|
||||
pub version: String,
|
||||
pub command: String,
|
||||
pub executed_at: SystemTime,
|
||||
pub success: bool,
|
||||
pub error_msg: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Queryable, Debug, Clone)]
|
||||
pub struct YoutubeSong {
|
||||
pub id: i64,
|
||||
pub spotify_id: String,
|
||||
pub artist: String,
|
||||
pub title: String,
|
||||
pub album: String,
|
||||
pub url: String,
|
||||
pub score: i32,
|
||||
}
|
||||
|
||||
#[derive(Insertable, Debug)]
|
||||
#[table_name = "youtube_songs"]
|
||||
pub struct YoutubeSongInsert {
|
||||
pub spotify_id: String,
|
||||
pub artist: String,
|
||||
pub title: String,
|
||||
pub album: String,
|
||||
pub url: String,
|
||||
}
|
||||
|
||||
#[derive(Queryable, Debug, Clone)]
|
||||
pub struct EphemeralMessage {
|
||||
pub channel_id: i64,
|
||||
pub message_id: i64,
|
||||
pub timeout: SystemTime,
|
||||
}
|
||||
|
||||
#[derive(Insertable, Debug)]
|
||||
#[table_name = "ephemeral_messages"]
|
||||
pub struct EphemeralMessageInsert {
|
||||
pub channel_id: i64,
|
||||
pub message_id: i64,
|
||||
pub timeout: SystemTime,
|
||||
}
|
||||
use super::entity;
|
||||
|
||||
pub use entity::ephemeral_messages::Model as EphemeralMessage;
|
||||
pub use entity::guild_playlists::Model as GuildPlaylist;
|
||||
pub use entity::guild_settings::Model as GuildSetting;
|
||||
pub use entity::media::Model as Media;
|
||||
pub use entity::statistics::Model as Statistic;
|
||||
pub use entity::youtube_songs::Model as YoutubeSong;
|
||||
|
@ -1,64 +0,0 @@
|
||||
table! {
|
||||
ephemeral_messages (channel_id, message_id) {
|
||||
channel_id -> Int8,
|
||||
message_id -> Int8,
|
||||
timeout -> Timestamp,
|
||||
}
|
||||
}
|
||||
|
||||
table! {
|
||||
guild_playlists (guild_id, name) {
|
||||
guild_id -> Int8,
|
||||
name -> Varchar,
|
||||
url -> Varchar,
|
||||
}
|
||||
}
|
||||
|
||||
table! {
|
||||
guild_settings (guild_id, key) {
|
||||
guild_id -> Int8,
|
||||
key -> Varchar,
|
||||
value -> Nullable<Varchar>,
|
||||
}
|
||||
}
|
||||
|
||||
table! {
|
||||
media (id) {
|
||||
id -> Int8,
|
||||
category -> Nullable<Varchar>,
|
||||
name -> Nullable<Varchar>,
|
||||
url -> Varchar,
|
||||
}
|
||||
}
|
||||
|
||||
table! {
|
||||
statistics (id) {
|
||||
id -> Int8,
|
||||
version -> Varchar,
|
||||
command -> Varchar,
|
||||
executed_at -> Timestamp,
|
||||
success -> Bool,
|
||||
error_msg -> Nullable<Text>,
|
||||
}
|
||||
}
|
||||
|
||||
table! {
|
||||
youtube_songs (id) {
|
||||
id -> Int8,
|
||||
spotify_id -> Varchar,
|
||||
artist -> Varchar,
|
||||
title -> Varchar,
|
||||
album -> Varchar,
|
||||
url -> Varchar,
|
||||
score -> Int4,
|
||||
}
|
||||
}
|
||||
|
||||
allow_tables_to_appear_in_same_query!(
|
||||
ephemeral_messages,
|
||||
guild_playlists,
|
||||
guild_settings,
|
||||
media,
|
||||
statistics,
|
||||
youtube_songs,
|
||||
);
|
@ -1,40 +0,0 @@
|
||||
use serenity::client::Context;
|
||||
use serenity::framework::standard::macros::command;
|
||||
use serenity::framework::standard::CommandResult;
|
||||
use serenity::model::channel::Message;
|
||||
|
||||
use crate::commands::common::handle_autodelete;
|
||||
use crate::providers::music::lavalink::Lavalink;
|
||||
use crate::utils::initialize_lavalink;
|
||||
use serenity_rich_interaction::core::SHORT_TIMEOUT;
|
||||
use serenity_rich_interaction::ephemeral_message::EphemeralMessage;
|
||||
use std::mem;
|
||||
use std::sync::Arc;
|
||||
|
||||
#[command]
|
||||
#[description("Resets the lavalink connection")]
|
||||
#[aliases("reconnect_lavalink", "reset-lavalink", "reconnect-lavalink")]
|
||||
#[num_args(0)]
|
||||
#[owners_only]
|
||||
async fn reset_lavalink(ctx: &Context, msg: &Message) -> CommandResult {
|
||||
let app_info = ctx.http.get_current_application_info().await?;
|
||||
destroy_lavalink(ctx).await;
|
||||
|
||||
initialize_lavalink(Arc::clone(&ctx.data), app_info).await?;
|
||||
|
||||
EphemeralMessage::create(&ctx.http, msg.channel_id, SHORT_TIMEOUT, |m| {
|
||||
m.content("Reconnected to lavalink")
|
||||
})
|
||||
.await?;
|
||||
handle_autodelete(ctx, msg).await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn destroy_lavalink(ctx: &Context) {
|
||||
let mut data = ctx.data.write().await;
|
||||
{
|
||||
let lava_client = data.remove::<Lavalink>().unwrap();
|
||||
mem::drop(lava_client);
|
||||
}
|
||||
}
|
@ -1,62 +0,0 @@
|
||||
use serenity::framework::standard::macros::command;
|
||||
use serenity::framework::standard::{Args, CommandError, CommandResult};
|
||||
use serenity::model::channel::Message;
|
||||
use serenity::prelude::*;
|
||||
|
||||
use crate::commands::common::handle_autodelete;
|
||||
use crate::commands::music::{get_music_player_for_guild, DJ_CHECK};
|
||||
use crate::messages::music::no_voicechannel::create_no_voicechannel_message;
|
||||
use serenity_rich_interaction::core::{MEDIUM_TIMEOUT, SHORT_TIMEOUT};
|
||||
use serenity_rich_interaction::ephemeral_message::EphemeralMessage;
|
||||
|
||||
#[command]
|
||||
#[only_in(guilds)]
|
||||
#[description("Loads an equalizer preset")]
|
||||
#[usage("<preset>")]
|
||||
#[num_args(1)]
|
||||
#[example("bass")]
|
||||
#[bucket("general")]
|
||||
#[checks(DJ)]
|
||||
async fn equalize(ctx: &Context, msg: &Message, mut args: Args) -> CommandResult {
|
||||
let guild = msg.guild(&ctx.cache).await.unwrap();
|
||||
log::debug!("Changing equalizer for {}", guild.id);
|
||||
let preset = args.single::<String>().unwrap();
|
||||
|
||||
let player = if let Some(player) = get_music_player_for_guild(ctx, guild.id).await {
|
||||
player
|
||||
} else {
|
||||
return create_no_voicechannel_message(&ctx.http, msg.channel_id)
|
||||
.await
|
||||
.map_err(CommandError::from);
|
||||
};
|
||||
|
||||
let bands = match preset.to_lowercase().as_str() {
|
||||
"metal" => lavalink_rs::EQ_METAL,
|
||||
"boost" => lavalink_rs::EQ_BOOST,
|
||||
"base" => lavalink_rs::EQ_BASE,
|
||||
"piano" => lavalink_rs::EQ_PIANO,
|
||||
_ => {
|
||||
EphemeralMessage::create(&ctx.http, msg.channel_id, MEDIUM_TIMEOUT, |m| {
|
||||
m.content(format!(
|
||||
"Unknown preset '{}'. Available are 'metal', 'boost', 'base' and 'piano'",
|
||||
preset
|
||||
))
|
||||
})
|
||||
.await?;
|
||||
handle_autodelete(ctx, msg).await?;
|
||||
return Ok(());
|
||||
}
|
||||
};
|
||||
{
|
||||
let mut player = player.lock().await;
|
||||
player.equalize_all(bands).await?;
|
||||
}
|
||||
EphemeralMessage::create(&ctx.http, msg.channel_id, SHORT_TIMEOUT, |m| {
|
||||
m.content(format!("🎛️ Changed equalizer to '{}'", preset))
|
||||
})
|
||||
.await?;
|
||||
|
||||
handle_autodelete(ctx, msg).await?;
|
||||
|
||||
Ok(())
|
||||
}
|
@ -1,33 +0,0 @@
|
||||
use serenity::framework::standard::macros::command;
|
||||
use serenity::framework::standard::{CommandError, CommandResult};
|
||||
use serenity::model::channel::Message;
|
||||
use serenity::prelude::*;
|
||||
|
||||
use crate::commands::common::handle_autodelete;
|
||||
use crate::commands::music::{get_music_player_for_guild, DJ_CHECK};
|
||||
use crate::messages::music::equalizer::create_equalizer_message;
|
||||
use crate::messages::music::no_voicechannel::create_no_voicechannel_message;
|
||||
|
||||
#[command]
|
||||
#[only_in(guilds)]
|
||||
#[description("Displays the equalizer for the music player")]
|
||||
#[usage("")]
|
||||
#[bucket("general")]
|
||||
#[checks(DJ)]
|
||||
async fn equalizer(ctx: &Context, msg: &Message) -> CommandResult {
|
||||
let guild = msg.guild(&ctx.cache).await.unwrap();
|
||||
log::debug!("Displaying equalizer for guild {}", guild.id);
|
||||
|
||||
let player = if let Some(player) = get_music_player_for_guild(ctx, guild.id).await {
|
||||
player
|
||||
} else {
|
||||
return create_no_voicechannel_message(&ctx.http, msg.channel_id)
|
||||
.await
|
||||
.map_err(CommandError::from);
|
||||
};
|
||||
|
||||
create_equalizer_message(&ctx, msg.channel_id, player).await?;
|
||||
handle_autodelete(ctx, msg).await?;
|
||||
|
||||
Ok(())
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue