diff --git a/.actrc b/.actrc new file mode 100644 index 0000000..64bdd0b --- /dev/null +++ b/.actrc @@ -0,0 +1,10 @@ +--container-architecture linux/amd64 +-P ubuntu-latest=ghcr.io/catthehacker/ubuntu:act-latest +--pull=false +--action-offline-mode +--container-options +--privileged +--container-options +--security-opt=seccomp=unconfined +--container-options +--security-opt=apparmor=unconfined diff --git a/.github/actions/rust-nightly-setup/action.yml b/.github/actions/rust-nightly-setup/action.yml new file mode 100644 index 0000000..69053ad --- /dev/null +++ b/.github/actions/rust-nightly-setup/action.yml @@ -0,0 +1,56 @@ +name: Rust Nightly Setup + +description: Install Linux prerequisites and setup Rust nightly toolchain for local and GitHub runners + +inputs: + rust_target: + description: Rust target triple to add + required: false + default: "" + +runs: + using: composite + steps: + - name: Installing Prerequisites (Linux) + shell: bash + run: | + if command -v sudo >/dev/null 2>&1; then + sudo apt-get update -y + sudo apt-get install -y python3 pip build-essential curl liburing-dev clang libclang-dev llvm-dev + else + apt-get update -y + apt-get install -y python3 pip build-essential curl liburing-dev clang libclang-dev llvm-dev + fi + + - name: Install rustup + shell: bash + run: | + if ! command -v rustup >/dev/null 2>&1; then + curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --profile minimal --default-toolchain nightly + fi + echo "$HOME/.cargo/bin" >> "$GITHUB_PATH" + + - name: Install Rust Nightly + shell: bash + run: | + if ! rustup toolchain list | grep -q '^nightly'; then + rustup toolchain install nightly --profile minimal + fi + rustup default nightly + + - name: Install rustfmt + shell: bash + run: | + rustup component add rustfmt --toolchain nightly + HOST_TRIPLE="$(rustc -vV | sed -n 's/^host: //p')" + if [ -n "$HOST_TRIPLE" ]; then + rustup component add rustfmt --toolchain "nightly-${HOST_TRIPLE}" + fi + + - name: Add Rust target + if: ${{ inputs.rust_target != '' }} + shell: bash + run: | + if ! rustup target list --installed --toolchain nightly | grep -q "^${{ inputs.rust_target }}$"; then + rustup target add "${{ inputs.rust_target }}" + fi diff --git a/.github/run-actions-locally.md b/.github/run-actions-locally.md index 93c3463..c320fa6 100644 --- a/.github/run-actions-locally.md +++ b/.github/run-actions-locally.md @@ -1,3 +1,209 @@ -## Run your GitHub Actions locally +## Run GitHub Actions locally with `act` -https://nektosact.com/introduction.html +Reference: https://nektosact.com/introduction.html + +## Prerequisites + +- Docker is installed and running. +- `act` is installed and available in `PATH`. +- Linux is required for full `io_uring` coverage. +- This repo includes a default `.actrc` for the local build workflow. + +### Install act + +```bash +curl --proto '=https' --tlsv1.2 -sSf https://raw.githubusercontent.com/nektos/act/master/install.sh | bash -s -- -b $HOME/.local/bin +``` + +### Install docker + +Reference: https://docs.docker.com/engine/install + + +### Check your environment + +```bash +docker --version +act --version +``` + +## `io_uring` setup + +Local `io_uring` tests depend on both the host kernel and the Docker runtime used by `act`. + +- Linux kernel should support `io_uring` (recommended `>= 5.10`). +- `io_uring` must not be disabled by kernel policy. +- `act` must create the job container with `--privileged`, `seccomp=unconfined`, and `apparmor=unconfined`. +- Your user must be able to access Docker normally; rootless/restricted Docker setups may still block `io_uring` inside `act`. + +Quick host check: + +```bash +uname -r +cat /proc/sys/kernel/io_uring_disabled +docker info +``` + +Known-good `.actrc`: + +```text +--container-architecture linux/amd64 +-P ubuntu-latest=ghcr.io/catthehacker/ubuntu:act-latest +--pull=false +--action-offline-mode +--privileged +--container-options +--security-opt=seccomp=unconfined +--container-options +--security-opt=apparmor=unconfined +``` + +## Why this exists + +We hit a local `act` failure where the host supported `io_uring`, but the `act` job container did not actually start with the required Docker security settings. + +Observed error: + +```text +io_uring_queue_init_params error -1 +``` + +What we confirmed: + +- Host kernel supported `io_uring`. +- `/proc/sys/kernel/io_uring_disabled` was `0`. +- Docker itself was healthy and reachable. +- The failing `act` job container had `Privileged=false`. +- The failing `act` job container only had `apparmor=unconfined`, not `seccomp=unconfined`. + +Root cause: + +- A stale reused `act` container had been created before the Docker security options were corrected. +- Because reuse preserves the old container configuration, later `act` runs kept using the wrong runtime settings. + +## Verify the `act` container + +Inspect the running job container: + +```bash +docker inspect --format '{{.HostConfig.Privileged}}' +docker inspect --format '{{json .HostConfig.SecurityOpt}}' +``` + +Expected: + +- `true` +- security options including both `seccomp=unconfined` and `apparmor=unconfined` + +If you change `.actrc` container security settings, remove the old `act` container before rerunning: + +```bash +docker ps +docker rm -f +``` + +## Common commands + +First run or refresh image: + +```bash +act -W .github/workflows/build.yaml -j build --pull=true +``` + +Normal run: + +```bash +act -W .github/workflows/build.yaml -j build +``` + +Verbose run: + +```bash +act -W .github/workflows/build.yaml -j build -v +``` + +Reuse only after the security settings are known-good: + +```bash +act -W .github/workflows/build.yaml -j build --reuse +``` + +Run the release workflow locally with a GitHub token: + +```bash +act workflow_dispatch \ + -W .github/workflows/build-release.yml \ + -j build-release \ + -s GITHUB_TOKEN=ghp_xxx +``` + +The release workflow uses `softprops/action-gh-release` to create or update a GitHub +Release. On GitHub Actions, `GITHUB_TOKEN` is provided automatically. When running under +`act`, secrets are not available unless passed with `-s` or `--secret-file`, so the +workflow skips the publish step unless a token is provided. Without this guard, the +release step fails with: + +```text +Parameter token or opts.auth is required +``` + +Use a token only when you intentionally want the local run to publish or update a real +GitHub release. For local build and packaging checks, omit `GITHUB_TOKEN`; the workflow +will still build and verify release artifacts. + +### Keep release artifacts in the local checkout + +By default, `act` may run the job in a copied container workspace. Files generated by the +workflow, including release tarballs, can remain inside the job container instead of +appearing in this repo checkout. + +Use `--bind` when you want generated files to be written back to the local workspace: + +```bash +act workflow_dispatch \ + -W .github/workflows/build-release.yml \ + -j build-release \ + --bind +``` + +With `--bind`, the release workflow writes the package and checksum to: + +```text +target/release-artifacts///bin/ +target/release-artifacts///lib/ +target/release-artifacts///lib/lib-list.txt +target/release-artifacts///manifest.txt +target/release-artifacts//mududb--x86_64-unknown-linux-gnu.tar.gz +target/release-artifacts//mududb--x86_64-unknown-linux-gnu.tar.gz.sha256 +target/release-artifacts//CHANGELOG_RELEASE.md +``` + +The tarball stores the payload under a top-level `/` directory. Binaries are in +`/bin/`, `lib/lib-list.txt` is copied from `build-release/lib-list.txt`, and +`manifest.txt` records the packaged files. When the `act` job runs as root with `--bind`, +the workflow resets the generated +`target/release-artifacts/` directory ownership to the local checkout owner and +group so generated files are not left as `root:root`. It also mirrors owner permissions +to group and other users for generated artifact files and directories. + +## Workflow inputs + +Enable `cargo clean`: + +```bash +act workflow_dispatch -W .github/workflows/build.yaml -j build --input clean_cargo=true +``` + +Run release tests: + +```bash +act workflow_dispatch -W .github/workflows/build.yaml -j build --input release_test=true +``` + +## Optional local Rust caches + +```bash +export CARGO_HOME="$HOME/.cargo" +export RUSTUP_HOME="$HOME/.rustup" +act -W .github/workflows/build.yaml -j build +``` diff --git a/.github/workflows/build-release.yml b/.github/workflows/build-release.yml new file mode 100644 index 0000000..f70de19 --- /dev/null +++ b/.github/workflows/build-release.yml @@ -0,0 +1,215 @@ +name: Release + +on: + push: + tags: + - 'v*' + workflow_dispatch: + inputs: + prerelease: + description: 'Mark as pre-release' + required: false + type: boolean + default: true + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +permissions: + contents: write + packages: write + +jobs: + build-release: + name: Build Release - ${{ matrix.os }} + runs-on: ${{ matrix.os }} + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + strategy: + matrix: + os: [ubuntu-latest] + include: + - os: ubuntu-latest + rust_target: x86_64-unknown-linux-gnu + asset_suffix: x86_64-unknown-linux-gnu + + steps: + - name: Checkout Code + uses: actions/checkout@v5 + with: + fetch-depth: 0 + + - name: Resolve Release Version + id: version + run: | + if [[ "${GITHUB_REF_TYPE}" == "tag" && -n "${GITHUB_REF_NAME}" ]]; then + VERSION="${GITHUB_REF_NAME}" + else + VERSION="v$(date -u +'%Y%m%d.%H%M')" + fi + echo "tag=${VERSION}" >> $GITHUB_OUTPUT + echo "version=${VERSION}" >> $GITHUB_OUTPUT + echo "Resolved version: ${VERSION}" + + - name: Setup Rust Nightly + if: matrix.os == 'ubuntu-latest' + uses: ./.github/actions/rust-nightly-setup + with: + rust_target: ${{ matrix.rust_target }} + + - name: Cache Cargo Registry + uses: actions/cache@v3 + with: + path: | + ~/.cargo/registry + ~/.cargo/git + target + key: ${{ runner.os }}-cargo-release-${{ hashFiles('**/Cargo.lock') }} + restore-keys: | + ${{ runner.os }}-cargo-release + + - name: Build Release Binaries + run: | + RUSTFLAGS="-C link-arg=-Wl,-rpath,\$ORIGIN/../lib" \ + cargo build --release --target ${{ matrix.rust_target }} + + - name: Collect Binaries + run: | + VERSION="${{ steps.version.outputs.version }}" + ARTIFACT_DIR="target/release-artifacts/${VERSION}" + PACKAGE_DIR="${ARTIFACT_DIR}/${VERSION}" + BIN_DIR="${PACKAGE_DIR}/bin" + LIB_DIR="${PACKAGE_DIR}/lib" + SOURCE_LIB_LIST_FILE="build-release/lib-list.txt" + LIB_LIST_FILE="${LIB_DIR}/lib-list.txt" + MANIFEST_FILE="${PACKAGE_DIR}/manifest.txt" + rm -rf "${ARTIFACT_DIR}" + mkdir -p "${BIN_DIR}" "${LIB_DIR}" + + # Define supported binaries and their descriptions + declare -A BIN_MAP + BIN_MAP=( + ["mudu_package"]="mpk" + ["mudu_gen"]="mgen" + ["mudu_transpiler"]="mtp" + ["mudud"]="mudud" + ["mudu_cli"]="mcli" + ) + + TARGET_DIR="target/${{ matrix.rust_target }}/release" + + for pkg_name in "${!BIN_MAP[@]}"; do + bin_name="${BIN_MAP[$pkg_name]}" + bin_path="$TARGET_DIR/$bin_name" + if [[ -f "$bin_path" ]]; then + cp "$bin_path" "${BIN_DIR}/" + echo "Copied $bin_name to ${BIN_DIR}/" + else + echo "WARNING: Binary $bin_name not found at $bin_path" + fi + done + + SUFFIX="${{ matrix.asset_suffix }}" + ARCHIVE_NAME="mududb-${VERSION}-${SUFFIX}.tar.gz" + ARCHIVE_URI="https://github.com/${GITHUB_REPOSITORY}/releases/download/${VERSION}/${ARCHIVE_NAME}" + + if [[ ! -f "${SOURCE_LIB_LIST_FILE}" ]]; then + echo "ERROR: Dynamic library list not found at ${SOURCE_LIB_LIST_FILE}" + exit 1 + fi + cp "${SOURCE_LIB_LIST_FILE}" "${LIB_LIST_FILE}" + + { + echo "name=mududb" + echo "version=${VERSION}" + echo "target=${{ matrix.rust_target }}" + echo "archive=${ARCHIVE_NAME}" + echo "archive_uri=${ARCHIVE_URI}" + echo "bin_dir=bin" + echo "lib_dir=lib" + echo "lib_list=lib/lib-list.txt" + echo "" + echo "[files]" + find "${PACKAGE_DIR}" -type f -printf "%P\n" | sort + } > "${MANIFEST_FILE}" + + # Create tarball with a top-level / directory. + tar -czf "${ARTIFACT_DIR}/${ARCHIVE_NAME}" -C "${ARTIFACT_DIR}" "${VERSION}" + + echo "archive=${ARCHIVE_NAME}" >> $GITHUB_OUTPUT + + # Generate SHA256 checksums + sha256sum "${ARTIFACT_DIR}/${ARCHIVE_NAME}" > "${ARTIFACT_DIR}/${ARCHIVE_NAME}.sha256" + echo "Generated checksum file" + + - name: Generate Changelog + run: | + VERSION="${{ steps.version.outputs.version }}" + ARTIFACT_DIR="target/release-artifacts/${VERSION}" + CHANGELOG_FILE="${ARTIFACT_DIR}/CHANGELOG_RELEASE.md" + mkdir -p "${ARTIFACT_DIR}" + echo "# Changelog: ${VERSION}" > "${CHANGELOG_FILE}" + echo "" >> "${CHANGELOG_FILE}" + echo "## Changes" >> "${CHANGELOG_FILE}" + echo "" >> "${CHANGELOG_FILE}" + + # Get previous tag or use initial commit + PREV_TAG=$(git tag --sort=-v:refname | grep -v "${VERSION}" | head -1) + if [[ -n "$PREV_TAG" ]]; then + echo "Changes since ${PREV_TAG}:" >> "${CHANGELOG_FILE}" + echo "" >> "${CHANGELOG_FILE}" + git log "${PREV_TAG}..HEAD" --pretty=format:"- %s (%h)" >> "${CHANGELOG_FILE}" + else + echo "Initial release:" >> "${CHANGELOG_FILE}" + echo "" >> "${CHANGELOG_FILE}" + git log --pretty=format:"- %s (%h)" >> "${CHANGELOG_FILE}" + fi + + echo "" >> "${CHANGELOG_FILE}" + echo "" >> "${CHANGELOG_FILE}" + echo "**Full Commit History**: https://github.com/${{ github.repository }}/commits/${{ github.ref_name }}" >> "${CHANGELOG_FILE}" + + - name: Normalize Local Artifact Ownership + run: | + VERSION="${{ steps.version.outputs.version }}" + ARTIFACT_ROOT="target/release-artifacts" + ARTIFACT_DIR="${ARTIFACT_ROOT}/${VERSION}" + + # When act runs with --bind as root, keep generated local files owned by + # the host checkout owner instead of root. + if [[ "$(id -u)" -eq 0 ]]; then + WORKSPACE_OWNER="$(stat -c '%u:%g' "${GITHUB_WORKSPACE:-.}")" + chown "${WORKSPACE_OWNER}" "${ARTIFACT_ROOT}" || true + chown -R "${WORKSPACE_OWNER}" "${ARTIFACT_DIR}" + fi + + - name: Create GitHub Release + if: ${{ env.GITHUB_TOKEN != '' }} + uses: softprops/action-gh-release@v2 + with: + tag_name: ${{ steps.version.outputs.tag }} + name: "MuduDB ${{ steps.version.outputs.version }}" + body_path: target/release-artifacts/${{ steps.version.outputs.version }}/CHANGELOG_RELEASE.md + files: | + target/release-artifacts/${{ steps.version.outputs.version }}/*.tar.gz + target/release-artifacts/${{ steps.version.outputs.version }}/*.sha256 + draft: false + prerelease: ${{ inputs.prerelease || false }} + generate_release_notes: false + + - name: Skip GitHub Release + if: ${{ env.GITHUB_TOKEN == '' }} + run: | + echo "GITHUB_TOKEN is not set; skipping GitHub release publishing." + + - name: Verify Release Assets + run: | + VERSION="${{ steps.version.outputs.version }}" + ARTIFACT_DIR="target/release-artifacts/${VERSION}" + + echo "Release artifacts:" + ls -lh "${ARTIFACT_DIR}/" + echo "" + echo "Checksums:" + cat "${ARTIFACT_DIR}"/*.sha256 || true diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 137dd2c..9288ade 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -3,13 +3,45 @@ name: Build on: push: branches: [ main, master ] + paths-ignore: + - '**/*.md' + - 'doc/**' + - '.github/run-actions-locally.md' pull_request: branches: [ main, master ] + paths-ignore: + - '**/*.md' + - 'doc/**' + - '.github/run-actions-locally.md' + workflow_dispatch: + inputs: + clean_cargo: + description: 'Run cargo clean before build' + required: false + type: boolean + default: false + release_test: + description: 'Run tests in release mode' + required: false + type: boolean + default: false + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true jobs: build: name: Build - ${{ matrix.os }} runs-on: ${{ matrix.os }} + env: + ENABLE_CARGO_CLEAN: ${{ github.event.inputs.clean_cargo || 'true' }} + ENABLE_RELEASE_TEST: ${{ github.event.inputs.release_test || 'true' }} + CARGO_INCREMENTAL: 0 + CARGO_BUILD_JOBS: 2 + CARGO_PROFILE_DEV_DEBUG: 0 + CARGO_PROFILE_TEST_DEBUG: 0 + CARGO_PROFILE_RELEASE_DEBUG: 0 strategy: matrix: os: [ ubuntu-latest ] @@ -21,24 +53,21 @@ jobs: - name: Checkout Code uses: actions/checkout@v5 - - name: Installing Prerequisites (Linux) + - name: Setup Rust Nightly if: matrix.os == 'ubuntu-latest' - run: | - sudo apt-get update -y - sudo apt-get install -y python3 pip build-essential curl liburing-dev - curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y - echo "PATH=$PATH:$HOME/.cargo/bin" >> $GITHUB_ENV + uses: ./.github/actions/rust-nightly-setup + with: + rust_target: ${{ matrix.rust_target }} - - name: Install Rust Nightly + - name: Free disk space + if: matrix.os == 'ubuntu-latest' run: | - rustup toolchain install nightly - rustup default nightly - - - name: Install rustfmt - run: rustup component add rustfmt --toolchain nightly - - - name: Update Rust Toolchain - run: rustup update nightly + df -h + sudo rm -rf /usr/share/dotnet + sudo rm -rf /usr/local/lib/android + sudo rm -rf /opt/ghc + docker system prune -af || true + df -h - name: Cache Cargo Registry uses: actions/cache@v3 @@ -46,20 +75,34 @@ jobs: path: | ~/.cargo/registry ~/.cargo/git - target key: ${{ runner.os }}-cargo-nightly-${{ hashFiles('**/Cargo.lock') }} restore-keys: | ${{ runner.os }}-cargo-nightly - - name: Clean cargo cache + - name: Clean cargo cache (optional) + if: env.ENABLE_CARGO_CLEAN == 'true' run: cargo clean - - name: Build - run: cargo build --release + - name: Check (debug) + if: env.ENABLE_RELEASE_TEST != 'true' + run: cargo check + + - name: Check (release) + if: env.ENABLE_RELEASE_TEST == 'true' + run: cargo check --release - name: Verify Install Script (Linux) if: matrix.os == 'ubuntu-latest' run: python3 script/build/install_binaries.py --dry-run - - name: Test + - name: Inspect io_uring Environment (Linux) + if: matrix.os == 'ubuntu-latest' + run: bash script/build/inspect_iouring_env.sh + + - name: Test (debug) + if: env.ENABLE_RELEASE_TEST != 'true' + run: cargo test + + - name: Test (release) + if: env.ENABLE_RELEASE_TEST == 'true' run: cargo test --release diff --git a/Cargo.lock b/Cargo.lock index ab93364..8a42e18 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2412,12 +2412,8 @@ name = "game-backend" version = "0.1.0" dependencies = [ "chrono", - "mudu", - "mudu_binding", - "mudu_contract", - "mudu_type", + "mududb", "serde_json", - "sys_interface", "uuid", "wit-bindgen 0.54.0", ] @@ -3274,12 +3270,8 @@ dependencies = [ name = "key-value" version = "0.1.0" dependencies = [ - "mudu", "mudu_adapter", - "mudu_binding", - "mudu_contract", - "mudu_type", - "sys_interface", + "mududb", "wit-bindgen 0.54.0", ] @@ -3781,12 +3773,7 @@ name = "mod_0" version = "0.1.0" dependencies = [ "lazy_static", - "mudu", - "mudu_binding", - "mudu_contract", - "mudu_macro", - "mudu_type", - "sys_interface", + "mududb", "wit-bindgen 0.54.0", ] @@ -3953,32 +3940,6 @@ dependencies = [ "uuid", ] -[[package]] -name = "mudu_macro" -version = "0.1.0" -dependencies = [ - "mudu", - "mudu_binding", - "mudu_contract", - "mudu_type", - "proc-macro2", - "quote", - "syn 2.0.111", - "wit-bindgen 0.54.0", -] - -[[package]] -name = "mudu_macro_test" -version = "0.1.0" -dependencies = [ - "mudu", - "mudu_binding", - "mudu_contract", - "mudu_macro", - "mudu_type", - "wit-bindgen 0.54.0", -] - [[package]] name = "mudu_package" version = "0.1.0" @@ -4122,6 +4083,31 @@ dependencies = [ "tracing", ] +[[package]] +name = "mududb" +version = "0.1.0" +dependencies = [ + "mudu", + "mudu_binding", + "mudu_contract", + "mudu_sys", + "mudu_type", + "sys_interface", +] + +[[package]] +name = "mudup" +version = "0.1.0" +dependencies = [ + "anyhow", + "clap", + "reqwest", + "serde", + "sha2", + "tokio", + "toml 1.1.0+spec-1.1.0", +] + [[package]] name = "mysql" version = "28.0.0" @@ -6731,16 +6717,11 @@ dependencies = [ "async-backtrace", "clap", "lazy_static", - "mudu", "mudu_adapter", - "mudu_binding", "mudu_cli", - "mudu_contract", "mudu_runtime", - "mudu_sys", - "mudu_type", "mudu_utils", - "sys_interface", + "mududb", "testing", "tokio", "wit-bindgen 0.54.0", @@ -7150,12 +7131,7 @@ dependencies = [ "chrono", "fallible-iterator 0.3.0", "lazy_static", - "mudu", - "mudu_binding", - "mudu_contract", - "mudu_sys", - "mudu_type", - "sys_interface", + "mududb", "uuid", "wit-bindgen 0.54.0", ] @@ -7175,13 +7151,7 @@ name = "wallet" version = "0.1.0" dependencies = [ "lazy_static", - "mudu", - "mudu_binding", - "mudu_contract", - "mudu_sys", - "mudu_type", - "sys_interface", - "uuid", + "mududb", "wit-bindgen 0.54.0", ] @@ -8516,15 +8486,10 @@ version = "0.1.0" dependencies = [ "async-backtrace", "clap", - "mudu", "mudu_adapter", - "mudu_binding", "mudu_cli", - "mudu_contract", - "mudu_sys", - "mudu_type", "mudu_utils", - "sys_interface", + "mududb", "tokio", "wit-bindgen 0.54.0", ] diff --git a/Cargo.toml b/Cargo.toml index 11ac065..7c73272 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,6 +2,7 @@ resolver = "2" members = [ + "mududb", "testing", "mudu", "mudu_sys", @@ -20,8 +21,6 @@ members = [ "sql_parser", "tree-sitter-sql", "tree-sitter-wit", - "mudu_macro", - "mudu_macro_test", "mudu_wasm", "mudu_utils", "mudu_api_sync", @@ -31,7 +30,11 @@ members = [ "mudud", "mudu_package", "mudu_transpiler", - "mudu_cli"] + "mudu_cli", + "mudup"] + +[profile.release] +panic = "abort" [workspace.dependencies] arbitrary = { version = "1.4.2", features = ["derive", "derive_arbitrary"] } @@ -39,6 +42,7 @@ test_utils = { path = "test_utils" } sys_interface = { path = "sys_interface" } mudu_adapter = { path = "mudu_adapter" } mudu = { path = "mudu" } +mududb = { path = "mududb" } mudu_sys = { path = "mudu_sys" } mudu_binding = { path = "mudu_binding" } md-5 = { version = "0.11.0-rc.0" } @@ -49,11 +53,11 @@ tree-sitter-wit = { path = "tree-sitter-wit" } tree-sitter = { version = "0.26.2" } tree-sitter-language = { version = "0.1.6" } serde_json = { version = "1.0.145", features = ["preserve_order"] } +sha2 = { version = "0.10.9" } project-root = { version = "0.2.2" } mudu_runtime = { path = "mudu_runtime" } mudu_kernel = { path = "mudu_kernel" } mudu_cli = { path = "mudu_cli" } -mudu_macro = { path = "mudu_macro" } mudu_utils = { path = "mudu_utils" } mudu_type = { path = "mudu_type" } mudu_contract = { path = "mudu_contract" } diff --git a/build-release/lib-list.txt b/build-release/lib-list.txt new file mode 100644 index 0000000..e69de29 diff --git a/doc/cn/how_to_start.cn.md b/doc/cn/how_to_start.cn.md index 454f5fc..d739100 100644 --- a/doc/cn/how_to_start.cn.md +++ b/doc/cn/how_to_start.cn.md @@ -14,7 +14,16 @@ git clone https://github.com/scuptio/mududb.git ```bash sudo apt-get update -y -sudo apt-get install -y python3 python3-pip clang build-essential curl liburing-dev +sudo apt-get install -y \ + python3 \ + python3-pip \ + python-is-python3 \ + build-essential \ + curl liburing-dev \ + clang \ + libclang-dev \ + llvm-dev \ + pkgconf ``` 这些软件包的用途如下: @@ -23,8 +32,7 @@ sudo apt-get install -y python3 python3-pip clang build-essential curl liburing- - `build-essential`:Linux 上原生编译所需 - `curl`:用于通过 `rustup` 安装 Rust - `liburing-dev`:仅 Linux 上由 `mudu_kernel` 使用原生 `io_uring` 后端时需要 - -如果你是在 Windows 上构建,则不需要 `liburing-dev`,因为原生 `io_uring` 路径仅适用于 Linux。 +- `clang`、`libclang-dev`、`llvm-dev`:*[bindgen](https://github.com/rust-lang/rust-bindgen)* 需要 ### Rust 工具链 diff --git a/doc/cn/procedure.cn.md b/doc/cn/procedure.cn.md index 43cfa4f..c5693bf 100644 --- a/doc/cn/procedure.cn.md +++ b/doc/cn/procedure.cn.md @@ -53,7 +53,7 @@ Mudu Runtime 当前支持 Rust。基于 Rust 的过程使用如下函数签名 ## 过程规范 ``` -#[mudu_proc] +/**mudu-proc**/ fn {procedure_name}( oid: OID, {argument_list...} @@ -64,9 +64,9 @@ fn {procedure_name}( 一个合法的 Rust 函数名。 -### 宏 `#[mudu_proc]`: +### 标记 `/**mudu-proc**/`: -用于将该函数标记为 Mudu Procedure。 +用于将紧随其后的函数标记为 Mudu Procedure,供 transpiler 生成过程包装代码。 ### 参数: @@ -81,7 +81,7 @@ fn {procedure_name}( 常见可用形式包括标量类型,如 `i32`、`i64`、`String`、`f32`、`f64`,以及当前示例中已经使用到的 `Vec` 等容器形式。 -精确支持范围以当前 `mudu_macro` / `mudu_type` 实现为准,而不是本文中的一个固定短名单。 +精确支持范围以当前 `mudu_type` 转换体系和 transpiler 实现为准,而不是本文中的一个固定短名单。 ### 返回值: @@ -323,7 +323,7 @@ content="[Transfer](../../example/wallet/src/rust/procedures.rs#L23-L104)" lang="rust" --> ```rust -#[mudu_proc] +/**mudu-proc**/ pub fn transfer_funds(oid: OID, from_user_id: i32, to_user_id: i32, amount: i32) -> RS<()> { // Check amount > 0 if amount <= 0 { @@ -468,7 +468,7 @@ Mudu 的强类型 API 提供了: ```rust // Prepare AI training dataset without export/import -#[mudu_proc] +/**mudu-proc**/ fn prepare_training_data(oid: OID) -> RS<()> { mudu_command(oid, sql_stmt!("..."), @@ -490,7 +490,7 @@ fn prepare_training_data(oid: OID) -> RS<()> { use chrono::Utc; use uuid::Uuid; -#[mudu_proc] +/**mudu-proc**/ fn create_order(oid: OID, user_id: i32) -> RS { // Do something .... diff --git a/doc/en/how_to_start.md b/doc/en/how_to_start.md index 5778c85..6c25004 100644 --- a/doc/en/how_to_start.md +++ b/doc/en/how_to_start.md @@ -13,7 +13,16 @@ Install the native build dependencies first: ```bash sudo apt-get update -y -sudo apt-get install -y python3 python3-pip clang build-essential curl liburing-dev +sudo apt-get install -y \ + python3 \ + python3-pip \ + python-is-python3 \ + build-essential \ + curl liburing-dev \ + clang \ + libclang-dev \ + llvm-dev \ + pkgconf ``` These packages are used for: @@ -22,8 +31,8 @@ These packages are used for: - `build-essential`: required for native compilation on Linux - `curl`: used to install Rust via `rustup` - `liburing-dev`: required only for the Linux native `io_uring` backend used by `mudu_kernel` +- `clang`, `libclang-dev`, `llvm-dev`: required by *[bindgen](https://github.com/rust-lang/rust-bindgen)* -If you are building on Windows, you do not need `liburing-dev`, because the native `io_uring` path is Linux-only. ### Rust toolchain diff --git a/doc/en/procedure.md b/doc/en/procedure.md index 84f9f3f..8c86346 100644 --- a/doc/en/procedure.md +++ b/doc/en/procedure.md @@ -66,7 +66,7 @@ Mudu Runtime currently supports Rust. A Rust-based procedure uses the following ## Procedure specification ``` -#[mudu_proc] +/**mudu-proc**/ fn {procedure_name}( oid: OID, {argument_list...} @@ -77,9 +77,9 @@ fn {procedure_name}( A valid Rust function name. -### Macro #[mudu_proc]: +### Marker `/**mudu-proc**/`: -Marks the function as a Mudu procedure. +Marks the following function as a Mudu procedure for the transpiler. ### Parameters: @@ -94,7 +94,7 @@ Input arguments must be representable by Mudu's datum / tuple conversion system. Commonly used supported forms include scalar values such as `i32`, `i64`, `String`, `f32`, and `f64`, as well as container forms used by current examples such as `Vec`. -The exact supported surface is defined by the current `mudu_macro` / `mudu_type` implementation rather than a fixed +The exact supported surface is defined by the current `mudu_type` conversion and transpiler implementation rather than a fixed short whitelist in this document. ### Return value: @@ -336,7 +336,7 @@ content="[Transfer](../../example/wallet/src/rust/procedures.rs#L23-L104)" lang="rust" --> ```rust -#[mudu_proc] +/**mudu-proc**/ pub fn transfer_funds(oid: OID, from_user_id: i32, to_user_id: i32, amount: i32) -> RS<()> { // Check amount > 0 if amount <= 0 { @@ -483,7 +483,7 @@ One example is preparing AI training datasets without export/import steps. ```rust // Prepare AI training dataset without export/import -#[mudu_proc] +/**mudu-proc**/ fn prepare_training_data(oid: OID) -> RS<()> { mudu_command(oid, sql_stmt!("..."), @@ -505,7 +505,7 @@ For example, you can use the `uuid` and `chrono` crates: use chrono::Utc; use uuid::Uuid; -#[mudu_proc] +/**mudu-proc**/ fn create_order(oid: OID, user_id: i32) -> RS { // Do something .... diff --git a/doc/pic/architecture.svg b/doc/pic/architecture.svg index 1f455b2..f6c84f3 100644 --- a/doc/pic/architecture.svg +++ b/doc/pic/architecture.svg @@ -13,7 +13,7 @@ diff --git a/doc/pic/mudu_logo.svg b/doc/pic/mudu_logo.svg index 29bbc17..18df6a2 100644 --- a/doc/pic/mudu_logo.svg +++ b/doc/pic/mudu_logo.svg @@ -1,60 +1,20 @@ - - - - - - - - - - - - - - - - - - - Mu - du - D - B - - - \ No newline at end of file + + + + + + + + + + + + + + + + + + + MuduDB + diff --git a/example/game-backend/Cargo.toml b/example/game-backend/Cargo.toml index 2d2c283..03b5e7a 100644 --- a/example/game-backend/Cargo.toml +++ b/example/game-backend/Cargo.toml @@ -7,11 +7,7 @@ edition = "2024" crate-type = ["cdylib"] [dependencies] -mudu = { workspace = true } -mudu_type = { workspace = true } -mudu_contract = { workspace = true } -mudu_binding = { workspace = true } -sys_interface = { workspace = true, features = ["async"] } +mududb = { workspace = true, features = ["async"] } wit-bindgen = { workspace = true } uuid = { workspace = true } chrono = { workspace = true } diff --git a/example/game-backend/package/package.desc.json b/example/game-backend/package/package.desc.json index ac6a952..9e72b4f 100644 --- a/example/game-backend/package/package.desc.json +++ b/example/game-backend/package/package.desc.json @@ -3,35 +3,35 @@ "game_backend": [ { "module_name": "game_backend", - "proc_name": "event", + "proc_name": "command", "param_desc": { - "fields": [] - }, - "return_desc": { "fields": [ { "dat_type": { "id": "Binary", "param": null }, - "name": "0" + "name": "message" } ] - } - }, - { - "module_name": "game_backend", - "proc_name": "command", - "param_desc": { + }, + "return_desc": { "fields": [ { "dat_type": { "id": "Binary", "param": null }, - "name": "message" + "name": "0" } ] + } + }, + { + "module_name": "game_backend", + "proc_name": "event", + "param_desc": { + "fields": [] }, "return_desc": { "fields": [ diff --git a/example/game-backend/src/generated/game_object.rs b/example/game-backend/src/generated/game_object.rs index 4bf1f11..a6ebbe9 100644 --- a/example/game-backend/src/generated/game_object.rs +++ b/example/game-backend/src/generated/game_object.rs @@ -1,4 +1,4 @@ #[derive(Clone)] pub struct GameObject { pub id: u64, -} +} \ No newline at end of file diff --git a/example/game-backend/src/generated/instance.rs b/example/game-backend/src/generated/instance.rs index 664cb2a..39a2102 100644 --- a/example/game-backend/src/generated/instance.rs +++ b/example/game-backend/src/generated/instance.rs @@ -18,4 +18,4 @@ impl Instance { pub fn get(id: u64) -> Option { MAP.with(|m| m.borrow().get(&id).cloned()) } -} +} \ No newline at end of file diff --git a/example/game-backend/src/generated/mod.rs b/example/game-backend/src/generated/mod.rs index 0e8fefe..0a89331 100644 --- a/example/game-backend/src/generated/mod.rs +++ b/example/game-backend/src/generated/mod.rs @@ -1,3 +1,3 @@ mod game_object; mod instance; -pub mod procedure; +pub mod procedure; \ No newline at end of file diff --git a/example/game-backend/src/generated/procedure.rs b/example/game-backend/src/generated/procedure.rs index dc5151c..d6c7b06 100644 --- a/example/game-backend/src/generated/procedure.rs +++ b/example/game-backend/src/generated/procedure.rs @@ -1,5 +1,5 @@ -use mudu::common::id::OID; -use mudu::common::result::RS; +use mududb::common::id::OID; +use mududb::common::result::RS; /**mudu-proc**/ pub fn command(oid: OID, message: Vec) -> RS> { @@ -10,174 +10,220 @@ pub fn command(oid: OID, message: Vec) -> RS> { pub fn event(oid: OID) -> RS> { Ok(Vec::new()) } -fn mp2_event(param: Vec) -> Vec { - ::mudu_binding::procedure::procedure_invoke::invoke_procedure(param, mudu_inner_p2_event) + fn mp2_command(param:Vec) -> Vec { + ::mududb::binding::procedure::procedure_invoke::invoke_procedure( + param, + mudu_inner_p2_command, + ) } -pub fn mudu_inner_p2_event( - param: ::mudu_contract::procedure::procedure_param::ProcedureParam, -) -> ::mudu::common::result::RS<::mudu_contract::procedure::procedure_result::ProcedureResult> { - let return_desc = mudu_result_desc_event().clone(); - let res = event(param.session_id()); +pub fn mudu_inner_p2_command( + param: ::mududb::contract::procedure::procedure_param::ProcedureParam, +) -> ::mududb::common::result::RS< + ::mududb::contract::procedure::procedure_result::ProcedureResult, +> { + let res = command( + param.session_id(), + + + param.param_list()[0].expect_binary().clone(), + + + ); match res { Ok(tuple) => { - let return_list = { vec![::mudu_type::dat_value::DatValue::from_binary(tuple)] }; - Ok(::mudu_contract::procedure::procedure_result::ProcedureResult::new(return_list)) + let return_list = { + + vec![ + + ::mududb::types::dat_value::DatValue::from_binary(tuple) + + ] + + }; + Ok(::mududb::contract::procedure::procedure_result::ProcedureResult::new(return_list)) } Err(e) => Err(e), } } -pub fn mudu_argv_desc_event() -> &'static ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc { - static ARGV_DESC: std::sync::OnceLock< - ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc, - > = std::sync::OnceLock::new(); - ARGV_DESC.get_or_init(|| ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc::new(vec![])) +pub fn mudu_argv_desc_command() -> &'static ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc { + static ARGV_DESC: std::sync::OnceLock<::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc> = + std::sync::OnceLock::new(); + ARGV_DESC.get_or_init(|| + { + ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc::new(vec![ + + ::mududb::contract::tuple::datum_desc::DatumDesc::new( + "message".to_string(), + + ::mududb::types::dat_type::DatType::new_no_param(::mududb::types::dat_type_id::DatTypeID::Binary) + + ), + + ]) + } + ) } -pub fn mudu_result_desc_event() -> &'static ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc -{ - static RESULT_DESC: std::sync::OnceLock< - ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc, - > = std::sync::OnceLock::new(); - RESULT_DESC.get_or_init(|| { - ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc::new(vec![ - ::mudu_contract::tuple::datum_desc::DatumDesc::new( - "0".to_string(), - ::mudu_type::dat_type::DatType::new_no_param( - ::mudu_type::dat_type_id::DatTypeID::Binary, +pub fn mudu_result_desc_command() -> &'static ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc { + static RESULT_DESC: std::sync::OnceLock<::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc> = + std::sync::OnceLock::new(); + RESULT_DESC.get_or_init(|| + { + ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc::new(vec![ + + ::mududb::contract::tuple::datum_desc::DatumDesc::new( + "0".to_string(), + + ::mududb::types::dat_type::DatType::new_no_param(::mududb::types::dat_type_id::DatTypeID::Binary) + ), - ), - ]) - }) + + ]) + } + ) } -pub fn mudu_proc_desc_event() -> &'static ::mudu_contract::procedure::proc_desc::ProcDesc { - static _PROC_DESC: std::sync::OnceLock<::mudu_contract::procedure::proc_desc::ProcDesc> = - std::sync::OnceLock::new(); - _PROC_DESC.get_or_init(|| { - ::mudu_contract::procedure::proc_desc::ProcDesc::new( - "game_backend".to_string(), - "event".to_string(), - mudu_argv_desc_event().clone(), - mudu_result_desc_event().clone(), - false, - ) - }) +pub fn mudu_proc_desc_command() -> &'static ::mududb::contract::procedure::proc_desc::ProcDesc { + static _PROC_DESC: std::sync::OnceLock< + ::mududb::contract::procedure::proc_desc::ProcDesc, + > = std::sync::OnceLock::new(); + _PROC_DESC + .get_or_init(|| { + ::mududb::contract::procedure::proc_desc::ProcDesc::new( + "game_backend".to_string(), + "command".to_string(), + mudu_argv_desc_command().clone(), + mudu_result_desc_command().clone(), + false + ) + }) } -mod mod_event { +mod mod_command { wit_bindgen::generate!({ inline: - r##"package mudu:mp2-event; - world mudu-app-mp2-event { - export mp2-event: func(param:list) -> list; + r##"package mudu:mp2-command; + world mudu-app-mp2-command { + export mp2-command: func(param:list) -> list; } "##, - + }); #[allow(non_camel_case_types)] #[allow(unused)] - struct GuestEvent {} + struct GuestCommand {} - impl Guest for GuestEvent { - fn mp2_event(param: Vec) -> Vec { - super::mp2_event(param) + impl Guest for GuestCommand { + fn mp2_command(param:Vec) -> Vec { + super::mp2_command(param) } } - export!(GuestEvent); + export!(GuestCommand); } -fn mp2_command(param: Vec) -> Vec { - ::mudu_binding::procedure::procedure_invoke::invoke_procedure(param, mudu_inner_p2_command) + fn mp2_event(param:Vec) -> Vec { + ::mududb::binding::procedure::procedure_invoke::invoke_procedure( + param, + mudu_inner_p2_event, + ) } -pub fn mudu_inner_p2_command( - param: ::mudu_contract::procedure::procedure_param::ProcedureParam, -) -> ::mudu::common::result::RS<::mudu_contract::procedure::procedure_result::ProcedureResult> { - let return_desc = mudu_result_desc_command().clone(); - let res = command( +pub fn mudu_inner_p2_event( + param: ::mududb::contract::procedure::procedure_param::ProcedureParam, +) -> ::mududb::common::result::RS< + ::mududb::contract::procedure::procedure_result::ProcedureResult, +> { + let res = event( param.session_id(), - param.param_list()[0].expect_binary().clone(), + ); match res { Ok(tuple) => { - let return_list = { vec![::mudu_type::dat_value::DatValue::from_binary(tuple)] }; - Ok(::mudu_contract::procedure::procedure_result::ProcedureResult::new(return_list)) + let return_list = { + + vec![ + + ::mududb::types::dat_value::DatValue::from_binary(tuple) + + ] + + }; + Ok(::mududb::contract::procedure::procedure_result::ProcedureResult::new(return_list)) } Err(e) => Err(e), } } -pub fn mudu_argv_desc_command() -> &'static ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc -{ - static ARGV_DESC: std::sync::OnceLock< - ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc, - > = std::sync::OnceLock::new(); - ARGV_DESC.get_or_init(|| { - ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc::new(vec![ - ::mudu_contract::tuple::datum_desc::DatumDesc::new( - "message".to_string(), - ::mudu_type::dat_type::DatType::new_no_param( - ::mudu_type::dat_type_id::DatTypeID::Binary, - ), - ), - ]) - }) +pub fn mudu_argv_desc_event() -> &'static ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc { + static ARGV_DESC: std::sync::OnceLock<::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc> = + std::sync::OnceLock::new(); + ARGV_DESC.get_or_init(|| + { + ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc::new(vec![ + + ]) + } + ) } -pub fn mudu_result_desc_command() --> &'static ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc { - static RESULT_DESC: std::sync::OnceLock< - ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc, - > = std::sync::OnceLock::new(); - RESULT_DESC.get_or_init(|| { - ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc::new(vec![ - ::mudu_contract::tuple::datum_desc::DatumDesc::new( - "0".to_string(), - ::mudu_type::dat_type::DatType::new_no_param( - ::mudu_type::dat_type_id::DatTypeID::Binary, +pub fn mudu_result_desc_event() -> &'static ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc { + static RESULT_DESC: std::sync::OnceLock<::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc> = + std::sync::OnceLock::new(); + RESULT_DESC.get_or_init(|| + { + ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc::new(vec![ + + ::mududb::contract::tuple::datum_desc::DatumDesc::new( + "0".to_string(), + + ::mududb::types::dat_type::DatType::new_no_param(::mududb::types::dat_type_id::DatTypeID::Binary) + ), - ), - ]) - }) + + ]) + } + ) } -pub fn mudu_proc_desc_command() -> &'static ::mudu_contract::procedure::proc_desc::ProcDesc { - static _PROC_DESC: std::sync::OnceLock<::mudu_contract::procedure::proc_desc::ProcDesc> = - std::sync::OnceLock::new(); - _PROC_DESC.get_or_init(|| { - ::mudu_contract::procedure::proc_desc::ProcDesc::new( - "game_backend".to_string(), - "command".to_string(), - mudu_argv_desc_command().clone(), - mudu_result_desc_command().clone(), - false, - ) - }) +pub fn mudu_proc_desc_event() -> &'static ::mududb::contract::procedure::proc_desc::ProcDesc { + static _PROC_DESC: std::sync::OnceLock< + ::mududb::contract::procedure::proc_desc::ProcDesc, + > = std::sync::OnceLock::new(); + _PROC_DESC + .get_or_init(|| { + ::mududb::contract::procedure::proc_desc::ProcDesc::new( + "game_backend".to_string(), + "event".to_string(), + mudu_argv_desc_event().clone(), + mudu_result_desc_event().clone(), + false + ) + }) } -mod mod_command { +mod mod_event { wit_bindgen::generate!({ inline: - r##"package mudu:mp2-command; - world mudu-app-mp2-command { - export mp2-command: func(param:list) -> list; + r##"package mudu:mp2-event; + world mudu-app-mp2-event { + export mp2-event: func(param:list) -> list; } "##, - + }); #[allow(non_camel_case_types)] #[allow(unused)] - struct GuestCommand {} + struct GuestEvent {} - impl Guest for GuestCommand { - fn mp2_command(param: Vec) -> Vec { - super::mp2_command(param) + impl Guest for GuestEvent { + fn mp2_event(param:Vec) -> Vec { + super::mp2_event(param) } } - export!(GuestCommand); -} + export!(GuestEvent); +} \ No newline at end of file diff --git a/example/game-backend/src/rust/procedure.rs b/example/game-backend/src/rust/procedure.rs index 9df10b8..1988282 100644 --- a/example/game-backend/src/rust/procedure.rs +++ b/example/game-backend/src/rust/procedure.rs @@ -1,5 +1,5 @@ -use mudu::common::id::OID; -use mudu::common::result::RS; +use mududb::common::id::OID; +use mududb::common::result::RS; /**mudu-proc**/ pub fn command(oid: OID, message: Vec) -> RS> { diff --git a/example/key-value/Cargo.toml b/example/key-value/Cargo.toml index 48c447a..717b863 100644 --- a/example/key-value/Cargo.toml +++ b/example/key-value/Cargo.toml @@ -7,18 +7,9 @@ edition = "2024" crate-type = ["cdylib"] [dependencies] -mudu = { workspace = true } -mudu_type = { workspace = true } -mudu_contract = { workspace = true } -mudu_binding = { workspace = true } +mududb = { workspace = true, features = ["async"] } wit-bindgen = { workspace = true } -[target.'cfg(target_arch = "wasm32")'.dependencies] -sys_interface = { workspace = true, features = ["async"] } - -[target.'cfg(not(target_arch = "wasm32"))'.dependencies] -sys_interface = { workspace = true, features = ["async"] } - [target.'cfg(not(target_arch = "wasm32"))'.dev-dependencies] mudu_adapter = { workspace = true } -sys_interface = { workspace = true, features = ["async", "standalone-adapter"] } +mududb = { workspace = true, features = ["async", "standalone-adapter"] } diff --git a/example/key-value/package/package.desc.json b/example/key-value/package/package.desc.json index 9c2c963..679d4fb 100644 --- a/example/key-value/package/package.desc.json +++ b/example/key-value/package/package.desc.json @@ -3,7 +3,7 @@ "key_value": [ { "module_name": "key_value", - "proc_name": "kv_insert", + "proc_name": "kv_read_modify_write", "param_desc": { "fields": [ { @@ -26,17 +26,29 @@ } } }, - "name": "value" + "name": "append_value" } ] }, "return_desc": { - "fields": [] + "fields": [ + { + "dat_type": { + "id": "String", + "param": { + "String": { + "length": 65536 + } + } + }, + "name": "0" + } + ] } }, { "module_name": "key_value", - "proc_name": "kv_scan", + "proc_name": "kv_insert", "param_desc": { "fields": [ { @@ -48,7 +60,7 @@ } } }, - "name": "start_user_key" + "name": "user_key" }, { "dat_type": { @@ -59,37 +71,17 @@ } } }, - "name": "end_user_key" + "name": "value" } ] }, "return_desc": { - "fields": [ - { - "dat_type": { - "id": "Array", - "param": { - "Array": { - "dat_type": { - "id": "String", - "param": { - "String": { - "length": 65536 - } - } - }, - "max_size": null - } - } - }, - "name": "0" - } - ] + "fields": [] } }, { "module_name": "key_value", - "proc_name": "kv_read_modify_write", + "proc_name": "kv_scan", "param_desc": { "fields": [ { @@ -101,7 +93,7 @@ } } }, - "name": "user_key" + "name": "start_user_key" }, { "dat_type": { @@ -112,7 +104,7 @@ } } }, - "name": "append_value" + "name": "end_user_key" } ] }, @@ -120,10 +112,18 @@ "fields": [ { "dat_type": { - "id": "String", + "id": "Array", "param": { - "String": { - "length": 65536 + "Array": { + "dat_type": { + "id": "String", + "param": { + "String": { + "length": 65536 + } + } + }, + "max_size": null } } }, @@ -134,7 +134,7 @@ }, { "module_name": "key_value", - "proc_name": "kv_update", + "proc_name": "kv_read", "param_desc": { "fields": [ { @@ -147,7 +147,11 @@ } }, "name": "user_key" - }, + } + ] + }, + "return_desc": { + "fields": [ { "dat_type": { "id": "String", @@ -157,17 +161,14 @@ } } }, - "name": "value" + "name": "0" } ] - }, - "return_desc": { - "fields": [] } }, { "module_name": "key_value", - "proc_name": "kv_read", + "proc_name": "kv_update", "param_desc": { "fields": [ { @@ -180,11 +181,7 @@ } }, "name": "user_key" - } - ] - }, - "return_desc": { - "fields": [ + }, { "dat_type": { "id": "String", @@ -194,9 +191,12 @@ } } }, - "name": "0" + "name": "value" } ] + }, + "return_desc": { + "fields": [] } } ] diff --git a/example/key-value/src/generated/mod.rs b/example/key-value/src/generated/mod.rs index b3c780a..a7ffbf9 100644 --- a/example/key-value/src/generated/mod.rs +++ b/example/key-value/src/generated/mod.rs @@ -1 +1 @@ -pub mod procedure; +pub mod procedure; \ No newline at end of file diff --git a/example/key-value/src/generated/procedure.rs b/example/key-value/src/generated/procedure.rs index 2378541..ceaf9a5 100644 --- a/example/key-value/src/generated/procedure.rs +++ b/example/key-value/src/generated/procedure.rs @@ -1,8 +1,8 @@ -use mudu::common::result::RS; -use mudu::common::xid::XID; -use mudu::error::ec::EC; -use mudu::m_error; -use sys_interface::async_api::{mudu_get, mudu_put, mudu_range}; +use mududb::common::result::RS; +use mududb::common::xid::XID; +use mududb::error::ec::EC; +use mududb::m_error; +use mududb::sys_interface::async_api::{mudu_get, mudu_put, mudu_range}; fn kv_data_key(user_key: &str) -> String { format!("user/{user_key}") @@ -20,8 +20,7 @@ fn decode_utf8(label: &str, bytes: Vec) -> RS { async fn read_value(session_id: XID, user_key: &str) -> RS { let key = kv_data_key(user_key); - let value = mudu_get(session_id, key.as_bytes()) - .await? + let value = mudu_get(session_id, key.as_bytes()).await? .ok_or_else(|| m_error!(EC::NoneErr, format!("key-value key not found: {user_key}")))?; decode_utf8("value", value) } @@ -40,8 +39,7 @@ pub async fn kv_read(xid: XID, user_key: String) -> RS { /**mudu-proc**/ pub async fn kv_update(xid: XID, user_key: String, value: String) -> RS<()> { let key = kv_data_key(&user_key); - let _ = mudu_get(xid, key.as_bytes()) - .await? + let _ = mudu_get(xid, key.as_bytes()).await? .ok_or_else(|| m_error!(EC::NoneErr, format!("key-value key not found: {user_key}")))?; mudu_put(xid, key.as_bytes(), value.as_bytes()).await } @@ -71,66 +69,293 @@ pub async fn kv_read_modify_write(xid: XID, user_key: String, append_value: Stri mudu_put(xid, key.as_bytes(), current.as_bytes()).await?; Ok(current) } -async fn mp2_kv_insert(param: Vec) -> Vec { - ::mudu_binding::procedure::procedure_invoke::invoke_procedure_async( + +#[cfg(test)] +mod tests { + use super::{kv_insert, kv_read, kv_read_modify_write, kv_scan, kv_update}; + use std::path::PathBuf; + use std::sync::{Mutex, OnceLock}; + use std::time::{SystemTime, UNIX_EPOCH}; + use mududb::sys_interface::async_api::{mudu_close, mudu_open}; + + fn test_lock() -> &'static Mutex<()> { + static LOCK: OnceLock> = OnceLock::new(); + LOCK.get_or_init(|| Mutex::new(())) + } + + fn temp_db_path(name: &str) -> PathBuf { + let suffix = SystemTime::now() + .duration_since(UNIX_EPOCH) + .expect("system time before unix epoch") + .as_nanos(); + std::env::temp_dir().join(format!("key_value_{name}_{suffix}.db")) + } + + #[test] + async fn key_value_procedures_roundtrip_against_standalone_adapter() { + let _guard = test_lock().lock().unwrap_or_else(|err| err.into_inner()); + let db_path = temp_db_path("roundtrip"); + mudu_adapter::config::reset_db_path_override_for_test(); + mudu_adapter::syscall::set_db_path(&db_path); + + let xid = mudu_open().await.unwrap(); + kv_insert(xid, "a".to_string(), "1".to_string()).await.unwrap(); + kv_insert(xid, "b".to_string(), "2".to_string()).await.unwrap(); + + assert_eq!(kv_read(xid, "a".to_string()).unwrap(), "1"); + + kv_update(xid, "a".to_string(), "3".to_string()).await.unwrap(); + assert_eq!(kv_read(xid, "a".to_string()).unwrap(), "3"); + + let rows = kv_scan(xid, "a".to_string(), "z".to_string()).await.unwrap(); + assert_eq!(rows, vec!["user/a=3".to_string(), "user/b=2".to_string()]); + + let updated = kv_read_modify_write(xid, "a".to_string(), "-tail".to_string()).await.unwrap(); + assert_eq!(updated, "3-tail"); + assert_eq!(kv_read(xid, "a".to_string()).unwrap(), "3-tail"); + + mudu_close(xid).await.unwrap(); + } + + #[test] + async fn kv_update_requires_existing_key() { + let _guard = test_lock().lock().unwrap_or_else(|err| err.into_inner()); + let db_path = temp_db_path("missing"); + mudu_adapter::config::reset_db_path_override_for_test(); + mudu_adapter::syscall::set_db_path(&db_path); + + let xid = mudu_open().await.unwrap(); + let err = kv_update(xid, "missing".to_string(), "x".to_string()).await.unwrap_err(); + assert!(err.message().contains("missing")); + mudu_close(xid).await.unwrap(); + } +} +async fn mp2_kv_read_modify_write(param:Vec) -> Vec { + ::mududb::binding::procedure::procedure_invoke::invoke_procedure_async( param, - mudu_inner_p2_kv_insert, - ) - .await + mudu_inner_p2_kv_read_modify_write, + ).await } -pub async fn mudu_inner_p2_kv_insert( - param: ::mudu_contract::procedure::procedure_param::ProcedureParam, -) -> ::mudu::common::result::RS<::mudu_contract::procedure::procedure_result::ProcedureResult> { - let return_desc = mudu_result_desc_kv_insert().clone(); - let res = kv_insert( +pub async fn mudu_inner_p2_kv_read_modify_write( + param: ::mududb::contract::procedure::procedure_param::ProcedureParam, +) -> ::mududb::common::result::RS< + ::mududb::contract::procedure::procedure_result::ProcedureResult, +> { + let res = kv_read_modify_write( param.session_id(), - ::mudu_type::datum::value_to_typed::(¶m.param_list()[0], "String")?, - ::mudu_type::datum::value_to_typed::(¶m.param_list()[1], "String")?, + + + ::mududb::types::datum::value_to_typed::< + String, + _, + >(¶m.param_list()[0], "String")?, + + + + ::mududb::types::datum::value_to_typed::< + String, + _, + >(¶m.param_list()[1], "String")?, + + + ).await; + match res { + Ok(tuple) => { + let return_list = { + + vec![ + + ::mududb::types::datum::value_from_typed(&tuple, "String")? + + ] + + }; + Ok(::mududb::contract::procedure::procedure_result::ProcedureResult::new(return_list)) + } + Err(e) => Err(e), + } +} + +pub fn mudu_argv_desc_kv_read_modify_write() -> &'static ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc { + static ARGV_DESC: std::sync::OnceLock<::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc> = + std::sync::OnceLock::new(); + ARGV_DESC.get_or_init(|| + { + ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc::new(vec![ + + ::mududb::contract::tuple::datum_desc::DatumDesc::new( + "user_key".to_string(), + + ::dat_type().clone() + + ), + + ::mududb::contract::tuple::datum_desc::DatumDesc::new( + "append_value".to_string(), + + ::dat_type().clone() + + ), + + ]) + } + ) +} + +pub fn mudu_result_desc_kv_read_modify_write() -> &'static ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc { + static RESULT_DESC: std::sync::OnceLock<::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc> = + std::sync::OnceLock::new(); + RESULT_DESC.get_or_init(|| + { + ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc::new(vec![ + + ::mududb::contract::tuple::datum_desc::DatumDesc::new( + "0".to_string(), + + ::dat_type().clone() + + ), + + ]) + } ) - .await; - let tuple = res; - Ok(::mudu_contract::procedure::procedure_result::ProcedureResult::from(tuple, &return_desc)?) } -pub fn mudu_argv_desc_kv_insert() --> &'static ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc { - static ARGV_DESC: std::sync::OnceLock< - ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc, +pub fn mudu_proc_desc_kv_read_modify_write() -> &'static ::mududb::contract::procedure::proc_desc::ProcDesc { + static _PROC_DESC: std::sync::OnceLock< + ::mududb::contract::procedure::proc_desc::ProcDesc, > = std::sync::OnceLock::new(); - ARGV_DESC.get_or_init(|| { - <(String, String) as ::mudu_contract::tuple::tuple_datum::TupleDatum>::tuple_desc_static(&{ - let _vec: Vec = <[_]>::into_vec(std::boxed::Box::new(["user_key", "value"])) - .iter() - .map(|s| s.to_string()) - .collect(); - _vec + _PROC_DESC + .get_or_init(|| { + ::mududb::contract::procedure::proc_desc::ProcDesc::new( + "key_value".to_string(), + "kv_read_modify_write".to_string(), + mudu_argv_desc_kv_read_modify_write().clone(), + mudu_result_desc_kv_read_modify_write().clone(), + false + ) }) - }) } -pub fn mudu_result_desc_kv_insert() --> &'static ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc { - static RESULT_DESC: std::sync::OnceLock< - ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc, - > = std::sync::OnceLock::new(); - RESULT_DESC.get_or_init(|| { - <() as ::mudu_contract::tuple::tuple_datum::TupleDatum>::tuple_desc_static(&[]) - }) +mod mod_kv_read_modify_write { + wit_bindgen::generate!({ + inline: + r##"package mudu:mp2-kv-read-modify-write; + world mudu-app-mp2-kv-read-modify-write { + export mp2-kv-read-modify-write: func(param:list) -> list; + } + "##, + async: true + }); + + #[allow(non_camel_case_types)] + #[allow(unused)] + struct GuestKvReadModifyWrite {} + + impl Guest for GuestKvReadModifyWrite { + async fn mp2_kv_read_modify_write(param:Vec) -> Vec { + super::mp2_kv_read_modify_write(param).await + } + } + + export!(GuestKvReadModifyWrite); +} +async fn mp2_kv_insert(param:Vec) -> Vec { + ::mududb::binding::procedure::procedure_invoke::invoke_procedure_async( + param, + mudu_inner_p2_kv_insert, + ).await } -pub fn mudu_proc_desc_kv_insert() -> &'static ::mudu_contract::procedure::proc_desc::ProcDesc { - static _PROC_DESC: std::sync::OnceLock<::mudu_contract::procedure::proc_desc::ProcDesc> = +pub async fn mudu_inner_p2_kv_insert( + param: ::mududb::contract::procedure::procedure_param::ProcedureParam, +) -> ::mududb::common::result::RS< + ::mududb::contract::procedure::procedure_result::ProcedureResult, +> { + let res = kv_insert( + param.session_id(), + + + ::mududb::types::datum::value_to_typed::< + String, + _, + >(¶m.param_list()[0], "String")?, + + + + ::mududb::types::datum::value_to_typed::< + String, + _, + >(¶m.param_list()[1], "String")?, + + + ).await; + match res { + Ok(tuple) => { + let return_list = { + + vec![] + + }; + Ok(::mududb::contract::procedure::procedure_result::ProcedureResult::new(return_list)) + } + Err(e) => Err(e), + } +} + +pub fn mudu_argv_desc_kv_insert() -> &'static ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc { + static ARGV_DESC: std::sync::OnceLock<::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc> = std::sync::OnceLock::new(); - _PROC_DESC.get_or_init(|| { - ::mudu_contract::procedure::proc_desc::ProcDesc::new( - "key_value".to_string(), - "kv_insert".to_string(), - mudu_argv_desc_kv_insert().clone(), - mudu_result_desc_kv_insert().clone(), - false, - ) - }) + ARGV_DESC.get_or_init(|| + { + ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc::new(vec![ + + ::mududb::contract::tuple::datum_desc::DatumDesc::new( + "user_key".to_string(), + + ::dat_type().clone() + + ), + + ::mududb::contract::tuple::datum_desc::DatumDesc::new( + "value".to_string(), + + ::dat_type().clone() + + ), + + ]) + } + ) +} + +pub fn mudu_result_desc_kv_insert() -> &'static ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc { + static RESULT_DESC: std::sync::OnceLock<::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc> = + std::sync::OnceLock::new(); + RESULT_DESC.get_or_init(|| + { + ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc::new(vec![ + + ]) + } + ) +} + +pub fn mudu_proc_desc_kv_insert() -> &'static ::mududb::contract::procedure::proc_desc::ProcDesc { + static _PROC_DESC: std::sync::OnceLock< + ::mududb::contract::procedure::proc_desc::ProcDesc, + > = std::sync::OnceLock::new(); + _PROC_DESC + .get_or_init(|| { + ::mududb::contract::procedure::proc_desc::ProcDesc::new( + "key_value".to_string(), + "kv_insert".to_string(), + mudu_argv_desc_kv_insert().clone(), + mudu_result_desc_kv_insert().clone(), + false + ) + }) } mod mod_kv_insert { @@ -149,74 +374,119 @@ mod mod_kv_insert { struct GuestKvInsert {} impl Guest for GuestKvInsert { - async fn mp2_kv_insert(param: Vec) -> Vec { + async fn mp2_kv_insert(param:Vec) -> Vec { super::mp2_kv_insert(param).await } } export!(GuestKvInsert); } -async fn mp2_kv_scan(param: Vec) -> Vec { - ::mudu_binding::procedure::procedure_invoke::invoke_procedure_async( +async fn mp2_kv_scan(param:Vec) -> Vec { + ::mududb::binding::procedure::procedure_invoke::invoke_procedure_async( param, mudu_inner_p2_kv_scan, - ) - .await + ).await } pub async fn mudu_inner_p2_kv_scan( - param: ::mudu_contract::procedure::procedure_param::ProcedureParam, -) -> ::mudu::common::result::RS<::mudu_contract::procedure::procedure_result::ProcedureResult> { - let return_desc = mudu_result_desc_kv_scan().clone(); + param: ::mududb::contract::procedure::procedure_param::ProcedureParam, +) -> ::mududb::common::result::RS< + ::mududb::contract::procedure::procedure_result::ProcedureResult, +> { let res = kv_scan( param.session_id(), - ::mudu_type::datum::value_to_typed::(¶m.param_list()[0], "String")?, - ::mudu_type::datum::value_to_typed::(¶m.param_list()[1], "String")?, - ) - .await; - let tuple = res; - Ok(::mudu_contract::procedure::procedure_result::ProcedureResult::from(tuple, &return_desc)?) + + + ::mududb::types::datum::value_to_typed::< + String, + _, + >(¶m.param_list()[0], "String")?, + + + + ::mududb::types::datum::value_to_typed::< + String, + _, + >(¶m.param_list()[1], "String")?, + + + ).await; + match res { + Ok(tuple) => { + let return_list = { + + vec![ + + ::mududb::types::datum::value_from_typed(&tuple, "Vec")? + + ] + + }; + Ok(::mududb::contract::procedure::procedure_result::ProcedureResult::new(return_list)) + } + Err(e) => Err(e), + } } -pub fn mudu_argv_desc_kv_scan() -> &'static ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc -{ - static ARGV_DESC: std::sync::OnceLock< - ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc, - > = std::sync::OnceLock::new(); - ARGV_DESC.get_or_init(|| { - <(String, String) as ::mudu_contract::tuple::tuple_datum::TupleDatum>::tuple_desc_static(&{ - let _vec: Vec = - <[_]>::into_vec(std::boxed::Box::new(["start_user_key", "end_user_key"])) - .iter() - .map(|s| s.to_string()) - .collect(); - _vec - }) - }) +pub fn mudu_argv_desc_kv_scan() -> &'static ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc { + static ARGV_DESC: std::sync::OnceLock<::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc> = + std::sync::OnceLock::new(); + ARGV_DESC.get_or_init(|| + { + ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc::new(vec![ + + ::mududb::contract::tuple::datum_desc::DatumDesc::new( + "start_user_key".to_string(), + + ::dat_type().clone() + + ), + + ::mududb::contract::tuple::datum_desc::DatumDesc::new( + "end_user_key".to_string(), + + ::dat_type().clone() + + ), + + ]) + } + ) } -pub fn mudu_result_desc_kv_scan() --> &'static ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc { - static RESULT_DESC: std::sync::OnceLock< - ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc, - > = std::sync::OnceLock::new(); - RESULT_DESC.get_or_init(|| { - <(Vec,) as ::mudu_contract::tuple::tuple_datum::TupleDatum>::tuple_desc_static(&[]) - }) +pub fn mudu_result_desc_kv_scan() -> &'static ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc { + static RESULT_DESC: std::sync::OnceLock<::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc> = + std::sync::OnceLock::new(); + RESULT_DESC.get_or_init(|| + { + ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc::new(vec![ + + ::mududb::contract::tuple::datum_desc::DatumDesc::new( + "0".to_string(), + + as ::mududb::types::datum::Datum>::dat_type().clone() + + ), + + ]) + } + ) } -pub fn mudu_proc_desc_kv_scan() -> &'static ::mudu_contract::procedure::proc_desc::ProcDesc { - static _PROC_DESC: std::sync::OnceLock<::mudu_contract::procedure::proc_desc::ProcDesc> = - std::sync::OnceLock::new(); - _PROC_DESC.get_or_init(|| { - ::mudu_contract::procedure::proc_desc::ProcDesc::new( - "key_value".to_string(), - "kv_scan".to_string(), - mudu_argv_desc_kv_scan().clone(), - mudu_result_desc_kv_scan().clone(), - false, - ) - }) +pub fn mudu_proc_desc_kv_scan() -> &'static ::mududb::contract::procedure::proc_desc::ProcDesc { + static _PROC_DESC: std::sync::OnceLock< + ::mududb::contract::procedure::proc_desc::ProcDesc, + > = std::sync::OnceLock::new(); + _PROC_DESC + .get_or_init(|| { + ::mududb::contract::procedure::proc_desc::ProcDesc::new( + "key_value".to_string(), + "kv_scan".to_string(), + mudu_argv_desc_kv_scan().clone(), + mudu_result_desc_kv_scan().clone(), + false + ) + }) } mod mod_kv_scan { @@ -235,83 +505,113 @@ mod mod_kv_scan { struct GuestKvScan {} impl Guest for GuestKvScan { - async fn mp2_kv_scan(param: Vec) -> Vec { + async fn mp2_kv_scan(param:Vec) -> Vec { super::mp2_kv_scan(param).await } } export!(GuestKvScan); } -async fn mp2_kv_read_modify_write(param: Vec) -> Vec { - ::mudu_binding::procedure::procedure_invoke::invoke_procedure_async( +async fn mp2_kv_read(param:Vec) -> Vec { + ::mududb::binding::procedure::procedure_invoke::invoke_procedure_async( param, - mudu_inner_p2_kv_read_modify_write, - ) - .await + mudu_inner_p2_kv_read, + ).await } -pub async fn mudu_inner_p2_kv_read_modify_write( - param: ::mudu_contract::procedure::procedure_param::ProcedureParam, -) -> ::mudu::common::result::RS<::mudu_contract::procedure::procedure_result::ProcedureResult> { - let return_desc = mudu_result_desc_kv_read_modify_write().clone(); - let res = kv_read_modify_write( +pub async fn mudu_inner_p2_kv_read( + param: ::mududb::contract::procedure::procedure_param::ProcedureParam, +) -> ::mududb::common::result::RS< + ::mududb::contract::procedure::procedure_result::ProcedureResult, +> { + let res = kv_read( param.session_id(), - ::mudu_type::datum::value_to_typed::(¶m.param_list()[0], "String")?, - ::mudu_type::datum::value_to_typed::(¶m.param_list()[1], "String")?, - ) - .await; - let tuple = res; - Ok(::mudu_contract::procedure::procedure_result::ProcedureResult::from(tuple, &return_desc)?) + + + ::mududb::types::datum::value_to_typed::< + String, + _, + >(¶m.param_list()[0], "String")?, + + + ).await; + match res { + Ok(tuple) => { + let return_list = { + + vec![ + + ::mududb::types::datum::value_from_typed(&tuple, "String")? + + ] + + }; + Ok(::mududb::contract::procedure::procedure_result::ProcedureResult::new(return_list)) + } + Err(e) => Err(e), + } } -pub fn mudu_argv_desc_kv_read_modify_write() --> &'static ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc { - static ARGV_DESC: std::sync::OnceLock< - ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc, - > = std::sync::OnceLock::new(); - ARGV_DESC.get_or_init(|| { - <(String, String) as ::mudu_contract::tuple::tuple_datum::TupleDatum>::tuple_desc_static(&{ - let _vec: Vec = - <[_]>::into_vec(std::boxed::Box::new(["user_key", "append_value"])) - .iter() - .map(|s| s.to_string()) - .collect(); - _vec - }) - }) +pub fn mudu_argv_desc_kv_read() -> &'static ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc { + static ARGV_DESC: std::sync::OnceLock<::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc> = + std::sync::OnceLock::new(); + ARGV_DESC.get_or_init(|| + { + ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc::new(vec![ + + ::mududb::contract::tuple::datum_desc::DatumDesc::new( + "user_key".to_string(), + + ::dat_type().clone() + + ), + + ]) + } + ) } -pub fn mudu_result_desc_kv_read_modify_write() --> &'static ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc { - static RESULT_DESC: std::sync::OnceLock< - ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc, - > = std::sync::OnceLock::new(); - RESULT_DESC.get_or_init(|| { - <(String,) as ::mudu_contract::tuple::tuple_datum::TupleDatum>::tuple_desc_static(&[]) - }) +pub fn mudu_result_desc_kv_read() -> &'static ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc { + static RESULT_DESC: std::sync::OnceLock<::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc> = + std::sync::OnceLock::new(); + RESULT_DESC.get_or_init(|| + { + ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc::new(vec![ + + ::mududb::contract::tuple::datum_desc::DatumDesc::new( + "0".to_string(), + + ::dat_type().clone() + + ), + + ]) + } + ) } -pub fn mudu_proc_desc_kv_read_modify_write() --> &'static ::mudu_contract::procedure::proc_desc::ProcDesc { - static _PROC_DESC: std::sync::OnceLock<::mudu_contract::procedure::proc_desc::ProcDesc> = - std::sync::OnceLock::new(); - _PROC_DESC.get_or_init(|| { - ::mudu_contract::procedure::proc_desc::ProcDesc::new( - "key_value".to_string(), - "kv_read_modify_write".to_string(), - mudu_argv_desc_kv_read_modify_write().clone(), - mudu_result_desc_kv_read_modify_write().clone(), - false, - ) - }) +pub fn mudu_proc_desc_kv_read() -> &'static ::mududb::contract::procedure::proc_desc::ProcDesc { + static _PROC_DESC: std::sync::OnceLock< + ::mududb::contract::procedure::proc_desc::ProcDesc, + > = std::sync::OnceLock::new(); + _PROC_DESC + .get_or_init(|| { + ::mududb::contract::procedure::proc_desc::ProcDesc::new( + "key_value".to_string(), + "kv_read".to_string(), + mudu_argv_desc_kv_read().clone(), + mudu_result_desc_kv_read().clone(), + false + ) + }) } -mod mod_kv_read_modify_write { +mod mod_kv_read { wit_bindgen::generate!({ inline: - r##"package mudu:mp2-kv-read-modify-write; - world mudu-app-mp2-kv-read-modify-write { - export mp2-kv-read-modify-write: func(param:list) -> list; + r##"package mudu:mp2-kv-read; + world mudu-app-mp2-kv-read { + export mp2-kv-read: func(param:list) -> list; } "##, async: true @@ -319,76 +619,111 @@ mod mod_kv_read_modify_write { #[allow(non_camel_case_types)] #[allow(unused)] - struct GuestKvReadModifyWrite {} + struct GuestKvRead {} - impl Guest for GuestKvReadModifyWrite { - async fn mp2_kv_read_modify_write(param: Vec) -> Vec { - super::mp2_kv_read_modify_write(param).await + impl Guest for GuestKvRead { + async fn mp2_kv_read(param:Vec) -> Vec { + super::mp2_kv_read(param).await } } - export!(GuestKvReadModifyWrite); + export!(GuestKvRead); } -async fn mp2_kv_update(param: Vec) -> Vec { - ::mudu_binding::procedure::procedure_invoke::invoke_procedure_async( +async fn mp2_kv_update(param:Vec) -> Vec { + ::mududb::binding::procedure::procedure_invoke::invoke_procedure_async( param, mudu_inner_p2_kv_update, - ) - .await + ).await } pub async fn mudu_inner_p2_kv_update( - param: ::mudu_contract::procedure::procedure_param::ProcedureParam, -) -> ::mudu::common::result::RS<::mudu_contract::procedure::procedure_result::ProcedureResult> { - let return_desc = mudu_result_desc_kv_update().clone(); + param: ::mududb::contract::procedure::procedure_param::ProcedureParam, +) -> ::mududb::common::result::RS< + ::mududb::contract::procedure::procedure_result::ProcedureResult, +> { let res = kv_update( param.session_id(), - ::mudu_type::datum::value_to_typed::(¶m.param_list()[0], "String")?, - ::mudu_type::datum::value_to_typed::(¶m.param_list()[1], "String")?, - ) - .await; - let tuple = res; - Ok(::mudu_contract::procedure::procedure_result::ProcedureResult::from(tuple, &return_desc)?) + + + ::mududb::types::datum::value_to_typed::< + String, + _, + >(¶m.param_list()[0], "String")?, + + + + ::mududb::types::datum::value_to_typed::< + String, + _, + >(¶m.param_list()[1], "String")?, + + + ).await; + match res { + Ok(tuple) => { + let return_list = { + + vec![] + + }; + Ok(::mududb::contract::procedure::procedure_result::ProcedureResult::new(return_list)) + } + Err(e) => Err(e), + } } -pub fn mudu_argv_desc_kv_update() --> &'static ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc { - static ARGV_DESC: std::sync::OnceLock< - ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc, - > = std::sync::OnceLock::new(); - ARGV_DESC.get_or_init(|| { - <(String, String) as ::mudu_contract::tuple::tuple_datum::TupleDatum>::tuple_desc_static(&{ - let _vec: Vec = <[_]>::into_vec(std::boxed::Box::new(["user_key", "value"])) - .iter() - .map(|s| s.to_string()) - .collect(); - _vec - }) - }) +pub fn mudu_argv_desc_kv_update() -> &'static ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc { + static ARGV_DESC: std::sync::OnceLock<::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc> = + std::sync::OnceLock::new(); + ARGV_DESC.get_or_init(|| + { + ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc::new(vec![ + + ::mududb::contract::tuple::datum_desc::DatumDesc::new( + "user_key".to_string(), + + ::dat_type().clone() + + ), + + ::mududb::contract::tuple::datum_desc::DatumDesc::new( + "value".to_string(), + + ::dat_type().clone() + + ), + + ]) + } + ) } -pub fn mudu_result_desc_kv_update() --> &'static ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc { - static RESULT_DESC: std::sync::OnceLock< - ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc, - > = std::sync::OnceLock::new(); - RESULT_DESC.get_or_init(|| { - <() as ::mudu_contract::tuple::tuple_datum::TupleDatum>::tuple_desc_static(&[]) - }) +pub fn mudu_result_desc_kv_update() -> &'static ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc { + static RESULT_DESC: std::sync::OnceLock<::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc> = + std::sync::OnceLock::new(); + RESULT_DESC.get_or_init(|| + { + ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc::new(vec![ + + ]) + } + ) } -pub fn mudu_proc_desc_kv_update() -> &'static ::mudu_contract::procedure::proc_desc::ProcDesc { - static _PROC_DESC: std::sync::OnceLock<::mudu_contract::procedure::proc_desc::ProcDesc> = - std::sync::OnceLock::new(); - _PROC_DESC.get_or_init(|| { - ::mudu_contract::procedure::proc_desc::ProcDesc::new( - "key_value".to_string(), - "kv_update".to_string(), - mudu_argv_desc_kv_update().clone(), - mudu_result_desc_kv_update().clone(), - false, - ) - }) +pub fn mudu_proc_desc_kv_update() -> &'static ::mududb::contract::procedure::proc_desc::ProcDesc { + static _PROC_DESC: std::sync::OnceLock< + ::mududb::contract::procedure::proc_desc::ProcDesc, + > = std::sync::OnceLock::new(); + _PROC_DESC + .get_or_init(|| { + ::mududb::contract::procedure::proc_desc::ProcDesc::new( + "key_value".to_string(), + "kv_update".to_string(), + mudu_argv_desc_kv_update().clone(), + mudu_result_desc_kv_update().clone(), + false + ) + }) } mod mod_kv_update { @@ -407,94 +742,10 @@ mod mod_kv_update { struct GuestKvUpdate {} impl Guest for GuestKvUpdate { - async fn mp2_kv_update(param: Vec) -> Vec { + async fn mp2_kv_update(param:Vec) -> Vec { super::mp2_kv_update(param).await } } export!(GuestKvUpdate); -} -async fn mp2_kv_read(param: Vec) -> Vec { - ::mudu_binding::procedure::procedure_invoke::invoke_procedure_async( - param, - mudu_inner_p2_kv_read, - ) - .await -} - -pub async fn mudu_inner_p2_kv_read( - param: ::mudu_contract::procedure::procedure_param::ProcedureParam, -) -> ::mudu::common::result::RS<::mudu_contract::procedure::procedure_result::ProcedureResult> { - let return_desc = mudu_result_desc_kv_read().clone(); - let res = kv_read( - param.session_id(), - ::mudu_type::datum::value_to_typed::(¶m.param_list()[0], "String")?, - ) - .await; - let tuple = res; - Ok(::mudu_contract::procedure::procedure_result::ProcedureResult::from(tuple, &return_desc)?) -} - -pub fn mudu_argv_desc_kv_read() -> &'static ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc -{ - static ARGV_DESC: std::sync::OnceLock< - ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc, - > = std::sync::OnceLock::new(); - ARGV_DESC.get_or_init(|| { - <(String,) as ::mudu_contract::tuple::tuple_datum::TupleDatum>::tuple_desc_static(&{ - let _vec: Vec = <[_]>::into_vec(std::boxed::Box::new(["user_key"])) - .iter() - .map(|s| s.to_string()) - .collect(); - _vec - }) - }) -} - -pub fn mudu_result_desc_kv_read() --> &'static ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc { - static RESULT_DESC: std::sync::OnceLock< - ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc, - > = std::sync::OnceLock::new(); - RESULT_DESC.get_or_init(|| { - <(String,) as ::mudu_contract::tuple::tuple_datum::TupleDatum>::tuple_desc_static(&[]) - }) -} - -pub fn mudu_proc_desc_kv_read() -> &'static ::mudu_contract::procedure::proc_desc::ProcDesc { - static _PROC_DESC: std::sync::OnceLock<::mudu_contract::procedure::proc_desc::ProcDesc> = - std::sync::OnceLock::new(); - _PROC_DESC.get_or_init(|| { - ::mudu_contract::procedure::proc_desc::ProcDesc::new( - "key_value".to_string(), - "kv_read".to_string(), - mudu_argv_desc_kv_read().clone(), - mudu_result_desc_kv_read().clone(), - false, - ) - }) -} - -mod mod_kv_read { - wit_bindgen::generate!({ - inline: - r##"package mudu:mp2-kv-read; - world mudu-app-mp2-kv-read { - export mp2-kv-read: func(param:list) -> list; - } - "##, - async: true - }); - - #[allow(non_camel_case_types)] - #[allow(unused)] - struct GuestKvRead {} - - impl Guest for GuestKvRead { - async fn mp2_kv_read(param: Vec) -> Vec { - super::mp2_kv_read(param).await - } - } - - export!(GuestKvRead); -} +} \ No newline at end of file diff --git a/example/key-value/src/rust/procedure.rs b/example/key-value/src/rust/procedure.rs index c4eeb65..7bc4930 100644 --- a/example/key-value/src/rust/procedure.rs +++ b/example/key-value/src/rust/procedure.rs @@ -1,8 +1,8 @@ -use mudu::common::result::RS; -use mudu::common::xid::XID; -use mudu::error::ec::EC; -use mudu::m_error; -use sys_interface::sync_api::{mudu_get, mudu_put, mudu_range}; +use mududb::common::result::RS; +use mududb::common::xid::XID; +use mududb::error::ec::EC; +use mududb::m_error; +use mududb::sys_interface::sync_api::{mudu_get, mudu_put, mudu_range}; fn kv_data_key(user_key: &str) -> String { format!("user/{user_key}") @@ -76,7 +76,7 @@ mod tests { use std::path::PathBuf; use std::sync::{Mutex, OnceLock}; use std::time::{SystemTime, UNIX_EPOCH}; - use sys_interface::sync_api::{mudu_close, mudu_open}; + use mududb::sys_interface::sync_api::{mudu_close, mudu_open}; fn test_lock() -> &'static Mutex<()> { static LOCK: OnceLock> = OnceLock::new(); diff --git a/example/tpcc/Cargo.toml b/example/tpcc/Cargo.toml index ff37365..11b39b0 100644 --- a/example/tpcc/Cargo.toml +++ b/example/tpcc/Cargo.toml @@ -18,19 +18,14 @@ benchmark-runner = [ "dep:mudu_utils", "dep:tokio", "debug_trace", - "sys_interface/standalone-adapter", + "mududb/standalone-adapter", ] [dependencies] -mudu = { workspace = true } -mudu_sys = { workspace = true } -mudu_type = { workspace = true } -mudu_contract = { workspace = true } -mudu_binding = { workspace = true } +mududb = { workspace = true, features = ["async"] } mudu_adapter = { workspace = true, optional = true } mudu_cli = { workspace = true, optional = true } mudu_utils = { workspace = true, optional = true, features = ["debug_trace"] } -sys_interface = { workspace = true, features = ["async"] } wit-bindgen = { workspace = true } lazy_static = { workspace = true } clap = { workspace = true, optional = true, features = ["derive"] } @@ -40,7 +35,7 @@ async-backtrace = { workspace = true, optional = true } [target.'cfg(not(target_arch = "wasm32"))'.dev-dependencies] mudu_adapter = { workspace = true } mudu_runtime = { workspace = true } -sys_interface = { workspace = true, features = ["standalone-adapter"] } +mududb = { workspace = true, features = ["async", "standalone-adapter"] } testing = { path = "../../testing" } [[bin]] diff --git a/example/tpcc/package/package.desc.json b/example/tpcc/package/package.desc.json index ae2f39a..1a261d1 100644 --- a/example/tpcc/package/package.desc.json +++ b/example/tpcc/package/package.desc.json @@ -3,7 +3,7 @@ "tpcc": [ { "module_name": "tpcc", - "proc_name": "tpcc_order_status", + "proc_name": "tpcc_new_order", "param_desc": { "fields": [ { @@ -26,6 +26,51 @@ "param": null }, "name": "customer_id" + }, + { + "dat_type": { + "id": "Array", + "param": { + "Array": { + "dat_type": { + "id": "I32", + "param": null + }, + "max_size": null + } + } + }, + "name": "item_ids" + }, + { + "dat_type": { + "id": "Array", + "param": { + "Array": { + "dat_type": { + "id": "I32", + "param": null + }, + "max_size": null + } + } + }, + "name": "supplier_warehouse_ids" + }, + { + "dat_type": { + "id": "Array", + "param": { + "Array": { + "dat_type": { + "id": "I32", + "param": null + }, + "max_size": null + } + } + }, + "name": "quantities" } ] }, @@ -47,7 +92,7 @@ }, { "module_name": "tpcc", - "proc_name": "tpcc_payment", + "proc_name": "tpcc_delivery", "param_desc": { "fields": [ { @@ -69,14 +114,7 @@ "id": "I32", "param": null }, - "name": "customer_id" - }, - { - "dat_type": { - "id": "I32", - "param": null - }, - "name": "amount" + "name": "carrier_id" } ] }, @@ -84,8 +122,12 @@ "fields": [ { "dat_type": { - "id": "I32", - "param": null + "id": "String", + "param": { + "String": { + "length": 65536 + } + } }, "name": "0" } @@ -94,7 +136,7 @@ }, { "module_name": "tpcc", - "proc_name": "tpcc_stock_level", + "proc_name": "tpcc_seed", "param_desc": { "fields": [ { @@ -102,39 +144,45 @@ "id": "I32", "param": null }, - "name": "warehouse_id" + "name": "warehouse_count" }, { "dat_type": { "id": "I32", "param": null }, - "name": "district_id" + "name": "district_count" }, { "dat_type": { "id": "I32", "param": null }, - "name": "threshold" - } - ] - }, - "return_desc": { - "fields": [ + "name": "customer_count" + }, { "dat_type": { "id": "I32", "param": null }, - "name": "0" + "name": "item_count" + }, + { + "dat_type": { + "id": "I32", + "param": null + }, + "name": "initial_stock" } ] + }, + "return_desc": { + "fields": [] } }, { "module_name": "tpcc", - "proc_name": "tpcc_new_order", + "proc_name": "tpcc_payment", "param_desc": { "fields": [ { @@ -160,48 +208,10 @@ }, { "dat_type": { - "id": "Array", - "param": { - "Array": { - "dat_type": { - "id": "I32", - "param": null - }, - "max_size": null - } - } - }, - "name": "item_ids" - }, - { - "dat_type": { - "id": "Array", - "param": { - "Array": { - "dat_type": { - "id": "I32", - "param": null - }, - "max_size": null - } - } - }, - "name": "supplier_warehouse_ids" - }, - { - "dat_type": { - "id": "Array", - "param": { - "Array": { - "dat_type": { - "id": "I32", - "param": null - }, - "max_size": null - } - } + "id": "I32", + "param": null }, - "name": "quantities" + "name": "amount" } ] }, @@ -209,12 +219,8 @@ "fields": [ { "dat_type": { - "id": "String", - "param": { - "String": { - "length": 65536 - } - } + "id": "I32", + "param": null }, "name": "0" } @@ -223,7 +229,7 @@ }, { "module_name": "tpcc", - "proc_name": "tpcc_seed", + "proc_name": "tpcc_stock_level", "param_desc": { "fields": [ { @@ -231,45 +237,39 @@ "id": "I32", "param": null }, - "name": "warehouse_count" - }, - { - "dat_type": { - "id": "I32", - "param": null - }, - "name": "district_count" + "name": "warehouse_id" }, { "dat_type": { "id": "I32", "param": null }, - "name": "customer_count" + "name": "district_id" }, { "dat_type": { "id": "I32", "param": null }, - "name": "item_count" - }, + "name": "threshold" + } + ] + }, + "return_desc": { + "fields": [ { "dat_type": { "id": "I32", "param": null }, - "name": "initial_stock" + "name": "0" } ] - }, - "return_desc": { - "fields": [] } }, { "module_name": "tpcc", - "proc_name": "tpcc_delivery", + "proc_name": "tpcc_order_status", "param_desc": { "fields": [ { @@ -291,7 +291,7 @@ "id": "I32", "param": null }, - "name": "carrier_id" + "name": "customer_id" } ] }, diff --git a/example/tpcc/package/type.desc.json b/example/tpcc/package/type.desc.json index 4395094..507bf38 100644 --- a/example/tpcc/package/type.desc.json +++ b/example/tpcc/package/type.desc.json @@ -1,89 +1,104 @@ { "types": { - "Customer": [ + "Stock": [ 2, { - "record_name": "customer", + "record_name": "stock", "record_fields": [ { - "field_name": "c_id", + "field_name": "s_i_id", "field_type": [ 0, 6 ] }, { - "field_name": "c_d_id", + "field_name": "s_w_id", "field_type": [ 0, 6 ] }, { - "field_name": "c_w_id", + "field_name": "s_quantity", "field_type": [ 0, 6 ] }, { - "field_name": "c_first", + "field_name": "s_ytd", "field_type": [ 0, - 14 + 6 ] }, { - "field_name": "c_last", + "field_name": "s_order_cnt", "field_type": [ 0, - 14 + 6 ] }, { - "field_name": "c_discount", + "field_name": "s_remote_cnt", "field_type": [ 0, 6 ] - }, + } + ] + } + ], + "District": [ + 2, + { + "record_name": "district", + "record_fields": [ { - "field_name": "c_credit", + "field_name": "d_id", "field_type": [ 0, - 14 + 6 ] }, { - "field_name": "c_balance", + "field_name": "d_w_id", "field_type": [ 0, 6 ] }, { - "field_name": "c_ytd_payment", + "field_name": "d_name", + "field_type": [ + 0, + 14 + ] + }, + { + "field_name": "d_tax", "field_type": [ 0, 6 ] }, { - "field_name": "c_payment_cnt", + "field_name": "d_ytd", "field_type": [ 0, 6 ] }, { - "field_name": "c_delivery_cnt", + "field_name": "d_next_o_id", "field_type": [ 0, 6 ] }, { - "field_name": "c_last_order_id", + "field_name": "d_last_delivery_o_id", "field_type": [ 0, 6 @@ -92,48 +107,56 @@ ] } ], - "Stock": [ + "NewOrder": [ 2, { - "record_name": "stock", + "record_name": "new_order", "record_fields": [ { - "field_name": "s_i_id", + "field_name": "no_o_id", "field_type": [ 0, 6 ] }, { - "field_name": "s_w_id", + "field_name": "no_d_id", "field_type": [ 0, 6 ] }, { - "field_name": "s_quantity", + "field_name": "no_w_id", "field_type": [ 0, 6 ] - }, + } + ] + } + ], + "Item": [ + 2, + { + "record_name": "item", + "record_fields": [ { - "field_name": "s_ytd", + "field_name": "i_id", "field_type": [ 0, 6 ] }, { - "field_name": "s_order_cnt", + "field_name": "i_name", "field_type": [ 0, - 6 + 14 ] }, { - "field_name": "s_remote_cnt", + "field_name": "i_price", "field_type": [ 0, 6 @@ -142,84 +165,105 @@ ] } ], - "District": [ + "Orders": [ 2, { - "record_name": "district", + "record_name": "orders", "record_fields": [ { - "field_name": "d_id", + "field_name": "o_id", "field_type": [ 0, 6 ] }, { - "field_name": "d_w_id", + "field_name": "o_d_id", "field_type": [ 0, 6 ] }, { - "field_name": "d_name", + "field_name": "o_w_id", "field_type": [ 0, - 14 + 6 ] }, { - "field_name": "d_tax", + "field_name": "o_c_id", "field_type": [ 0, 6 ] }, { - "field_name": "d_ytd", + "field_name": "o_entry_d", + "field_type": [ + 0, + 14 + ] + }, + { + "field_name": "o_carrier_id", "field_type": [ 0, 6 ] }, { - "field_name": "d_next_o_id", + "field_name": "o_ol_cnt", "field_type": [ 0, 6 ] }, { - "field_name": "d_last_delivery_o_id", + "field_name": "o_all_local", "field_type": [ 0, 6 ] + }, + { + "field_name": "o_status", + "field_type": [ + 0, + 14 + ] } ] } ], - "Item": [ + "Warehouse": [ 2, { - "record_name": "item", + "record_name": "warehouse", "record_fields": [ { - "field_name": "i_id", + "field_name": "w_id", "field_type": [ 0, 6 ] }, { - "field_name": "i_name", + "field_name": "w_name", "field_type": [ 0, 14 ] }, { - "field_name": "i_price", + "field_name": "w_tax", + "field_type": [ + 0, + 6 + ] + }, + { + "field_name": "w_ytd", "field_type": [ 0, 6 @@ -228,105 +272,90 @@ ] } ], - "OrderLine": [ + "Customer": [ 2, { - "record_name": "order_line", + "record_name": "customer", "record_fields": [ { - "field_name": "ol_o_id", + "field_name": "c_id", "field_type": [ 0, 6 ] }, { - "field_name": "ol_d_id", + "field_name": "c_d_id", "field_type": [ 0, 6 ] }, { - "field_name": "ol_w_id", + "field_name": "c_w_id", "field_type": [ 0, 6 ] }, { - "field_name": "ol_number", + "field_name": "c_first", "field_type": [ 0, - 6 + 14 ] }, { - "field_name": "ol_i_id", + "field_name": "c_last", "field_type": [ 0, - 6 + 14 ] }, { - "field_name": "ol_supply_w_id", + "field_name": "c_discount", "field_type": [ 0, 6 ] }, { - "field_name": "ol_delivery_d", + "field_name": "c_credit", "field_type": [ 0, 14 ] }, { - "field_name": "ol_quantity", + "field_name": "c_balance", "field_type": [ 0, 6 ] }, { - "field_name": "ol_amount", - "field_type": [ - 0, - 6 - ] - } - ] - } - ], - "Warehouse": [ - 2, - { - "record_name": "warehouse", - "record_fields": [ - { - "field_name": "w_id", + "field_name": "c_ytd_payment", "field_type": [ 0, 6 ] }, { - "field_name": "w_name", + "field_name": "c_payment_cnt", "field_type": [ 0, - 14 + 6 ] }, { - "field_name": "w_tax", + "field_name": "c_delivery_cnt", "field_type": [ 0, 6 ] }, { - "field_name": "w_ytd", + "field_name": "c_last_order_id", "field_type": [ 0, 6 @@ -335,69 +364,62 @@ ] } ], - "Orders": [ + "History": [ 2, { - "record_name": "orders", + "record_name": "history", "record_fields": [ { - "field_name": "o_id", + "field_name": "h_id", "field_type": [ 0, - 6 + 14 ] }, { - "field_name": "o_d_id", + "field_name": "h_c_id", "field_type": [ 0, 6 ] }, { - "field_name": "o_w_id", + "field_name": "h_c_d_id", "field_type": [ 0, 6 ] }, { - "field_name": "o_c_id", + "field_name": "h_c_w_id", "field_type": [ 0, 6 ] }, { - "field_name": "o_entry_d", - "field_type": [ - 0, - 14 - ] - }, - { - "field_name": "o_carrier_id", + "field_name": "h_d_id", "field_type": [ 0, 6 ] }, { - "field_name": "o_ol_cnt", + "field_name": "h_w_id", "field_type": [ 0, 6 ] }, { - "field_name": "o_all_local", + "field_name": "h_amount", "field_type": [ 0, 6 ] }, { - "field_name": "o_status", + "field_name": "h_data", "field_type": [ 0, 14 @@ -406,95 +428,73 @@ ] } ], - "NewOrder": [ + "OrderLine": [ 2, { - "record_name": "new_order", + "record_name": "order_line", "record_fields": [ { - "field_name": "no_o_id", + "field_name": "ol_o_id", "field_type": [ 0, 6 ] }, { - "field_name": "no_d_id", + "field_name": "ol_d_id", "field_type": [ 0, 6 ] }, { - "field_name": "no_w_id", + "field_name": "ol_w_id", "field_type": [ 0, 6 ] - } - ] - } - ], - "History": [ - 2, - { - "record_name": "history", - "record_fields": [ - { - "field_name": "h_id", - "field_type": [ - 0, - 14 - ] }, { - "field_name": "h_c_id", + "field_name": "ol_number", "field_type": [ 0, 6 ] }, { - "field_name": "h_c_d_id", + "field_name": "ol_i_id", "field_type": [ 0, 6 ] }, { - "field_name": "h_c_w_id", + "field_name": "ol_supply_w_id", "field_type": [ 0, 6 ] }, { - "field_name": "h_d_id", + "field_name": "ol_delivery_d", "field_type": [ 0, - 6 + 14 ] }, { - "field_name": "h_w_id", + "field_name": "ol_quantity", "field_type": [ 0, 6 ] }, { - "field_name": "h_amount", + "field_name": "ol_amount", "field_type": [ 0, 6 ] - }, - { - "field_name": "h_data", - "field_type": [ - 0, - 14 - ] } ] } diff --git a/example/tpcc/src/bin/tpcc_benchmark.rs b/example/tpcc/src/bin/tpcc_benchmark.rs index d89bf37..18c3189 100644 --- a/example/tpcc/src/bin/tpcc_benchmark.rs +++ b/example/tpcc/src/bin/tpcc_benchmark.rs @@ -1,17 +1,17 @@ use clap::{Parser, ValueEnum}; -use mudu::common::result::RS; -use mudu::error::ec::EC::NotImplemented; -use mudu::m_error; -use mudu_binding::procedure::procedure_invoke; +use mududb::common::result::RS; +use mududb::error::ec::EC::NotImplemented; +use mududb::m_error; +use mududb::binding::procedure::procedure_invoke; use mudu_cli::client::async_client::{AsyncClient, AsyncClientImpl}; use mudu_cli::management::install_app_package; -use mudu_contract::procedure::procedure_param::ProcedureParam; -use mudu_contract::tuple::tuple_datum::TupleDatum; -use mudu_contract::{sql_params, sql_stmt}; +use mududb::contract::procedure::procedure_param::ProcedureParam; +use mududb::contract::tuple::tuple_datum::TupleDatum; +use mududb::contract::{sql_params, sql_stmt}; use std::fs; use std::path::PathBuf; use std::time::Instant; -use sys_interface::sync_api::{mudu_close, mudu_command, mudu_open}; +use mududb::sys_interface::sync_api::{mudu_close, mudu_command, mudu_open}; use tpcc::rust::procedure::{ tpcc_delivery, tpcc_new_order, tpcc_order_status, tpcc_payment, tpcc_seed, tpcc_stock_level, }; @@ -159,27 +159,27 @@ async fn run_tcp(args: Args) -> RS<()> { let start = Instant::now(); if let Some(mpk_path) = &args.mpk { let mpk_binary = fs::read(mpk_path) - .map_err(|e| m_error!(mudu::error::ec::EC::IOErr, "read tpcc mpk error", e))?; + .map_err(|e| m_error!(mududb::error::ec::EC::IOErr, "read tpcc mpk error", e))?; install_app_package(&args.http_addr, mpk_binary) .await - .map_err(|e| m_error!(mudu::error::ec::EC::NetErr, "install tpcc mpk error", e))?; + .map_err(|e| m_error!(mududb::error::ec::EC::NetErr, "install tpcc mpk error", e))?; } let mut client = AsyncClientImpl::connect(&args.tcp_addr) .await .map_err(|e| { m_error!( - mudu::error::ec::EC::NetErr, + mududb::error::ec::EC::NetErr, "connect tpcc tcp client error", e ) })?; let session_id = client - .create_session(mudu_contract::protocol::SessionCreateRequest::new(None)) + .create_session(mududb::contract::protocol::SessionCreateRequest::new(None)) .await .map_err(|e| { m_error!( - mudu::error::ec::EC::NetErr, + mududb::error::ec::EC::NetErr, "create tpcc tcp session error", e ) @@ -263,13 +263,13 @@ async fn run_tcp(args: Args) -> RS<()> { } let _ = client - .close_session(mudu_contract::protocol::SessionCloseRequest::new( + .close_session(mududb::contract::protocol::SessionCloseRequest::new( session_id, )) .await .map_err(|e| { m_error!( - mudu::error::ec::EC::NetErr, + mududb::error::ec::EC::NetErr, "close tpcc tcp session error", e ) @@ -392,7 +392,7 @@ async fn invoke_void( ) -> RS<()> { let payload = serialize_param(tuple)?; let result_binary = client - .invoke_procedure(mudu_contract::protocol::ProcedureInvokeRequest::new( + .invoke_procedure(mududb::contract::protocol::ProcedureInvokeRequest::new( session_id, procedure_name.to_string(), payload, @@ -400,7 +400,7 @@ async fn invoke_void( .await .map_err(|e| { m_error!( - mudu::error::ec::EC::NetErr, + mududb::error::ec::EC::NetErr, "invoke void procedure error", e ) @@ -419,7 +419,7 @@ async fn invoke_typed( ) -> RS { let payload = serialize_param(tuple)?; let result_binary = client - .invoke_procedure(mudu_contract::protocol::ProcedureInvokeRequest::new( + .invoke_procedure(mududb::contract::protocol::ProcedureInvokeRequest::new( session_id, procedure_name.to_string(), payload, @@ -427,7 +427,7 @@ async fn invoke_typed( .await .map_err(|e| { m_error!( - mudu::error::ec::EC::NetErr, + mududb::error::ec::EC::NetErr, "invoke typed procedure error", e ) @@ -465,7 +465,7 @@ async fn main() { #[cfg(all(test, target_os = "linux"))] mod tests { use super::{Args, BenchmarkMode, run_sync, run_tcp}; - use mudu::common::result::RS; + use mududb::common::result::RS; use mudu_runtime::backend::backend::Backend; use mudu_runtime::backend::mududb_cfg::{MuduDBCfg, ServerMode}; use mudu_utils::notifier::{Notifier, notify_wait}; @@ -519,8 +519,8 @@ mod tests { fn stop(self) -> RS<()> { self.stop.notify_all(); self.handle.join().map_err(|_| { - mudu::m_error!( - mudu::error::ec::EC::ThreadErr, + mududb::m_error!( + mududb::error::ec::EC::ThreadErr, "join tpcc benchmark mudud thread error" ) })? @@ -537,15 +537,15 @@ mod tests { let db_path = temp_dir("db"); let mpk_path = temp_dir("mpk"); fs::create_dir_all(&db_path).map_err(|e| { - mudu::m_error!( - mudu::error::ec::EC::IOErr, + mududb::m_error!( + mududb::error::ec::EC::IOErr, "create tpcc benchmark db dir error", e ) })?; fs::create_dir_all(&mpk_path).map_err(|e| { - mudu::m_error!( - mudu::error::ec::EC::IOErr, + mududb::m_error!( + mududb::error::ec::EC::IOErr, "create tpcc benchmark mpk dir error", e ) diff --git a/example/tpcc/src/generated/customer.rs b/example/tpcc/src/generated/customer.rs index 08f1a72..9e5c56f 100644 --- a/example/tpcc/src/generated/customer.rs +++ b/example/tpcc/src/generated/customer.rs @@ -1,20 +1,20 @@ pub mod object { use lazy_static::lazy_static; -use mudu::common::result::RS; -use mudu_type::dat_binary::DatBinary; -use mudu_type::dat_textual::DatTextual; -use mudu_type::dat_type::DatType; -use mudu_type::dat_type_id::DatTypeID; -use mudu_type::dat_value::DatValue; -use mudu_type::datum::{Datum, DatumDyn}; -use mudu_contract::database::attr_field_access; -use mudu_contract::database::attr_value::AttrValue; -use mudu_contract::database::entity::Entity; -use mudu_contract::database::entity_utils; -use mudu_contract::tuple::datum_desc::DatumDesc; -use mudu_contract::tuple::tuple_field_desc::TupleFieldDesc; -use mudu_contract::tuple::tuple_datum::TupleDatumMarker; -use mudu_contract::database::sql_params::SQLParamMarker; +use mududb::common::result::RS; +use mududb::contract::database::attr_field_access; +use mududb::contract::database::attr_value::AttrValue; +use mududb::contract::database::entity::Entity; +use mududb::contract::database::entity_utils; +use mududb::contract::database::sql_params::SQLParamMarker; +use mududb::contract::tuple::datum_desc::DatumDesc; +use mududb::contract::tuple::tuple_field_desc::TupleFieldDesc; +use mududb::contract::tuple::tuple_datum::TupleDatumMarker; +use mududb::types::dat_binary::DatBinary; +use mududb::types::dat_textual::DatTextual; +use mududb::types::dat_type::DatType; +use mududb::types::dat_type_id::DatTypeID; +use mududb::types::dat_value::DatValue; +use mududb::types::datum::{Datum, DatumDyn}; // constant definition const CUSTOMER:&str = "customer"; diff --git a/example/tpcc/src/generated/district.rs b/example/tpcc/src/generated/district.rs index bc85890..03f1e29 100644 --- a/example/tpcc/src/generated/district.rs +++ b/example/tpcc/src/generated/district.rs @@ -1,20 +1,20 @@ pub mod object { use lazy_static::lazy_static; -use mudu::common::result::RS; -use mudu_type::dat_binary::DatBinary; -use mudu_type::dat_textual::DatTextual; -use mudu_type::dat_type::DatType; -use mudu_type::dat_type_id::DatTypeID; -use mudu_type::dat_value::DatValue; -use mudu_type::datum::{Datum, DatumDyn}; -use mudu_contract::database::attr_field_access; -use mudu_contract::database::attr_value::AttrValue; -use mudu_contract::database::entity::Entity; -use mudu_contract::database::entity_utils; -use mudu_contract::tuple::datum_desc::DatumDesc; -use mudu_contract::tuple::tuple_field_desc::TupleFieldDesc; -use mudu_contract::tuple::tuple_datum::TupleDatumMarker; -use mudu_contract::database::sql_params::SQLParamMarker; +use mududb::common::result::RS; +use mududb::contract::database::attr_field_access; +use mududb::contract::database::attr_value::AttrValue; +use mududb::contract::database::entity::Entity; +use mududb::contract::database::entity_utils; +use mududb::contract::database::sql_params::SQLParamMarker; +use mududb::contract::tuple::datum_desc::DatumDesc; +use mududb::contract::tuple::tuple_field_desc::TupleFieldDesc; +use mududb::contract::tuple::tuple_datum::TupleDatumMarker; +use mududb::types::dat_binary::DatBinary; +use mududb::types::dat_textual::DatTextual; +use mududb::types::dat_type::DatType; +use mududb::types::dat_type_id::DatTypeID; +use mududb::types::dat_value::DatValue; +use mududb::types::datum::{Datum, DatumDyn}; // constant definition const DISTRICT:&str = "district"; diff --git a/example/tpcc/src/generated/history.rs b/example/tpcc/src/generated/history.rs index 011a293..64ca597 100644 --- a/example/tpcc/src/generated/history.rs +++ b/example/tpcc/src/generated/history.rs @@ -1,20 +1,20 @@ pub mod object { use lazy_static::lazy_static; -use mudu::common::result::RS; -use mudu_type::dat_binary::DatBinary; -use mudu_type::dat_textual::DatTextual; -use mudu_type::dat_type::DatType; -use mudu_type::dat_type_id::DatTypeID; -use mudu_type::dat_value::DatValue; -use mudu_type::datum::{Datum, DatumDyn}; -use mudu_contract::database::attr_field_access; -use mudu_contract::database::attr_value::AttrValue; -use mudu_contract::database::entity::Entity; -use mudu_contract::database::entity_utils; -use mudu_contract::tuple::datum_desc::DatumDesc; -use mudu_contract::tuple::tuple_field_desc::TupleFieldDesc; -use mudu_contract::tuple::tuple_datum::TupleDatumMarker; -use mudu_contract::database::sql_params::SQLParamMarker; +use mududb::common::result::RS; +use mududb::contract::database::attr_field_access; +use mududb::contract::database::attr_value::AttrValue; +use mududb::contract::database::entity::Entity; +use mududb::contract::database::entity_utils; +use mududb::contract::database::sql_params::SQLParamMarker; +use mududb::contract::tuple::datum_desc::DatumDesc; +use mududb::contract::tuple::tuple_field_desc::TupleFieldDesc; +use mududb::contract::tuple::tuple_datum::TupleDatumMarker; +use mududb::types::dat_binary::DatBinary; +use mududb::types::dat_textual::DatTextual; +use mududb::types::dat_type::DatType; +use mududb::types::dat_type_id::DatTypeID; +use mududb::types::dat_value::DatValue; +use mududb::types::datum::{Datum, DatumDyn}; // constant definition const HISTORY:&str = "history"; diff --git a/example/tpcc/src/generated/item.rs b/example/tpcc/src/generated/item.rs index 7a7847d..38bdb8d 100644 --- a/example/tpcc/src/generated/item.rs +++ b/example/tpcc/src/generated/item.rs @@ -1,20 +1,20 @@ pub mod object { use lazy_static::lazy_static; -use mudu::common::result::RS; -use mudu_type::dat_binary::DatBinary; -use mudu_type::dat_textual::DatTextual; -use mudu_type::dat_type::DatType; -use mudu_type::dat_type_id::DatTypeID; -use mudu_type::dat_value::DatValue; -use mudu_type::datum::{Datum, DatumDyn}; -use mudu_contract::database::attr_field_access; -use mudu_contract::database::attr_value::AttrValue; -use mudu_contract::database::entity::Entity; -use mudu_contract::database::entity_utils; -use mudu_contract::tuple::datum_desc::DatumDesc; -use mudu_contract::tuple::tuple_field_desc::TupleFieldDesc; -use mudu_contract::tuple::tuple_datum::TupleDatumMarker; -use mudu_contract::database::sql_params::SQLParamMarker; +use mududb::common::result::RS; +use mududb::contract::database::attr_field_access; +use mududb::contract::database::attr_value::AttrValue; +use mududb::contract::database::entity::Entity; +use mududb::contract::database::entity_utils; +use mududb::contract::database::sql_params::SQLParamMarker; +use mududb::contract::tuple::datum_desc::DatumDesc; +use mududb::contract::tuple::tuple_field_desc::TupleFieldDesc; +use mududb::contract::tuple::tuple_datum::TupleDatumMarker; +use mududb::types::dat_binary::DatBinary; +use mududb::types::dat_textual::DatTextual; +use mududb::types::dat_type::DatType; +use mududb::types::dat_type_id::DatTypeID; +use mududb::types::dat_value::DatValue; +use mududb::types::datum::{Datum, DatumDyn}; // constant definition const ITEM:&str = "item"; diff --git a/example/tpcc/src/generated/new_order.rs b/example/tpcc/src/generated/new_order.rs index b246665..4c94502 100644 --- a/example/tpcc/src/generated/new_order.rs +++ b/example/tpcc/src/generated/new_order.rs @@ -1,20 +1,20 @@ pub mod object { use lazy_static::lazy_static; -use mudu::common::result::RS; -use mudu_type::dat_binary::DatBinary; -use mudu_type::dat_textual::DatTextual; -use mudu_type::dat_type::DatType; -use mudu_type::dat_type_id::DatTypeID; -use mudu_type::dat_value::DatValue; -use mudu_type::datum::{Datum, DatumDyn}; -use mudu_contract::database::attr_field_access; -use mudu_contract::database::attr_value::AttrValue; -use mudu_contract::database::entity::Entity; -use mudu_contract::database::entity_utils; -use mudu_contract::tuple::datum_desc::DatumDesc; -use mudu_contract::tuple::tuple_field_desc::TupleFieldDesc; -use mudu_contract::tuple::tuple_datum::TupleDatumMarker; -use mudu_contract::database::sql_params::SQLParamMarker; +use mududb::common::result::RS; +use mududb::contract::database::attr_field_access; +use mududb::contract::database::attr_value::AttrValue; +use mududb::contract::database::entity::Entity; +use mududb::contract::database::entity_utils; +use mududb::contract::database::sql_params::SQLParamMarker; +use mududb::contract::tuple::datum_desc::DatumDesc; +use mududb::contract::tuple::tuple_field_desc::TupleFieldDesc; +use mududb::contract::tuple::tuple_datum::TupleDatumMarker; +use mududb::types::dat_binary::DatBinary; +use mududb::types::dat_textual::DatTextual; +use mududb::types::dat_type::DatType; +use mududb::types::dat_type_id::DatTypeID; +use mududb::types::dat_value::DatValue; +use mududb::types::datum::{Datum, DatumDyn}; // constant definition const NEW_ORDER:&str = "new_order"; diff --git a/example/tpcc/src/generated/order_line.rs b/example/tpcc/src/generated/order_line.rs index ae97da5..d22063e 100644 --- a/example/tpcc/src/generated/order_line.rs +++ b/example/tpcc/src/generated/order_line.rs @@ -1,20 +1,20 @@ pub mod object { use lazy_static::lazy_static; -use mudu::common::result::RS; -use mudu_type::dat_binary::DatBinary; -use mudu_type::dat_textual::DatTextual; -use mudu_type::dat_type::DatType; -use mudu_type::dat_type_id::DatTypeID; -use mudu_type::dat_value::DatValue; -use mudu_type::datum::{Datum, DatumDyn}; -use mudu_contract::database::attr_field_access; -use mudu_contract::database::attr_value::AttrValue; -use mudu_contract::database::entity::Entity; -use mudu_contract::database::entity_utils; -use mudu_contract::tuple::datum_desc::DatumDesc; -use mudu_contract::tuple::tuple_field_desc::TupleFieldDesc; -use mudu_contract::tuple::tuple_datum::TupleDatumMarker; -use mudu_contract::database::sql_params::SQLParamMarker; +use mududb::common::result::RS; +use mududb::contract::database::attr_field_access; +use mududb::contract::database::attr_value::AttrValue; +use mududb::contract::database::entity::Entity; +use mududb::contract::database::entity_utils; +use mududb::contract::database::sql_params::SQLParamMarker; +use mududb::contract::tuple::datum_desc::DatumDesc; +use mududb::contract::tuple::tuple_field_desc::TupleFieldDesc; +use mududb::contract::tuple::tuple_datum::TupleDatumMarker; +use mududb::types::dat_binary::DatBinary; +use mududb::types::dat_textual::DatTextual; +use mududb::types::dat_type::DatType; +use mududb::types::dat_type_id::DatTypeID; +use mududb::types::dat_value::DatValue; +use mududb::types::datum::{Datum, DatumDyn}; // constant definition const ORDER_LINE:&str = "order_line"; diff --git a/example/tpcc/src/generated/orders.rs b/example/tpcc/src/generated/orders.rs index d68c1aa..acc800b 100644 --- a/example/tpcc/src/generated/orders.rs +++ b/example/tpcc/src/generated/orders.rs @@ -1,20 +1,20 @@ pub mod object { use lazy_static::lazy_static; -use mudu::common::result::RS; -use mudu_type::dat_binary::DatBinary; -use mudu_type::dat_textual::DatTextual; -use mudu_type::dat_type::DatType; -use mudu_type::dat_type_id::DatTypeID; -use mudu_type::dat_value::DatValue; -use mudu_type::datum::{Datum, DatumDyn}; -use mudu_contract::database::attr_field_access; -use mudu_contract::database::attr_value::AttrValue; -use mudu_contract::database::entity::Entity; -use mudu_contract::database::entity_utils; -use mudu_contract::tuple::datum_desc::DatumDesc; -use mudu_contract::tuple::tuple_field_desc::TupleFieldDesc; -use mudu_contract::tuple::tuple_datum::TupleDatumMarker; -use mudu_contract::database::sql_params::SQLParamMarker; +use mududb::common::result::RS; +use mududb::contract::database::attr_field_access; +use mududb::contract::database::attr_value::AttrValue; +use mududb::contract::database::entity::Entity; +use mududb::contract::database::entity_utils; +use mududb::contract::database::sql_params::SQLParamMarker; +use mududb::contract::tuple::datum_desc::DatumDesc; +use mududb::contract::tuple::tuple_field_desc::TupleFieldDesc; +use mududb::contract::tuple::tuple_datum::TupleDatumMarker; +use mududb::types::dat_binary::DatBinary; +use mududb::types::dat_textual::DatTextual; +use mududb::types::dat_type::DatType; +use mududb::types::dat_type_id::DatTypeID; +use mududb::types::dat_value::DatValue; +use mududb::types::datum::{Datum, DatumDyn}; // constant definition const ORDERS:&str = "orders"; diff --git a/example/tpcc/src/generated/procedure.rs b/example/tpcc/src/generated/procedure.rs index 84e9726..dd608b1 100644 --- a/example/tpcc/src/generated/procedure.rs +++ b/example/tpcc/src/generated/procedure.rs @@ -9,18 +9,18 @@ use crate::generated::procedure_common::{ }; use crate::generated::stock::object::Stock; use crate::generated::warehouse::object::Warehouse; -use mudu::common::result::RS; -use mudu::common::xid::XID; -use mudu::error::ec::EC::MuduError; -use mudu::m_error; -use mudu_contract::database::entity::Entity; -use mudu_contract::{sql_params, sql_stmt}; -use sys_interface::async_api::{mudu_command, mudu_query}; +use mududb::common::result::RS; +use mududb::common::xid::XID; +use mududb::error::ec::EC::MuduError; +use mududb::m_error; +use mududb::contract::database::entity::Entity; +use mududb::contract::{sql_params, sql_stmt}; +use mududb::sys_interface::async_api::{mudu_command, mudu_query}; async fn query_one_entity( xid: XID, sql: &str, - params: &dyn mudu_contract::database::sql_params::SQLParams, + params: &dyn mududb::contract::database::sql_params::SQLParams, ) -> RS { mudu_query::(xid, sql_stmt!(&sql), params).await? .next_record()? @@ -30,7 +30,7 @@ async fn query_one_entity( async fn query_entities( xid: XID, sql: &str, - params: &dyn mudu_contract::database::sql_params::SQLParams, + params: &dyn mududb::contract::database::sql_params::SQLParams, ) -> RS> { let mut result_set = mudu_query::(xid, sql_stmt!(&sql), params).await?; let mut values = Vec::new(); @@ -43,7 +43,7 @@ async fn query_entities( async fn query_count_i32( xid: XID, sql: &str, - params: &dyn mudu_contract::database::sql_params::SQLParams, + params: &dyn mududb::contract::database::sql_params::SQLParams, ) -> RS { let value = mudu_query::(xid, sql_stmt!(&sql), params).await? .next_record()? @@ -347,7 +347,7 @@ pub async fn tpcc_payment( &"INSERT INTO history (h_id, h_c_id, h_c_d_id, h_c_w_id, h_d_id, h_w_id, h_amount, h_data) VALUES (?, ?, ?, ?, ?, ?, ?, ?)" ), sql_params!(&( - mudu_sys::random::next_uuid_v4_string(), + mududb::sys::random::next_uuid_v4_string(), customer_id, district_id, warehouse_id, @@ -463,10 +463,10 @@ mod tests { tpcc_delivery, tpcc_new_order, tpcc_order_status, tpcc_payment, tpcc_seed, tpcc_stock_level, }; use crate::test_lock; - use mudu_contract::{sql_params, sql_stmt}; + use mududb::contract::{sql_params, sql_stmt}; use std::path::PathBuf; use std::time::{SystemTime, UNIX_EPOCH}; - use sys_interface::async_api::{mudu_batch, mudu_close, mudu_open}; + use mududb::sys_interface::async_api::{mudu_batch, mudu_close, mudu_open}; fn temp_db_path(name: &str) -> PathBuf { let suffix = SystemTime::now() @@ -510,43 +510,63 @@ mod tests { mudu_close(xid).await.unwrap(); } } -async fn mp2_tpcc_order_status(param:Vec) -> Vec { - ::mudu_binding::procedure::procedure_invoke::invoke_procedure_async( +async fn mp2_tpcc_new_order(param:Vec) -> Vec { + ::mududb::binding::procedure::procedure_invoke::invoke_procedure_async( param, - mudu_inner_p2_tpcc_order_status, + mudu_inner_p2_tpcc_new_order, ).await } -pub async fn mudu_inner_p2_tpcc_order_status( - param: ::mudu_contract::procedure::procedure_param::ProcedureParam, -) -> ::mudu::common::result::RS< - ::mudu_contract::procedure::procedure_result::ProcedureResult, +pub async fn mudu_inner_p2_tpcc_new_order( + param: ::mududb::contract::procedure::procedure_param::ProcedureParam, +) -> ::mududb::common::result::RS< + ::mududb::contract::procedure::procedure_result::ProcedureResult, > { - let return_desc = mudu_result_desc_tpcc_order_status().clone(); - let res = tpcc_order_status( + let res = tpcc_new_order( param.session_id(), - ::mudu_type::datum::value_to_typed::< + ::mududb::types::datum::value_to_typed::< i32, _, >(¶m.param_list()[0], "i32")?, - ::mudu_type::datum::value_to_typed::< + ::mududb::types::datum::value_to_typed::< i32, _, >(¶m.param_list()[1], "i32")?, - ::mudu_type::datum::value_to_typed::< + ::mududb::types::datum::value_to_typed::< i32, _, >(¶m.param_list()[2], "i32")?, + + ::mududb::types::datum::value_to_typed::< + Vec, + _, + >(¶m.param_list()[3], "Vec")?, + + + + ::mududb::types::datum::value_to_typed::< + Vec, + _, + >(¶m.param_list()[4], "Vec")?, + + + + ::mududb::types::datum::value_to_typed::< + Vec, + _, + >(¶m.param_list()[5], "Vec")?, + + ).await; match res { Ok(tuple) => { @@ -554,42 +574,63 @@ pub async fn mudu_inner_p2_tpcc_order_status( vec![ - ::mudu_type::datum::value_from_typed(&tuple, "String")? + ::mududb::types::datum::value_from_typed(&tuple, "String")? ] }; - Ok(::mudu_contract::procedure::procedure_result::ProcedureResult::new(return_list)) + Ok(::mududb::contract::procedure::procedure_result::ProcedureResult::new(return_list)) } Err(e) => Err(e), } } -pub fn mudu_argv_desc_tpcc_order_status() -> &'static ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc { - static ARGV_DESC: std::sync::OnceLock<::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc> = +pub fn mudu_argv_desc_tpcc_new_order() -> &'static ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc { + static ARGV_DESC: std::sync::OnceLock<::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc> = std::sync::OnceLock::new(); ARGV_DESC.get_or_init(|| { - ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc::new(vec![ + ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc::new(vec![ - ::mudu_contract::tuple::datum_desc::DatumDesc::new( + ::mududb::contract::tuple::datum_desc::DatumDesc::new( "warehouse_id".to_string(), - ::dat_type().clone() + ::dat_type().clone() ), - ::mudu_contract::tuple::datum_desc::DatumDesc::new( + ::mududb::contract::tuple::datum_desc::DatumDesc::new( "district_id".to_string(), - ::dat_type().clone() + ::dat_type().clone() ), - ::mudu_contract::tuple::datum_desc::DatumDesc::new( + ::mududb::contract::tuple::datum_desc::DatumDesc::new( "customer_id".to_string(), - ::dat_type().clone() + ::dat_type().clone() + + ), + + ::mududb::contract::tuple::datum_desc::DatumDesc::new( + "item_ids".to_string(), + + as ::mududb::types::datum::Datum>::dat_type().clone() + + ), + + ::mududb::contract::tuple::datum_desc::DatumDesc::new( + "supplier_warehouse_ids".to_string(), + + as ::mududb::types::datum::Datum>::dat_type().clone() + + ), + + ::mududb::contract::tuple::datum_desc::DatumDesc::new( + "quantities".to_string(), + + as ::mududb::types::datum::Datum>::dat_type().clone() ), @@ -598,17 +639,17 @@ pub fn mudu_argv_desc_tpcc_order_status() -> &'static ::mudu_contract::tuple::t ) } -pub fn mudu_result_desc_tpcc_order_status() -> &'static ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc { - static RESULT_DESC: std::sync::OnceLock<::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc> = +pub fn mudu_result_desc_tpcc_new_order() -> &'static ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc { + static RESULT_DESC: std::sync::OnceLock<::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc> = std::sync::OnceLock::new(); RESULT_DESC.get_or_init(|| { - ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc::new(vec![ + ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc::new(vec![ - ::mudu_contract::tuple::datum_desc::DatumDesc::new( + ::mududb::contract::tuple::datum_desc::DatumDesc::new( "0".to_string(), - ::dat_type().clone() + ::dat_type().clone() ), @@ -617,28 +658,28 @@ pub fn mudu_result_desc_tpcc_order_status() -> &'static ::mudu_contract::tuple:: ) } -pub fn mudu_proc_desc_tpcc_order_status() -> &'static ::mudu_contract::procedure::proc_desc::ProcDesc { +pub fn mudu_proc_desc_tpcc_new_order() -> &'static ::mududb::contract::procedure::proc_desc::ProcDesc { static _PROC_DESC: std::sync::OnceLock< - ::mudu_contract::procedure::proc_desc::ProcDesc, + ::mududb::contract::procedure::proc_desc::ProcDesc, > = std::sync::OnceLock::new(); _PROC_DESC .get_or_init(|| { - ::mudu_contract::procedure::proc_desc::ProcDesc::new( + ::mududb::contract::procedure::proc_desc::ProcDesc::new( "tpcc".to_string(), - "tpcc_order_status".to_string(), - mudu_argv_desc_tpcc_order_status().clone(), - mudu_result_desc_tpcc_order_status().clone(), + "tpcc_new_order".to_string(), + mudu_argv_desc_tpcc_new_order().clone(), + mudu_result_desc_tpcc_new_order().clone(), false ) }) } -mod mod_tpcc_order_status { +mod mod_tpcc_new_order { wit_bindgen::generate!({ inline: - r##"package mudu:mp2-tpcc-order-status; - world mudu-app-mp2-tpcc-order-status { - export mp2-tpcc-order-status: func(param:list) -> list; + r##"package mudu:mp2-tpcc-new-order; + world mudu-app-mp2-tpcc-new-order { + export mp2-tpcc-new-order: func(param:list) -> list; } "##, async: true @@ -646,60 +687,52 @@ mod mod_tpcc_order_status { #[allow(non_camel_case_types)] #[allow(unused)] - struct GuestTpccOrderStatus {} + struct GuestTpccNewOrder {} - impl Guest for GuestTpccOrderStatus { - async fn mp2_tpcc_order_status(param:Vec) -> Vec { - super::mp2_tpcc_order_status(param).await + impl Guest for GuestTpccNewOrder { + async fn mp2_tpcc_new_order(param:Vec) -> Vec { + super::mp2_tpcc_new_order(param).await } } - export!(GuestTpccOrderStatus); + export!(GuestTpccNewOrder); } -async fn mp2_tpcc_payment(param:Vec) -> Vec { - ::mudu_binding::procedure::procedure_invoke::invoke_procedure_async( +async fn mp2_tpcc_delivery(param:Vec) -> Vec { + ::mududb::binding::procedure::procedure_invoke::invoke_procedure_async( param, - mudu_inner_p2_tpcc_payment, + mudu_inner_p2_tpcc_delivery, ).await } -pub async fn mudu_inner_p2_tpcc_payment( - param: ::mudu_contract::procedure::procedure_param::ProcedureParam, -) -> ::mudu::common::result::RS< - ::mudu_contract::procedure::procedure_result::ProcedureResult, +pub async fn mudu_inner_p2_tpcc_delivery( + param: ::mududb::contract::procedure::procedure_param::ProcedureParam, +) -> ::mududb::common::result::RS< + ::mududb::contract::procedure::procedure_result::ProcedureResult, > { - let return_desc = mudu_result_desc_tpcc_payment().clone(); - let res = tpcc_payment( + let res = tpcc_delivery( param.session_id(), - ::mudu_type::datum::value_to_typed::< + ::mududb::types::datum::value_to_typed::< i32, _, >(¶m.param_list()[0], "i32")?, - ::mudu_type::datum::value_to_typed::< + ::mududb::types::datum::value_to_typed::< i32, _, >(¶m.param_list()[1], "i32")?, - ::mudu_type::datum::value_to_typed::< + ::mududb::types::datum::value_to_typed::< i32, _, >(¶m.param_list()[2], "i32")?, - - ::mudu_type::datum::value_to_typed::< - i32, - _, - >(¶m.param_list()[3], "i32")?, - - ).await; match res { Ok(tuple) => { @@ -707,49 +740,42 @@ pub async fn mudu_inner_p2_tpcc_payment( vec![ - ::mudu_type::datum::value_from_typed(&tuple, "i32")? + ::mududb::types::datum::value_from_typed(&tuple, "String")? ] }; - Ok(::mudu_contract::procedure::procedure_result::ProcedureResult::new(return_list)) + Ok(::mududb::contract::procedure::procedure_result::ProcedureResult::new(return_list)) } Err(e) => Err(e), } } -pub fn mudu_argv_desc_tpcc_payment() -> &'static ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc { - static ARGV_DESC: std::sync::OnceLock<::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc> = +pub fn mudu_argv_desc_tpcc_delivery() -> &'static ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc { + static ARGV_DESC: std::sync::OnceLock<::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc> = std::sync::OnceLock::new(); ARGV_DESC.get_or_init(|| { - ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc::new(vec![ + ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc::new(vec![ - ::mudu_contract::tuple::datum_desc::DatumDesc::new( + ::mududb::contract::tuple::datum_desc::DatumDesc::new( "warehouse_id".to_string(), - ::dat_type().clone() + ::dat_type().clone() ), - ::mudu_contract::tuple::datum_desc::DatumDesc::new( + ::mududb::contract::tuple::datum_desc::DatumDesc::new( "district_id".to_string(), - ::dat_type().clone() - - ), - - ::mudu_contract::tuple::datum_desc::DatumDesc::new( - "customer_id".to_string(), - - ::dat_type().clone() + ::dat_type().clone() ), - ::mudu_contract::tuple::datum_desc::DatumDesc::new( - "amount".to_string(), + ::mududb::contract::tuple::datum_desc::DatumDesc::new( + "carrier_id".to_string(), - ::dat_type().clone() + ::dat_type().clone() ), @@ -758,17 +784,17 @@ pub fn mudu_argv_desc_tpcc_payment() -> &'static ::mudu_contract::tuple::tuple_ ) } -pub fn mudu_result_desc_tpcc_payment() -> &'static ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc { - static RESULT_DESC: std::sync::OnceLock<::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc> = +pub fn mudu_result_desc_tpcc_delivery() -> &'static ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc { + static RESULT_DESC: std::sync::OnceLock<::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc> = std::sync::OnceLock::new(); RESULT_DESC.get_or_init(|| { - ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc::new(vec![ + ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc::new(vec![ - ::mudu_contract::tuple::datum_desc::DatumDesc::new( + ::mududb::contract::tuple::datum_desc::DatumDesc::new( "0".to_string(), - ::dat_type().clone() + ::dat_type().clone() ), @@ -777,28 +803,28 @@ pub fn mudu_result_desc_tpcc_payment() -> &'static ::mudu_contract::tuple::tuple ) } -pub fn mudu_proc_desc_tpcc_payment() -> &'static ::mudu_contract::procedure::proc_desc::ProcDesc { +pub fn mudu_proc_desc_tpcc_delivery() -> &'static ::mududb::contract::procedure::proc_desc::ProcDesc { static _PROC_DESC: std::sync::OnceLock< - ::mudu_contract::procedure::proc_desc::ProcDesc, + ::mududb::contract::procedure::proc_desc::ProcDesc, > = std::sync::OnceLock::new(); _PROC_DESC .get_or_init(|| { - ::mudu_contract::procedure::proc_desc::ProcDesc::new( + ::mududb::contract::procedure::proc_desc::ProcDesc::new( "tpcc".to_string(), - "tpcc_payment".to_string(), - mudu_argv_desc_tpcc_payment().clone(), - mudu_result_desc_tpcc_payment().clone(), + "tpcc_delivery".to_string(), + mudu_argv_desc_tpcc_delivery().clone(), + mudu_result_desc_tpcc_delivery().clone(), false ) }) } -mod mod_tpcc_payment { +mod mod_tpcc_delivery { wit_bindgen::generate!({ inline: - r##"package mudu:mp2-tpcc-payment; - world mudu-app-mp2-tpcc-payment { - export mp2-tpcc-payment: func(param:list) -> list; + r##"package mudu:mp2-tpcc-delivery; + world mudu-app-mp2-tpcc-delivery { + export mp2-tpcc-delivery: func(param:list) -> list; } "##, async: true @@ -806,96 +832,119 @@ mod mod_tpcc_payment { #[allow(non_camel_case_types)] #[allow(unused)] - struct GuestTpccPayment {} + struct GuestTpccDelivery {} - impl Guest for GuestTpccPayment { - async fn mp2_tpcc_payment(param:Vec) -> Vec { - super::mp2_tpcc_payment(param).await + impl Guest for GuestTpccDelivery { + async fn mp2_tpcc_delivery(param:Vec) -> Vec { + super::mp2_tpcc_delivery(param).await } } - export!(GuestTpccPayment); + export!(GuestTpccDelivery); } -async fn mp2_tpcc_stock_level(param:Vec) -> Vec { - ::mudu_binding::procedure::procedure_invoke::invoke_procedure_async( +async fn mp2_tpcc_seed(param:Vec) -> Vec { + ::mududb::binding::procedure::procedure_invoke::invoke_procedure_async( param, - mudu_inner_p2_tpcc_stock_level, + mudu_inner_p2_tpcc_seed, ).await } -pub async fn mudu_inner_p2_tpcc_stock_level( - param: ::mudu_contract::procedure::procedure_param::ProcedureParam, -) -> ::mudu::common::result::RS< - ::mudu_contract::procedure::procedure_result::ProcedureResult, +pub async fn mudu_inner_p2_tpcc_seed( + param: ::mududb::contract::procedure::procedure_param::ProcedureParam, +) -> ::mududb::common::result::RS< + ::mududb::contract::procedure::procedure_result::ProcedureResult, > { - let return_desc = mudu_result_desc_tpcc_stock_level().clone(); - let res = tpcc_stock_level( + let res = tpcc_seed( param.session_id(), - ::mudu_type::datum::value_to_typed::< + ::mududb::types::datum::value_to_typed::< i32, _, >(¶m.param_list()[0], "i32")?, - ::mudu_type::datum::value_to_typed::< + ::mududb::types::datum::value_to_typed::< i32, _, >(¶m.param_list()[1], "i32")?, - ::mudu_type::datum::value_to_typed::< + ::mududb::types::datum::value_to_typed::< i32, _, >(¶m.param_list()[2], "i32")?, + + ::mududb::types::datum::value_to_typed::< + i32, + _, + >(¶m.param_list()[3], "i32")?, + + + + ::mududb::types::datum::value_to_typed::< + i32, + _, + >(¶m.param_list()[4], "i32")?, + + ).await; match res { Ok(tuple) => { let return_list = { - vec![ - - ::mudu_type::datum::value_from_typed(&tuple, "i32")? - - ] + vec![] }; - Ok(::mudu_contract::procedure::procedure_result::ProcedureResult::new(return_list)) + Ok(::mududb::contract::procedure::procedure_result::ProcedureResult::new(return_list)) } Err(e) => Err(e), } } -pub fn mudu_argv_desc_tpcc_stock_level() -> &'static ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc { - static ARGV_DESC: std::sync::OnceLock<::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc> = +pub fn mudu_argv_desc_tpcc_seed() -> &'static ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc { + static ARGV_DESC: std::sync::OnceLock<::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc> = std::sync::OnceLock::new(); ARGV_DESC.get_or_init(|| { - ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc::new(vec![ + ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc::new(vec![ - ::mudu_contract::tuple::datum_desc::DatumDesc::new( - "warehouse_id".to_string(), + ::mududb::contract::tuple::datum_desc::DatumDesc::new( + "warehouse_count".to_string(), - ::dat_type().clone() + ::dat_type().clone() ), - ::mudu_contract::tuple::datum_desc::DatumDesc::new( - "district_id".to_string(), + ::mududb::contract::tuple::datum_desc::DatumDesc::new( + "district_count".to_string(), - ::dat_type().clone() + ::dat_type().clone() ), - ::mudu_contract::tuple::datum_desc::DatumDesc::new( - "threshold".to_string(), + ::mududb::contract::tuple::datum_desc::DatumDesc::new( + "customer_count".to_string(), + + ::dat_type().clone() + + ), + + ::mududb::contract::tuple::datum_desc::DatumDesc::new( + "item_count".to_string(), + + ::dat_type().clone() + + ), + + ::mududb::contract::tuple::datum_desc::DatumDesc::new( + "initial_stock".to_string(), - ::dat_type().clone() + ::dat_type().clone() ), @@ -904,47 +953,40 @@ pub fn mudu_argv_desc_tpcc_stock_level() -> &'static ::mudu_contract::tuple::tu ) } -pub fn mudu_result_desc_tpcc_stock_level() -> &'static ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc { - static RESULT_DESC: std::sync::OnceLock<::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc> = +pub fn mudu_result_desc_tpcc_seed() -> &'static ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc { + static RESULT_DESC: std::sync::OnceLock<::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc> = std::sync::OnceLock::new(); RESULT_DESC.get_or_init(|| { - ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc::new(vec![ - - ::mudu_contract::tuple::datum_desc::DatumDesc::new( - "0".to_string(), - - ::dat_type().clone() - - ), + ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc::new(vec![ ]) } ) } -pub fn mudu_proc_desc_tpcc_stock_level() -> &'static ::mudu_contract::procedure::proc_desc::ProcDesc { +pub fn mudu_proc_desc_tpcc_seed() -> &'static ::mududb::contract::procedure::proc_desc::ProcDesc { static _PROC_DESC: std::sync::OnceLock< - ::mudu_contract::procedure::proc_desc::ProcDesc, + ::mududb::contract::procedure::proc_desc::ProcDesc, > = std::sync::OnceLock::new(); _PROC_DESC .get_or_init(|| { - ::mudu_contract::procedure::proc_desc::ProcDesc::new( + ::mududb::contract::procedure::proc_desc::ProcDesc::new( "tpcc".to_string(), - "tpcc_stock_level".to_string(), - mudu_argv_desc_tpcc_stock_level().clone(), - mudu_result_desc_tpcc_stock_level().clone(), + "tpcc_seed".to_string(), + mudu_argv_desc_tpcc_seed().clone(), + mudu_result_desc_tpcc_seed().clone(), false ) }) } -mod mod_tpcc_stock_level { +mod mod_tpcc_seed { wit_bindgen::generate!({ inline: - r##"package mudu:mp2-tpcc-stock-level; - world mudu-app-mp2-tpcc-stock-level { - export mp2-tpcc-stock-level: func(param:list) -> list; + r##"package mudu:mp2-tpcc-seed; + world mudu-app-mp2-tpcc-seed { + export mp2-tpcc-seed: func(param:list) -> list; } "##, async: true @@ -952,72 +994,57 @@ mod mod_tpcc_stock_level { #[allow(non_camel_case_types)] #[allow(unused)] - struct GuestTpccStockLevel {} + struct GuestTpccSeed {} - impl Guest for GuestTpccStockLevel { - async fn mp2_tpcc_stock_level(param:Vec) -> Vec { - super::mp2_tpcc_stock_level(param).await + impl Guest for GuestTpccSeed { + async fn mp2_tpcc_seed(param:Vec) -> Vec { + super::mp2_tpcc_seed(param).await } } - export!(GuestTpccStockLevel); + export!(GuestTpccSeed); } -async fn mp2_tpcc_new_order(param:Vec) -> Vec { - ::mudu_binding::procedure::procedure_invoke::invoke_procedure_async( +async fn mp2_tpcc_payment(param:Vec) -> Vec { + ::mududb::binding::procedure::procedure_invoke::invoke_procedure_async( param, - mudu_inner_p2_tpcc_new_order, + mudu_inner_p2_tpcc_payment, ).await } -pub async fn mudu_inner_p2_tpcc_new_order( - param: ::mudu_contract::procedure::procedure_param::ProcedureParam, -) -> ::mudu::common::result::RS< - ::mudu_contract::procedure::procedure_result::ProcedureResult, +pub async fn mudu_inner_p2_tpcc_payment( + param: ::mududb::contract::procedure::procedure_param::ProcedureParam, +) -> ::mududb::common::result::RS< + ::mududb::contract::procedure::procedure_result::ProcedureResult, > { - let return_desc = mudu_result_desc_tpcc_new_order().clone(); - let res = tpcc_new_order( + let res = tpcc_payment( param.session_id(), - ::mudu_type::datum::value_to_typed::< + ::mududb::types::datum::value_to_typed::< i32, _, >(¶m.param_list()[0], "i32")?, - ::mudu_type::datum::value_to_typed::< + ::mududb::types::datum::value_to_typed::< i32, _, >(¶m.param_list()[1], "i32")?, - ::mudu_type::datum::value_to_typed::< + ::mududb::types::datum::value_to_typed::< i32, _, >(¶m.param_list()[2], "i32")?, - ::mudu_type::datum::value_to_typed::< - Vec, - _, - >(¶m.param_list()[3], "Vec")?, - - - - ::mudu_type::datum::value_to_typed::< - Vec, - _, - >(¶m.param_list()[4], "Vec")?, - - - - ::mudu_type::datum::value_to_typed::< - Vec, + ::mududb::types::datum::value_to_typed::< + i32, _, - >(¶m.param_list()[5], "Vec")?, + >(¶m.param_list()[3], "i32")?, ).await; @@ -1027,63 +1054,49 @@ pub async fn mudu_inner_p2_tpcc_new_order( vec![ - ::mudu_type::datum::value_from_typed(&tuple, "String")? + ::mududb::types::datum::value_from_typed(&tuple, "i32")? ] }; - Ok(::mudu_contract::procedure::procedure_result::ProcedureResult::new(return_list)) + Ok(::mududb::contract::procedure::procedure_result::ProcedureResult::new(return_list)) } Err(e) => Err(e), } } -pub fn mudu_argv_desc_tpcc_new_order() -> &'static ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc { - static ARGV_DESC: std::sync::OnceLock<::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc> = +pub fn mudu_argv_desc_tpcc_payment() -> &'static ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc { + static ARGV_DESC: std::sync::OnceLock<::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc> = std::sync::OnceLock::new(); ARGV_DESC.get_or_init(|| { - ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc::new(vec![ + ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc::new(vec![ - ::mudu_contract::tuple::datum_desc::DatumDesc::new( + ::mududb::contract::tuple::datum_desc::DatumDesc::new( "warehouse_id".to_string(), - ::dat_type().clone() + ::dat_type().clone() ), - ::mudu_contract::tuple::datum_desc::DatumDesc::new( + ::mududb::contract::tuple::datum_desc::DatumDesc::new( "district_id".to_string(), - ::dat_type().clone() + ::dat_type().clone() ), - ::mudu_contract::tuple::datum_desc::DatumDesc::new( + ::mududb::contract::tuple::datum_desc::DatumDesc::new( "customer_id".to_string(), - ::dat_type().clone() + ::dat_type().clone() ), - ::mudu_contract::tuple::datum_desc::DatumDesc::new( - "item_ids".to_string(), - - as ::mudu_type::datum::Datum>::dat_type().clone() - - ), - - ::mudu_contract::tuple::datum_desc::DatumDesc::new( - "supplier_warehouse_ids".to_string(), - - as ::mudu_type::datum::Datum>::dat_type().clone() - - ), - - ::mudu_contract::tuple::datum_desc::DatumDesc::new( - "quantities".to_string(), + ::mududb::contract::tuple::datum_desc::DatumDesc::new( + "amount".to_string(), - as ::mudu_type::datum::Datum>::dat_type().clone() + ::dat_type().clone() ), @@ -1092,17 +1105,17 @@ pub fn mudu_argv_desc_tpcc_new_order() -> &'static ::mudu_contract::tuple::tupl ) } -pub fn mudu_result_desc_tpcc_new_order() -> &'static ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc { - static RESULT_DESC: std::sync::OnceLock<::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc> = +pub fn mudu_result_desc_tpcc_payment() -> &'static ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc { + static RESULT_DESC: std::sync::OnceLock<::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc> = std::sync::OnceLock::new(); RESULT_DESC.get_or_init(|| { - ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc::new(vec![ + ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc::new(vec![ - ::mudu_contract::tuple::datum_desc::DatumDesc::new( + ::mududb::contract::tuple::datum_desc::DatumDesc::new( "0".to_string(), - ::dat_type().clone() + ::dat_type().clone() ), @@ -1111,28 +1124,28 @@ pub fn mudu_result_desc_tpcc_new_order() -> &'static ::mudu_contract::tuple::tup ) } -pub fn mudu_proc_desc_tpcc_new_order() -> &'static ::mudu_contract::procedure::proc_desc::ProcDesc { +pub fn mudu_proc_desc_tpcc_payment() -> &'static ::mududb::contract::procedure::proc_desc::ProcDesc { static _PROC_DESC: std::sync::OnceLock< - ::mudu_contract::procedure::proc_desc::ProcDesc, + ::mududb::contract::procedure::proc_desc::ProcDesc, > = std::sync::OnceLock::new(); _PROC_DESC .get_or_init(|| { - ::mudu_contract::procedure::proc_desc::ProcDesc::new( + ::mududb::contract::procedure::proc_desc::ProcDesc::new( "tpcc".to_string(), - "tpcc_new_order".to_string(), - mudu_argv_desc_tpcc_new_order().clone(), - mudu_result_desc_tpcc_new_order().clone(), + "tpcc_payment".to_string(), + mudu_argv_desc_tpcc_payment().clone(), + mudu_result_desc_tpcc_payment().clone(), false ) }) } -mod mod_tpcc_new_order { +mod mod_tpcc_payment { wit_bindgen::generate!({ inline: - r##"package mudu:mp2-tpcc-new-order; - world mudu-app-mp2-tpcc-new-order { - export mp2-tpcc-new-order: func(param:list) -> list; + r##"package mudu:mp2-tpcc-payment; + world mudu-app-mp2-tpcc-payment { + export mp2-tpcc-payment: func(param:list) -> list; } "##, async: true @@ -1140,120 +1153,95 @@ mod mod_tpcc_new_order { #[allow(non_camel_case_types)] #[allow(unused)] - struct GuestTpccNewOrder {} + struct GuestTpccPayment {} - impl Guest for GuestTpccNewOrder { - async fn mp2_tpcc_new_order(param:Vec) -> Vec { - super::mp2_tpcc_new_order(param).await + impl Guest for GuestTpccPayment { + async fn mp2_tpcc_payment(param:Vec) -> Vec { + super::mp2_tpcc_payment(param).await } } - export!(GuestTpccNewOrder); + export!(GuestTpccPayment); } -async fn mp2_tpcc_seed(param:Vec) -> Vec { - ::mudu_binding::procedure::procedure_invoke::invoke_procedure_async( +async fn mp2_tpcc_stock_level(param:Vec) -> Vec { + ::mududb::binding::procedure::procedure_invoke::invoke_procedure_async( param, - mudu_inner_p2_tpcc_seed, + mudu_inner_p2_tpcc_stock_level, ).await } -pub async fn mudu_inner_p2_tpcc_seed( - param: ::mudu_contract::procedure::procedure_param::ProcedureParam, -) -> ::mudu::common::result::RS< - ::mudu_contract::procedure::procedure_result::ProcedureResult, +pub async fn mudu_inner_p2_tpcc_stock_level( + param: ::mududb::contract::procedure::procedure_param::ProcedureParam, +) -> ::mududb::common::result::RS< + ::mududb::contract::procedure::procedure_result::ProcedureResult, > { - let return_desc = mudu_result_desc_tpcc_seed().clone(); - let res = tpcc_seed( + let res = tpcc_stock_level( param.session_id(), - ::mudu_type::datum::value_to_typed::< + ::mududb::types::datum::value_to_typed::< i32, _, >(¶m.param_list()[0], "i32")?, - ::mudu_type::datum::value_to_typed::< + ::mududb::types::datum::value_to_typed::< i32, _, >(¶m.param_list()[1], "i32")?, - ::mudu_type::datum::value_to_typed::< + ::mududb::types::datum::value_to_typed::< i32, _, >(¶m.param_list()[2], "i32")?, - - ::mudu_type::datum::value_to_typed::< - i32, - _, - >(¶m.param_list()[3], "i32")?, - - - - ::mudu_type::datum::value_to_typed::< - i32, - _, - >(¶m.param_list()[4], "i32")?, - - ).await; match res { Ok(tuple) => { let return_list = { - vec![] + vec![ + + ::mududb::types::datum::value_from_typed(&tuple, "i32")? + + ] }; - Ok(::mudu_contract::procedure::procedure_result::ProcedureResult::new(return_list)) + Ok(::mududb::contract::procedure::procedure_result::ProcedureResult::new(return_list)) } Err(e) => Err(e), } } -pub fn mudu_argv_desc_tpcc_seed() -> &'static ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc { - static ARGV_DESC: std::sync::OnceLock<::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc> = +pub fn mudu_argv_desc_tpcc_stock_level() -> &'static ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc { + static ARGV_DESC: std::sync::OnceLock<::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc> = std::sync::OnceLock::new(); ARGV_DESC.get_or_init(|| { - ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc::new(vec![ - - ::mudu_contract::tuple::datum_desc::DatumDesc::new( - "warehouse_count".to_string(), - - ::dat_type().clone() - - ), - - ::mudu_contract::tuple::datum_desc::DatumDesc::new( - "district_count".to_string(), - - ::dat_type().clone() - - ), + ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc::new(vec![ - ::mudu_contract::tuple::datum_desc::DatumDesc::new( - "customer_count".to_string(), + ::mududb::contract::tuple::datum_desc::DatumDesc::new( + "warehouse_id".to_string(), - ::dat_type().clone() + ::dat_type().clone() ), - ::mudu_contract::tuple::datum_desc::DatumDesc::new( - "item_count".to_string(), + ::mududb::contract::tuple::datum_desc::DatumDesc::new( + "district_id".to_string(), - ::dat_type().clone() + ::dat_type().clone() ), - ::mudu_contract::tuple::datum_desc::DatumDesc::new( - "initial_stock".to_string(), + ::mududb::contract::tuple::datum_desc::DatumDesc::new( + "threshold".to_string(), - ::dat_type().clone() + ::dat_type().clone() ), @@ -1262,40 +1250,47 @@ pub fn mudu_argv_desc_tpcc_seed() -> &'static ::mudu_contract::tuple::tuple_fie ) } -pub fn mudu_result_desc_tpcc_seed() -> &'static ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc { - static RESULT_DESC: std::sync::OnceLock<::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc> = +pub fn mudu_result_desc_tpcc_stock_level() -> &'static ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc { + static RESULT_DESC: std::sync::OnceLock<::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc> = std::sync::OnceLock::new(); RESULT_DESC.get_or_init(|| { - ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc::new(vec![ + ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc::new(vec![ + + ::mududb::contract::tuple::datum_desc::DatumDesc::new( + "0".to_string(), + + ::dat_type().clone() + + ), ]) } ) } -pub fn mudu_proc_desc_tpcc_seed() -> &'static ::mudu_contract::procedure::proc_desc::ProcDesc { +pub fn mudu_proc_desc_tpcc_stock_level() -> &'static ::mududb::contract::procedure::proc_desc::ProcDesc { static _PROC_DESC: std::sync::OnceLock< - ::mudu_contract::procedure::proc_desc::ProcDesc, + ::mududb::contract::procedure::proc_desc::ProcDesc, > = std::sync::OnceLock::new(); _PROC_DESC .get_or_init(|| { - ::mudu_contract::procedure::proc_desc::ProcDesc::new( + ::mududb::contract::procedure::proc_desc::ProcDesc::new( "tpcc".to_string(), - "tpcc_seed".to_string(), - mudu_argv_desc_tpcc_seed().clone(), - mudu_result_desc_tpcc_seed().clone(), + "tpcc_stock_level".to_string(), + mudu_argv_desc_tpcc_stock_level().clone(), + mudu_result_desc_tpcc_stock_level().clone(), false ) }) } -mod mod_tpcc_seed { +mod mod_tpcc_stock_level { wit_bindgen::generate!({ inline: - r##"package mudu:mp2-tpcc-seed; - world mudu-app-mp2-tpcc-seed { - export mp2-tpcc-seed: func(param:list) -> list; + r##"package mudu:mp2-tpcc-stock-level; + world mudu-app-mp2-tpcc-stock-level { + export mp2-tpcc-stock-level: func(param:list) -> list; } "##, async: true @@ -1303,48 +1298,47 @@ mod mod_tpcc_seed { #[allow(non_camel_case_types)] #[allow(unused)] - struct GuestTpccSeed {} + struct GuestTpccStockLevel {} - impl Guest for GuestTpccSeed { - async fn mp2_tpcc_seed(param:Vec) -> Vec { - super::mp2_tpcc_seed(param).await + impl Guest for GuestTpccStockLevel { + async fn mp2_tpcc_stock_level(param:Vec) -> Vec { + super::mp2_tpcc_stock_level(param).await } } - export!(GuestTpccSeed); + export!(GuestTpccStockLevel); } -async fn mp2_tpcc_delivery(param:Vec) -> Vec { - ::mudu_binding::procedure::procedure_invoke::invoke_procedure_async( +async fn mp2_tpcc_order_status(param:Vec) -> Vec { + ::mududb::binding::procedure::procedure_invoke::invoke_procedure_async( param, - mudu_inner_p2_tpcc_delivery, + mudu_inner_p2_tpcc_order_status, ).await } -pub async fn mudu_inner_p2_tpcc_delivery( - param: ::mudu_contract::procedure::procedure_param::ProcedureParam, -) -> ::mudu::common::result::RS< - ::mudu_contract::procedure::procedure_result::ProcedureResult, +pub async fn mudu_inner_p2_tpcc_order_status( + param: ::mududb::contract::procedure::procedure_param::ProcedureParam, +) -> ::mududb::common::result::RS< + ::mududb::contract::procedure::procedure_result::ProcedureResult, > { - let return_desc = mudu_result_desc_tpcc_delivery().clone(); - let res = tpcc_delivery( + let res = tpcc_order_status( param.session_id(), - ::mudu_type::datum::value_to_typed::< + ::mududb::types::datum::value_to_typed::< i32, _, >(¶m.param_list()[0], "i32")?, - ::mudu_type::datum::value_to_typed::< + ::mududb::types::datum::value_to_typed::< i32, _, >(¶m.param_list()[1], "i32")?, - ::mudu_type::datum::value_to_typed::< + ::mududb::types::datum::value_to_typed::< i32, _, >(¶m.param_list()[2], "i32")?, @@ -1357,42 +1351,42 @@ pub async fn mudu_inner_p2_tpcc_delivery( vec![ - ::mudu_type::datum::value_from_typed(&tuple, "String")? + ::mududb::types::datum::value_from_typed(&tuple, "String")? ] }; - Ok(::mudu_contract::procedure::procedure_result::ProcedureResult::new(return_list)) + Ok(::mududb::contract::procedure::procedure_result::ProcedureResult::new(return_list)) } Err(e) => Err(e), } } -pub fn mudu_argv_desc_tpcc_delivery() -> &'static ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc { - static ARGV_DESC: std::sync::OnceLock<::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc> = +pub fn mudu_argv_desc_tpcc_order_status() -> &'static ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc { + static ARGV_DESC: std::sync::OnceLock<::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc> = std::sync::OnceLock::new(); ARGV_DESC.get_or_init(|| { - ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc::new(vec![ + ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc::new(vec![ - ::mudu_contract::tuple::datum_desc::DatumDesc::new( + ::mududb::contract::tuple::datum_desc::DatumDesc::new( "warehouse_id".to_string(), - ::dat_type().clone() + ::dat_type().clone() ), - ::mudu_contract::tuple::datum_desc::DatumDesc::new( + ::mududb::contract::tuple::datum_desc::DatumDesc::new( "district_id".to_string(), - ::dat_type().clone() + ::dat_type().clone() ), - ::mudu_contract::tuple::datum_desc::DatumDesc::new( - "carrier_id".to_string(), + ::mududb::contract::tuple::datum_desc::DatumDesc::new( + "customer_id".to_string(), - ::dat_type().clone() + ::dat_type().clone() ), @@ -1401,17 +1395,17 @@ pub fn mudu_argv_desc_tpcc_delivery() -> &'static ::mudu_contract::tuple::tuple ) } -pub fn mudu_result_desc_tpcc_delivery() -> &'static ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc { - static RESULT_DESC: std::sync::OnceLock<::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc> = +pub fn mudu_result_desc_tpcc_order_status() -> &'static ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc { + static RESULT_DESC: std::sync::OnceLock<::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc> = std::sync::OnceLock::new(); RESULT_DESC.get_or_init(|| { - ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc::new(vec![ + ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc::new(vec![ - ::mudu_contract::tuple::datum_desc::DatumDesc::new( + ::mududb::contract::tuple::datum_desc::DatumDesc::new( "0".to_string(), - ::dat_type().clone() + ::dat_type().clone() ), @@ -1420,28 +1414,28 @@ pub fn mudu_result_desc_tpcc_delivery() -> &'static ::mudu_contract::tuple::tupl ) } -pub fn mudu_proc_desc_tpcc_delivery() -> &'static ::mudu_contract::procedure::proc_desc::ProcDesc { +pub fn mudu_proc_desc_tpcc_order_status() -> &'static ::mududb::contract::procedure::proc_desc::ProcDesc { static _PROC_DESC: std::sync::OnceLock< - ::mudu_contract::procedure::proc_desc::ProcDesc, + ::mududb::contract::procedure::proc_desc::ProcDesc, > = std::sync::OnceLock::new(); _PROC_DESC .get_or_init(|| { - ::mudu_contract::procedure::proc_desc::ProcDesc::new( + ::mududb::contract::procedure::proc_desc::ProcDesc::new( "tpcc".to_string(), - "tpcc_delivery".to_string(), - mudu_argv_desc_tpcc_delivery().clone(), - mudu_result_desc_tpcc_delivery().clone(), + "tpcc_order_status".to_string(), + mudu_argv_desc_tpcc_order_status().clone(), + mudu_result_desc_tpcc_order_status().clone(), false ) }) } -mod mod_tpcc_delivery { +mod mod_tpcc_order_status { wit_bindgen::generate!({ inline: - r##"package mudu:mp2-tpcc-delivery; - world mudu-app-mp2-tpcc-delivery { - export mp2-tpcc-delivery: func(param:list) -> list; + r##"package mudu:mp2-tpcc-order-status; + world mudu-app-mp2-tpcc-order-status { + export mp2-tpcc-order-status: func(param:list) -> list; } "##, async: true @@ -1449,13 +1443,13 @@ mod mod_tpcc_delivery { #[allow(non_camel_case_types)] #[allow(unused)] - struct GuestTpccDelivery {} + struct GuestTpccOrderStatus {} - impl Guest for GuestTpccDelivery { - async fn mp2_tpcc_delivery(param:Vec) -> Vec { - super::mp2_tpcc_delivery(param).await + impl Guest for GuestTpccOrderStatus { + async fn mp2_tpcc_order_status(param:Vec) -> Vec { + super::mp2_tpcc_order_status(param).await } } - export!(GuestTpccDelivery); + export!(GuestTpccOrderStatus); } \ No newline at end of file diff --git a/example/tpcc/src/generated/procedure_common.rs b/example/tpcc/src/generated/procedure_common.rs index d4c75de..2809e53 100644 --- a/example/tpcc/src/generated/procedure_common.rs +++ b/example/tpcc/src/generated/procedure_common.rs @@ -1,6 +1,6 @@ -use mudu::common::result::RS; -use mudu::error::ec::EC; -use mudu::m_error; +use mududb::common::result::RS; +use mududb::error::ec::EC; +use mududb::m_error; pub fn require_positive(name: &str, value: i32) -> RS<()> { if value <= 0 { diff --git a/example/tpcc/src/generated/stock.rs b/example/tpcc/src/generated/stock.rs index bc21848..ec23273 100644 --- a/example/tpcc/src/generated/stock.rs +++ b/example/tpcc/src/generated/stock.rs @@ -1,20 +1,20 @@ pub mod object { use lazy_static::lazy_static; -use mudu::common::result::RS; -use mudu_type::dat_binary::DatBinary; -use mudu_type::dat_textual::DatTextual; -use mudu_type::dat_type::DatType; -use mudu_type::dat_type_id::DatTypeID; -use mudu_type::dat_value::DatValue; -use mudu_type::datum::{Datum, DatumDyn}; -use mudu_contract::database::attr_field_access; -use mudu_contract::database::attr_value::AttrValue; -use mudu_contract::database::entity::Entity; -use mudu_contract::database::entity_utils; -use mudu_contract::tuple::datum_desc::DatumDesc; -use mudu_contract::tuple::tuple_field_desc::TupleFieldDesc; -use mudu_contract::tuple::tuple_datum::TupleDatumMarker; -use mudu_contract::database::sql_params::SQLParamMarker; +use mududb::common::result::RS; +use mududb::contract::database::attr_field_access; +use mududb::contract::database::attr_value::AttrValue; +use mududb::contract::database::entity::Entity; +use mududb::contract::database::entity_utils; +use mududb::contract::database::sql_params::SQLParamMarker; +use mududb::contract::tuple::datum_desc::DatumDesc; +use mududb::contract::tuple::tuple_field_desc::TupleFieldDesc; +use mududb::contract::tuple::tuple_datum::TupleDatumMarker; +use mududb::types::dat_binary::DatBinary; +use mududb::types::dat_textual::DatTextual; +use mududb::types::dat_type::DatType; +use mududb::types::dat_type_id::DatTypeID; +use mududb::types::dat_value::DatValue; +use mududb::types::datum::{Datum, DatumDyn}; // constant definition const STOCK:&str = "stock"; diff --git a/example/tpcc/src/generated/warehouse.rs b/example/tpcc/src/generated/warehouse.rs index 0ab7acb..24a06d2 100644 --- a/example/tpcc/src/generated/warehouse.rs +++ b/example/tpcc/src/generated/warehouse.rs @@ -1,20 +1,20 @@ pub mod object { use lazy_static::lazy_static; -use mudu::common::result::RS; -use mudu_type::dat_binary::DatBinary; -use mudu_type::dat_textual::DatTextual; -use mudu_type::dat_type::DatType; -use mudu_type::dat_type_id::DatTypeID; -use mudu_type::dat_value::DatValue; -use mudu_type::datum::{Datum, DatumDyn}; -use mudu_contract::database::attr_field_access; -use mudu_contract::database::attr_value::AttrValue; -use mudu_contract::database::entity::Entity; -use mudu_contract::database::entity_utils; -use mudu_contract::tuple::datum_desc::DatumDesc; -use mudu_contract::tuple::tuple_field_desc::TupleFieldDesc; -use mudu_contract::tuple::tuple_datum::TupleDatumMarker; -use mudu_contract::database::sql_params::SQLParamMarker; +use mududb::common::result::RS; +use mududb::contract::database::attr_field_access; +use mududb::contract::database::attr_value::AttrValue; +use mududb::contract::database::entity::Entity; +use mududb::contract::database::entity_utils; +use mududb::contract::database::sql_params::SQLParamMarker; +use mududb::contract::tuple::datum_desc::DatumDesc; +use mududb::contract::tuple::tuple_field_desc::TupleFieldDesc; +use mududb::contract::tuple::tuple_datum::TupleDatumMarker; +use mududb::types::dat_binary::DatBinary; +use mududb::types::dat_textual::DatTextual; +use mududb::types::dat_type::DatType; +use mududb::types::dat_type_id::DatTypeID; +use mududb::types::dat_value::DatValue; +use mududb::types::datum::{Datum, DatumDyn}; // constant definition const WAREHOUSE:&str = "warehouse"; diff --git a/example/tpcc/src/rust/customer.rs b/example/tpcc/src/rust/customer.rs index 6f26c12..d9bc6dc 100644 --- a/example/tpcc/src/rust/customer.rs +++ b/example/tpcc/src/rust/customer.rs @@ -1,20 +1,20 @@ pub mod object { use lazy_static::lazy_static; -use mudu::common::result::RS; -use mudu_type::dat_binary::DatBinary; -use mudu_type::dat_textual::DatTextual; -use mudu_type::dat_type::DatType; -use mudu_type::dat_type_id::DatTypeID; -use mudu_type::dat_value::DatValue; -use mudu_type::datum::{Datum, DatumDyn}; -use mudu_contract::database::attr_field_access; -use mudu_contract::database::attr_value::AttrValue; -use mudu_contract::database::entity::Entity; -use mudu_contract::database::entity_utils; -use mudu_contract::tuple::datum_desc::DatumDesc; -use mudu_contract::tuple::tuple_field_desc::TupleFieldDesc; -use mudu_contract::tuple::tuple_datum::TupleDatumMarker; -use mudu_contract::database::sql_params::SQLParamMarker; +use mududb::common::result::RS; +use mududb::contract::database::attr_field_access; +use mududb::contract::database::attr_value::AttrValue; +use mududb::contract::database::entity::Entity; +use mududb::contract::database::entity_utils; +use mududb::contract::database::sql_params::SQLParamMarker; +use mududb::contract::tuple::datum_desc::DatumDesc; +use mududb::contract::tuple::tuple_field_desc::TupleFieldDesc; +use mududb::contract::tuple::tuple_datum::TupleDatumMarker; +use mududb::types::dat_binary::DatBinary; +use mududb::types::dat_textual::DatTextual; +use mududb::types::dat_type::DatType; +use mududb::types::dat_type_id::DatTypeID; +use mududb::types::dat_value::DatValue; +use mududb::types::datum::{Datum, DatumDyn}; // constant definition const CUSTOMER:&str = "customer"; diff --git a/example/tpcc/src/rust/district.rs b/example/tpcc/src/rust/district.rs index 97546ec..b65d0ca 100644 --- a/example/tpcc/src/rust/district.rs +++ b/example/tpcc/src/rust/district.rs @@ -1,20 +1,20 @@ pub mod object { use lazy_static::lazy_static; -use mudu::common::result::RS; -use mudu_type::dat_binary::DatBinary; -use mudu_type::dat_textual::DatTextual; -use mudu_type::dat_type::DatType; -use mudu_type::dat_type_id::DatTypeID; -use mudu_type::dat_value::DatValue; -use mudu_type::datum::{Datum, DatumDyn}; -use mudu_contract::database::attr_field_access; -use mudu_contract::database::attr_value::AttrValue; -use mudu_contract::database::entity::Entity; -use mudu_contract::database::entity_utils; -use mudu_contract::tuple::datum_desc::DatumDesc; -use mudu_contract::tuple::tuple_field_desc::TupleFieldDesc; -use mudu_contract::tuple::tuple_datum::TupleDatumMarker; -use mudu_contract::database::sql_params::SQLParamMarker; +use mududb::common::result::RS; +use mududb::contract::database::attr_field_access; +use mududb::contract::database::attr_value::AttrValue; +use mududb::contract::database::entity::Entity; +use mududb::contract::database::entity_utils; +use mududb::contract::database::sql_params::SQLParamMarker; +use mududb::contract::tuple::datum_desc::DatumDesc; +use mududb::contract::tuple::tuple_field_desc::TupleFieldDesc; +use mududb::contract::tuple::tuple_datum::TupleDatumMarker; +use mududb::types::dat_binary::DatBinary; +use mududb::types::dat_textual::DatTextual; +use mududb::types::dat_type::DatType; +use mududb::types::dat_type_id::DatTypeID; +use mududb::types::dat_value::DatValue; +use mududb::types::datum::{Datum, DatumDyn}; // constant definition const DISTRICT:&str = "district"; diff --git a/example/tpcc/src/rust/history.rs b/example/tpcc/src/rust/history.rs index 56c1b0b..e538e5b 100644 --- a/example/tpcc/src/rust/history.rs +++ b/example/tpcc/src/rust/history.rs @@ -1,20 +1,20 @@ pub mod object { use lazy_static::lazy_static; -use mudu::common::result::RS; -use mudu_type::dat_binary::DatBinary; -use mudu_type::dat_textual::DatTextual; -use mudu_type::dat_type::DatType; -use mudu_type::dat_type_id::DatTypeID; -use mudu_type::dat_value::DatValue; -use mudu_type::datum::{Datum, DatumDyn}; -use mudu_contract::database::attr_field_access; -use mudu_contract::database::attr_value::AttrValue; -use mudu_contract::database::entity::Entity; -use mudu_contract::database::entity_utils; -use mudu_contract::tuple::datum_desc::DatumDesc; -use mudu_contract::tuple::tuple_field_desc::TupleFieldDesc; -use mudu_contract::tuple::tuple_datum::TupleDatumMarker; -use mudu_contract::database::sql_params::SQLParamMarker; +use mududb::common::result::RS; +use mududb::contract::database::attr_field_access; +use mududb::contract::database::attr_value::AttrValue; +use mududb::contract::database::entity::Entity; +use mududb::contract::database::entity_utils; +use mududb::contract::database::sql_params::SQLParamMarker; +use mududb::contract::tuple::datum_desc::DatumDesc; +use mududb::contract::tuple::tuple_field_desc::TupleFieldDesc; +use mududb::contract::tuple::tuple_datum::TupleDatumMarker; +use mududb::types::dat_binary::DatBinary; +use mududb::types::dat_textual::DatTextual; +use mududb::types::dat_type::DatType; +use mududb::types::dat_type_id::DatTypeID; +use mududb::types::dat_value::DatValue; +use mududb::types::datum::{Datum, DatumDyn}; // constant definition const HISTORY:&str = "history"; diff --git a/example/tpcc/src/rust/item.rs b/example/tpcc/src/rust/item.rs index f706c29..4888a6a 100644 --- a/example/tpcc/src/rust/item.rs +++ b/example/tpcc/src/rust/item.rs @@ -1,20 +1,20 @@ pub mod object { use lazy_static::lazy_static; -use mudu::common::result::RS; -use mudu_type::dat_binary::DatBinary; -use mudu_type::dat_textual::DatTextual; -use mudu_type::dat_type::DatType; -use mudu_type::dat_type_id::DatTypeID; -use mudu_type::dat_value::DatValue; -use mudu_type::datum::{Datum, DatumDyn}; -use mudu_contract::database::attr_field_access; -use mudu_contract::database::attr_value::AttrValue; -use mudu_contract::database::entity::Entity; -use mudu_contract::database::entity_utils; -use mudu_contract::tuple::datum_desc::DatumDesc; -use mudu_contract::tuple::tuple_field_desc::TupleFieldDesc; -use mudu_contract::tuple::tuple_datum::TupleDatumMarker; -use mudu_contract::database::sql_params::SQLParamMarker; +use mududb::common::result::RS; +use mududb::contract::database::attr_field_access; +use mududb::contract::database::attr_value::AttrValue; +use mududb::contract::database::entity::Entity; +use mududb::contract::database::entity_utils; +use mududb::contract::database::sql_params::SQLParamMarker; +use mududb::contract::tuple::datum_desc::DatumDesc; +use mududb::contract::tuple::tuple_field_desc::TupleFieldDesc; +use mududb::contract::tuple::tuple_datum::TupleDatumMarker; +use mududb::types::dat_binary::DatBinary; +use mududb::types::dat_textual::DatTextual; +use mududb::types::dat_type::DatType; +use mududb::types::dat_type_id::DatTypeID; +use mududb::types::dat_value::DatValue; +use mududb::types::datum::{Datum, DatumDyn}; // constant definition const ITEM:&str = "item"; diff --git a/example/tpcc/src/rust/new_order.rs b/example/tpcc/src/rust/new_order.rs index 9b98fe8..eb498d8 100644 --- a/example/tpcc/src/rust/new_order.rs +++ b/example/tpcc/src/rust/new_order.rs @@ -1,20 +1,20 @@ pub mod object { use lazy_static::lazy_static; -use mudu::common::result::RS; -use mudu_type::dat_binary::DatBinary; -use mudu_type::dat_textual::DatTextual; -use mudu_type::dat_type::DatType; -use mudu_type::dat_type_id::DatTypeID; -use mudu_type::dat_value::DatValue; -use mudu_type::datum::{Datum, DatumDyn}; -use mudu_contract::database::attr_field_access; -use mudu_contract::database::attr_value::AttrValue; -use mudu_contract::database::entity::Entity; -use mudu_contract::database::entity_utils; -use mudu_contract::tuple::datum_desc::DatumDesc; -use mudu_contract::tuple::tuple_field_desc::TupleFieldDesc; -use mudu_contract::tuple::tuple_datum::TupleDatumMarker; -use mudu_contract::database::sql_params::SQLParamMarker; +use mududb::common::result::RS; +use mududb::contract::database::attr_field_access; +use mududb::contract::database::attr_value::AttrValue; +use mududb::contract::database::entity::Entity; +use mududb::contract::database::entity_utils; +use mududb::contract::database::sql_params::SQLParamMarker; +use mududb::contract::tuple::datum_desc::DatumDesc; +use mududb::contract::tuple::tuple_field_desc::TupleFieldDesc; +use mududb::contract::tuple::tuple_datum::TupleDatumMarker; +use mududb::types::dat_binary::DatBinary; +use mududb::types::dat_textual::DatTextual; +use mududb::types::dat_type::DatType; +use mududb::types::dat_type_id::DatTypeID; +use mududb::types::dat_value::DatValue; +use mududb::types::datum::{Datum, DatumDyn}; // constant definition const NEW_ORDER:&str = "new_order"; diff --git a/example/tpcc/src/rust/order_line.rs b/example/tpcc/src/rust/order_line.rs index 3c50680..67a5a57 100644 --- a/example/tpcc/src/rust/order_line.rs +++ b/example/tpcc/src/rust/order_line.rs @@ -1,20 +1,20 @@ pub mod object { use lazy_static::lazy_static; -use mudu::common::result::RS; -use mudu_type::dat_binary::DatBinary; -use mudu_type::dat_textual::DatTextual; -use mudu_type::dat_type::DatType; -use mudu_type::dat_type_id::DatTypeID; -use mudu_type::dat_value::DatValue; -use mudu_type::datum::{Datum, DatumDyn}; -use mudu_contract::database::attr_field_access; -use mudu_contract::database::attr_value::AttrValue; -use mudu_contract::database::entity::Entity; -use mudu_contract::database::entity_utils; -use mudu_contract::tuple::datum_desc::DatumDesc; -use mudu_contract::tuple::tuple_field_desc::TupleFieldDesc; -use mudu_contract::tuple::tuple_datum::TupleDatumMarker; -use mudu_contract::database::sql_params::SQLParamMarker; +use mududb::common::result::RS; +use mududb::contract::database::attr_field_access; +use mududb::contract::database::attr_value::AttrValue; +use mududb::contract::database::entity::Entity; +use mududb::contract::database::entity_utils; +use mududb::contract::database::sql_params::SQLParamMarker; +use mududb::contract::tuple::datum_desc::DatumDesc; +use mududb::contract::tuple::tuple_field_desc::TupleFieldDesc; +use mududb::contract::tuple::tuple_datum::TupleDatumMarker; +use mududb::types::dat_binary::DatBinary; +use mududb::types::dat_textual::DatTextual; +use mududb::types::dat_type::DatType; +use mududb::types::dat_type_id::DatTypeID; +use mududb::types::dat_value::DatValue; +use mududb::types::datum::{Datum, DatumDyn}; // constant definition const ORDER_LINE:&str = "order_line"; diff --git a/example/tpcc/src/rust/orders.rs b/example/tpcc/src/rust/orders.rs index 4455b14..f111785 100644 --- a/example/tpcc/src/rust/orders.rs +++ b/example/tpcc/src/rust/orders.rs @@ -1,20 +1,20 @@ pub mod object { use lazy_static::lazy_static; -use mudu::common::result::RS; -use mudu_type::dat_binary::DatBinary; -use mudu_type::dat_textual::DatTextual; -use mudu_type::dat_type::DatType; -use mudu_type::dat_type_id::DatTypeID; -use mudu_type::dat_value::DatValue; -use mudu_type::datum::{Datum, DatumDyn}; -use mudu_contract::database::attr_field_access; -use mudu_contract::database::attr_value::AttrValue; -use mudu_contract::database::entity::Entity; -use mudu_contract::database::entity_utils; -use mudu_contract::tuple::datum_desc::DatumDesc; -use mudu_contract::tuple::tuple_field_desc::TupleFieldDesc; -use mudu_contract::tuple::tuple_datum::TupleDatumMarker; -use mudu_contract::database::sql_params::SQLParamMarker; +use mududb::common::result::RS; +use mududb::contract::database::attr_field_access; +use mududb::contract::database::attr_value::AttrValue; +use mududb::contract::database::entity::Entity; +use mududb::contract::database::entity_utils; +use mududb::contract::database::sql_params::SQLParamMarker; +use mududb::contract::tuple::datum_desc::DatumDesc; +use mududb::contract::tuple::tuple_field_desc::TupleFieldDesc; +use mududb::contract::tuple::tuple_datum::TupleDatumMarker; +use mududb::types::dat_binary::DatBinary; +use mududb::types::dat_textual::DatTextual; +use mududb::types::dat_type::DatType; +use mududb::types::dat_type_id::DatTypeID; +use mududb::types::dat_value::DatValue; +use mududb::types::datum::{Datum, DatumDyn}; // constant definition const ORDERS:&str = "orders"; diff --git a/example/tpcc/src/rust/procedure.rs b/example/tpcc/src/rust/procedure.rs index 0ebec70..5733eb7 100644 --- a/example/tpcc/src/rust/procedure.rs +++ b/example/tpcc/src/rust/procedure.rs @@ -9,18 +9,18 @@ use crate::rust::procedure_common::{ }; use crate::rust::stock::object::Stock; use crate::rust::warehouse::object::Warehouse; -use mudu::common::result::RS; -use mudu::common::xid::XID; -use mudu::error::ec::EC::MuduError; -use mudu::m_error; -use mudu_contract::database::entity::Entity; -use mudu_contract::{sql_params, sql_stmt}; -use sys_interface::sync_api::{mudu_command, mudu_query}; +use mududb::common::result::RS; +use mududb::common::xid::XID; +use mududb::error::ec::EC::MuduError; +use mududb::m_error; +use mududb::contract::database::entity::Entity; +use mududb::contract::{sql_params, sql_stmt}; +use mududb::sys_interface::sync_api::{mudu_command, mudu_query}; fn query_one_entity( xid: XID, sql: &str, - params: &dyn mudu_contract::database::sql_params::SQLParams, + params: &dyn mududb::contract::database::sql_params::SQLParams, ) -> RS { mudu_query::(xid, sql_stmt!(&sql), params)? .next_record()? @@ -30,7 +30,7 @@ fn query_one_entity( fn query_entities( xid: XID, sql: &str, - params: &dyn mudu_contract::database::sql_params::SQLParams, + params: &dyn mududb::contract::database::sql_params::SQLParams, ) -> RS> { let mut result_set = mudu_query::(xid, sql_stmt!(&sql), params)?; let mut values = Vec::new(); @@ -43,7 +43,7 @@ fn query_entities( fn query_count_i32( xid: XID, sql: &str, - params: &dyn mudu_contract::database::sql_params::SQLParams, + params: &dyn mududb::contract::database::sql_params::SQLParams, ) -> RS { let value = mudu_query::(xid, sql_stmt!(&sql), params)? .next_record()? @@ -347,7 +347,7 @@ pub fn tpcc_payment( &"INSERT INTO history (h_id, h_c_id, h_c_d_id, h_c_w_id, h_d_id, h_w_id, h_amount, h_data) VALUES (?, ?, ?, ?, ?, ?, ?, ?)" ), sql_params!(&( - mudu_sys::random::next_uuid_v4_string(), + mududb::sys::random::next_uuid_v4_string(), customer_id, district_id, warehouse_id, @@ -463,10 +463,10 @@ mod tests { tpcc_delivery, tpcc_new_order, tpcc_order_status, tpcc_payment, tpcc_seed, tpcc_stock_level, }; use crate::test_lock; - use mudu_contract::{sql_params, sql_stmt}; + use mududb::contract::{sql_params, sql_stmt}; use std::path::PathBuf; use std::time::{SystemTime, UNIX_EPOCH}; - use sys_interface::sync_api::{mudu_batch, mudu_close, mudu_open}; + use mududb::sys_interface::sync_api::{mudu_batch, mudu_close, mudu_open}; fn temp_db_path(name: &str) -> PathBuf { let suffix = SystemTime::now() diff --git a/example/tpcc/src/rust/procedure_common.rs b/example/tpcc/src/rust/procedure_common.rs index 2543790..58faadc 100644 --- a/example/tpcc/src/rust/procedure_common.rs +++ b/example/tpcc/src/rust/procedure_common.rs @@ -1,6 +1,6 @@ -use mudu::common::result::RS; -use mudu::error::ec::EC; -use mudu::m_error; +use mududb::common::result::RS; +use mududb::error::ec::EC; +use mududb::m_error; pub fn require_positive(name: &str, value: i32) -> RS<()> { if value <= 0 { diff --git a/example/tpcc/src/rust/stock.rs b/example/tpcc/src/rust/stock.rs index 09ac731..a9d8e89 100644 --- a/example/tpcc/src/rust/stock.rs +++ b/example/tpcc/src/rust/stock.rs @@ -1,20 +1,20 @@ pub mod object { use lazy_static::lazy_static; -use mudu::common::result::RS; -use mudu_type::dat_binary::DatBinary; -use mudu_type::dat_textual::DatTextual; -use mudu_type::dat_type::DatType; -use mudu_type::dat_type_id::DatTypeID; -use mudu_type::dat_value::DatValue; -use mudu_type::datum::{Datum, DatumDyn}; -use mudu_contract::database::attr_field_access; -use mudu_contract::database::attr_value::AttrValue; -use mudu_contract::database::entity::Entity; -use mudu_contract::database::entity_utils; -use mudu_contract::tuple::datum_desc::DatumDesc; -use mudu_contract::tuple::tuple_field_desc::TupleFieldDesc; -use mudu_contract::tuple::tuple_datum::TupleDatumMarker; -use mudu_contract::database::sql_params::SQLParamMarker; +use mududb::common::result::RS; +use mududb::contract::database::attr_field_access; +use mududb::contract::database::attr_value::AttrValue; +use mududb::contract::database::entity::Entity; +use mududb::contract::database::entity_utils; +use mududb::contract::database::sql_params::SQLParamMarker; +use mududb::contract::tuple::datum_desc::DatumDesc; +use mududb::contract::tuple::tuple_field_desc::TupleFieldDesc; +use mududb::contract::tuple::tuple_datum::TupleDatumMarker; +use mududb::types::dat_binary::DatBinary; +use mududb::types::dat_textual::DatTextual; +use mududb::types::dat_type::DatType; +use mududb::types::dat_type_id::DatTypeID; +use mududb::types::dat_value::DatValue; +use mududb::types::datum::{Datum, DatumDyn}; // constant definition const STOCK:&str = "stock"; diff --git a/example/tpcc/src/rust/warehouse.rs b/example/tpcc/src/rust/warehouse.rs index 144210c..193a651 100644 --- a/example/tpcc/src/rust/warehouse.rs +++ b/example/tpcc/src/rust/warehouse.rs @@ -1,20 +1,20 @@ pub mod object { use lazy_static::lazy_static; -use mudu::common::result::RS; -use mudu_type::dat_binary::DatBinary; -use mudu_type::dat_textual::DatTextual; -use mudu_type::dat_type::DatType; -use mudu_type::dat_type_id::DatTypeID; -use mudu_type::dat_value::DatValue; -use mudu_type::datum::{Datum, DatumDyn}; -use mudu_contract::database::attr_field_access; -use mudu_contract::database::attr_value::AttrValue; -use mudu_contract::database::entity::Entity; -use mudu_contract::database::entity_utils; -use mudu_contract::tuple::datum_desc::DatumDesc; -use mudu_contract::tuple::tuple_field_desc::TupleFieldDesc; -use mudu_contract::tuple::tuple_datum::TupleDatumMarker; -use mudu_contract::database::sql_params::SQLParamMarker; +use mududb::common::result::RS; +use mududb::contract::database::attr_field_access; +use mududb::contract::database::attr_value::AttrValue; +use mududb::contract::database::entity::Entity; +use mududb::contract::database::entity_utils; +use mududb::contract::database::sql_params::SQLParamMarker; +use mududb::contract::tuple::datum_desc::DatumDesc; +use mududb::contract::tuple::tuple_field_desc::TupleFieldDesc; +use mududb::contract::tuple::tuple_datum::TupleDatumMarker; +use mududb::types::dat_binary::DatBinary; +use mududb::types::dat_textual::DatTextual; +use mududb::types::dat_type::DatType; +use mududb::types::dat_type_id::DatTypeID; +use mududb::types::dat_value::DatValue; +use mududb::types::datum::{Datum, DatumDyn}; // constant definition const WAREHOUSE:&str = "warehouse"; diff --git a/example/vote/Cargo.toml b/example/vote/Cargo.toml index 556d28d..f28634b 100644 --- a/example/vote/Cargo.toml +++ b/example/vote/Cargo.toml @@ -8,22 +8,12 @@ crate-type = ["cdylib"] [dependencies] -mudu = { workspace = true } -mudu_sys = { workspace = true } -mudu_type = { workspace = true } -mudu_contract = { workspace = true } -mudu_binding = { workspace = true} +mududb = { workspace = true, features = ["async"] } wit-bindgen = { workspace = true } uuid = { workspace = true } lazy_static = { workspace = true } chrono = { workspace = true } fallible-iterator = { workspace = true } -[target.'cfg(target_arch = "wasm32")'.dependencies] -sys_interface = { workspace = true, features = ["async"] } - -[target.'cfg(not(target_arch = "wasm32"))'.dependencies] -sys_interface = { workspace = true, features = ["async"] } - [target.'cfg(not(target_arch = "wasm32"))'.dev-dependencies] -sys_interface = { workspace = true, features = ["async", "standalone-adapter"] } +mududb = { workspace = true, features = ["async", "standalone-adapter"] } diff --git a/example/vote/package/package.desc.json b/example/vote/package/package.desc.json index 54e6bbd..f6ead13 100644 --- a/example/vote/package/package.desc.json +++ b/example/vote/package/package.desc.json @@ -3,7 +3,7 @@ "vote": [ { "module_name": "vote", - "proc_name": "create_user", + "proc_name": "add_option", "param_desc": { "fields": [ { @@ -15,7 +15,18 @@ } } }, - "name": "phone" + "name": "vote_id" + }, + { + "dat_type": { + "id": "String", + "param": { + "String": { + "length": 65536 + } + } + }, + "name": "option_text" } ] }, @@ -87,6 +98,39 @@ "fields": [] } }, + { + "module_name": "vote", + "proc_name": "withdraw_vote", + "param_desc": { + "fields": [ + { + "dat_type": { + "id": "String", + "param": { + "String": { + "length": 65536 + } + } + }, + "name": "user_id" + }, + { + "dat_type": { + "id": "String", + "param": { + "String": { + "length": 65536 + } + } + }, + "name": "vote_id" + } + ] + }, + "return_desc": { + "fields": [] + } + }, { "module_name": "vote", "proc_name": "get_vote_result", @@ -257,51 +301,6 @@ ] } }, - { - "module_name": "vote", - "proc_name": "add_option", - "param_desc": { - "fields": [ - { - "dat_type": { - "id": "String", - "param": { - "String": { - "length": 65536 - } - } - }, - "name": "vote_id" - }, - { - "dat_type": { - "id": "String", - "param": { - "String": { - "length": 65536 - } - } - }, - "name": "option_text" - } - ] - }, - "return_desc": { - "fields": [ - { - "dat_type": { - "id": "String", - "param": { - "String": { - "length": 65536 - } - } - }, - "name": "0" - } - ] - } - }, { "module_name": "vote", "proc_name": "create_vote", @@ -385,7 +384,7 @@ }, { "module_name": "vote", - "proc_name": "withdraw_vote", + "proc_name": "create_user", "param_desc": { "fields": [ { @@ -397,8 +396,12 @@ } } }, - "name": "user_id" - }, + "name": "phone" + } + ] + }, + "return_desc": { + "fields": [ { "dat_type": { "id": "String", @@ -408,12 +411,9 @@ } } }, - "name": "vote_id" + "name": "0" } ] - }, - "return_desc": { - "fields": [] } } ] diff --git a/example/vote/package/type.desc.json b/example/vote/package/type.desc.json index 23d39cc..2b5e710 100644 --- a/example/vote/package/type.desc.json +++ b/example/vote/package/type.desc.json @@ -1,43 +1,101 @@ { "types": { - "VoteHistoryItem": [ + "VoteResult": [ 2, { - "record_name": "vote_history_item", + "record_name": "vote_result", "record_fields": [ { "field_name": "vote_id", "field_type": [ 0, - 12 + 14 ] }, { "field_name": "topic", "field_type": [ 0, - 12 + 14 ] }, { - "field_name": "action_time", + "field_name": "vote_ended", "field_type": [ 0, 6 ] }, { - "field_name": "is_withdrawn", + "field_name": "total_votes", "field_type": [ 0, 6 ] }, { - "field_name": "vote_ended", + "field_name": "options", "field_type": [ 0, - 6 + 14 + ] + } + ] + } + ], + "Options": [ + 2, + { + "record_name": "options", + "record_fields": [ + { + "field_name": "option_id", + "field_type": [ + 0, + 14 + ] + }, + { + "field_name": "vote_id", + "field_type": [ + 0, + 14 + ] + }, + { + "field_name": "option_text", + "field_type": [ + 0, + 14 + ] + } + ] + } + ], + "VoteChoices": [ + 2, + { + "record_name": "vote_choices", + "record_fields": [ + { + "field_name": "choice_id", + "field_type": [ + 0, + 14 + ] + }, + { + "field_name": "action_id", + "field_type": [ + 0, + 14 + ] + }, + { + "field_name": "option_id", + "field_type": [ + 0, + 14 ] } ] @@ -52,21 +110,21 @@ "field_name": "action_id", "field_type": [ 0, - 12 + 14 ] }, { "field_name": "user_id", "field_type": [ 0, - 12 + 14 ] }, { "field_name": "vote_id", "field_type": [ 0, - 12 + 14 ] }, { @@ -95,28 +153,28 @@ "field_name": "vote_id", "field_type": [ 0, - 12 + 14 ] }, { "field_name": "creator_id", "field_type": [ 0, - 12 + 14 ] }, { "field_name": "topic", "field_type": [ 0, - 12 + 14 ] }, { "field_name": "vote_type", "field_type": [ 0, - 12 + 14 ] }, { @@ -137,36 +195,7 @@ "field_name": "visibility_rule", "field_type": [ 0, - 12 - ] - } - ] - } - ], - "VoteChoices": [ - 2, - { - "record_name": "vote_choices", - "record_fields": [ - { - "field_name": "choice_id", - "field_type": [ - 0, - 12 - ] - }, - { - "field_name": "action_id", - "field_type": [ - 0, - 12 - ] - }, - { - "field_name": "option_id", - "field_type": [ - 0, - 12 + 14 ] } ] @@ -181,86 +210,57 @@ "field_name": "user_id", "field_type": [ 0, - 12 + 14 ] }, { "field_name": "phone", "field_type": [ 0, - 12 + 14 ] } ] } ], - "Options": [ - 2, - { - "record_name": "options", - "record_fields": [ - { - "field_name": "option_id", - "field_type": [ - 0, - 12 - ] - }, - { - "field_name": "vote_id", - "field_type": [ - 0, - 12 - ] - }, - { - "field_name": "option_text", - "field_type": [ - 0, - 12 - ] - } - ] - } - ], - "VoteResult": [ + "VoteHistoryItem": [ 2, { - "record_name": "vote_result", + "record_name": "vote_history_item", "record_fields": [ { "field_name": "vote_id", "field_type": [ 0, - 12 + 14 ] }, { "field_name": "topic", "field_type": [ 0, - 12 + 14 ] }, { - "field_name": "vote_ended", + "field_name": "action_time", "field_type": [ 0, 6 ] }, { - "field_name": "total_votes", + "field_name": "is_withdrawn", "field_type": [ 0, 6 ] }, { - "field_name": "options", + "field_name": "vote_ended", "field_type": [ 0, - 12 + 6 ] } ] diff --git a/example/vote/src/generated/mod.rs b/example/vote/src/generated/mod.rs index c3c7e4d..e3051a8 100644 --- a/example/vote/src/generated/mod.rs +++ b/example/vote/src/generated/mod.rs @@ -5,4 +5,4 @@ pub mod vote_actions; pub mod vote_choices; pub mod vote_history_item; pub mod vote_result; -pub mod votes; +pub mod votes; \ No newline at end of file diff --git a/example/vote/src/generated/options.rs b/example/vote/src/generated/options.rs index 1952386..2583ac1 100644 --- a/example/vote/src/generated/options.rs +++ b/example/vote/src/generated/options.rs @@ -1,388 +1,417 @@ pub mod object { - use lazy_static::lazy_static; - use mudu::common::result::RS; - use mudu_contract::database::attr_field_access; - use mudu_contract::database::attr_value::AttrValue; - use mudu_contract::database::entity::Entity; - use mudu_contract::database::entity_utils; - use mudu_contract::database::sql_params::SQLParamMarker; - use mudu_contract::tuple::datum_desc::DatumDesc; - use mudu_contract::tuple::tuple_datum::TupleDatumMarker; - use mudu_contract::tuple::tuple_field_desc::TupleFieldDesc; - use mudu_type::dat_binary::DatBinary; - use mudu_type::dat_textual::DatTextual; - use mudu_type::dat_type::DatType; - use mudu_type::dat_type_id::DatTypeID; - use mudu_type::dat_value::DatValue; - use mudu_type::datum::{Datum, DatumDyn}; - - // constant definition - const OPTIONS: &str = "options"; - - const OPTION_ID: &str = "option_id"; - - const VOTE_ID: &str = "vote_id"; - - const OPTION_TEXT: &str = "option_text"; - - // entity struct definition - #[derive(Debug, Clone, Default)] - pub struct Options { - option_id: AttrOptionId, - - vote_id: AttrVoteId, +use lazy_static::lazy_static; +use mududb::common::result::RS; +use mududb::contract::database::attr_field_access; +use mududb::contract::database::attr_value::AttrValue; +use mududb::contract::database::entity::Entity; +use mududb::contract::database::entity_utils; +use mududb::contract::database::sql_params::SQLParamMarker; +use mududb::contract::tuple::datum_desc::DatumDesc; +use mududb::contract::tuple::tuple_field_desc::TupleFieldDesc; +use mududb::contract::tuple::tuple_datum::TupleDatumMarker; +use mududb::types::dat_binary::DatBinary; +use mududb::types::dat_textual::DatTextual; +use mududb::types::dat_type::DatType; +use mududb::types::dat_type_id::DatTypeID; +use mududb::types::dat_value::DatValue; +use mududb::types::datum::{Datum, DatumDyn}; + +// constant definition +const OPTIONS:&str = "options"; + +const OPTION_ID:&str = "option_id"; + +const VOTE_ID:&str = "vote_id"; + +const OPTION_TEXT:&str = "option_text"; + + +// entity struct definition +#[derive(Debug, Clone, Default)] +pub struct Options { + + option_id: AttrOptionId, + + vote_id: AttrVoteId, + + option_text: AttrOptionText, + +} - option_text: AttrOptionText, +impl TupleDatumMarker for Options {} + +impl SQLParamMarker for Options {} + +impl Options { + pub fn new( + option_id: Option, + vote_id: Option, + option_text: Option, + + ) -> Self { + let s = Self { + + option_id : AttrOptionId::from(option_id), + + vote_id : AttrVoteId::from(vote_id), + + option_text : AttrOptionText::from(option_text), + + }; + s } - impl TupleDatumMarker for Options {} - - impl SQLParamMarker for Options {} - - impl Options { - pub fn new( - option_id: Option, - vote_id: Option, - option_text: Option, - ) -> Self { - let s = Self { - option_id: AttrOptionId::from(option_id), - - vote_id: AttrVoteId::from(vote_id), - - option_text: AttrOptionText::from(option_text), - }; - s - } - - pub fn new_empty() -> Self { - Self::default() - } + pub fn new_empty() -> Self { + Self::default() + } - pub fn set_option_id(&mut self, option_id: String) { - self.option_id.update(option_id) - } + + pub fn set_option_id( + &mut self, + option_id: String, + ) { + self.option_id.update(option_id) + } - pub fn get_option_id(&self) -> &Option { - self.option_id.get() - } + pub fn get_option_id( + &self, + ) -> &Option { + self.option_id.get() + } + + pub fn set_vote_id( + &mut self, + vote_id: String, + ) { + self.vote_id.update(vote_id) + } - pub fn set_vote_id(&mut self, vote_id: String) { - self.vote_id.update(vote_id) - } + pub fn get_vote_id( + &self, + ) -> &Option { + self.vote_id.get() + } + + pub fn set_option_text( + &mut self, + option_text: String, + ) { + self.option_text.update(option_text) + } - pub fn get_vote_id(&self) -> &Option { - self.vote_id.get() - } + pub fn get_option_text( + &self, + ) -> &Option { + self.option_text.get() + } + +} - pub fn set_option_text(&mut self, option_text: String) { - self.option_text.update(option_text) +impl Datum for Options { + fn dat_type() -> &'static DatType { + lazy_static! { + static ref DAT_TYPE: DatType = entity_utils::entity_dat_type::(); } + &DAT_TYPE + } - pub fn get_option_text(&self) -> &Option { - self.option_text.get() - } + fn from_binary(binary: &[u8]) -> RS { + entity_utils::entity_from_binary(binary) } - impl Datum for Options { - fn dat_type() -> &'static DatType { - lazy_static! { - static ref DAT_TYPE: DatType = entity_utils::entity_dat_type::(); - } - &DAT_TYPE - } + fn from_value(value: &DatValue) -> RS { + entity_utils::entity_from_value(value) + } - fn from_binary(binary: &[u8]) -> RS { - entity_utils::entity_from_binary(binary) - } + fn from_textual(textual: &str) -> RS { + entity_utils::entity_from_textual(textual) + } +} - fn from_value(value: &DatValue) -> RS { - entity_utils::entity_from_value(value) - } +impl DatumDyn for Options { + fn dat_type_id(&self) -> RS { + entity_utils::entity_dat_type_id() + } - fn from_textual(textual: &str) -> RS { - entity_utils::entity_from_textual(textual) - } + fn to_binary(&self, dat_type: &DatType) -> RS { + entity_utils::entity_to_binary(self, dat_type) } - impl DatumDyn for Options { - fn dat_type_id(&self) -> RS { - entity_utils::entity_dat_type_id() - } + fn to_textual(&self, dat_type: &DatType) -> RS { + entity_utils::entity_to_textual(self, dat_type) + } - fn to_binary(&self, dat_type: &DatType) -> RS { - entity_utils::entity_to_binary(self, dat_type) - } + fn to_value(&self, dat_type: &DatType) -> RS { + entity_utils::entity_to_value(self, dat_type) + } - fn to_textual(&self, dat_type: &DatType) -> RS { - entity_utils::entity_to_textual(self, dat_type) - } + fn clone_boxed(&self) -> Box { + entity_utils::entity_clone_boxed(self) + } +} - fn to_value(&self, dat_type: &DatType) -> RS { - entity_utils::entity_to_value(self, dat_type) - } +impl Entity for Options { + fn new_empty() -> Self { + Self::new_empty() + } - fn clone_boxed(&self) -> Box { - entity_utils::entity_clone_boxed(self) - } + fn tuple_desc() -> &'static TupleFieldDesc { + lazy_static! { + static ref TUPLE_DESC: TupleFieldDesc = TupleFieldDesc::new(vec![ + + AttrOptionId::datum_desc().clone(), + + AttrVoteId::datum_desc().clone(), + + AttrOptionText::datum_desc().clone(), + + ]); + } + &TUPLE_DESC } - impl Entity for Options { - fn new_empty() -> Self { - Self::new_empty() - } + fn object_name() -> &'static str { + OPTIONS + } - fn tuple_desc() -> &'static TupleFieldDesc { - lazy_static! { - static ref TUPLE_DESC: TupleFieldDesc = TupleFieldDesc::new(vec![ - AttrOptionId::datum_desc().clone(), - AttrVoteId::datum_desc().clone(), - AttrOptionText::datum_desc().clone(), - ]); + fn get_field_binary(&self, field: &str) -> RS>> { + match field { + + OPTION_ID => { + attr_field_access::attr_get_binary::<_>(self.option_id.get()) } - &TUPLE_DESC - } - - fn object_name() -> &'static str { - OPTIONS + + VOTE_ID => { + attr_field_access::attr_get_binary::<_>(self.vote_id.get()) + } + + OPTION_TEXT => { + attr_field_access::attr_get_binary::<_>(self.option_text.get()) + } + + _ => { panic!("unknown name"); } } + } - fn get_field_binary(&self, field: &str) -> RS>> { - match field { - OPTION_ID => attr_field_access::attr_get_binary::<_>(self.option_id.get()), - - VOTE_ID => attr_field_access::attr_get_binary::<_>(self.vote_id.get()), - - OPTION_TEXT => attr_field_access::attr_get_binary::<_>(self.option_text.get()), - - _ => { - panic!("unknown name"); - } + fn set_field_binary>(&mut self, field: &str, binary: B) -> RS<()> { + match field { + + OPTION_ID => { + attr_field_access::attr_set_binary::<_, _>(self.option_id.get_mut(), binary.as_ref())?; } + + VOTE_ID => { + attr_field_access::attr_set_binary::<_, _>(self.vote_id.get_mut(), binary.as_ref())?; + } + + OPTION_TEXT => { + attr_field_access::attr_set_binary::<_, _>(self.option_text.get_mut(), binary.as_ref())?; + } + + _ => { panic!("unknown name"); } } + Ok(()) + } - fn set_field_binary>(&mut self, field: &str, binary: B) -> RS<()> { - match field { - OPTION_ID => { - attr_field_access::attr_set_binary::<_, _>( - self.option_id.get_mut(), - binary.as_ref(), - )?; - } - - VOTE_ID => { - attr_field_access::attr_set_binary::<_, _>( - self.vote_id.get_mut(), - binary.as_ref(), - )?; - } - - OPTION_TEXT => { - attr_field_access::attr_set_binary::<_, _>( - self.option_text.get_mut(), - binary.as_ref(), - )?; - } - - _ => { - panic!("unknown name"); - } + fn get_field_value(&self, field: &str) -> RS> { + match field { + + OPTION_ID => { + attr_field_access::attr_get_value::<_>(self.option_id.get()) + } + + VOTE_ID => { + attr_field_access::attr_get_value::<_>(self.vote_id.get()) } - Ok(()) + + OPTION_TEXT => { + attr_field_access::attr_get_value::<_>(self.option_text.get()) + } + + _ => { panic!("unknown name"); } } + } - fn get_field_value(&self, field: &str) -> RS> { - match field { - OPTION_ID => attr_field_access::attr_get_value::<_>(self.option_id.get()), - - VOTE_ID => attr_field_access::attr_get_value::<_>(self.vote_id.get()), - - OPTION_TEXT => attr_field_access::attr_get_value::<_>(self.option_text.get()), - - _ => { - panic!("unknown name"); - } + fn set_field_value>(&mut self, field: &str, value: B) -> RS<()> { + match field { + + OPTION_ID => { + attr_field_access::attr_set_value::<_, _>(self.option_id.get_mut(), value)?; + } + + VOTE_ID => { + attr_field_access::attr_set_value::<_, _>(self.vote_id.get_mut(), value)?; } + + OPTION_TEXT => { + attr_field_access::attr_set_value::<_, _>(self.option_text.get_mut(), value)?; + } + + _ => { panic!("unknown name"); } } + Ok(()) + } +} - fn set_field_value>(&mut self, field: &str, value: B) -> RS<()> { - match field { - OPTION_ID => { - attr_field_access::attr_set_value::<_, _>(self.option_id.get_mut(), value)?; - } - - VOTE_ID => { - attr_field_access::attr_set_value::<_, _>(self.vote_id.get_mut(), value)?; - } - OPTION_TEXT => { - attr_field_access::attr_set_value::<_, _>(self.option_text.get_mut(), value)?; - } +// attribute struct definition +#[derive(Default, Clone, Debug)] +pub struct AttrOptionId { + is_dirty:bool, + value: Option +} - _ => { - panic!("unknown name"); - } - } - Ok(()) +impl AttrOptionId { + fn from(value:Option) -> Self { + Self { + is_dirty: false, + value } } - // attribute struct definition - #[derive(Default, Clone, Debug)] - pub struct AttrOptionId { - is_dirty: bool, - value: Option, + fn get(&self) -> &Option { + &self.value } - impl AttrOptionId { - fn from(value: Option) -> Self { - Self { - is_dirty: false, - value, - } - } + fn get_mut(&mut self) -> &mut Option { + &mut self.value + } - fn get(&self) -> &Option { - &self.value - } + fn set(&mut self, value:Option) { + self.value = value + } - fn get_mut(&mut self) -> &mut Option { - &mut self.value - } + fn update(&mut self, value: String) { + self.is_dirty = true; + self.value = Some(value) + } +} - fn set(&mut self, value: Option) { - self.value = value - } +impl AttrValue for AttrOptionId { + fn dat_type() -> &'static DatType { + static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); + ONCE_LOCK.get_or_init(|| Self::attr_dat_type()) + } - fn update(&mut self, value: String) { - self.is_dirty = true; - self.value = Some(value) - } + fn datum_desc() -> &'static DatumDesc { + static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); + ONCE_LOCK.get_or_init(|| Self::attr_datum_desc()) } - impl AttrValue for AttrOptionId { - fn dat_type() -> &'static DatType { - static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); - ONCE_LOCK.get_or_init(|| Self::attr_dat_type()) - } + fn object_name() -> &'static str { + OPTIONS + } - fn datum_desc() -> &'static DatumDesc { - static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); - ONCE_LOCK.get_or_init(|| Self::attr_datum_desc()) - } + fn attr_name() -> &'static str { + OPTION_ID + } +} - fn object_name() -> &'static str { - OPTIONS - } +// attribute struct definition +#[derive(Default, Clone, Debug)] +pub struct AttrVoteId { + is_dirty:bool, + value: Option +} - fn attr_name() -> &'static str { - OPTION_ID +impl AttrVoteId { + fn from(value:Option) -> Self { + Self { + is_dirty: false, + value } } - // attribute struct definition - #[derive(Default, Clone, Debug)] - pub struct AttrVoteId { - is_dirty: bool, - value: Option, + fn get(&self) -> &Option { + &self.value } - impl AttrVoteId { - fn from(value: Option) -> Self { - Self { - is_dirty: false, - value, - } - } + fn get_mut(&mut self) -> &mut Option { + &mut self.value + } - fn get(&self) -> &Option { - &self.value - } + fn set(&mut self, value:Option) { + self.value = value + } - fn get_mut(&mut self) -> &mut Option { - &mut self.value - } + fn update(&mut self, value: String) { + self.is_dirty = true; + self.value = Some(value) + } +} - fn set(&mut self, value: Option) { - self.value = value - } +impl AttrValue for AttrVoteId { + fn dat_type() -> &'static DatType { + static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); + ONCE_LOCK.get_or_init(|| Self::attr_dat_type()) + } - fn update(&mut self, value: String) { - self.is_dirty = true; - self.value = Some(value) - } + fn datum_desc() -> &'static DatumDesc { + static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); + ONCE_LOCK.get_or_init(|| Self::attr_datum_desc()) } - impl AttrValue for AttrVoteId { - fn dat_type() -> &'static DatType { - static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); - ONCE_LOCK.get_or_init(|| Self::attr_dat_type()) - } + fn object_name() -> &'static str { + OPTIONS + } - fn datum_desc() -> &'static DatumDesc { - static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); - ONCE_LOCK.get_or_init(|| Self::attr_datum_desc()) - } + fn attr_name() -> &'static str { + VOTE_ID + } +} - fn object_name() -> &'static str { - OPTIONS - } +// attribute struct definition +#[derive(Default, Clone, Debug)] +pub struct AttrOptionText { + is_dirty:bool, + value: Option +} - fn attr_name() -> &'static str { - VOTE_ID +impl AttrOptionText { + fn from(value:Option) -> Self { + Self { + is_dirty: false, + value } } - // attribute struct definition - #[derive(Default, Clone, Debug)] - pub struct AttrOptionText { - is_dirty: bool, - value: Option, + fn get(&self) -> &Option { + &self.value } - impl AttrOptionText { - fn from(value: Option) -> Self { - Self { - is_dirty: false, - value, - } - } - - fn get(&self) -> &Option { - &self.value - } - - fn get_mut(&mut self) -> &mut Option { - &mut self.value - } + fn get_mut(&mut self) -> &mut Option { + &mut self.value + } - fn set(&mut self, value: Option) { - self.value = value - } + fn set(&mut self, value:Option) { + self.value = value + } - fn update(&mut self, value: String) { - self.is_dirty = true; - self.value = Some(value) - } + fn update(&mut self, value: String) { + self.is_dirty = true; + self.value = Some(value) } +} - impl AttrValue for AttrOptionText { - fn dat_type() -> &'static DatType { - static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); - ONCE_LOCK.get_or_init(|| Self::attr_dat_type()) - } +impl AttrValue for AttrOptionText { + fn dat_type() -> &'static DatType { + static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); + ONCE_LOCK.get_or_init(|| Self::attr_dat_type()) + } - fn datum_desc() -> &'static DatumDesc { - static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); - ONCE_LOCK.get_or_init(|| Self::attr_datum_desc()) - } + fn datum_desc() -> &'static DatumDesc { + static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); + ONCE_LOCK.get_or_init(|| Self::attr_datum_desc()) + } - fn object_name() -> &'static str { - OPTIONS - } + fn object_name() -> &'static str { + OPTIONS + } - fn attr_name() -> &'static str { - OPTION_TEXT - } + fn attr_name() -> &'static str { + OPTION_TEXT } } + + +} \ No newline at end of file diff --git a/example/vote/src/generated/procedure.rs b/example/vote/src/generated/procedure.rs index 4510b4a..7a099be 100644 --- a/example/vote/src/generated/procedure.rs +++ b/example/vote/src/generated/procedure.rs @@ -4,24 +4,23 @@ use crate::generated::vote_history_item::object::VoteHistoryItem; use crate::generated::vote_result::object::VoteResult; use crate::generated::votes::object::Votes; use fallible_iterator::FallibleIterator; -use mudu::common::result::RS; -use mudu::common::xid::XID; -use mudu::error::ec::EC::MuduError; -use mudu::m_error; -use mudu_contract::database::entity_set::RecordSet; -use mudu_contract::{sql_params, sql_stmt}; -use sys_interface::async_api::{mudu_command, mudu_query}; +use mududb::common::result::RS; +use mududb::common::xid::XID; +use mududb::error::ec::EC::MuduError; +use mududb::m_error; +use mududb::contract::database::entity_set::RecordSet; +use mududb::contract::{sql_params, sql_stmt}; +use mududb::sys_interface::async_api::{mudu_command, mudu_query}; // User management /**mudu-proc**/ pub async fn create_user(xid: XID, phone: String) -> RS { - let user_id = mudu_sys::random::next_uuid_v4_string(); + let user_id = mududb::sys::random::next_uuid_v4_string(); mudu_command( xid, sql_stmt!(&"INSERT INTO users (user_id, phone) VALUES (?, ?)"), sql_params!(&(user_id.clone(), phone)), - ) - .await?; + ).await?; Ok(user_id) } @@ -37,7 +36,7 @@ pub async fn create_vote( visibility_rule: String, ) -> RS { // Validate input - if end_time <= mudu_sys::time::utc_now().timestamp() { + if end_time <= mududb::sys::time::utc_now().timestamp() { return Err(m_error!( MuduError, "End time must be in future".to_string() @@ -62,7 +61,7 @@ pub async fn create_vote( )); } - let vote_id = mudu_sys::random::next_uuid_v4_string(); + let vote_id = mududb::sys::random::next_uuid_v4_string(); mudu_command( xid, sql_stmt!( @@ -77,35 +76,28 @@ pub async fn create_vote( // Add option to vote /**mudu-proc**/ pub async fn add_option(xid: XID, vote_id: String, option_text: String) -> RS { - let option_id = mudu_sys::random::next_uuid_v4_string(); + let option_id = mududb::sys::random::next_uuid_v4_string(); mudu_command( xid, sql_stmt!(&"INSERT INTO options (option_id, vote_id, option_text) VALUES (?, ?, ?)"), sql_params!(&(option_id.clone(), vote_id, option_text)), - ) - .await?; + ).await?; Ok(option_id) } // Submit vote /**mudu-proc**/ -pub async fn cast_vote( - xid: XID, - user_id: String, - vote_id: String, - option_ids: Vec, -) -> RS<()> { +pub async fn cast_vote(xid: XID, user_id: String, vote_id: String, option_ids: Vec) -> RS<()> { // Check if vote is active let vote = mudu_query::( xid, sql_stmt!(&"SELECT * FROM votes WHERE vote_id = ?"), sql_params!(&(vote_id.clone(),)), - ) - .await? + ).await? .next()? .ok_or_else(|| m_error!(MuduError, "Vote not found".to_string()))?; - if mudu_sys::time::utc_now().timestamp() > vote.get_end_time().unwrap() as i64 { + if mududb::sys::time::utc_now().timestamp() > vote.get_end_time().unwrap() as i64 { return Err(m_error!(MuduError, "Voting has ended".to_string())); } @@ -116,8 +108,7 @@ pub async fn cast_vote( &"SELECT * FROM vote_actions WHERE user_id = ? AND vote_id = ? AND is_withdrawn = 0" ), sql_params!(&(user_id.clone(), vote_id.clone())), - ) - .await?; + ).await?; let has_active_vote = rs.next()?.is_some(); if has_active_vote { @@ -139,8 +130,8 @@ pub async fn cast_vote( } // Create vote action - let action_id = mudu_sys::random::next_uuid_v4_string(); - let action_time = mudu_sys::time::utc_now().timestamp(); + let action_id = mududb::sys::random::next_uuid_v4_string(); + let action_time = mududb::sys::time::utc_now().timestamp(); mudu_command( xid, sql_stmt!( @@ -148,12 +139,11 @@ pub async fn cast_vote( VALUES (?, ?, ?, ?)" ), sql_params!(&(action_id.clone(), user_id.clone(), vote_id, action_time)), - ) - .await?; + ).await?; // Create vote choices for option_id in option_ids { - let choice_id = mudu_sys::random::next_uuid_v4_string(); + let choice_id = mududb::sys::random::next_uuid_v4_string(); mudu_command( xid, sql_stmt!( @@ -161,8 +151,7 @@ pub async fn cast_vote( VALUES (?, ?, ?)" ), sql_params!(&(choice_id, action_id.clone(), option_id)), - ) - .await?; + ).await?; } Ok(()) @@ -175,12 +164,11 @@ pub async fn withdraw_vote(xid: XID, user_id: String, vote_id: String) -> RS<()> xid, sql_stmt!(&"SELECT * FROM votes WHERE vote_id = ?"), sql_params!(&(vote_id.clone(),)), - ) - .await? + ).await? .next()? .ok_or_else(|| m_error!(MuduError, "Vote not found".to_string()))?; - if mudu_sys::time::utc_now().timestamp() > vote.get_end_time().unwrap() as i64 { + if mududb::sys::time::utc_now().timestamp() > vote.get_end_time().unwrap() as i64 { return Err(m_error!( MuduError, "Voting has ended, cannot withdraw".to_string() @@ -193,8 +181,7 @@ pub async fn withdraw_vote(xid: XID, user_id: String, vote_id: String) -> RS<()> &"SELECT * FROM vote_actions WHERE user_id = ? AND vote_id = ? AND is_withdrawn = 0" ), sql_params!(&(user_id, vote_id)), - ) - .await? + ).await? .next()? .ok_or_else(|| m_error!(MuduError, "No active vote to withdraw".to_string()))?; @@ -206,8 +193,7 @@ pub async fn withdraw_vote(xid: XID, user_id: String, vote_id: String) -> RS<()> WHERE action_id = ?" ), sql_params!(&(action_id.clone(),)), - ) - .await?; + ).await?; Ok(()) } @@ -219,12 +205,11 @@ pub async fn get_vote_result(xid: XID, vote_id: String) -> RS { xid, sql_stmt!(&"SELECT * FROM votes WHERE vote_id = ?"), sql_params!(&(vote_id.clone(),)), - ) - .await? + ).await? .next()? .ok_or_else(|| m_error!(MuduError, "Vote not found".to_string()))?; - let now = mudu_sys::time::utc_now().timestamp(); + let now = mududb::sys::time::utc_now().timestamp(); let vote_ended = now > vote.get_end_time().unwrap() as i64; // Check visibility rules @@ -240,8 +225,7 @@ pub async fn get_vote_result(xid: XID, vote_id: String) -> RS { xid, sql_stmt!(&"SELECT * FROM options WHERE vote_id = ?"), sql_params!(&(vote_id)), - ) - .await? + ).await? .collect::>()?; let total_votes = mudu_query::( @@ -252,8 +236,7 @@ pub async fn get_vote_result(xid: XID, vote_id: String) -> RS { WHERE vote_id = ? AND is_withdrawn = 0" ), sql_params!(&(vote_id.clone(),)), - ) - .await? + ).await? .next()? .unwrap_or(0); @@ -270,8 +253,7 @@ pub async fn get_vote_result(xid: XID, vote_id: String) -> RS { option.get_option_id().as_ref().unwrap().to_string(), vote_id.to_string() )), - ) - .await? + ).await? .next()? .unwrap_or(0); } @@ -297,13 +279,12 @@ pub async fn get_voting_history(xid: XID, user_id: String) -> RS>()?; let mut history = Vec::new(); for action in actions { - let vote_ended = (mudu_sys::time::utc_now().timestamp() + let vote_ended = (mududb::sys::time::utc_now().timestamp() > action.get_action_time().unwrap() as i64) as i32; history.push(VoteHistoryItem::new( Some(action.get_vote_id().as_ref().unwrap().to_string()), @@ -316,73 +297,196 @@ pub async fn get_voting_history(xid: XID, user_id: String) -> RS) -> Vec { - ::mudu_binding::procedure::procedure_invoke::invoke_procedure_async( + +#[cfg(test)] +mod tests { + use super::create_vote; + + #[test] + async fn create_vote_rejects_past_deadline() { + let err = create_vote( + 1, + "creator".to_string(), + "topic".to_string(), + "single".to_string(), + 1, + 0, + "always".to_string(), + ).await + .unwrap_err(); + assert!(err.to_string().contains("End time must be in future")); + } + + #[test] + async fn create_vote_rejects_invalid_vote_type_and_single_choice_mismatch() { + let future = mududb::sys::time::utc_now().timestamp() + 3600; + + let vote_type_err = create_vote( + 1, + "creator".to_string(), + "topic".to_string(), + "ranked".to_string(), + 1, + future, + "always".to_string(), + ).await + .unwrap_err(); + assert!( + vote_type_err + .to_string() + .contains("Vote type must be 'single' or 'multiple'") + ); + + let single_err = create_vote( + 1, + "creator".to_string(), + "topic".to_string(), + "single".to_string(), + 2, + future, + "always".to_string(), + ).await + .unwrap_err(); + assert!( + single_err + .to_string() + .contains("Single vote requires max_choices=1") + ); + } + + #[test] + async fn create_vote_rejects_invalid_visibility_rule() { + let future = mududb::sys::time::utc_now().timestamp() + 3600; + let err = create_vote( + 1, + "creator".to_string(), + "topic".to_string(), + "multiple".to_string(), + 3, + future, + "hidden".to_string(), + ).await + .unwrap_err(); + assert!( + err.to_string() + .contains("Visibility rule must be 'always' or 'after_end'") + ); + } +} +async fn mp2_add_option(param:Vec) -> Vec { + ::mududb::binding::procedure::procedure_invoke::invoke_procedure_async( param, - mudu_inner_p2_create_user, - ) - .await + mudu_inner_p2_add_option, + ).await } -pub async fn mudu_inner_p2_create_user( - param: ::mudu_contract::procedure::procedure_param::ProcedureParam, -) -> ::mudu::common::result::RS<::mudu_contract::procedure::procedure_result::ProcedureResult> { - let return_desc = mudu_result_desc_create_user().clone(); - let res = create_user( +pub async fn mudu_inner_p2_add_option( + param: ::mududb::contract::procedure::procedure_param::ProcedureParam, +) -> ::mududb::common::result::RS< + ::mududb::contract::procedure::procedure_result::ProcedureResult, +> { + let res = add_option( param.session_id(), - ::mudu_type::datum::value_to_typed::(¶m.param_list()[0], "String")?, - ) - .await; - let tuple = res; - Ok(::mudu_contract::procedure::procedure_result::ProcedureResult::from(tuple, &return_desc)?) + + + ::mududb::types::datum::value_to_typed::< + String, + _, + >(¶m.param_list()[0], "String")?, + + + + ::mududb::types::datum::value_to_typed::< + String, + _, + >(¶m.param_list()[1], "String")?, + + + ).await; + match res { + Ok(tuple) => { + let return_list = { + + vec![ + + ::mududb::types::datum::value_from_typed(&tuple, "String")? + + ] + + }; + Ok(::mududb::contract::procedure::procedure_result::ProcedureResult::new(return_list)) + } + Err(e) => Err(e), + } } -pub fn mudu_argv_desc_create_user() --> &'static ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc { - static ARGV_DESC: std::sync::OnceLock< - ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc, - > = std::sync::OnceLock::new(); - ARGV_DESC.get_or_init(|| { - <(String,) as ::mudu_contract::tuple::tuple_datum::TupleDatum>::tuple_desc_static(&{ - let _vec: Vec = <[_]>::into_vec(std::boxed::Box::new(["phone"])) - .iter() - .map(|s| s.to_string()) - .collect(); - _vec - }) - }) +pub fn mudu_argv_desc_add_option() -> &'static ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc { + static ARGV_DESC: std::sync::OnceLock<::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc> = + std::sync::OnceLock::new(); + ARGV_DESC.get_or_init(|| + { + ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc::new(vec![ + + ::mududb::contract::tuple::datum_desc::DatumDesc::new( + "vote_id".to_string(), + + ::dat_type().clone() + + ), + + ::mududb::contract::tuple::datum_desc::DatumDesc::new( + "option_text".to_string(), + + ::dat_type().clone() + + ), + + ]) + } + ) } -pub fn mudu_result_desc_create_user() --> &'static ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc { - static RESULT_DESC: std::sync::OnceLock< - ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc, - > = std::sync::OnceLock::new(); - RESULT_DESC.get_or_init(|| { - <(String,) as ::mudu_contract::tuple::tuple_datum::TupleDatum>::tuple_desc_static(&[]) - }) +pub fn mudu_result_desc_add_option() -> &'static ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc { + static RESULT_DESC: std::sync::OnceLock<::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc> = + std::sync::OnceLock::new(); + RESULT_DESC.get_or_init(|| + { + ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc::new(vec![ + + ::mududb::contract::tuple::datum_desc::DatumDesc::new( + "0".to_string(), + + ::dat_type().clone() + + ), + + ]) + } + ) } -pub fn mudu_proc_desc_create_user() -> &'static ::mudu_contract::procedure::proc_desc::ProcDesc { - static _PROC_DESC: std::sync::OnceLock<::mudu_contract::procedure::proc_desc::ProcDesc> = - std::sync::OnceLock::new(); - _PROC_DESC.get_or_init(|| { - ::mudu_contract::procedure::proc_desc::ProcDesc::new( - "vote".to_string(), - "create_user".to_string(), - mudu_argv_desc_create_user().clone(), - mudu_result_desc_create_user().clone(), - false, - ) - }) +pub fn mudu_proc_desc_add_option() -> &'static ::mududb::contract::procedure::proc_desc::ProcDesc { + static _PROC_DESC: std::sync::OnceLock< + ::mududb::contract::procedure::proc_desc::ProcDesc, + > = std::sync::OnceLock::new(); + _PROC_DESC + .get_or_init(|| { + ::mududb::contract::procedure::proc_desc::ProcDesc::new( + "vote".to_string(), + "add_option".to_string(), + mudu_argv_desc_add_option().clone(), + mudu_result_desc_add_option().clone(), + false + ) + }) } -mod mod_create_user { +mod mod_add_option { wit_bindgen::generate!({ inline: - r##"package mudu:mp2-create-user; - world mudu-app-mp2-create-user { - export mp2-create-user: func(param:list) -> list; + r##"package mudu:mp2-add-option; + world mudu-app-mp2-add-option { + export mp2-add-option: func(param:list) -> list; } "##, async: true @@ -390,102 +494,125 @@ mod mod_create_user { #[allow(non_camel_case_types)] #[allow(unused)] - struct GuestCreateUser {} + struct GuestAddOption {} - impl Guest for GuestCreateUser { - async fn mp2_create_user(param: Vec) -> Vec { - super::mp2_create_user(param).await + impl Guest for GuestAddOption { + async fn mp2_add_option(param:Vec) -> Vec { + super::mp2_add_option(param).await } } - export!(GuestCreateUser); + export!(GuestAddOption); } -async fn mp2_cast_vote(param: Vec) -> Vec { - ::mudu_binding::procedure::procedure_invoke::invoke_procedure_async( +async fn mp2_cast_vote(param:Vec) -> Vec { + ::mududb::binding::procedure::procedure_invoke::invoke_procedure_async( param, mudu_inner_p2_cast_vote, - ) - .await + ).await } pub async fn mudu_inner_p2_cast_vote( - param: ::mudu_contract::procedure::procedure_param::ProcedureParam, -) -> ::mudu::common::result::RS<::mudu_contract::procedure::procedure_result::ProcedureResult> { - let return_desc = mudu_result_desc_cast_vote().clone(); + param: ::mududb::contract::procedure::procedure_param::ProcedureParam, +) -> ::mududb::common::result::RS< + ::mududb::contract::procedure::procedure_result::ProcedureResult, +> { let res = cast_vote( param.session_id(), - ::mudu_type::datum::value_to_typed::(¶m.param_list()[0], "String")?, - ::mudu_type::datum::value_to_typed::(¶m.param_list()[1], "String")?, - ::mudu_type::datum::value_to_typed::, _>( - ¶m.param_list()[2], - "Vec", - )?, - ) - .await; - let tuple = res; - Ok(::mudu_contract::procedure::procedure_result::ProcedureResult::from(tuple, &return_desc)?) + + + ::mududb::types::datum::value_to_typed::< + String, + _, + >(¶m.param_list()[0], "String")?, + + + + ::mududb::types::datum::value_to_typed::< + String, + _, + >(¶m.param_list()[1], "String")?, + + + + ::mududb::types::datum::value_to_typed::< + Vec, + _, + >(¶m.param_list()[2], "Vec")?, + + + ).await; + match res { + Ok(tuple) => { + let return_list = { + + vec![] + + }; + Ok(::mududb::contract::procedure::procedure_result::ProcedureResult::new(return_list)) + } + Err(e) => Err(e), + } } -pub fn mudu_argv_desc_cast_vote() --> &'static ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc { - static ARGV_DESC: std::sync::OnceLock< - ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc, - > = std::sync::OnceLock::new(); - ARGV_DESC.get_or_init(|| { - <( - - String, - - String, - - Vec, - - ) as ::mudu_contract::tuple::tuple_datum::TupleDatum - >::tuple_desc_static( - &{ - let _vec: Vec = <[_]>::into_vec( - std::boxed::Box::new([ - - "user_id", - - "vote_id", - - "option_ids", - - - ]), - ) - .iter() - .map(|s| s.to_string()) - .collect(); - _vec - }, - ) - }) +pub fn mudu_argv_desc_cast_vote() -> &'static ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc { + static ARGV_DESC: std::sync::OnceLock<::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc> = + std::sync::OnceLock::new(); + ARGV_DESC.get_or_init(|| + { + ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc::new(vec![ + + ::mududb::contract::tuple::datum_desc::DatumDesc::new( + "user_id".to_string(), + + ::dat_type().clone() + + ), + + ::mududb::contract::tuple::datum_desc::DatumDesc::new( + "vote_id".to_string(), + + ::dat_type().clone() + + ), + + ::mududb::contract::tuple::datum_desc::DatumDesc::new( + "option_ids".to_string(), + + as ::mududb::types::datum::Datum>::dat_type().clone() + + ), + + ]) + } + ) } -pub fn mudu_result_desc_cast_vote() --> &'static ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc { - static RESULT_DESC: std::sync::OnceLock< - ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc, - > = std::sync::OnceLock::new(); - RESULT_DESC.get_or_init(|| { - <() as ::mudu_contract::tuple::tuple_datum::TupleDatum>::tuple_desc_static(&[]) - }) +pub fn mudu_result_desc_cast_vote() -> &'static ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc { + static RESULT_DESC: std::sync::OnceLock<::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc> = + std::sync::OnceLock::new(); + RESULT_DESC.get_or_init(|| + { + ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc::new(vec![ + + ]) + } + ) } -pub fn mudu_proc_desc_cast_vote() -> &'static ::mudu_contract::procedure::proc_desc::ProcDesc { - static _PROC_DESC: std::sync::OnceLock<::mudu_contract::procedure::proc_desc::ProcDesc> = - std::sync::OnceLock::new(); - _PROC_DESC.get_or_init(|| { - ::mudu_contract::procedure::proc_desc::ProcDesc::new( - "vote".to_string(), - "cast_vote".to_string(), - mudu_argv_desc_cast_vote().clone(), - mudu_result_desc_cast_vote().clone(), - false, - ) - }) +pub fn mudu_proc_desc_cast_vote() -> &'static ::mududb::contract::procedure::proc_desc::ProcDesc { + static _PROC_DESC: std::sync::OnceLock< + ::mududb::contract::procedure::proc_desc::ProcDesc, + > = std::sync::OnceLock::new(); + _PROC_DESC + .get_or_init(|| { + ::mududb::contract::procedure::proc_desc::ProcDesc::new( + "vote".to_string(), + "cast_vote".to_string(), + mudu_argv_desc_cast_vote().clone(), + mudu_result_desc_cast_vote().clone(), + false + ) + }) } mod mod_cast_vote { @@ -504,81 +631,116 @@ mod mod_cast_vote { struct GuestCastVote {} impl Guest for GuestCastVote { - async fn mp2_cast_vote(param: Vec) -> Vec { + async fn mp2_cast_vote(param:Vec) -> Vec { super::mp2_cast_vote(param).await } } export!(GuestCastVote); } -async fn mp2_get_vote_result(param: Vec) -> Vec { - ::mudu_binding::procedure::procedure_invoke::invoke_procedure_async( +async fn mp2_withdraw_vote(param:Vec) -> Vec { + ::mududb::binding::procedure::procedure_invoke::invoke_procedure_async( param, - mudu_inner_p2_get_vote_result, - ) - .await + mudu_inner_p2_withdraw_vote, + ).await } -pub async fn mudu_inner_p2_get_vote_result( - param: ::mudu_contract::procedure::procedure_param::ProcedureParam, -) -> ::mudu::common::result::RS<::mudu_contract::procedure::procedure_result::ProcedureResult> { - let return_desc = mudu_result_desc_get_vote_result().clone(); - let res = get_vote_result( +pub async fn mudu_inner_p2_withdraw_vote( + param: ::mududb::contract::procedure::procedure_param::ProcedureParam, +) -> ::mududb::common::result::RS< + ::mududb::contract::procedure::procedure_result::ProcedureResult, +> { + let res = withdraw_vote( param.session_id(), - ::mudu_type::datum::value_to_typed::(¶m.param_list()[0], "String")?, - ) - .await; - let tuple = res; - Ok(::mudu_contract::procedure::procedure_result::ProcedureResult::from(tuple, &return_desc)?) + + + ::mududb::types::datum::value_to_typed::< + String, + _, + >(¶m.param_list()[0], "String")?, + + + + ::mududb::types::datum::value_to_typed::< + String, + _, + >(¶m.param_list()[1], "String")?, + + + ).await; + match res { + Ok(tuple) => { + let return_list = { + + vec![] + + }; + Ok(::mududb::contract::procedure::procedure_result::ProcedureResult::new(return_list)) + } + Err(e) => Err(e), + } } -pub fn mudu_argv_desc_get_vote_result() --> &'static ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc { - static ARGV_DESC: std::sync::OnceLock< - ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc, - > = std::sync::OnceLock::new(); - ARGV_DESC.get_or_init(|| { - <(String,) as ::mudu_contract::tuple::tuple_datum::TupleDatum>::tuple_desc_static(&{ - let _vec: Vec = <[_]>::into_vec(std::boxed::Box::new(["vote_id"])) - .iter() - .map(|s| s.to_string()) - .collect(); - _vec - }) - }) +pub fn mudu_argv_desc_withdraw_vote() -> &'static ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc { + static ARGV_DESC: std::sync::OnceLock<::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc> = + std::sync::OnceLock::new(); + ARGV_DESC.get_or_init(|| + { + ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc::new(vec![ + + ::mududb::contract::tuple::datum_desc::DatumDesc::new( + "user_id".to_string(), + + ::dat_type().clone() + + ), + + ::mududb::contract::tuple::datum_desc::DatumDesc::new( + "vote_id".to_string(), + + ::dat_type().clone() + + ), + + ]) + } + ) } -pub fn mudu_result_desc_get_vote_result() --> &'static ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc { - static RESULT_DESC: std::sync::OnceLock< - ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc, - > = std::sync::OnceLock::new(); - RESULT_DESC.get_or_init(|| { - <(VoteResult,) as ::mudu_contract::tuple::tuple_datum::TupleDatum>::tuple_desc_static(&[]) - }) +pub fn mudu_result_desc_withdraw_vote() -> &'static ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc { + static RESULT_DESC: std::sync::OnceLock<::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc> = + std::sync::OnceLock::new(); + RESULT_DESC.get_or_init(|| + { + ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc::new(vec![ + + ]) + } + ) } -pub fn mudu_proc_desc_get_vote_result() -> &'static ::mudu_contract::procedure::proc_desc::ProcDesc -{ - static _PROC_DESC: std::sync::OnceLock<::mudu_contract::procedure::proc_desc::ProcDesc> = - std::sync::OnceLock::new(); - _PROC_DESC.get_or_init(|| { - ::mudu_contract::procedure::proc_desc::ProcDesc::new( - "vote".to_string(), - "get_vote_result".to_string(), - mudu_argv_desc_get_vote_result().clone(), - mudu_result_desc_get_vote_result().clone(), - false, - ) - }) +pub fn mudu_proc_desc_withdraw_vote() -> &'static ::mududb::contract::procedure::proc_desc::ProcDesc { + static _PROC_DESC: std::sync::OnceLock< + ::mududb::contract::procedure::proc_desc::ProcDesc, + > = std::sync::OnceLock::new(); + _PROC_DESC + .get_or_init(|| { + ::mududb::contract::procedure::proc_desc::ProcDesc::new( + "vote".to_string(), + "withdraw_vote".to_string(), + mudu_argv_desc_withdraw_vote().clone(), + mudu_result_desc_withdraw_vote().clone(), + false + ) + }) } -mod mod_get_vote_result { +mod mod_withdraw_vote { wit_bindgen::generate!({ inline: - r##"package mudu:mp2-get-vote-result; - world mudu-app-mp2-get-vote-result { - export mp2-get-vote-result: func(param:list) -> list; + r##"package mudu:mp2-withdraw-vote; + world mudu-app-mp2-withdraw-vote { + export mp2-withdraw-vote: func(param:list) -> list; } "##, async: true @@ -586,90 +748,116 @@ mod mod_get_vote_result { #[allow(non_camel_case_types)] #[allow(unused)] - struct GuestGetVoteResult {} + struct GuestWithdrawVote {} - impl Guest for GuestGetVoteResult { - async fn mp2_get_vote_result(param: Vec) -> Vec { - super::mp2_get_vote_result(param).await + impl Guest for GuestWithdrawVote { + async fn mp2_withdraw_vote(param:Vec) -> Vec { + super::mp2_withdraw_vote(param).await } } - export!(GuestGetVoteResult); + export!(GuestWithdrawVote); } -async fn mp2_get_voting_history(param: Vec) -> Vec { - ::mudu_binding::procedure::procedure_invoke::invoke_procedure_async( +async fn mp2_get_vote_result(param:Vec) -> Vec { + ::mududb::binding::procedure::procedure_invoke::invoke_procedure_async( param, - mudu_inner_p2_get_voting_history, - ) - .await + mudu_inner_p2_get_vote_result, + ).await } -pub async fn mudu_inner_p2_get_voting_history( - param: ::mudu_contract::procedure::procedure_param::ProcedureParam, -) -> ::mudu::common::result::RS<::mudu_contract::procedure::procedure_result::ProcedureResult> { - let return_desc = mudu_result_desc_get_voting_history().clone(); - let res = get_voting_history( +pub async fn mudu_inner_p2_get_vote_result( + param: ::mududb::contract::procedure::procedure_param::ProcedureParam, +) -> ::mududb::common::result::RS< + ::mududb::contract::procedure::procedure_result::ProcedureResult, +> { + let res = get_vote_result( param.session_id(), - ::mudu_type::datum::value_to_typed::(¶m.param_list()[0], "String")?, - ) - .await; - let tuple = res; - Ok(::mudu_contract::procedure::procedure_result::ProcedureResult::from(tuple, &return_desc)?) + + + ::mududb::types::datum::value_to_typed::< + String, + _, + >(¶m.param_list()[0], "String")?, + + + ).await; + match res { + Ok(tuple) => { + let return_list = { + + vec![ + + ::mududb::types::datum::value_from_typed(&tuple, "VoteResult")? + + ] + + }; + Ok(::mududb::contract::procedure::procedure_result::ProcedureResult::new(return_list)) + } + Err(e) => Err(e), + } } -pub fn mudu_argv_desc_get_voting_history() --> &'static ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc { - static ARGV_DESC: std::sync::OnceLock< - ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc, - > = std::sync::OnceLock::new(); - ARGV_DESC.get_or_init(|| { - <(String,) as ::mudu_contract::tuple::tuple_datum::TupleDatum>::tuple_desc_static(&{ - let _vec: Vec = <[_]>::into_vec(std::boxed::Box::new(["user_id"])) - .iter() - .map(|s| s.to_string()) - .collect(); - _vec - }) - }) +pub fn mudu_argv_desc_get_vote_result() -> &'static ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc { + static ARGV_DESC: std::sync::OnceLock<::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc> = + std::sync::OnceLock::new(); + ARGV_DESC.get_or_init(|| + { + ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc::new(vec![ + + ::mududb::contract::tuple::datum_desc::DatumDesc::new( + "vote_id".to_string(), + + ::dat_type().clone() + + ), + + ]) + } + ) } -pub fn mudu_result_desc_get_voting_history() --> &'static ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc { - static RESULT_DESC: std::sync::OnceLock< - ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc, - > = std::sync::OnceLock::new(); - RESULT_DESC.get_or_init(|| { - <( +pub fn mudu_result_desc_get_vote_result() -> &'static ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc { + static RESULT_DESC: std::sync::OnceLock<::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc> = + std::sync::OnceLock::new(); + RESULT_DESC.get_or_init(|| + { + ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc::new(vec![ - Vec, + ::mududb::contract::tuple::datum_desc::DatumDesc::new( + "0".to_string(), + + ::dat_type().clone() + + ), - ) as ::mudu_contract::tuple::tuple_datum::TupleDatum>::tuple_desc_static( - &[], - ) - }) + ]) + } + ) } -pub fn mudu_proc_desc_get_voting_history() --> &'static ::mudu_contract::procedure::proc_desc::ProcDesc { - static _PROC_DESC: std::sync::OnceLock<::mudu_contract::procedure::proc_desc::ProcDesc> = - std::sync::OnceLock::new(); - _PROC_DESC.get_or_init(|| { - ::mudu_contract::procedure::proc_desc::ProcDesc::new( - "vote".to_string(), - "get_voting_history".to_string(), - mudu_argv_desc_get_voting_history().clone(), - mudu_result_desc_get_voting_history().clone(), - false, - ) - }) +pub fn mudu_proc_desc_get_vote_result() -> &'static ::mududb::contract::procedure::proc_desc::ProcDesc { + static _PROC_DESC: std::sync::OnceLock< + ::mududb::contract::procedure::proc_desc::ProcDesc, + > = std::sync::OnceLock::new(); + _PROC_DESC + .get_or_init(|| { + ::mududb::contract::procedure::proc_desc::ProcDesc::new( + "vote".to_string(), + "get_vote_result".to_string(), + mudu_argv_desc_get_vote_result().clone(), + mudu_result_desc_get_vote_result().clone(), + false + ) + }) } -mod mod_get_voting_history { +mod mod_get_vote_result { wit_bindgen::generate!({ inline: - r##"package mudu:mp2-get-voting-history; - world mudu-app-mp2-get-voting-history { - export mp2-get-voting-history: func(param:list) -> list; + r##"package mudu:mp2-get-vote-result; + world mudu-app-mp2-get-vote-result { + export mp2-get-vote-result: func(param:list) -> list; } "##, async: true @@ -677,85 +865,116 @@ mod mod_get_voting_history { #[allow(non_camel_case_types)] #[allow(unused)] - struct GuestGetVotingHistory {} + struct GuestGetVoteResult {} - impl Guest for GuestGetVotingHistory { - async fn mp2_get_voting_history(param: Vec) -> Vec { - super::mp2_get_voting_history(param).await + impl Guest for GuestGetVoteResult { + async fn mp2_get_vote_result(param:Vec) -> Vec { + super::mp2_get_vote_result(param).await } } - export!(GuestGetVotingHistory); + export!(GuestGetVoteResult); } -async fn mp2_add_option(param: Vec) -> Vec { - ::mudu_binding::procedure::procedure_invoke::invoke_procedure_async( +async fn mp2_get_voting_history(param:Vec) -> Vec { + ::mududb::binding::procedure::procedure_invoke::invoke_procedure_async( param, - mudu_inner_p2_add_option, - ) - .await + mudu_inner_p2_get_voting_history, + ).await } -pub async fn mudu_inner_p2_add_option( - param: ::mudu_contract::procedure::procedure_param::ProcedureParam, -) -> ::mudu::common::result::RS<::mudu_contract::procedure::procedure_result::ProcedureResult> { - let return_desc = mudu_result_desc_add_option().clone(); - let res = add_option( +pub async fn mudu_inner_p2_get_voting_history( + param: ::mududb::contract::procedure::procedure_param::ProcedureParam, +) -> ::mududb::common::result::RS< + ::mududb::contract::procedure::procedure_result::ProcedureResult, +> { + let res = get_voting_history( param.session_id(), - ::mudu_type::datum::value_to_typed::(¶m.param_list()[0], "String")?, - ::mudu_type::datum::value_to_typed::(¶m.param_list()[1], "String")?, - ) - .await; - let tuple = res; - Ok(::mudu_contract::procedure::procedure_result::ProcedureResult::from(tuple, &return_desc)?) + + + ::mududb::types::datum::value_to_typed::< + String, + _, + >(¶m.param_list()[0], "String")?, + + + ).await; + match res { + Ok(tuple) => { + let return_list = { + + vec![ + + ::mududb::types::datum::value_from_typed(&tuple, "Vec")? + + ] + + }; + Ok(::mududb::contract::procedure::procedure_result::ProcedureResult::new(return_list)) + } + Err(e) => Err(e), + } } -pub fn mudu_argv_desc_add_option() --> &'static ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc { - static ARGV_DESC: std::sync::OnceLock< - ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc, - > = std::sync::OnceLock::new(); - ARGV_DESC.get_or_init(|| { - <(String, String) as ::mudu_contract::tuple::tuple_datum::TupleDatum>::tuple_desc_static(&{ - let _vec: Vec = - <[_]>::into_vec(std::boxed::Box::new(["vote_id", "option_text"])) - .iter() - .map(|s| s.to_string()) - .collect(); - _vec - }) - }) +pub fn mudu_argv_desc_get_voting_history() -> &'static ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc { + static ARGV_DESC: std::sync::OnceLock<::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc> = + std::sync::OnceLock::new(); + ARGV_DESC.get_or_init(|| + { + ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc::new(vec![ + + ::mududb::contract::tuple::datum_desc::DatumDesc::new( + "user_id".to_string(), + + ::dat_type().clone() + + ), + + ]) + } + ) } -pub fn mudu_result_desc_add_option() --> &'static ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc { - static RESULT_DESC: std::sync::OnceLock< - ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc, - > = std::sync::OnceLock::new(); - RESULT_DESC.get_or_init(|| { - <(String,) as ::mudu_contract::tuple::tuple_datum::TupleDatum>::tuple_desc_static(&[]) - }) +pub fn mudu_result_desc_get_voting_history() -> &'static ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc { + static RESULT_DESC: std::sync::OnceLock<::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc> = + std::sync::OnceLock::new(); + RESULT_DESC.get_or_init(|| + { + ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc::new(vec![ + + ::mududb::contract::tuple::datum_desc::DatumDesc::new( + "0".to_string(), + + as ::mududb::types::datum::Datum>::dat_type().clone() + + ), + + ]) + } + ) } -pub fn mudu_proc_desc_add_option() -> &'static ::mudu_contract::procedure::proc_desc::ProcDesc { - static _PROC_DESC: std::sync::OnceLock<::mudu_contract::procedure::proc_desc::ProcDesc> = - std::sync::OnceLock::new(); - _PROC_DESC.get_or_init(|| { - ::mudu_contract::procedure::proc_desc::ProcDesc::new( - "vote".to_string(), - "add_option".to_string(), - mudu_argv_desc_add_option().clone(), - mudu_result_desc_add_option().clone(), - false, - ) - }) +pub fn mudu_proc_desc_get_voting_history() -> &'static ::mududb::contract::procedure::proc_desc::ProcDesc { + static _PROC_DESC: std::sync::OnceLock< + ::mududb::contract::procedure::proc_desc::ProcDesc, + > = std::sync::OnceLock::new(); + _PROC_DESC + .get_or_init(|| { + ::mududb::contract::procedure::proc_desc::ProcDesc::new( + "vote".to_string(), + "get_voting_history".to_string(), + mudu_argv_desc_get_voting_history().clone(), + mudu_result_desc_get_voting_history().clone(), + false + ) + }) } -mod mod_add_option { +mod mod_get_voting_history { wit_bindgen::generate!({ inline: - r##"package mudu:mp2-add-option; - world mudu-app-mp2-add-option { - export mp2-add-option: func(param:list) -> list; + r##"package mudu:mp2-get-voting-history; + world mudu-app-mp2-get-voting-history { + export mp2-get-voting-history: func(param:list) -> list; } "##, async: true @@ -763,114 +982,178 @@ mod mod_add_option { #[allow(non_camel_case_types)] #[allow(unused)] - struct GuestAddOption {} + struct GuestGetVotingHistory {} - impl Guest for GuestAddOption { - async fn mp2_add_option(param: Vec) -> Vec { - super::mp2_add_option(param).await + impl Guest for GuestGetVotingHistory { + async fn mp2_get_voting_history(param:Vec) -> Vec { + super::mp2_get_voting_history(param).await } } - export!(GuestAddOption); + export!(GuestGetVotingHistory); } -async fn mp2_create_vote(param: Vec) -> Vec { - ::mudu_binding::procedure::procedure_invoke::invoke_procedure_async( +async fn mp2_create_vote(param:Vec) -> Vec { + ::mududb::binding::procedure::procedure_invoke::invoke_procedure_async( param, mudu_inner_p2_create_vote, - ) - .await + ).await } pub async fn mudu_inner_p2_create_vote( - param: ::mudu_contract::procedure::procedure_param::ProcedureParam, -) -> ::mudu::common::result::RS<::mudu_contract::procedure::procedure_result::ProcedureResult> { - let return_desc = mudu_result_desc_create_vote().clone(); + param: ::mududb::contract::procedure::procedure_param::ProcedureParam, +) -> ::mududb::common::result::RS< + ::mududb::contract::procedure::procedure_result::ProcedureResult, +> { let res = create_vote( param.session_id(), - ::mudu_type::datum::value_to_typed::(¶m.param_list()[0], "String")?, - ::mudu_type::datum::value_to_typed::(¶m.param_list()[1], "String")?, - ::mudu_type::datum::value_to_typed::(¶m.param_list()[2], "String")?, - ::mudu_type::datum::value_to_typed::(¶m.param_list()[3], "i64")?, - ::mudu_type::datum::value_to_typed::(¶m.param_list()[4], "i64")?, - ::mudu_type::datum::value_to_typed::(¶m.param_list()[5], "String")?, - ) - .await; - let tuple = res; - Ok(::mudu_contract::procedure::procedure_result::ProcedureResult::from(tuple, &return_desc)?) + + + ::mududb::types::datum::value_to_typed::< + String, + _, + >(¶m.param_list()[0], "String")?, + + + + ::mududb::types::datum::value_to_typed::< + String, + _, + >(¶m.param_list()[1], "String")?, + + + + ::mududb::types::datum::value_to_typed::< + String, + _, + >(¶m.param_list()[2], "String")?, + + + + ::mududb::types::datum::value_to_typed::< + i64, + _, + >(¶m.param_list()[3], "i64")?, + + + + ::mududb::types::datum::value_to_typed::< + i64, + _, + >(¶m.param_list()[4], "i64")?, + + + + ::mududb::types::datum::value_to_typed::< + String, + _, + >(¶m.param_list()[5], "String")?, + + + ).await; + match res { + Ok(tuple) => { + let return_list = { + + vec![ + + ::mududb::types::datum::value_from_typed(&tuple, "String")? + + ] + + }; + Ok(::mududb::contract::procedure::procedure_result::ProcedureResult::new(return_list)) + } + Err(e) => Err(e), + } } -pub fn mudu_argv_desc_create_vote() --> &'static ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc { - static ARGV_DESC: std::sync::OnceLock< - ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc, - > = std::sync::OnceLock::new(); - ARGV_DESC.get_or_init(|| { - <( - - String, - - String, - - String, - - i64, - - i64, - - String, - - ) as ::mudu_contract::tuple::tuple_datum::TupleDatum - >::tuple_desc_static( - &{ - let _vec: Vec = <[_]>::into_vec( - std::boxed::Box::new([ - - "creator_id", - - "topic", - - "vote_type", - - "max_choices", - - "end_time", - - "visibility_rule", - - - ]), - ) - .iter() - .map(|s| s.to_string()) - .collect(); - _vec - }, - ) - }) +pub fn mudu_argv_desc_create_vote() -> &'static ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc { + static ARGV_DESC: std::sync::OnceLock<::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc> = + std::sync::OnceLock::new(); + ARGV_DESC.get_or_init(|| + { + ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc::new(vec![ + + ::mududb::contract::tuple::datum_desc::DatumDesc::new( + "creator_id".to_string(), + + ::dat_type().clone() + + ), + + ::mududb::contract::tuple::datum_desc::DatumDesc::new( + "topic".to_string(), + + ::dat_type().clone() + + ), + + ::mududb::contract::tuple::datum_desc::DatumDesc::new( + "vote_type".to_string(), + + ::dat_type().clone() + + ), + + ::mududb::contract::tuple::datum_desc::DatumDesc::new( + "max_choices".to_string(), + + ::dat_type().clone() + + ), + + ::mududb::contract::tuple::datum_desc::DatumDesc::new( + "end_time".to_string(), + + ::dat_type().clone() + + ), + + ::mududb::contract::tuple::datum_desc::DatumDesc::new( + "visibility_rule".to_string(), + + ::dat_type().clone() + + ), + + ]) + } + ) } -pub fn mudu_result_desc_create_vote() --> &'static ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc { - static RESULT_DESC: std::sync::OnceLock< - ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc, - > = std::sync::OnceLock::new(); - RESULT_DESC.get_or_init(|| { - <(String,) as ::mudu_contract::tuple::tuple_datum::TupleDatum>::tuple_desc_static(&[]) - }) +pub fn mudu_result_desc_create_vote() -> &'static ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc { + static RESULT_DESC: std::sync::OnceLock<::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc> = + std::sync::OnceLock::new(); + RESULT_DESC.get_or_init(|| + { + ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc::new(vec![ + + ::mududb::contract::tuple::datum_desc::DatumDesc::new( + "0".to_string(), + + ::dat_type().clone() + + ), + + ]) + } + ) } -pub fn mudu_proc_desc_create_vote() -> &'static ::mudu_contract::procedure::proc_desc::ProcDesc { - static _PROC_DESC: std::sync::OnceLock<::mudu_contract::procedure::proc_desc::ProcDesc> = - std::sync::OnceLock::new(); - _PROC_DESC.get_or_init(|| { - ::mudu_contract::procedure::proc_desc::ProcDesc::new( - "vote".to_string(), - "create_vote".to_string(), - mudu_argv_desc_create_vote().clone(), - mudu_result_desc_create_vote().clone(), - false, - ) - }) +pub fn mudu_proc_desc_create_vote() -> &'static ::mududb::contract::procedure::proc_desc::ProcDesc { + static _PROC_DESC: std::sync::OnceLock< + ::mududb::contract::procedure::proc_desc::ProcDesc, + > = std::sync::OnceLock::new(); + _PROC_DESC + .get_or_init(|| { + ::mududb::contract::procedure::proc_desc::ProcDesc::new( + "vote".to_string(), + "create_vote".to_string(), + mudu_argv_desc_create_vote().clone(), + mudu_result_desc_create_vote().clone(), + false + ) + }) } mod mod_create_vote { @@ -889,81 +1172,113 @@ mod mod_create_vote { struct GuestCreateVote {} impl Guest for GuestCreateVote { - async fn mp2_create_vote(param: Vec) -> Vec { + async fn mp2_create_vote(param:Vec) -> Vec { super::mp2_create_vote(param).await } } export!(GuestCreateVote); } -async fn mp2_withdraw_vote(param: Vec) -> Vec { - ::mudu_binding::procedure::procedure_invoke::invoke_procedure_async( +async fn mp2_create_user(param:Vec) -> Vec { + ::mududb::binding::procedure::procedure_invoke::invoke_procedure_async( param, - mudu_inner_p2_withdraw_vote, - ) - .await + mudu_inner_p2_create_user, + ).await } -pub async fn mudu_inner_p2_withdraw_vote( - param: ::mudu_contract::procedure::procedure_param::ProcedureParam, -) -> ::mudu::common::result::RS<::mudu_contract::procedure::procedure_result::ProcedureResult> { - let return_desc = mudu_result_desc_withdraw_vote().clone(); - let res = withdraw_vote( +pub async fn mudu_inner_p2_create_user( + param: ::mududb::contract::procedure::procedure_param::ProcedureParam, +) -> ::mududb::common::result::RS< + ::mududb::contract::procedure::procedure_result::ProcedureResult, +> { + let res = create_user( param.session_id(), - ::mudu_type::datum::value_to_typed::(¶m.param_list()[0], "String")?, - ::mudu_type::datum::value_to_typed::(¶m.param_list()[1], "String")?, - ) - .await; - let tuple = res; - Ok(::mudu_contract::procedure::procedure_result::ProcedureResult::from(tuple, &return_desc)?) + + + ::mududb::types::datum::value_to_typed::< + String, + _, + >(¶m.param_list()[0], "String")?, + + + ).await; + match res { + Ok(tuple) => { + let return_list = { + + vec![ + + ::mududb::types::datum::value_from_typed(&tuple, "String")? + + ] + + }; + Ok(::mududb::contract::procedure::procedure_result::ProcedureResult::new(return_list)) + } + Err(e) => Err(e), + } } -pub fn mudu_argv_desc_withdraw_vote() --> &'static ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc { - static ARGV_DESC: std::sync::OnceLock< - ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc, - > = std::sync::OnceLock::new(); - ARGV_DESC.get_or_init(|| { - <(String, String) as ::mudu_contract::tuple::tuple_datum::TupleDatum>::tuple_desc_static(&{ - let _vec: Vec = <[_]>::into_vec(std::boxed::Box::new(["user_id", "vote_id"])) - .iter() - .map(|s| s.to_string()) - .collect(); - _vec - }) - }) +pub fn mudu_argv_desc_create_user() -> &'static ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc { + static ARGV_DESC: std::sync::OnceLock<::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc> = + std::sync::OnceLock::new(); + ARGV_DESC.get_or_init(|| + { + ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc::new(vec![ + + ::mududb::contract::tuple::datum_desc::DatumDesc::new( + "phone".to_string(), + + ::dat_type().clone() + + ), + + ]) + } + ) } -pub fn mudu_result_desc_withdraw_vote() --> &'static ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc { - static RESULT_DESC: std::sync::OnceLock< - ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc, - > = std::sync::OnceLock::new(); - RESULT_DESC.get_or_init(|| { - <() as ::mudu_contract::tuple::tuple_datum::TupleDatum>::tuple_desc_static(&[]) - }) +pub fn mudu_result_desc_create_user() -> &'static ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc { + static RESULT_DESC: std::sync::OnceLock<::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc> = + std::sync::OnceLock::new(); + RESULT_DESC.get_or_init(|| + { + ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc::new(vec![ + + ::mududb::contract::tuple::datum_desc::DatumDesc::new( + "0".to_string(), + + ::dat_type().clone() + + ), + + ]) + } + ) } -pub fn mudu_proc_desc_withdraw_vote() -> &'static ::mudu_contract::procedure::proc_desc::ProcDesc { - static _PROC_DESC: std::sync::OnceLock<::mudu_contract::procedure::proc_desc::ProcDesc> = - std::sync::OnceLock::new(); - _PROC_DESC.get_or_init(|| { - ::mudu_contract::procedure::proc_desc::ProcDesc::new( - "vote".to_string(), - "withdraw_vote".to_string(), - mudu_argv_desc_withdraw_vote().clone(), - mudu_result_desc_withdraw_vote().clone(), - false, - ) - }) +pub fn mudu_proc_desc_create_user() -> &'static ::mududb::contract::procedure::proc_desc::ProcDesc { + static _PROC_DESC: std::sync::OnceLock< + ::mududb::contract::procedure::proc_desc::ProcDesc, + > = std::sync::OnceLock::new(); + _PROC_DESC + .get_or_init(|| { + ::mududb::contract::procedure::proc_desc::ProcDesc::new( + "vote".to_string(), + "create_user".to_string(), + mudu_argv_desc_create_user().clone(), + mudu_result_desc_create_user().clone(), + false + ) + }) } -mod mod_withdraw_vote { +mod mod_create_user { wit_bindgen::generate!({ inline: - r##"package mudu:mp2-withdraw-vote; - world mudu-app-mp2-withdraw-vote { - export mp2-withdraw-vote: func(param:list) -> list; + r##"package mudu:mp2-create-user; + world mudu-app-mp2-create-user { + export mp2-create-user: func(param:list) -> list; } "##, async: true @@ -971,13 +1286,13 @@ mod mod_withdraw_vote { #[allow(non_camel_case_types)] #[allow(unused)] - struct GuestWithdrawVote {} + struct GuestCreateUser {} - impl Guest for GuestWithdrawVote { - async fn mp2_withdraw_vote(param: Vec) -> Vec { - super::mp2_withdraw_vote(param).await + impl Guest for GuestCreateUser { + async fn mp2_create_user(param:Vec) -> Vec { + super::mp2_create_user(param).await } } - export!(GuestWithdrawVote); -} + export!(GuestCreateUser); +} \ No newline at end of file diff --git a/example/vote/src/generated/users.rs b/example/vote/src/generated/users.rs index 82e530a..49287c5 100644 --- a/example/vote/src/generated/users.rs +++ b/example/vote/src/generated/users.rs @@ -1,301 +1,326 @@ pub mod object { - use lazy_static::lazy_static; - use mudu::common::result::RS; - use mudu_contract::database::attr_field_access; - use mudu_contract::database::attr_value::AttrValue; - use mudu_contract::database::entity::Entity; - use mudu_contract::database::entity_utils; - use mudu_contract::database::sql_params::SQLParamMarker; - use mudu_contract::tuple::datum_desc::DatumDesc; - use mudu_contract::tuple::tuple_datum::TupleDatumMarker; - use mudu_contract::tuple::tuple_field_desc::TupleFieldDesc; - use mudu_type::dat_binary::DatBinary; - use mudu_type::dat_textual::DatTextual; - use mudu_type::dat_type::DatType; - use mudu_type::dat_type_id::DatTypeID; - use mudu_type::dat_value::DatValue; - use mudu_type::datum::{Datum, DatumDyn}; - - // constant definition - const USERS: &str = "users"; - - const USER_ID: &str = "user_id"; - - const PHONE: &str = "phone"; - - // entity struct definition - #[derive(Debug, Clone, Default)] - pub struct Users { - user_id: AttrUserId, - - phone: AttrPhone, - } - - impl TupleDatumMarker for Users {} - - impl SQLParamMarker for Users {} - - impl Users { - pub fn new(user_id: Option, phone: Option) -> Self { - let s = Self { - user_id: AttrUserId::from(user_id), - - phone: AttrPhone::from(phone), - }; - s - } - - pub fn new_empty() -> Self { - Self::default() - } - - pub fn set_user_id(&mut self, user_id: String) { - self.user_id.update(user_id) - } +use lazy_static::lazy_static; +use mududb::common::result::RS; +use mududb::contract::database::attr_field_access; +use mududb::contract::database::attr_value::AttrValue; +use mududb::contract::database::entity::Entity; +use mududb::contract::database::entity_utils; +use mududb::contract::database::sql_params::SQLParamMarker; +use mududb::contract::tuple::datum_desc::DatumDesc; +use mududb::contract::tuple::tuple_field_desc::TupleFieldDesc; +use mududb::contract::tuple::tuple_datum::TupleDatumMarker; +use mududb::types::dat_binary::DatBinary; +use mududb::types::dat_textual::DatTextual; +use mududb::types::dat_type::DatType; +use mududb::types::dat_type_id::DatTypeID; +use mududb::types::dat_value::DatValue; +use mududb::types::datum::{Datum, DatumDyn}; + +// constant definition +const USERS:&str = "users"; + +const USER_ID:&str = "user_id"; + +const PHONE:&str = "phone"; + + +// entity struct definition +#[derive(Debug, Clone, Default)] +pub struct Users { + + user_id: AttrUserId, + + phone: AttrPhone, + +} - pub fn get_user_id(&self) -> &Option { - self.user_id.get() - } +impl TupleDatumMarker for Users {} + +impl SQLParamMarker for Users {} + +impl Users { + pub fn new( + user_id: Option, + phone: Option, + + ) -> Self { + let s = Self { + + user_id : AttrUserId::from(user_id), + + phone : AttrPhone::from(phone), + + }; + s + } - pub fn set_phone(&mut self, phone: String) { - self.phone.update(phone) - } + pub fn new_empty() -> Self { + Self::default() + } - pub fn get_phone(&self) -> &Option { - self.phone.get() - } + + pub fn set_user_id( + &mut self, + user_id: String, + ) { + self.user_id.update(user_id) } - impl Datum for Users { - fn dat_type() -> &'static DatType { - lazy_static! { - static ref DAT_TYPE: DatType = entity_utils::entity_dat_type::(); - } - &DAT_TYPE - } + pub fn get_user_id( + &self, + ) -> &Option { + self.user_id.get() + } + + pub fn set_phone( + &mut self, + phone: String, + ) { + self.phone.update(phone) + } - fn from_binary(binary: &[u8]) -> RS { - entity_utils::entity_from_binary(binary) - } + pub fn get_phone( + &self, + ) -> &Option { + self.phone.get() + } + +} - fn from_value(value: &DatValue) -> RS { - entity_utils::entity_from_value(value) +impl Datum for Users { + fn dat_type() -> &'static DatType { + lazy_static! { + static ref DAT_TYPE: DatType = entity_utils::entity_dat_type::(); } + &DAT_TYPE + } - fn from_textual(textual: &str) -> RS { - entity_utils::entity_from_textual(textual) - } + fn from_binary(binary: &[u8]) -> RS { + entity_utils::entity_from_binary(binary) } - impl DatumDyn for Users { - fn dat_type_id(&self) -> RS { - entity_utils::entity_dat_type_id() - } + fn from_value(value: &DatValue) -> RS { + entity_utils::entity_from_value(value) + } - fn to_binary(&self, dat_type: &DatType) -> RS { - entity_utils::entity_to_binary(self, dat_type) - } + fn from_textual(textual: &str) -> RS { + entity_utils::entity_from_textual(textual) + } +} - fn to_textual(&self, dat_type: &DatType) -> RS { - entity_utils::entity_to_textual(self, dat_type) - } +impl DatumDyn for Users { + fn dat_type_id(&self) -> RS { + entity_utils::entity_dat_type_id() + } - fn to_value(&self, dat_type: &DatType) -> RS { - entity_utils::entity_to_value(self, dat_type) - } + fn to_binary(&self, dat_type: &DatType) -> RS { + entity_utils::entity_to_binary(self, dat_type) + } - fn clone_boxed(&self) -> Box { - entity_utils::entity_clone_boxed(self) - } + fn to_textual(&self, dat_type: &DatType) -> RS { + entity_utils::entity_to_textual(self, dat_type) } - impl Entity for Users { - fn new_empty() -> Self { - Self::new_empty() - } + fn to_value(&self, dat_type: &DatType) -> RS { + entity_utils::entity_to_value(self, dat_type) + } - fn tuple_desc() -> &'static TupleFieldDesc { - lazy_static! { - static ref TUPLE_DESC: TupleFieldDesc = TupleFieldDesc::new(vec![ - AttrUserId::datum_desc().clone(), - AttrPhone::datum_desc().clone(), - ]); - } - &TUPLE_DESC - } + fn clone_boxed(&self) -> Box { + entity_utils::entity_clone_boxed(self) + } +} - fn object_name() -> &'static str { - USERS - } +impl Entity for Users { + fn new_empty() -> Self { + Self::new_empty() + } - fn get_field_binary(&self, field: &str) -> RS>> { - match field { - USER_ID => attr_field_access::attr_get_binary::<_>(self.user_id.get()), + fn tuple_desc() -> &'static TupleFieldDesc { + lazy_static! { + static ref TUPLE_DESC: TupleFieldDesc = TupleFieldDesc::new(vec![ + + AttrUserId::datum_desc().clone(), + + AttrPhone::datum_desc().clone(), + + ]); + } + &TUPLE_DESC + } - PHONE => attr_field_access::attr_get_binary::<_>(self.phone.get()), + fn object_name() -> &'static str { + USERS + } - _ => { - panic!("unknown name"); - } + fn get_field_binary(&self, field: &str) -> RS>> { + match field { + + USER_ID => { + attr_field_access::attr_get_binary::<_>(self.user_id.get()) + } + + PHONE => { + attr_field_access::attr_get_binary::<_>(self.phone.get()) } + + _ => { panic!("unknown name"); } } + } - fn set_field_binary>(&mut self, field: &str, binary: B) -> RS<()> { - match field { - USER_ID => { - attr_field_access::attr_set_binary::<_, _>( - self.user_id.get_mut(), - binary.as_ref(), - )?; - } - - PHONE => { - attr_field_access::attr_set_binary::<_, _>( - self.phone.get_mut(), - binary.as_ref(), - )?; - } - - _ => { - panic!("unknown name"); - } + fn set_field_binary>(&mut self, field: &str, binary: B) -> RS<()> { + match field { + + USER_ID => { + attr_field_access::attr_set_binary::<_, _>(self.user_id.get_mut(), binary.as_ref())?; + } + + PHONE => { + attr_field_access::attr_set_binary::<_, _>(self.phone.get_mut(), binary.as_ref())?; } - Ok(()) + + _ => { panic!("unknown name"); } } + Ok(()) + } - fn get_field_value(&self, field: &str) -> RS> { - match field { - USER_ID => attr_field_access::attr_get_value::<_>(self.user_id.get()), - - PHONE => attr_field_access::attr_get_value::<_>(self.phone.get()), - - _ => { - panic!("unknown name"); - } + fn get_field_value(&self, field: &str) -> RS> { + match field { + + USER_ID => { + attr_field_access::attr_get_value::<_>(self.user_id.get()) } + + PHONE => { + attr_field_access::attr_get_value::<_>(self.phone.get()) + } + + _ => { panic!("unknown name"); } } + } - fn set_field_value>(&mut self, field: &str, value: B) -> RS<()> { - match field { - USER_ID => { - attr_field_access::attr_set_value::<_, _>(self.user_id.get_mut(), value)?; - } - - PHONE => { - attr_field_access::attr_set_value::<_, _>(self.phone.get_mut(), value)?; - } - - _ => { - panic!("unknown name"); - } + fn set_field_value>(&mut self, field: &str, value: B) -> RS<()> { + match field { + + USER_ID => { + attr_field_access::attr_set_value::<_, _>(self.user_id.get_mut(), value)?; + } + + PHONE => { + attr_field_access::attr_set_value::<_, _>(self.phone.get_mut(), value)?; } - Ok(()) + + _ => { panic!("unknown name"); } } + Ok(()) } +} - // attribute struct definition - #[derive(Default, Clone, Debug)] - pub struct AttrUserId { - is_dirty: bool, - value: Option, - } - impl AttrUserId { - fn from(value: Option) -> Self { - Self { - is_dirty: false, - value, - } - } +// attribute struct definition +#[derive(Default, Clone, Debug)] +pub struct AttrUserId { + is_dirty:bool, + value: Option +} - fn get(&self) -> &Option { - &self.value +impl AttrUserId { + fn from(value:Option) -> Self { + Self { + is_dirty: false, + value } + } - fn get_mut(&mut self) -> &mut Option { - &mut self.value - } + fn get(&self) -> &Option { + &self.value + } - fn set(&mut self, value: Option) { - self.value = value - } + fn get_mut(&mut self) -> &mut Option { + &mut self.value + } - fn update(&mut self, value: String) { - self.is_dirty = true; - self.value = Some(value) - } + fn set(&mut self, value:Option) { + self.value = value } - impl AttrValue for AttrUserId { - fn dat_type() -> &'static DatType { - static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); - ONCE_LOCK.get_or_init(|| Self::attr_dat_type()) - } + fn update(&mut self, value: String) { + self.is_dirty = true; + self.value = Some(value) + } +} - fn datum_desc() -> &'static DatumDesc { - static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); - ONCE_LOCK.get_or_init(|| Self::attr_datum_desc()) - } +impl AttrValue for AttrUserId { + fn dat_type() -> &'static DatType { + static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); + ONCE_LOCK.get_or_init(|| Self::attr_dat_type()) + } - fn object_name() -> &'static str { - USERS - } + fn datum_desc() -> &'static DatumDesc { + static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); + ONCE_LOCK.get_or_init(|| Self::attr_datum_desc()) + } - fn attr_name() -> &'static str { - USER_ID - } + fn object_name() -> &'static str { + USERS } - // attribute struct definition - #[derive(Default, Clone, Debug)] - pub struct AttrPhone { - is_dirty: bool, - value: Option, + fn attr_name() -> &'static str { + USER_ID } +} - impl AttrPhone { - fn from(value: Option) -> Self { - Self { - is_dirty: false, - value, - } - } +// attribute struct definition +#[derive(Default, Clone, Debug)] +pub struct AttrPhone { + is_dirty:bool, + value: Option +} - fn get(&self) -> &Option { - &self.value +impl AttrPhone { + fn from(value:Option) -> Self { + Self { + is_dirty: false, + value } + } - fn get_mut(&mut self) -> &mut Option { - &mut self.value - } + fn get(&self) -> &Option { + &self.value + } - fn set(&mut self, value: Option) { - self.value = value - } + fn get_mut(&mut self) -> &mut Option { + &mut self.value + } - fn update(&mut self, value: String) { - self.is_dirty = true; - self.value = Some(value) - } + fn set(&mut self, value:Option) { + self.value = value } - impl AttrValue for AttrPhone { - fn dat_type() -> &'static DatType { - static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); - ONCE_LOCK.get_or_init(|| Self::attr_dat_type()) - } + fn update(&mut self, value: String) { + self.is_dirty = true; + self.value = Some(value) + } +} - fn datum_desc() -> &'static DatumDesc { - static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); - ONCE_LOCK.get_or_init(|| Self::attr_datum_desc()) - } +impl AttrValue for AttrPhone { + fn dat_type() -> &'static DatType { + static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); + ONCE_LOCK.get_or_init(|| Self::attr_dat_type()) + } - fn object_name() -> &'static str { - USERS - } + fn datum_desc() -> &'static DatumDesc { + static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); + ONCE_LOCK.get_or_init(|| Self::attr_datum_desc()) + } - fn attr_name() -> &'static str { - PHONE - } + fn object_name() -> &'static str { + USERS + } + + fn attr_name() -> &'static str { + PHONE } } + + +} \ No newline at end of file diff --git a/example/vote/src/generated/vote_actions.rs b/example/vote/src/generated/vote_actions.rs index 835f0fd..f86b43b 100644 --- a/example/vote/src/generated/vote_actions.rs +++ b/example/vote/src/generated/vote_actions.rs @@ -1,556 +1,599 @@ pub mod object { - use lazy_static::lazy_static; - use mudu::common::result::RS; - use mudu_contract::database::attr_field_access; - use mudu_contract::database::attr_value::AttrValue; - use mudu_contract::database::entity::Entity; - use mudu_contract::database::entity_utils; - use mudu_contract::database::sql_params::SQLParamMarker; - use mudu_contract::tuple::datum_desc::DatumDesc; - use mudu_contract::tuple::tuple_datum::TupleDatumMarker; - use mudu_contract::tuple::tuple_field_desc::TupleFieldDesc; - use mudu_type::dat_binary::DatBinary; - use mudu_type::dat_textual::DatTextual; - use mudu_type::dat_type::DatType; - use mudu_type::dat_type_id::DatTypeID; - use mudu_type::dat_value::DatValue; - use mudu_type::datum::{Datum, DatumDyn}; - - // constant definition - const VOTE_ACTIONS: &str = "vote_actions"; - - const ACTION_ID: &str = "action_id"; - - const USER_ID: &str = "user_id"; - - const VOTE_ID: &str = "vote_id"; - - const ACTION_TIME: &str = "action_time"; - - const IS_WITHDRAWN: &str = "is_withdrawn"; - - // entity struct definition - #[derive(Debug, Clone, Default)] - pub struct VoteActions { - action_id: AttrActionId, - - user_id: AttrUserId, - - vote_id: AttrVoteId, +use lazy_static::lazy_static; +use mududb::common::result::RS; +use mududb::contract::database::attr_field_access; +use mududb::contract::database::attr_value::AttrValue; +use mududb::contract::database::entity::Entity; +use mududb::contract::database::entity_utils; +use mududb::contract::database::sql_params::SQLParamMarker; +use mududb::contract::tuple::datum_desc::DatumDesc; +use mududb::contract::tuple::tuple_field_desc::TupleFieldDesc; +use mududb::contract::tuple::tuple_datum::TupleDatumMarker; +use mududb::types::dat_binary::DatBinary; +use mududb::types::dat_textual::DatTextual; +use mududb::types::dat_type::DatType; +use mududb::types::dat_type_id::DatTypeID; +use mududb::types::dat_value::DatValue; +use mududb::types::datum::{Datum, DatumDyn}; + +// constant definition +const VOTE_ACTIONS:&str = "vote_actions"; + +const ACTION_ID:&str = "action_id"; + +const USER_ID:&str = "user_id"; + +const VOTE_ID:&str = "vote_id"; + +const ACTION_TIME:&str = "action_time"; + +const IS_WITHDRAWN:&str = "is_withdrawn"; + + +// entity struct definition +#[derive(Debug, Clone, Default)] +pub struct VoteActions { + + action_id: AttrActionId, + + user_id: AttrUserId, + + vote_id: AttrVoteId, + + action_time: AttrActionTime, + + is_withdrawn: AttrIsWithdrawn, + +} - action_time: AttrActionTime, +impl TupleDatumMarker for VoteActions {} + +impl SQLParamMarker for VoteActions {} + +impl VoteActions { + pub fn new( + action_id: Option, + user_id: Option, + vote_id: Option, + action_time: Option, + is_withdrawn: Option, + + ) -> Self { + let s = Self { + + action_id : AttrActionId::from(action_id), + + user_id : AttrUserId::from(user_id), + + vote_id : AttrVoteId::from(vote_id), + + action_time : AttrActionTime::from(action_time), + + is_withdrawn : AttrIsWithdrawn::from(is_withdrawn), + + }; + s + } - is_withdrawn: AttrIsWithdrawn, + pub fn new_empty() -> Self { + Self::default() } - impl TupleDatumMarker for VoteActions {} + + pub fn set_action_id( + &mut self, + action_id: String, + ) { + self.action_id.update(action_id) + } - impl SQLParamMarker for VoteActions {} + pub fn get_action_id( + &self, + ) -> &Option { + self.action_id.get() + } + + pub fn set_user_id( + &mut self, + user_id: String, + ) { + self.user_id.update(user_id) + } - impl VoteActions { - pub fn new( - action_id: Option, - user_id: Option, - vote_id: Option, - action_time: Option, - is_withdrawn: Option, - ) -> Self { - let s = Self { - action_id: AttrActionId::from(action_id), + pub fn get_user_id( + &self, + ) -> &Option { + self.user_id.get() + } + + pub fn set_vote_id( + &mut self, + vote_id: String, + ) { + self.vote_id.update(vote_id) + } - user_id: AttrUserId::from(user_id), + pub fn get_vote_id( + &self, + ) -> &Option { + self.vote_id.get() + } + + pub fn set_action_time( + &mut self, + action_time: i32, + ) { + self.action_time.update(action_time) + } - vote_id: AttrVoteId::from(vote_id), + pub fn get_action_time( + &self, + ) -> &Option { + self.action_time.get() + } + + pub fn set_is_withdrawn( + &mut self, + is_withdrawn: i32, + ) { + self.is_withdrawn.update(is_withdrawn) + } - action_time: AttrActionTime::from(action_time), + pub fn get_is_withdrawn( + &self, + ) -> &Option { + self.is_withdrawn.get() + } + +} - is_withdrawn: AttrIsWithdrawn::from(is_withdrawn), - }; - s +impl Datum for VoteActions { + fn dat_type() -> &'static DatType { + lazy_static! { + static ref DAT_TYPE: DatType = entity_utils::entity_dat_type::(); } + &DAT_TYPE + } - pub fn new_empty() -> Self { - Self::default() - } + fn from_binary(binary: &[u8]) -> RS { + entity_utils::entity_from_binary(binary) + } - pub fn set_action_id(&mut self, action_id: String) { - self.action_id.update(action_id) - } + fn from_value(value: &DatValue) -> RS { + entity_utils::entity_from_value(value) + } - pub fn get_action_id(&self) -> &Option { - self.action_id.get() - } + fn from_textual(textual: &str) -> RS { + entity_utils::entity_from_textual(textual) + } +} - pub fn set_user_id(&mut self, user_id: String) { - self.user_id.update(user_id) - } +impl DatumDyn for VoteActions { + fn dat_type_id(&self) -> RS { + entity_utils::entity_dat_type_id() + } - pub fn get_user_id(&self) -> &Option { - self.user_id.get() - } + fn to_binary(&self, dat_type: &DatType) -> RS { + entity_utils::entity_to_binary(self, dat_type) + } - pub fn set_vote_id(&mut self, vote_id: String) { - self.vote_id.update(vote_id) - } + fn to_textual(&self, dat_type: &DatType) -> RS { + entity_utils::entity_to_textual(self, dat_type) + } - pub fn get_vote_id(&self) -> &Option { - self.vote_id.get() - } + fn to_value(&self, dat_type: &DatType) -> RS { + entity_utils::entity_to_value(self, dat_type) + } - pub fn set_action_time(&mut self, action_time: i32) { - self.action_time.update(action_time) - } + fn clone_boxed(&self) -> Box { + entity_utils::entity_clone_boxed(self) + } +} - pub fn get_action_time(&self) -> &Option { - self.action_time.get() - } +impl Entity for VoteActions { + fn new_empty() -> Self { + Self::new_empty() + } - pub fn set_is_withdrawn(&mut self, is_withdrawn: i32) { - self.is_withdrawn.update(is_withdrawn) - } + fn tuple_desc() -> &'static TupleFieldDesc { + lazy_static! { + static ref TUPLE_DESC: TupleFieldDesc = TupleFieldDesc::new(vec![ + + AttrActionId::datum_desc().clone(), + + AttrUserId::datum_desc().clone(), + + AttrVoteId::datum_desc().clone(), + + AttrActionTime::datum_desc().clone(), + + AttrIsWithdrawn::datum_desc().clone(), + + ]); + } + &TUPLE_DESC + } - pub fn get_is_withdrawn(&self) -> &Option { - self.is_withdrawn.get() - } + fn object_name() -> &'static str { + VOTE_ACTIONS } - impl Datum for VoteActions { - fn dat_type() -> &'static DatType { - lazy_static! { - static ref DAT_TYPE: DatType = entity_utils::entity_dat_type::(); + fn get_field_binary(&self, field: &str) -> RS>> { + match field { + + ACTION_ID => { + attr_field_access::attr_get_binary::<_>(self.action_id.get()) } - &DAT_TYPE - } - - fn from_binary(binary: &[u8]) -> RS { - entity_utils::entity_from_binary(binary) - } - - fn from_value(value: &DatValue) -> RS { - entity_utils::entity_from_value(value) - } - - fn from_textual(textual: &str) -> RS { - entity_utils::entity_from_textual(textual) + + USER_ID => { + attr_field_access::attr_get_binary::<_>(self.user_id.get()) + } + + VOTE_ID => { + attr_field_access::attr_get_binary::<_>(self.vote_id.get()) + } + + ACTION_TIME => { + attr_field_access::attr_get_binary::<_>(self.action_time.get()) + } + + IS_WITHDRAWN => { + attr_field_access::attr_get_binary::<_>(self.is_withdrawn.get()) + } + + _ => { panic!("unknown name"); } } } - impl DatumDyn for VoteActions { - fn dat_type_id(&self) -> RS { - entity_utils::entity_dat_type_id() - } - - fn to_binary(&self, dat_type: &DatType) -> RS { - entity_utils::entity_to_binary(self, dat_type) - } - - fn to_textual(&self, dat_type: &DatType) -> RS { - entity_utils::entity_to_textual(self, dat_type) - } - - fn to_value(&self, dat_type: &DatType) -> RS { - entity_utils::entity_to_value(self, dat_type) - } - - fn clone_boxed(&self) -> Box { - entity_utils::entity_clone_boxed(self) + fn set_field_binary>(&mut self, field: &str, binary: B) -> RS<()> { + match field { + + ACTION_ID => { + attr_field_access::attr_set_binary::<_, _>(self.action_id.get_mut(), binary.as_ref())?; + } + + USER_ID => { + attr_field_access::attr_set_binary::<_, _>(self.user_id.get_mut(), binary.as_ref())?; + } + + VOTE_ID => { + attr_field_access::attr_set_binary::<_, _>(self.vote_id.get_mut(), binary.as_ref())?; + } + + ACTION_TIME => { + attr_field_access::attr_set_binary::<_, _>(self.action_time.get_mut(), binary.as_ref())?; + } + + IS_WITHDRAWN => { + attr_field_access::attr_set_binary::<_, _>(self.is_withdrawn.get_mut(), binary.as_ref())?; + } + + _ => { panic!("unknown name"); } } + Ok(()) } - impl Entity for VoteActions { - fn new_empty() -> Self { - Self::new_empty() - } - - fn tuple_desc() -> &'static TupleFieldDesc { - lazy_static! { - static ref TUPLE_DESC: TupleFieldDesc = TupleFieldDesc::new(vec![ - AttrActionId::datum_desc().clone(), - AttrUserId::datum_desc().clone(), - AttrVoteId::datum_desc().clone(), - AttrActionTime::datum_desc().clone(), - AttrIsWithdrawn::datum_desc().clone(), - ]); + fn get_field_value(&self, field: &str) -> RS> { + match field { + + ACTION_ID => { + attr_field_access::attr_get_value::<_>(self.action_id.get()) } - &TUPLE_DESC - } - - fn object_name() -> &'static str { - VOTE_ACTIONS - } - - fn get_field_binary(&self, field: &str) -> RS>> { - match field { - ACTION_ID => attr_field_access::attr_get_binary::<_>(self.action_id.get()), - - USER_ID => attr_field_access::attr_get_binary::<_>(self.user_id.get()), - - VOTE_ID => attr_field_access::attr_get_binary::<_>(self.vote_id.get()), - - ACTION_TIME => attr_field_access::attr_get_binary::<_>(self.action_time.get()), - - IS_WITHDRAWN => attr_field_access::attr_get_binary::<_>(self.is_withdrawn.get()), - - _ => { - panic!("unknown name"); - } + + USER_ID => { + attr_field_access::attr_get_value::<_>(self.user_id.get()) } - } - - fn set_field_binary>(&mut self, field: &str, binary: B) -> RS<()> { - match field { - ACTION_ID => { - attr_field_access::attr_set_binary::<_, _>( - self.action_id.get_mut(), - binary.as_ref(), - )?; - } - - USER_ID => { - attr_field_access::attr_set_binary::<_, _>( - self.user_id.get_mut(), - binary.as_ref(), - )?; - } - - VOTE_ID => { - attr_field_access::attr_set_binary::<_, _>( - self.vote_id.get_mut(), - binary.as_ref(), - )?; - } - - ACTION_TIME => { - attr_field_access::attr_set_binary::<_, _>( - self.action_time.get_mut(), - binary.as_ref(), - )?; - } - - IS_WITHDRAWN => { - attr_field_access::attr_set_binary::<_, _>( - self.is_withdrawn.get_mut(), - binary.as_ref(), - )?; - } - - _ => { - panic!("unknown name"); - } + + VOTE_ID => { + attr_field_access::attr_get_value::<_>(self.vote_id.get()) } - Ok(()) + + ACTION_TIME => { + attr_field_access::attr_get_value::<_>(self.action_time.get()) + } + + IS_WITHDRAWN => { + attr_field_access::attr_get_value::<_>(self.is_withdrawn.get()) + } + + _ => { panic!("unknown name"); } } + } - fn get_field_value(&self, field: &str) -> RS> { - match field { - ACTION_ID => attr_field_access::attr_get_value::<_>(self.action_id.get()), - - USER_ID => attr_field_access::attr_get_value::<_>(self.user_id.get()), - - VOTE_ID => attr_field_access::attr_get_value::<_>(self.vote_id.get()), - - ACTION_TIME => attr_field_access::attr_get_value::<_>(self.action_time.get()), - - IS_WITHDRAWN => attr_field_access::attr_get_value::<_>(self.is_withdrawn.get()), - - _ => { - panic!("unknown name"); - } + fn set_field_value>(&mut self, field: &str, value: B) -> RS<()> { + match field { + + ACTION_ID => { + attr_field_access::attr_set_value::<_, _>(self.action_id.get_mut(), value)?; + } + + USER_ID => { + attr_field_access::attr_set_value::<_, _>(self.user_id.get_mut(), value)?; } + + VOTE_ID => { + attr_field_access::attr_set_value::<_, _>(self.vote_id.get_mut(), value)?; + } + + ACTION_TIME => { + attr_field_access::attr_set_value::<_, _>(self.action_time.get_mut(), value)?; + } + + IS_WITHDRAWN => { + attr_field_access::attr_set_value::<_, _>(self.is_withdrawn.get_mut(), value)?; + } + + _ => { panic!("unknown name"); } } + Ok(()) + } +} - fn set_field_value>(&mut self, field: &str, value: B) -> RS<()> { - match field { - ACTION_ID => { - attr_field_access::attr_set_value::<_, _>(self.action_id.get_mut(), value)?; - } - - USER_ID => { - attr_field_access::attr_set_value::<_, _>(self.user_id.get_mut(), value)?; - } - - VOTE_ID => { - attr_field_access::attr_set_value::<_, _>(self.vote_id.get_mut(), value)?; - } - - ACTION_TIME => { - attr_field_access::attr_set_value::<_, _>(self.action_time.get_mut(), value)?; - } - IS_WITHDRAWN => { - attr_field_access::attr_set_value::<_, _>(self.is_withdrawn.get_mut(), value)?; - } +// attribute struct definition +#[derive(Default, Clone, Debug)] +pub struct AttrActionId { + is_dirty:bool, + value: Option +} - _ => { - panic!("unknown name"); - } - } - Ok(()) +impl AttrActionId { + fn from(value:Option) -> Self { + Self { + is_dirty: false, + value } } - // attribute struct definition - #[derive(Default, Clone, Debug)] - pub struct AttrActionId { - is_dirty: bool, - value: Option, + fn get(&self) -> &Option { + &self.value } - impl AttrActionId { - fn from(value: Option) -> Self { - Self { - is_dirty: false, - value, - } - } + fn get_mut(&mut self) -> &mut Option { + &mut self.value + } - fn get(&self) -> &Option { - &self.value - } + fn set(&mut self, value:Option) { + self.value = value + } - fn get_mut(&mut self) -> &mut Option { - &mut self.value - } + fn update(&mut self, value: String) { + self.is_dirty = true; + self.value = Some(value) + } +} - fn set(&mut self, value: Option) { - self.value = value - } +impl AttrValue for AttrActionId { + fn dat_type() -> &'static DatType { + static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); + ONCE_LOCK.get_or_init(|| Self::attr_dat_type()) + } - fn update(&mut self, value: String) { - self.is_dirty = true; - self.value = Some(value) - } + fn datum_desc() -> &'static DatumDesc { + static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); + ONCE_LOCK.get_or_init(|| Self::attr_datum_desc()) } - impl AttrValue for AttrActionId { - fn dat_type() -> &'static DatType { - static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); - ONCE_LOCK.get_or_init(|| Self::attr_dat_type()) - } + fn object_name() -> &'static str { + VOTE_ACTIONS + } - fn datum_desc() -> &'static DatumDesc { - static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); - ONCE_LOCK.get_or_init(|| Self::attr_datum_desc()) - } + fn attr_name() -> &'static str { + ACTION_ID + } +} - fn object_name() -> &'static str { - VOTE_ACTIONS - } +// attribute struct definition +#[derive(Default, Clone, Debug)] +pub struct AttrUserId { + is_dirty:bool, + value: Option +} - fn attr_name() -> &'static str { - ACTION_ID +impl AttrUserId { + fn from(value:Option) -> Self { + Self { + is_dirty: false, + value } } - // attribute struct definition - #[derive(Default, Clone, Debug)] - pub struct AttrUserId { - is_dirty: bool, - value: Option, + fn get(&self) -> &Option { + &self.value } - impl AttrUserId { - fn from(value: Option) -> Self { - Self { - is_dirty: false, - value, - } - } + fn get_mut(&mut self) -> &mut Option { + &mut self.value + } - fn get(&self) -> &Option { - &self.value - } + fn set(&mut self, value:Option) { + self.value = value + } - fn get_mut(&mut self) -> &mut Option { - &mut self.value - } + fn update(&mut self, value: String) { + self.is_dirty = true; + self.value = Some(value) + } +} - fn set(&mut self, value: Option) { - self.value = value - } +impl AttrValue for AttrUserId { + fn dat_type() -> &'static DatType { + static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); + ONCE_LOCK.get_or_init(|| Self::attr_dat_type()) + } - fn update(&mut self, value: String) { - self.is_dirty = true; - self.value = Some(value) - } + fn datum_desc() -> &'static DatumDesc { + static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); + ONCE_LOCK.get_or_init(|| Self::attr_datum_desc()) } - impl AttrValue for AttrUserId { - fn dat_type() -> &'static DatType { - static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); - ONCE_LOCK.get_or_init(|| Self::attr_dat_type()) - } + fn object_name() -> &'static str { + VOTE_ACTIONS + } - fn datum_desc() -> &'static DatumDesc { - static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); - ONCE_LOCK.get_or_init(|| Self::attr_datum_desc()) - } + fn attr_name() -> &'static str { + USER_ID + } +} - fn object_name() -> &'static str { - VOTE_ACTIONS - } +// attribute struct definition +#[derive(Default, Clone, Debug)] +pub struct AttrVoteId { + is_dirty:bool, + value: Option +} - fn attr_name() -> &'static str { - USER_ID +impl AttrVoteId { + fn from(value:Option) -> Self { + Self { + is_dirty: false, + value } } - // attribute struct definition - #[derive(Default, Clone, Debug)] - pub struct AttrVoteId { - is_dirty: bool, - value: Option, + fn get(&self) -> &Option { + &self.value } - impl AttrVoteId { - fn from(value: Option) -> Self { - Self { - is_dirty: false, - value, - } - } + fn get_mut(&mut self) -> &mut Option { + &mut self.value + } - fn get(&self) -> &Option { - &self.value - } + fn set(&mut self, value:Option) { + self.value = value + } - fn get_mut(&mut self) -> &mut Option { - &mut self.value - } + fn update(&mut self, value: String) { + self.is_dirty = true; + self.value = Some(value) + } +} - fn set(&mut self, value: Option) { - self.value = value - } +impl AttrValue for AttrVoteId { + fn dat_type() -> &'static DatType { + static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); + ONCE_LOCK.get_or_init(|| Self::attr_dat_type()) + } - fn update(&mut self, value: String) { - self.is_dirty = true; - self.value = Some(value) - } + fn datum_desc() -> &'static DatumDesc { + static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); + ONCE_LOCK.get_or_init(|| Self::attr_datum_desc()) } - impl AttrValue for AttrVoteId { - fn dat_type() -> &'static DatType { - static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); - ONCE_LOCK.get_or_init(|| Self::attr_dat_type()) - } + fn object_name() -> &'static str { + VOTE_ACTIONS + } - fn datum_desc() -> &'static DatumDesc { - static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); - ONCE_LOCK.get_or_init(|| Self::attr_datum_desc()) - } + fn attr_name() -> &'static str { + VOTE_ID + } +} - fn object_name() -> &'static str { - VOTE_ACTIONS - } +// attribute struct definition +#[derive(Default, Clone, Debug)] +pub struct AttrActionTime { + is_dirty:bool, + value: Option +} - fn attr_name() -> &'static str { - VOTE_ID +impl AttrActionTime { + fn from(value:Option) -> Self { + Self { + is_dirty: false, + value } } - // attribute struct definition - #[derive(Default, Clone, Debug)] - pub struct AttrActionTime { - is_dirty: bool, - value: Option, + fn get(&self) -> &Option { + &self.value } - impl AttrActionTime { - fn from(value: Option) -> Self { - Self { - is_dirty: false, - value, - } - } + fn get_mut(&mut self) -> &mut Option { + &mut self.value + } - fn get(&self) -> &Option { - &self.value - } + fn set(&mut self, value:Option) { + self.value = value + } - fn get_mut(&mut self) -> &mut Option { - &mut self.value - } + fn update(&mut self, value: i32) { + self.is_dirty = true; + self.value = Some(value) + } +} - fn set(&mut self, value: Option) { - self.value = value - } +impl AttrValue for AttrActionTime { + fn dat_type() -> &'static DatType { + static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); + ONCE_LOCK.get_or_init(|| Self::attr_dat_type()) + } - fn update(&mut self, value: i32) { - self.is_dirty = true; - self.value = Some(value) - } + fn datum_desc() -> &'static DatumDesc { + static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); + ONCE_LOCK.get_or_init(|| Self::attr_datum_desc()) } - impl AttrValue for AttrActionTime { - fn dat_type() -> &'static DatType { - static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); - ONCE_LOCK.get_or_init(|| Self::attr_dat_type()) - } + fn object_name() -> &'static str { + VOTE_ACTIONS + } - fn datum_desc() -> &'static DatumDesc { - static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); - ONCE_LOCK.get_or_init(|| Self::attr_datum_desc()) - } + fn attr_name() -> &'static str { + ACTION_TIME + } +} - fn object_name() -> &'static str { - VOTE_ACTIONS - } +// attribute struct definition +#[derive(Default, Clone, Debug)] +pub struct AttrIsWithdrawn { + is_dirty:bool, + value: Option +} - fn attr_name() -> &'static str { - ACTION_TIME +impl AttrIsWithdrawn { + fn from(value:Option) -> Self { + Self { + is_dirty: false, + value } } - // attribute struct definition - #[derive(Default, Clone, Debug)] - pub struct AttrIsWithdrawn { - is_dirty: bool, - value: Option, + fn get(&self) -> &Option { + &self.value } - impl AttrIsWithdrawn { - fn from(value: Option) -> Self { - Self { - is_dirty: false, - value, - } - } - - fn get(&self) -> &Option { - &self.value - } - - fn get_mut(&mut self) -> &mut Option { - &mut self.value - } + fn get_mut(&mut self) -> &mut Option { + &mut self.value + } - fn set(&mut self, value: Option) { - self.value = value - } + fn set(&mut self, value:Option) { + self.value = value + } - fn update(&mut self, value: i32) { - self.is_dirty = true; - self.value = Some(value) - } + fn update(&mut self, value: i32) { + self.is_dirty = true; + self.value = Some(value) } +} - impl AttrValue for AttrIsWithdrawn { - fn dat_type() -> &'static DatType { - static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); - ONCE_LOCK.get_or_init(|| Self::attr_dat_type()) - } +impl AttrValue for AttrIsWithdrawn { + fn dat_type() -> &'static DatType { + static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); + ONCE_LOCK.get_or_init(|| Self::attr_dat_type()) + } - fn datum_desc() -> &'static DatumDesc { - static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); - ONCE_LOCK.get_or_init(|| Self::attr_datum_desc()) - } + fn datum_desc() -> &'static DatumDesc { + static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); + ONCE_LOCK.get_or_init(|| Self::attr_datum_desc()) + } - fn object_name() -> &'static str { - VOTE_ACTIONS - } + fn object_name() -> &'static str { + VOTE_ACTIONS + } - fn attr_name() -> &'static str { - IS_WITHDRAWN - } + fn attr_name() -> &'static str { + IS_WITHDRAWN } } + + +} \ No newline at end of file diff --git a/example/vote/src/generated/vote_choices.rs b/example/vote/src/generated/vote_choices.rs index fc73a77..e359755 100644 --- a/example/vote/src/generated/vote_choices.rs +++ b/example/vote/src/generated/vote_choices.rs @@ -1,388 +1,417 @@ pub mod object { - use lazy_static::lazy_static; - use mudu::common::result::RS; - use mudu_contract::database::attr_field_access; - use mudu_contract::database::attr_value::AttrValue; - use mudu_contract::database::entity::Entity; - use mudu_contract::database::entity_utils; - use mudu_contract::database::sql_params::SQLParamMarker; - use mudu_contract::tuple::datum_desc::DatumDesc; - use mudu_contract::tuple::tuple_datum::TupleDatumMarker; - use mudu_contract::tuple::tuple_field_desc::TupleFieldDesc; - use mudu_type::dat_binary::DatBinary; - use mudu_type::dat_textual::DatTextual; - use mudu_type::dat_type::DatType; - use mudu_type::dat_type_id::DatTypeID; - use mudu_type::dat_value::DatValue; - use mudu_type::datum::{Datum, DatumDyn}; - - // constant definition - const VOTE_CHOICES: &str = "vote_choices"; - - const CHOICE_ID: &str = "choice_id"; - - const ACTION_ID: &str = "action_id"; - - const OPTION_ID: &str = "option_id"; - - // entity struct definition - #[derive(Debug, Clone, Default)] - pub struct VoteChoices { - choice_id: AttrChoiceId, - - action_id: AttrActionId, +use lazy_static::lazy_static; +use mududb::common::result::RS; +use mududb::contract::database::attr_field_access; +use mududb::contract::database::attr_value::AttrValue; +use mududb::contract::database::entity::Entity; +use mududb::contract::database::entity_utils; +use mududb::contract::database::sql_params::SQLParamMarker; +use mududb::contract::tuple::datum_desc::DatumDesc; +use mududb::contract::tuple::tuple_field_desc::TupleFieldDesc; +use mududb::contract::tuple::tuple_datum::TupleDatumMarker; +use mududb::types::dat_binary::DatBinary; +use mududb::types::dat_textual::DatTextual; +use mududb::types::dat_type::DatType; +use mududb::types::dat_type_id::DatTypeID; +use mududb::types::dat_value::DatValue; +use mududb::types::datum::{Datum, DatumDyn}; + +// constant definition +const VOTE_CHOICES:&str = "vote_choices"; + +const CHOICE_ID:&str = "choice_id"; + +const ACTION_ID:&str = "action_id"; + +const OPTION_ID:&str = "option_id"; + + +// entity struct definition +#[derive(Debug, Clone, Default)] +pub struct VoteChoices { + + choice_id: AttrChoiceId, + + action_id: AttrActionId, + + option_id: AttrOptionId, + +} - option_id: AttrOptionId, +impl TupleDatumMarker for VoteChoices {} + +impl SQLParamMarker for VoteChoices {} + +impl VoteChoices { + pub fn new( + choice_id: Option, + action_id: Option, + option_id: Option, + + ) -> Self { + let s = Self { + + choice_id : AttrChoiceId::from(choice_id), + + action_id : AttrActionId::from(action_id), + + option_id : AttrOptionId::from(option_id), + + }; + s } - impl TupleDatumMarker for VoteChoices {} - - impl SQLParamMarker for VoteChoices {} - - impl VoteChoices { - pub fn new( - choice_id: Option, - action_id: Option, - option_id: Option, - ) -> Self { - let s = Self { - choice_id: AttrChoiceId::from(choice_id), - - action_id: AttrActionId::from(action_id), - - option_id: AttrOptionId::from(option_id), - }; - s - } - - pub fn new_empty() -> Self { - Self::default() - } + pub fn new_empty() -> Self { + Self::default() + } - pub fn set_choice_id(&mut self, choice_id: String) { - self.choice_id.update(choice_id) - } + + pub fn set_choice_id( + &mut self, + choice_id: String, + ) { + self.choice_id.update(choice_id) + } - pub fn get_choice_id(&self) -> &Option { - self.choice_id.get() - } + pub fn get_choice_id( + &self, + ) -> &Option { + self.choice_id.get() + } + + pub fn set_action_id( + &mut self, + action_id: String, + ) { + self.action_id.update(action_id) + } - pub fn set_action_id(&mut self, action_id: String) { - self.action_id.update(action_id) - } + pub fn get_action_id( + &self, + ) -> &Option { + self.action_id.get() + } + + pub fn set_option_id( + &mut self, + option_id: String, + ) { + self.option_id.update(option_id) + } - pub fn get_action_id(&self) -> &Option { - self.action_id.get() - } + pub fn get_option_id( + &self, + ) -> &Option { + self.option_id.get() + } + +} - pub fn set_option_id(&mut self, option_id: String) { - self.option_id.update(option_id) +impl Datum for VoteChoices { + fn dat_type() -> &'static DatType { + lazy_static! { + static ref DAT_TYPE: DatType = entity_utils::entity_dat_type::(); } + &DAT_TYPE + } - pub fn get_option_id(&self) -> &Option { - self.option_id.get() - } + fn from_binary(binary: &[u8]) -> RS { + entity_utils::entity_from_binary(binary) } - impl Datum for VoteChoices { - fn dat_type() -> &'static DatType { - lazy_static! { - static ref DAT_TYPE: DatType = entity_utils::entity_dat_type::(); - } - &DAT_TYPE - } + fn from_value(value: &DatValue) -> RS { + entity_utils::entity_from_value(value) + } - fn from_binary(binary: &[u8]) -> RS { - entity_utils::entity_from_binary(binary) - } + fn from_textual(textual: &str) -> RS { + entity_utils::entity_from_textual(textual) + } +} - fn from_value(value: &DatValue) -> RS { - entity_utils::entity_from_value(value) - } +impl DatumDyn for VoteChoices { + fn dat_type_id(&self) -> RS { + entity_utils::entity_dat_type_id() + } - fn from_textual(textual: &str) -> RS { - entity_utils::entity_from_textual(textual) - } + fn to_binary(&self, dat_type: &DatType) -> RS { + entity_utils::entity_to_binary(self, dat_type) } - impl DatumDyn for VoteChoices { - fn dat_type_id(&self) -> RS { - entity_utils::entity_dat_type_id() - } + fn to_textual(&self, dat_type: &DatType) -> RS { + entity_utils::entity_to_textual(self, dat_type) + } - fn to_binary(&self, dat_type: &DatType) -> RS { - entity_utils::entity_to_binary(self, dat_type) - } + fn to_value(&self, dat_type: &DatType) -> RS { + entity_utils::entity_to_value(self, dat_type) + } - fn to_textual(&self, dat_type: &DatType) -> RS { - entity_utils::entity_to_textual(self, dat_type) - } + fn clone_boxed(&self) -> Box { + entity_utils::entity_clone_boxed(self) + } +} - fn to_value(&self, dat_type: &DatType) -> RS { - entity_utils::entity_to_value(self, dat_type) - } +impl Entity for VoteChoices { + fn new_empty() -> Self { + Self::new_empty() + } - fn clone_boxed(&self) -> Box { - entity_utils::entity_clone_boxed(self) - } + fn tuple_desc() -> &'static TupleFieldDesc { + lazy_static! { + static ref TUPLE_DESC: TupleFieldDesc = TupleFieldDesc::new(vec![ + + AttrChoiceId::datum_desc().clone(), + + AttrActionId::datum_desc().clone(), + + AttrOptionId::datum_desc().clone(), + + ]); + } + &TUPLE_DESC } - impl Entity for VoteChoices { - fn new_empty() -> Self { - Self::new_empty() - } + fn object_name() -> &'static str { + VOTE_CHOICES + } - fn tuple_desc() -> &'static TupleFieldDesc { - lazy_static! { - static ref TUPLE_DESC: TupleFieldDesc = TupleFieldDesc::new(vec![ - AttrChoiceId::datum_desc().clone(), - AttrActionId::datum_desc().clone(), - AttrOptionId::datum_desc().clone(), - ]); + fn get_field_binary(&self, field: &str) -> RS>> { + match field { + + CHOICE_ID => { + attr_field_access::attr_get_binary::<_>(self.choice_id.get()) } - &TUPLE_DESC - } - - fn object_name() -> &'static str { - VOTE_CHOICES + + ACTION_ID => { + attr_field_access::attr_get_binary::<_>(self.action_id.get()) + } + + OPTION_ID => { + attr_field_access::attr_get_binary::<_>(self.option_id.get()) + } + + _ => { panic!("unknown name"); } } + } - fn get_field_binary(&self, field: &str) -> RS>> { - match field { - CHOICE_ID => attr_field_access::attr_get_binary::<_>(self.choice_id.get()), - - ACTION_ID => attr_field_access::attr_get_binary::<_>(self.action_id.get()), - - OPTION_ID => attr_field_access::attr_get_binary::<_>(self.option_id.get()), - - _ => { - panic!("unknown name"); - } + fn set_field_binary>(&mut self, field: &str, binary: B) -> RS<()> { + match field { + + CHOICE_ID => { + attr_field_access::attr_set_binary::<_, _>(self.choice_id.get_mut(), binary.as_ref())?; } + + ACTION_ID => { + attr_field_access::attr_set_binary::<_, _>(self.action_id.get_mut(), binary.as_ref())?; + } + + OPTION_ID => { + attr_field_access::attr_set_binary::<_, _>(self.option_id.get_mut(), binary.as_ref())?; + } + + _ => { panic!("unknown name"); } } + Ok(()) + } - fn set_field_binary>(&mut self, field: &str, binary: B) -> RS<()> { - match field { - CHOICE_ID => { - attr_field_access::attr_set_binary::<_, _>( - self.choice_id.get_mut(), - binary.as_ref(), - )?; - } - - ACTION_ID => { - attr_field_access::attr_set_binary::<_, _>( - self.action_id.get_mut(), - binary.as_ref(), - )?; - } - - OPTION_ID => { - attr_field_access::attr_set_binary::<_, _>( - self.option_id.get_mut(), - binary.as_ref(), - )?; - } - - _ => { - panic!("unknown name"); - } + fn get_field_value(&self, field: &str) -> RS> { + match field { + + CHOICE_ID => { + attr_field_access::attr_get_value::<_>(self.choice_id.get()) + } + + ACTION_ID => { + attr_field_access::attr_get_value::<_>(self.action_id.get()) } - Ok(()) + + OPTION_ID => { + attr_field_access::attr_get_value::<_>(self.option_id.get()) + } + + _ => { panic!("unknown name"); } } + } - fn get_field_value(&self, field: &str) -> RS> { - match field { - CHOICE_ID => attr_field_access::attr_get_value::<_>(self.choice_id.get()), - - ACTION_ID => attr_field_access::attr_get_value::<_>(self.action_id.get()), - - OPTION_ID => attr_field_access::attr_get_value::<_>(self.option_id.get()), - - _ => { - panic!("unknown name"); - } + fn set_field_value>(&mut self, field: &str, value: B) -> RS<()> { + match field { + + CHOICE_ID => { + attr_field_access::attr_set_value::<_, _>(self.choice_id.get_mut(), value)?; + } + + ACTION_ID => { + attr_field_access::attr_set_value::<_, _>(self.action_id.get_mut(), value)?; } + + OPTION_ID => { + attr_field_access::attr_set_value::<_, _>(self.option_id.get_mut(), value)?; + } + + _ => { panic!("unknown name"); } } + Ok(()) + } +} - fn set_field_value>(&mut self, field: &str, value: B) -> RS<()> { - match field { - CHOICE_ID => { - attr_field_access::attr_set_value::<_, _>(self.choice_id.get_mut(), value)?; - } - - ACTION_ID => { - attr_field_access::attr_set_value::<_, _>(self.action_id.get_mut(), value)?; - } - OPTION_ID => { - attr_field_access::attr_set_value::<_, _>(self.option_id.get_mut(), value)?; - } +// attribute struct definition +#[derive(Default, Clone, Debug)] +pub struct AttrChoiceId { + is_dirty:bool, + value: Option +} - _ => { - panic!("unknown name"); - } - } - Ok(()) +impl AttrChoiceId { + fn from(value:Option) -> Self { + Self { + is_dirty: false, + value } } - // attribute struct definition - #[derive(Default, Clone, Debug)] - pub struct AttrChoiceId { - is_dirty: bool, - value: Option, + fn get(&self) -> &Option { + &self.value } - impl AttrChoiceId { - fn from(value: Option) -> Self { - Self { - is_dirty: false, - value, - } - } + fn get_mut(&mut self) -> &mut Option { + &mut self.value + } - fn get(&self) -> &Option { - &self.value - } + fn set(&mut self, value:Option) { + self.value = value + } - fn get_mut(&mut self) -> &mut Option { - &mut self.value - } + fn update(&mut self, value: String) { + self.is_dirty = true; + self.value = Some(value) + } +} - fn set(&mut self, value: Option) { - self.value = value - } +impl AttrValue for AttrChoiceId { + fn dat_type() -> &'static DatType { + static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); + ONCE_LOCK.get_or_init(|| Self::attr_dat_type()) + } - fn update(&mut self, value: String) { - self.is_dirty = true; - self.value = Some(value) - } + fn datum_desc() -> &'static DatumDesc { + static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); + ONCE_LOCK.get_or_init(|| Self::attr_datum_desc()) } - impl AttrValue for AttrChoiceId { - fn dat_type() -> &'static DatType { - static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); - ONCE_LOCK.get_or_init(|| Self::attr_dat_type()) - } + fn object_name() -> &'static str { + VOTE_CHOICES + } - fn datum_desc() -> &'static DatumDesc { - static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); - ONCE_LOCK.get_or_init(|| Self::attr_datum_desc()) - } + fn attr_name() -> &'static str { + CHOICE_ID + } +} - fn object_name() -> &'static str { - VOTE_CHOICES - } +// attribute struct definition +#[derive(Default, Clone, Debug)] +pub struct AttrActionId { + is_dirty:bool, + value: Option +} - fn attr_name() -> &'static str { - CHOICE_ID +impl AttrActionId { + fn from(value:Option) -> Self { + Self { + is_dirty: false, + value } } - // attribute struct definition - #[derive(Default, Clone, Debug)] - pub struct AttrActionId { - is_dirty: bool, - value: Option, + fn get(&self) -> &Option { + &self.value } - impl AttrActionId { - fn from(value: Option) -> Self { - Self { - is_dirty: false, - value, - } - } + fn get_mut(&mut self) -> &mut Option { + &mut self.value + } - fn get(&self) -> &Option { - &self.value - } + fn set(&mut self, value:Option) { + self.value = value + } - fn get_mut(&mut self) -> &mut Option { - &mut self.value - } + fn update(&mut self, value: String) { + self.is_dirty = true; + self.value = Some(value) + } +} - fn set(&mut self, value: Option) { - self.value = value - } +impl AttrValue for AttrActionId { + fn dat_type() -> &'static DatType { + static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); + ONCE_LOCK.get_or_init(|| Self::attr_dat_type()) + } - fn update(&mut self, value: String) { - self.is_dirty = true; - self.value = Some(value) - } + fn datum_desc() -> &'static DatumDesc { + static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); + ONCE_LOCK.get_or_init(|| Self::attr_datum_desc()) } - impl AttrValue for AttrActionId { - fn dat_type() -> &'static DatType { - static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); - ONCE_LOCK.get_or_init(|| Self::attr_dat_type()) - } + fn object_name() -> &'static str { + VOTE_CHOICES + } - fn datum_desc() -> &'static DatumDesc { - static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); - ONCE_LOCK.get_or_init(|| Self::attr_datum_desc()) - } + fn attr_name() -> &'static str { + ACTION_ID + } +} - fn object_name() -> &'static str { - VOTE_CHOICES - } +// attribute struct definition +#[derive(Default, Clone, Debug)] +pub struct AttrOptionId { + is_dirty:bool, + value: Option +} - fn attr_name() -> &'static str { - ACTION_ID +impl AttrOptionId { + fn from(value:Option) -> Self { + Self { + is_dirty: false, + value } } - // attribute struct definition - #[derive(Default, Clone, Debug)] - pub struct AttrOptionId { - is_dirty: bool, - value: Option, + fn get(&self) -> &Option { + &self.value } - impl AttrOptionId { - fn from(value: Option) -> Self { - Self { - is_dirty: false, - value, - } - } - - fn get(&self) -> &Option { - &self.value - } - - fn get_mut(&mut self) -> &mut Option { - &mut self.value - } + fn get_mut(&mut self) -> &mut Option { + &mut self.value + } - fn set(&mut self, value: Option) { - self.value = value - } + fn set(&mut self, value:Option) { + self.value = value + } - fn update(&mut self, value: String) { - self.is_dirty = true; - self.value = Some(value) - } + fn update(&mut self, value: String) { + self.is_dirty = true; + self.value = Some(value) } +} - impl AttrValue for AttrOptionId { - fn dat_type() -> &'static DatType { - static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); - ONCE_LOCK.get_or_init(|| Self::attr_dat_type()) - } +impl AttrValue for AttrOptionId { + fn dat_type() -> &'static DatType { + static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); + ONCE_LOCK.get_or_init(|| Self::attr_dat_type()) + } - fn datum_desc() -> &'static DatumDesc { - static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); - ONCE_LOCK.get_or_init(|| Self::attr_datum_desc()) - } + fn datum_desc() -> &'static DatumDesc { + static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); + ONCE_LOCK.get_or_init(|| Self::attr_datum_desc()) + } - fn object_name() -> &'static str { - VOTE_CHOICES - } + fn object_name() -> &'static str { + VOTE_CHOICES + } - fn attr_name() -> &'static str { - OPTION_ID - } + fn attr_name() -> &'static str { + OPTION_ID } } + + +} \ No newline at end of file diff --git a/example/vote/src/generated/vote_history_item.rs b/example/vote/src/generated/vote_history_item.rs index 724c8e1..b481aaa 100644 --- a/example/vote/src/generated/vote_history_item.rs +++ b/example/vote/src/generated/vote_history_item.rs @@ -1,556 +1,599 @@ pub mod object { - use lazy_static::lazy_static; - use mudu::common::result::RS; - use mudu_contract::database::attr_field_access; - use mudu_contract::database::attr_value::AttrValue; - use mudu_contract::database::entity::Entity; - use mudu_contract::database::entity_utils; - use mudu_contract::database::sql_params::SQLParamMarker; - use mudu_contract::tuple::datum_desc::DatumDesc; - use mudu_contract::tuple::tuple_datum::TupleDatumMarker; - use mudu_contract::tuple::tuple_field_desc::TupleFieldDesc; - use mudu_type::dat_binary::DatBinary; - use mudu_type::dat_textual::DatTextual; - use mudu_type::dat_type::DatType; - use mudu_type::dat_type_id::DatTypeID; - use mudu_type::dat_value::DatValue; - use mudu_type::datum::{Datum, DatumDyn}; - - // constant definition - const VOTE_HISTORY_ITEM: &str = "vote_history_item"; - - const VOTE_ID: &str = "vote_id"; - - const TOPIC: &str = "topic"; - - const ACTION_TIME: &str = "action_time"; - - const IS_WITHDRAWN: &str = "is_withdrawn"; - - const VOTE_ENDED: &str = "vote_ended"; - - // entity struct definition - #[derive(Debug, Clone, Default)] - pub struct VoteHistoryItem { - vote_id: AttrVoteId, - - topic: AttrTopic, - - action_time: AttrActionTime, +use lazy_static::lazy_static; +use mududb::common::result::RS; +use mududb::contract::database::attr_field_access; +use mududb::contract::database::attr_value::AttrValue; +use mududb::contract::database::entity::Entity; +use mududb::contract::database::entity_utils; +use mududb::contract::database::sql_params::SQLParamMarker; +use mududb::contract::tuple::datum_desc::DatumDesc; +use mududb::contract::tuple::tuple_field_desc::TupleFieldDesc; +use mududb::contract::tuple::tuple_datum::TupleDatumMarker; +use mududb::types::dat_binary::DatBinary; +use mududb::types::dat_textual::DatTextual; +use mududb::types::dat_type::DatType; +use mududb::types::dat_type_id::DatTypeID; +use mududb::types::dat_value::DatValue; +use mududb::types::datum::{Datum, DatumDyn}; + +// constant definition +const VOTE_HISTORY_ITEM:&str = "vote_history_item"; + +const VOTE_ID:&str = "vote_id"; + +const TOPIC:&str = "topic"; + +const ACTION_TIME:&str = "action_time"; + +const IS_WITHDRAWN:&str = "is_withdrawn"; + +const VOTE_ENDED:&str = "vote_ended"; + + +// entity struct definition +#[derive(Debug, Clone, Default)] +pub struct VoteHistoryItem { + + vote_id: AttrVoteId, + + topic: AttrTopic, + + action_time: AttrActionTime, + + is_withdrawn: AttrIsWithdrawn, + + vote_ended: AttrVoteEnded, + +} - is_withdrawn: AttrIsWithdrawn, +impl TupleDatumMarker for VoteHistoryItem {} + +impl SQLParamMarker for VoteHistoryItem {} + +impl VoteHistoryItem { + pub fn new( + vote_id: Option, + topic: Option, + action_time: Option, + is_withdrawn: Option, + vote_ended: Option, + + ) -> Self { + let s = Self { + + vote_id : AttrVoteId::from(vote_id), + + topic : AttrTopic::from(topic), + + action_time : AttrActionTime::from(action_time), + + is_withdrawn : AttrIsWithdrawn::from(is_withdrawn), + + vote_ended : AttrVoteEnded::from(vote_ended), + + }; + s + } - vote_ended: AttrVoteEnded, + pub fn new_empty() -> Self { + Self::default() } - impl TupleDatumMarker for VoteHistoryItem {} + + pub fn set_vote_id( + &mut self, + vote_id: String, + ) { + self.vote_id.update(vote_id) + } - impl SQLParamMarker for VoteHistoryItem {} + pub fn get_vote_id( + &self, + ) -> &Option { + self.vote_id.get() + } + + pub fn set_topic( + &mut self, + topic: String, + ) { + self.topic.update(topic) + } - impl VoteHistoryItem { - pub fn new( - vote_id: Option, - topic: Option, - action_time: Option, - is_withdrawn: Option, - vote_ended: Option, - ) -> Self { - let s = Self { - vote_id: AttrVoteId::from(vote_id), + pub fn get_topic( + &self, + ) -> &Option { + self.topic.get() + } + + pub fn set_action_time( + &mut self, + action_time: i32, + ) { + self.action_time.update(action_time) + } - topic: AttrTopic::from(topic), + pub fn get_action_time( + &self, + ) -> &Option { + self.action_time.get() + } + + pub fn set_is_withdrawn( + &mut self, + is_withdrawn: i32, + ) { + self.is_withdrawn.update(is_withdrawn) + } - action_time: AttrActionTime::from(action_time), + pub fn get_is_withdrawn( + &self, + ) -> &Option { + self.is_withdrawn.get() + } + + pub fn set_vote_ended( + &mut self, + vote_ended: i32, + ) { + self.vote_ended.update(vote_ended) + } - is_withdrawn: AttrIsWithdrawn::from(is_withdrawn), + pub fn get_vote_ended( + &self, + ) -> &Option { + self.vote_ended.get() + } + +} - vote_ended: AttrVoteEnded::from(vote_ended), - }; - s +impl Datum for VoteHistoryItem { + fn dat_type() -> &'static DatType { + lazy_static! { + static ref DAT_TYPE: DatType = entity_utils::entity_dat_type::(); } + &DAT_TYPE + } - pub fn new_empty() -> Self { - Self::default() - } + fn from_binary(binary: &[u8]) -> RS { + entity_utils::entity_from_binary(binary) + } - pub fn set_vote_id(&mut self, vote_id: String) { - self.vote_id.update(vote_id) - } + fn from_value(value: &DatValue) -> RS { + entity_utils::entity_from_value(value) + } - pub fn get_vote_id(&self) -> &Option { - self.vote_id.get() - } + fn from_textual(textual: &str) -> RS { + entity_utils::entity_from_textual(textual) + } +} - pub fn set_topic(&mut self, topic: String) { - self.topic.update(topic) - } +impl DatumDyn for VoteHistoryItem { + fn dat_type_id(&self) -> RS { + entity_utils::entity_dat_type_id() + } - pub fn get_topic(&self) -> &Option { - self.topic.get() - } + fn to_binary(&self, dat_type: &DatType) -> RS { + entity_utils::entity_to_binary(self, dat_type) + } - pub fn set_action_time(&mut self, action_time: i32) { - self.action_time.update(action_time) - } + fn to_textual(&self, dat_type: &DatType) -> RS { + entity_utils::entity_to_textual(self, dat_type) + } - pub fn get_action_time(&self) -> &Option { - self.action_time.get() - } + fn to_value(&self, dat_type: &DatType) -> RS { + entity_utils::entity_to_value(self, dat_type) + } - pub fn set_is_withdrawn(&mut self, is_withdrawn: i32) { - self.is_withdrawn.update(is_withdrawn) - } + fn clone_boxed(&self) -> Box { + entity_utils::entity_clone_boxed(self) + } +} - pub fn get_is_withdrawn(&self) -> &Option { - self.is_withdrawn.get() - } +impl Entity for VoteHistoryItem { + fn new_empty() -> Self { + Self::new_empty() + } - pub fn set_vote_ended(&mut self, vote_ended: i32) { - self.vote_ended.update(vote_ended) - } + fn tuple_desc() -> &'static TupleFieldDesc { + lazy_static! { + static ref TUPLE_DESC: TupleFieldDesc = TupleFieldDesc::new(vec![ + + AttrVoteId::datum_desc().clone(), + + AttrTopic::datum_desc().clone(), + + AttrActionTime::datum_desc().clone(), + + AttrIsWithdrawn::datum_desc().clone(), + + AttrVoteEnded::datum_desc().clone(), + + ]); + } + &TUPLE_DESC + } - pub fn get_vote_ended(&self) -> &Option { - self.vote_ended.get() - } + fn object_name() -> &'static str { + VOTE_HISTORY_ITEM } - impl Datum for VoteHistoryItem { - fn dat_type() -> &'static DatType { - lazy_static! { - static ref DAT_TYPE: DatType = entity_utils::entity_dat_type::(); + fn get_field_binary(&self, field: &str) -> RS>> { + match field { + + VOTE_ID => { + attr_field_access::attr_get_binary::<_>(self.vote_id.get()) } - &DAT_TYPE - } - - fn from_binary(binary: &[u8]) -> RS { - entity_utils::entity_from_binary(binary) - } - - fn from_value(value: &DatValue) -> RS { - entity_utils::entity_from_value(value) - } - - fn from_textual(textual: &str) -> RS { - entity_utils::entity_from_textual(textual) + + TOPIC => { + attr_field_access::attr_get_binary::<_>(self.topic.get()) + } + + ACTION_TIME => { + attr_field_access::attr_get_binary::<_>(self.action_time.get()) + } + + IS_WITHDRAWN => { + attr_field_access::attr_get_binary::<_>(self.is_withdrawn.get()) + } + + VOTE_ENDED => { + attr_field_access::attr_get_binary::<_>(self.vote_ended.get()) + } + + _ => { panic!("unknown name"); } } } - impl DatumDyn for VoteHistoryItem { - fn dat_type_id(&self) -> RS { - entity_utils::entity_dat_type_id() - } - - fn to_binary(&self, dat_type: &DatType) -> RS { - entity_utils::entity_to_binary(self, dat_type) - } - - fn to_textual(&self, dat_type: &DatType) -> RS { - entity_utils::entity_to_textual(self, dat_type) - } - - fn to_value(&self, dat_type: &DatType) -> RS { - entity_utils::entity_to_value(self, dat_type) - } - - fn clone_boxed(&self) -> Box { - entity_utils::entity_clone_boxed(self) + fn set_field_binary>(&mut self, field: &str, binary: B) -> RS<()> { + match field { + + VOTE_ID => { + attr_field_access::attr_set_binary::<_, _>(self.vote_id.get_mut(), binary.as_ref())?; + } + + TOPIC => { + attr_field_access::attr_set_binary::<_, _>(self.topic.get_mut(), binary.as_ref())?; + } + + ACTION_TIME => { + attr_field_access::attr_set_binary::<_, _>(self.action_time.get_mut(), binary.as_ref())?; + } + + IS_WITHDRAWN => { + attr_field_access::attr_set_binary::<_, _>(self.is_withdrawn.get_mut(), binary.as_ref())?; + } + + VOTE_ENDED => { + attr_field_access::attr_set_binary::<_, _>(self.vote_ended.get_mut(), binary.as_ref())?; + } + + _ => { panic!("unknown name"); } } + Ok(()) } - impl Entity for VoteHistoryItem { - fn new_empty() -> Self { - Self::new_empty() - } - - fn tuple_desc() -> &'static TupleFieldDesc { - lazy_static! { - static ref TUPLE_DESC: TupleFieldDesc = TupleFieldDesc::new(vec![ - AttrVoteId::datum_desc().clone(), - AttrTopic::datum_desc().clone(), - AttrActionTime::datum_desc().clone(), - AttrIsWithdrawn::datum_desc().clone(), - AttrVoteEnded::datum_desc().clone(), - ]); + fn get_field_value(&self, field: &str) -> RS> { + match field { + + VOTE_ID => { + attr_field_access::attr_get_value::<_>(self.vote_id.get()) } - &TUPLE_DESC - } - - fn object_name() -> &'static str { - VOTE_HISTORY_ITEM - } - - fn get_field_binary(&self, field: &str) -> RS>> { - match field { - VOTE_ID => attr_field_access::attr_get_binary::<_>(self.vote_id.get()), - - TOPIC => attr_field_access::attr_get_binary::<_>(self.topic.get()), - - ACTION_TIME => attr_field_access::attr_get_binary::<_>(self.action_time.get()), - - IS_WITHDRAWN => attr_field_access::attr_get_binary::<_>(self.is_withdrawn.get()), - - VOTE_ENDED => attr_field_access::attr_get_binary::<_>(self.vote_ended.get()), - - _ => { - panic!("unknown name"); - } + + TOPIC => { + attr_field_access::attr_get_value::<_>(self.topic.get()) } - } - - fn set_field_binary>(&mut self, field: &str, binary: B) -> RS<()> { - match field { - VOTE_ID => { - attr_field_access::attr_set_binary::<_, _>( - self.vote_id.get_mut(), - binary.as_ref(), - )?; - } - - TOPIC => { - attr_field_access::attr_set_binary::<_, _>( - self.topic.get_mut(), - binary.as_ref(), - )?; - } - - ACTION_TIME => { - attr_field_access::attr_set_binary::<_, _>( - self.action_time.get_mut(), - binary.as_ref(), - )?; - } - - IS_WITHDRAWN => { - attr_field_access::attr_set_binary::<_, _>( - self.is_withdrawn.get_mut(), - binary.as_ref(), - )?; - } - - VOTE_ENDED => { - attr_field_access::attr_set_binary::<_, _>( - self.vote_ended.get_mut(), - binary.as_ref(), - )?; - } - - _ => { - panic!("unknown name"); - } + + ACTION_TIME => { + attr_field_access::attr_get_value::<_>(self.action_time.get()) } - Ok(()) + + IS_WITHDRAWN => { + attr_field_access::attr_get_value::<_>(self.is_withdrawn.get()) + } + + VOTE_ENDED => { + attr_field_access::attr_get_value::<_>(self.vote_ended.get()) + } + + _ => { panic!("unknown name"); } } + } - fn get_field_value(&self, field: &str) -> RS> { - match field { - VOTE_ID => attr_field_access::attr_get_value::<_>(self.vote_id.get()), - - TOPIC => attr_field_access::attr_get_value::<_>(self.topic.get()), - - ACTION_TIME => attr_field_access::attr_get_value::<_>(self.action_time.get()), - - IS_WITHDRAWN => attr_field_access::attr_get_value::<_>(self.is_withdrawn.get()), - - VOTE_ENDED => attr_field_access::attr_get_value::<_>(self.vote_ended.get()), - - _ => { - panic!("unknown name"); - } + fn set_field_value>(&mut self, field: &str, value: B) -> RS<()> { + match field { + + VOTE_ID => { + attr_field_access::attr_set_value::<_, _>(self.vote_id.get_mut(), value)?; + } + + TOPIC => { + attr_field_access::attr_set_value::<_, _>(self.topic.get_mut(), value)?; } + + ACTION_TIME => { + attr_field_access::attr_set_value::<_, _>(self.action_time.get_mut(), value)?; + } + + IS_WITHDRAWN => { + attr_field_access::attr_set_value::<_, _>(self.is_withdrawn.get_mut(), value)?; + } + + VOTE_ENDED => { + attr_field_access::attr_set_value::<_, _>(self.vote_ended.get_mut(), value)?; + } + + _ => { panic!("unknown name"); } } + Ok(()) + } +} - fn set_field_value>(&mut self, field: &str, value: B) -> RS<()> { - match field { - VOTE_ID => { - attr_field_access::attr_set_value::<_, _>(self.vote_id.get_mut(), value)?; - } - - TOPIC => { - attr_field_access::attr_set_value::<_, _>(self.topic.get_mut(), value)?; - } - - ACTION_TIME => { - attr_field_access::attr_set_value::<_, _>(self.action_time.get_mut(), value)?; - } - - IS_WITHDRAWN => { - attr_field_access::attr_set_value::<_, _>(self.is_withdrawn.get_mut(), value)?; - } - VOTE_ENDED => { - attr_field_access::attr_set_value::<_, _>(self.vote_ended.get_mut(), value)?; - } +// attribute struct definition +#[derive(Default, Clone, Debug)] +pub struct AttrVoteId { + is_dirty:bool, + value: Option +} - _ => { - panic!("unknown name"); - } - } - Ok(()) +impl AttrVoteId { + fn from(value:Option) -> Self { + Self { + is_dirty: false, + value } } - // attribute struct definition - #[derive(Default, Clone, Debug)] - pub struct AttrVoteId { - is_dirty: bool, - value: Option, + fn get(&self) -> &Option { + &self.value } - impl AttrVoteId { - fn from(value: Option) -> Self { - Self { - is_dirty: false, - value, - } - } + fn get_mut(&mut self) -> &mut Option { + &mut self.value + } - fn get(&self) -> &Option { - &self.value - } + fn set(&mut self, value:Option) { + self.value = value + } - fn get_mut(&mut self) -> &mut Option { - &mut self.value - } + fn update(&mut self, value: String) { + self.is_dirty = true; + self.value = Some(value) + } +} - fn set(&mut self, value: Option) { - self.value = value - } +impl AttrValue for AttrVoteId { + fn dat_type() -> &'static DatType { + static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); + ONCE_LOCK.get_or_init(|| Self::attr_dat_type()) + } - fn update(&mut self, value: String) { - self.is_dirty = true; - self.value = Some(value) - } + fn datum_desc() -> &'static DatumDesc { + static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); + ONCE_LOCK.get_or_init(|| Self::attr_datum_desc()) } - impl AttrValue for AttrVoteId { - fn dat_type() -> &'static DatType { - static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); - ONCE_LOCK.get_or_init(|| Self::attr_dat_type()) - } + fn object_name() -> &'static str { + VOTE_HISTORY_ITEM + } - fn datum_desc() -> &'static DatumDesc { - static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); - ONCE_LOCK.get_or_init(|| Self::attr_datum_desc()) - } + fn attr_name() -> &'static str { + VOTE_ID + } +} - fn object_name() -> &'static str { - VOTE_HISTORY_ITEM - } +// attribute struct definition +#[derive(Default, Clone, Debug)] +pub struct AttrTopic { + is_dirty:bool, + value: Option +} - fn attr_name() -> &'static str { - VOTE_ID +impl AttrTopic { + fn from(value:Option) -> Self { + Self { + is_dirty: false, + value } } - // attribute struct definition - #[derive(Default, Clone, Debug)] - pub struct AttrTopic { - is_dirty: bool, - value: Option, + fn get(&self) -> &Option { + &self.value } - impl AttrTopic { - fn from(value: Option) -> Self { - Self { - is_dirty: false, - value, - } - } + fn get_mut(&mut self) -> &mut Option { + &mut self.value + } - fn get(&self) -> &Option { - &self.value - } + fn set(&mut self, value:Option) { + self.value = value + } - fn get_mut(&mut self) -> &mut Option { - &mut self.value - } + fn update(&mut self, value: String) { + self.is_dirty = true; + self.value = Some(value) + } +} - fn set(&mut self, value: Option) { - self.value = value - } +impl AttrValue for AttrTopic { + fn dat_type() -> &'static DatType { + static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); + ONCE_LOCK.get_or_init(|| Self::attr_dat_type()) + } - fn update(&mut self, value: String) { - self.is_dirty = true; - self.value = Some(value) - } + fn datum_desc() -> &'static DatumDesc { + static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); + ONCE_LOCK.get_or_init(|| Self::attr_datum_desc()) } - impl AttrValue for AttrTopic { - fn dat_type() -> &'static DatType { - static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); - ONCE_LOCK.get_or_init(|| Self::attr_dat_type()) - } + fn object_name() -> &'static str { + VOTE_HISTORY_ITEM + } - fn datum_desc() -> &'static DatumDesc { - static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); - ONCE_LOCK.get_or_init(|| Self::attr_datum_desc()) - } + fn attr_name() -> &'static str { + TOPIC + } +} - fn object_name() -> &'static str { - VOTE_HISTORY_ITEM - } +// attribute struct definition +#[derive(Default, Clone, Debug)] +pub struct AttrActionTime { + is_dirty:bool, + value: Option +} - fn attr_name() -> &'static str { - TOPIC +impl AttrActionTime { + fn from(value:Option) -> Self { + Self { + is_dirty: false, + value } } - // attribute struct definition - #[derive(Default, Clone, Debug)] - pub struct AttrActionTime { - is_dirty: bool, - value: Option, + fn get(&self) -> &Option { + &self.value } - impl AttrActionTime { - fn from(value: Option) -> Self { - Self { - is_dirty: false, - value, - } - } + fn get_mut(&mut self) -> &mut Option { + &mut self.value + } - fn get(&self) -> &Option { - &self.value - } + fn set(&mut self, value:Option) { + self.value = value + } - fn get_mut(&mut self) -> &mut Option { - &mut self.value - } + fn update(&mut self, value: i32) { + self.is_dirty = true; + self.value = Some(value) + } +} - fn set(&mut self, value: Option) { - self.value = value - } +impl AttrValue for AttrActionTime { + fn dat_type() -> &'static DatType { + static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); + ONCE_LOCK.get_or_init(|| Self::attr_dat_type()) + } - fn update(&mut self, value: i32) { - self.is_dirty = true; - self.value = Some(value) - } + fn datum_desc() -> &'static DatumDesc { + static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); + ONCE_LOCK.get_or_init(|| Self::attr_datum_desc()) } - impl AttrValue for AttrActionTime { - fn dat_type() -> &'static DatType { - static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); - ONCE_LOCK.get_or_init(|| Self::attr_dat_type()) - } + fn object_name() -> &'static str { + VOTE_HISTORY_ITEM + } - fn datum_desc() -> &'static DatumDesc { - static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); - ONCE_LOCK.get_or_init(|| Self::attr_datum_desc()) - } + fn attr_name() -> &'static str { + ACTION_TIME + } +} - fn object_name() -> &'static str { - VOTE_HISTORY_ITEM - } +// attribute struct definition +#[derive(Default, Clone, Debug)] +pub struct AttrIsWithdrawn { + is_dirty:bool, + value: Option +} - fn attr_name() -> &'static str { - ACTION_TIME +impl AttrIsWithdrawn { + fn from(value:Option) -> Self { + Self { + is_dirty: false, + value } } - // attribute struct definition - #[derive(Default, Clone, Debug)] - pub struct AttrIsWithdrawn { - is_dirty: bool, - value: Option, + fn get(&self) -> &Option { + &self.value } - impl AttrIsWithdrawn { - fn from(value: Option) -> Self { - Self { - is_dirty: false, - value, - } - } + fn get_mut(&mut self) -> &mut Option { + &mut self.value + } - fn get(&self) -> &Option { - &self.value - } + fn set(&mut self, value:Option) { + self.value = value + } - fn get_mut(&mut self) -> &mut Option { - &mut self.value - } + fn update(&mut self, value: i32) { + self.is_dirty = true; + self.value = Some(value) + } +} - fn set(&mut self, value: Option) { - self.value = value - } +impl AttrValue for AttrIsWithdrawn { + fn dat_type() -> &'static DatType { + static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); + ONCE_LOCK.get_or_init(|| Self::attr_dat_type()) + } - fn update(&mut self, value: i32) { - self.is_dirty = true; - self.value = Some(value) - } + fn datum_desc() -> &'static DatumDesc { + static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); + ONCE_LOCK.get_or_init(|| Self::attr_datum_desc()) } - impl AttrValue for AttrIsWithdrawn { - fn dat_type() -> &'static DatType { - static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); - ONCE_LOCK.get_or_init(|| Self::attr_dat_type()) - } + fn object_name() -> &'static str { + VOTE_HISTORY_ITEM + } - fn datum_desc() -> &'static DatumDesc { - static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); - ONCE_LOCK.get_or_init(|| Self::attr_datum_desc()) - } + fn attr_name() -> &'static str { + IS_WITHDRAWN + } +} - fn object_name() -> &'static str { - VOTE_HISTORY_ITEM - } +// attribute struct definition +#[derive(Default, Clone, Debug)] +pub struct AttrVoteEnded { + is_dirty:bool, + value: Option +} - fn attr_name() -> &'static str { - IS_WITHDRAWN +impl AttrVoteEnded { + fn from(value:Option) -> Self { + Self { + is_dirty: false, + value } } - // attribute struct definition - #[derive(Default, Clone, Debug)] - pub struct AttrVoteEnded { - is_dirty: bool, - value: Option, + fn get(&self) -> &Option { + &self.value } - impl AttrVoteEnded { - fn from(value: Option) -> Self { - Self { - is_dirty: false, - value, - } - } - - fn get(&self) -> &Option { - &self.value - } - - fn get_mut(&mut self) -> &mut Option { - &mut self.value - } + fn get_mut(&mut self) -> &mut Option { + &mut self.value + } - fn set(&mut self, value: Option) { - self.value = value - } + fn set(&mut self, value:Option) { + self.value = value + } - fn update(&mut self, value: i32) { - self.is_dirty = true; - self.value = Some(value) - } + fn update(&mut self, value: i32) { + self.is_dirty = true; + self.value = Some(value) } +} - impl AttrValue for AttrVoteEnded { - fn dat_type() -> &'static DatType { - static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); - ONCE_LOCK.get_or_init(|| Self::attr_dat_type()) - } +impl AttrValue for AttrVoteEnded { + fn dat_type() -> &'static DatType { + static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); + ONCE_LOCK.get_or_init(|| Self::attr_dat_type()) + } - fn datum_desc() -> &'static DatumDesc { - static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); - ONCE_LOCK.get_or_init(|| Self::attr_datum_desc()) - } + fn datum_desc() -> &'static DatumDesc { + static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); + ONCE_LOCK.get_or_init(|| Self::attr_datum_desc()) + } - fn object_name() -> &'static str { - VOTE_HISTORY_ITEM - } + fn object_name() -> &'static str { + VOTE_HISTORY_ITEM + } - fn attr_name() -> &'static str { - VOTE_ENDED - } + fn attr_name() -> &'static str { + VOTE_ENDED } } + + +} \ No newline at end of file diff --git a/example/vote/src/generated/vote_result.rs b/example/vote/src/generated/vote_result.rs index e20a04e..7dc3972 100644 --- a/example/vote/src/generated/vote_result.rs +++ b/example/vote/src/generated/vote_result.rs @@ -1,556 +1,599 @@ pub mod object { - use lazy_static::lazy_static; - use mudu::common::result::RS; - use mudu_contract::database::attr_field_access; - use mudu_contract::database::attr_value::AttrValue; - use mudu_contract::database::entity::Entity; - use mudu_contract::database::entity_utils; - use mudu_contract::database::sql_params::SQLParamMarker; - use mudu_contract::tuple::datum_desc::DatumDesc; - use mudu_contract::tuple::tuple_datum::TupleDatumMarker; - use mudu_contract::tuple::tuple_field_desc::TupleFieldDesc; - use mudu_type::dat_binary::DatBinary; - use mudu_type::dat_textual::DatTextual; - use mudu_type::dat_type::DatType; - use mudu_type::dat_type_id::DatTypeID; - use mudu_type::dat_value::DatValue; - use mudu_type::datum::{Datum, DatumDyn}; - - // constant definition - const VOTE_RESULT: &str = "vote_result"; - - const VOTE_ID: &str = "vote_id"; - - const TOPIC: &str = "topic"; - - const VOTE_ENDED: &str = "vote_ended"; - - const TOTAL_VOTES: &str = "total_votes"; - - const OPTIONS: &str = "options"; - - // entity struct definition - #[derive(Debug, Clone, Default)] - pub struct VoteResult { - vote_id: AttrVoteId, - - topic: AttrTopic, - - vote_ended: AttrVoteEnded, +use lazy_static::lazy_static; +use mududb::common::result::RS; +use mududb::contract::database::attr_field_access; +use mududb::contract::database::attr_value::AttrValue; +use mududb::contract::database::entity::Entity; +use mududb::contract::database::entity_utils; +use mududb::contract::database::sql_params::SQLParamMarker; +use mududb::contract::tuple::datum_desc::DatumDesc; +use mududb::contract::tuple::tuple_field_desc::TupleFieldDesc; +use mududb::contract::tuple::tuple_datum::TupleDatumMarker; +use mududb::types::dat_binary::DatBinary; +use mududb::types::dat_textual::DatTextual; +use mududb::types::dat_type::DatType; +use mududb::types::dat_type_id::DatTypeID; +use mududb::types::dat_value::DatValue; +use mududb::types::datum::{Datum, DatumDyn}; + +// constant definition +const VOTE_RESULT:&str = "vote_result"; + +const VOTE_ID:&str = "vote_id"; + +const TOPIC:&str = "topic"; + +const VOTE_ENDED:&str = "vote_ended"; + +const TOTAL_VOTES:&str = "total_votes"; + +const OPTIONS:&str = "options"; + + +// entity struct definition +#[derive(Debug, Clone, Default)] +pub struct VoteResult { + + vote_id: AttrVoteId, + + topic: AttrTopic, + + vote_ended: AttrVoteEnded, + + total_votes: AttrTotalVotes, + + options: AttrOptions, + +} - total_votes: AttrTotalVotes, +impl TupleDatumMarker for VoteResult {} + +impl SQLParamMarker for VoteResult {} + +impl VoteResult { + pub fn new( + vote_id: Option, + topic: Option, + vote_ended: Option, + total_votes: Option, + options: Option, + + ) -> Self { + let s = Self { + + vote_id : AttrVoteId::from(vote_id), + + topic : AttrTopic::from(topic), + + vote_ended : AttrVoteEnded::from(vote_ended), + + total_votes : AttrTotalVotes::from(total_votes), + + options : AttrOptions::from(options), + + }; + s + } - options: AttrOptions, + pub fn new_empty() -> Self { + Self::default() } - impl TupleDatumMarker for VoteResult {} + + pub fn set_vote_id( + &mut self, + vote_id: String, + ) { + self.vote_id.update(vote_id) + } - impl SQLParamMarker for VoteResult {} + pub fn get_vote_id( + &self, + ) -> &Option { + self.vote_id.get() + } + + pub fn set_topic( + &mut self, + topic: String, + ) { + self.topic.update(topic) + } - impl VoteResult { - pub fn new( - vote_id: Option, - topic: Option, - vote_ended: Option, - total_votes: Option, - options: Option, - ) -> Self { - let s = Self { - vote_id: AttrVoteId::from(vote_id), + pub fn get_topic( + &self, + ) -> &Option { + self.topic.get() + } + + pub fn set_vote_ended( + &mut self, + vote_ended: i32, + ) { + self.vote_ended.update(vote_ended) + } - topic: AttrTopic::from(topic), + pub fn get_vote_ended( + &self, + ) -> &Option { + self.vote_ended.get() + } + + pub fn set_total_votes( + &mut self, + total_votes: i32, + ) { + self.total_votes.update(total_votes) + } - vote_ended: AttrVoteEnded::from(vote_ended), + pub fn get_total_votes( + &self, + ) -> &Option { + self.total_votes.get() + } + + pub fn set_options( + &mut self, + options: String, + ) { + self.options.update(options) + } - total_votes: AttrTotalVotes::from(total_votes), + pub fn get_options( + &self, + ) -> &Option { + self.options.get() + } + +} - options: AttrOptions::from(options), - }; - s +impl Datum for VoteResult { + fn dat_type() -> &'static DatType { + lazy_static! { + static ref DAT_TYPE: DatType = entity_utils::entity_dat_type::(); } + &DAT_TYPE + } - pub fn new_empty() -> Self { - Self::default() - } + fn from_binary(binary: &[u8]) -> RS { + entity_utils::entity_from_binary(binary) + } - pub fn set_vote_id(&mut self, vote_id: String) { - self.vote_id.update(vote_id) - } + fn from_value(value: &DatValue) -> RS { + entity_utils::entity_from_value(value) + } - pub fn get_vote_id(&self) -> &Option { - self.vote_id.get() - } + fn from_textual(textual: &str) -> RS { + entity_utils::entity_from_textual(textual) + } +} - pub fn set_topic(&mut self, topic: String) { - self.topic.update(topic) - } +impl DatumDyn for VoteResult { + fn dat_type_id(&self) -> RS { + entity_utils::entity_dat_type_id() + } - pub fn get_topic(&self) -> &Option { - self.topic.get() - } + fn to_binary(&self, dat_type: &DatType) -> RS { + entity_utils::entity_to_binary(self, dat_type) + } - pub fn set_vote_ended(&mut self, vote_ended: i32) { - self.vote_ended.update(vote_ended) - } + fn to_textual(&self, dat_type: &DatType) -> RS { + entity_utils::entity_to_textual(self, dat_type) + } - pub fn get_vote_ended(&self) -> &Option { - self.vote_ended.get() - } + fn to_value(&self, dat_type: &DatType) -> RS { + entity_utils::entity_to_value(self, dat_type) + } - pub fn set_total_votes(&mut self, total_votes: i32) { - self.total_votes.update(total_votes) - } + fn clone_boxed(&self) -> Box { + entity_utils::entity_clone_boxed(self) + } +} - pub fn get_total_votes(&self) -> &Option { - self.total_votes.get() - } +impl Entity for VoteResult { + fn new_empty() -> Self { + Self::new_empty() + } - pub fn set_options(&mut self, options: String) { - self.options.update(options) - } + fn tuple_desc() -> &'static TupleFieldDesc { + lazy_static! { + static ref TUPLE_DESC: TupleFieldDesc = TupleFieldDesc::new(vec![ + + AttrVoteId::datum_desc().clone(), + + AttrTopic::datum_desc().clone(), + + AttrVoteEnded::datum_desc().clone(), + + AttrTotalVotes::datum_desc().clone(), + + AttrOptions::datum_desc().clone(), + + ]); + } + &TUPLE_DESC + } - pub fn get_options(&self) -> &Option { - self.options.get() - } + fn object_name() -> &'static str { + VOTE_RESULT } - impl Datum for VoteResult { - fn dat_type() -> &'static DatType { - lazy_static! { - static ref DAT_TYPE: DatType = entity_utils::entity_dat_type::(); + fn get_field_binary(&self, field: &str) -> RS>> { + match field { + + VOTE_ID => { + attr_field_access::attr_get_binary::<_>(self.vote_id.get()) } - &DAT_TYPE - } - - fn from_binary(binary: &[u8]) -> RS { - entity_utils::entity_from_binary(binary) - } - - fn from_value(value: &DatValue) -> RS { - entity_utils::entity_from_value(value) - } - - fn from_textual(textual: &str) -> RS { - entity_utils::entity_from_textual(textual) + + TOPIC => { + attr_field_access::attr_get_binary::<_>(self.topic.get()) + } + + VOTE_ENDED => { + attr_field_access::attr_get_binary::<_>(self.vote_ended.get()) + } + + TOTAL_VOTES => { + attr_field_access::attr_get_binary::<_>(self.total_votes.get()) + } + + OPTIONS => { + attr_field_access::attr_get_binary::<_>(self.options.get()) + } + + _ => { panic!("unknown name"); } } } - impl DatumDyn for VoteResult { - fn dat_type_id(&self) -> RS { - entity_utils::entity_dat_type_id() - } - - fn to_binary(&self, dat_type: &DatType) -> RS { - entity_utils::entity_to_binary(self, dat_type) - } - - fn to_textual(&self, dat_type: &DatType) -> RS { - entity_utils::entity_to_textual(self, dat_type) - } - - fn to_value(&self, dat_type: &DatType) -> RS { - entity_utils::entity_to_value(self, dat_type) - } - - fn clone_boxed(&self) -> Box { - entity_utils::entity_clone_boxed(self) + fn set_field_binary>(&mut self, field: &str, binary: B) -> RS<()> { + match field { + + VOTE_ID => { + attr_field_access::attr_set_binary::<_, _>(self.vote_id.get_mut(), binary.as_ref())?; + } + + TOPIC => { + attr_field_access::attr_set_binary::<_, _>(self.topic.get_mut(), binary.as_ref())?; + } + + VOTE_ENDED => { + attr_field_access::attr_set_binary::<_, _>(self.vote_ended.get_mut(), binary.as_ref())?; + } + + TOTAL_VOTES => { + attr_field_access::attr_set_binary::<_, _>(self.total_votes.get_mut(), binary.as_ref())?; + } + + OPTIONS => { + attr_field_access::attr_set_binary::<_, _>(self.options.get_mut(), binary.as_ref())?; + } + + _ => { panic!("unknown name"); } } + Ok(()) } - impl Entity for VoteResult { - fn new_empty() -> Self { - Self::new_empty() - } - - fn tuple_desc() -> &'static TupleFieldDesc { - lazy_static! { - static ref TUPLE_DESC: TupleFieldDesc = TupleFieldDesc::new(vec![ - AttrVoteId::datum_desc().clone(), - AttrTopic::datum_desc().clone(), - AttrVoteEnded::datum_desc().clone(), - AttrTotalVotes::datum_desc().clone(), - AttrOptions::datum_desc().clone(), - ]); + fn get_field_value(&self, field: &str) -> RS> { + match field { + + VOTE_ID => { + attr_field_access::attr_get_value::<_>(self.vote_id.get()) } - &TUPLE_DESC - } - - fn object_name() -> &'static str { - VOTE_RESULT - } - - fn get_field_binary(&self, field: &str) -> RS>> { - match field { - VOTE_ID => attr_field_access::attr_get_binary::<_>(self.vote_id.get()), - - TOPIC => attr_field_access::attr_get_binary::<_>(self.topic.get()), - - VOTE_ENDED => attr_field_access::attr_get_binary::<_>(self.vote_ended.get()), - - TOTAL_VOTES => attr_field_access::attr_get_binary::<_>(self.total_votes.get()), - - OPTIONS => attr_field_access::attr_get_binary::<_>(self.options.get()), - - _ => { - panic!("unknown name"); - } + + TOPIC => { + attr_field_access::attr_get_value::<_>(self.topic.get()) } - } - - fn set_field_binary>(&mut self, field: &str, binary: B) -> RS<()> { - match field { - VOTE_ID => { - attr_field_access::attr_set_binary::<_, _>( - self.vote_id.get_mut(), - binary.as_ref(), - )?; - } - - TOPIC => { - attr_field_access::attr_set_binary::<_, _>( - self.topic.get_mut(), - binary.as_ref(), - )?; - } - - VOTE_ENDED => { - attr_field_access::attr_set_binary::<_, _>( - self.vote_ended.get_mut(), - binary.as_ref(), - )?; - } - - TOTAL_VOTES => { - attr_field_access::attr_set_binary::<_, _>( - self.total_votes.get_mut(), - binary.as_ref(), - )?; - } - - OPTIONS => { - attr_field_access::attr_set_binary::<_, _>( - self.options.get_mut(), - binary.as_ref(), - )?; - } - - _ => { - panic!("unknown name"); - } + + VOTE_ENDED => { + attr_field_access::attr_get_value::<_>(self.vote_ended.get()) } - Ok(()) + + TOTAL_VOTES => { + attr_field_access::attr_get_value::<_>(self.total_votes.get()) + } + + OPTIONS => { + attr_field_access::attr_get_value::<_>(self.options.get()) + } + + _ => { panic!("unknown name"); } } + } - fn get_field_value(&self, field: &str) -> RS> { - match field { - VOTE_ID => attr_field_access::attr_get_value::<_>(self.vote_id.get()), - - TOPIC => attr_field_access::attr_get_value::<_>(self.topic.get()), - - VOTE_ENDED => attr_field_access::attr_get_value::<_>(self.vote_ended.get()), - - TOTAL_VOTES => attr_field_access::attr_get_value::<_>(self.total_votes.get()), - - OPTIONS => attr_field_access::attr_get_value::<_>(self.options.get()), - - _ => { - panic!("unknown name"); - } + fn set_field_value>(&mut self, field: &str, value: B) -> RS<()> { + match field { + + VOTE_ID => { + attr_field_access::attr_set_value::<_, _>(self.vote_id.get_mut(), value)?; + } + + TOPIC => { + attr_field_access::attr_set_value::<_, _>(self.topic.get_mut(), value)?; } + + VOTE_ENDED => { + attr_field_access::attr_set_value::<_, _>(self.vote_ended.get_mut(), value)?; + } + + TOTAL_VOTES => { + attr_field_access::attr_set_value::<_, _>(self.total_votes.get_mut(), value)?; + } + + OPTIONS => { + attr_field_access::attr_set_value::<_, _>(self.options.get_mut(), value)?; + } + + _ => { panic!("unknown name"); } } + Ok(()) + } +} - fn set_field_value>(&mut self, field: &str, value: B) -> RS<()> { - match field { - VOTE_ID => { - attr_field_access::attr_set_value::<_, _>(self.vote_id.get_mut(), value)?; - } - - TOPIC => { - attr_field_access::attr_set_value::<_, _>(self.topic.get_mut(), value)?; - } - - VOTE_ENDED => { - attr_field_access::attr_set_value::<_, _>(self.vote_ended.get_mut(), value)?; - } - - TOTAL_VOTES => { - attr_field_access::attr_set_value::<_, _>(self.total_votes.get_mut(), value)?; - } - OPTIONS => { - attr_field_access::attr_set_value::<_, _>(self.options.get_mut(), value)?; - } +// attribute struct definition +#[derive(Default, Clone, Debug)] +pub struct AttrVoteId { + is_dirty:bool, + value: Option +} - _ => { - panic!("unknown name"); - } - } - Ok(()) +impl AttrVoteId { + fn from(value:Option) -> Self { + Self { + is_dirty: false, + value } } - // attribute struct definition - #[derive(Default, Clone, Debug)] - pub struct AttrVoteId { - is_dirty: bool, - value: Option, + fn get(&self) -> &Option { + &self.value } - impl AttrVoteId { - fn from(value: Option) -> Self { - Self { - is_dirty: false, - value, - } - } + fn get_mut(&mut self) -> &mut Option { + &mut self.value + } - fn get(&self) -> &Option { - &self.value - } + fn set(&mut self, value:Option) { + self.value = value + } - fn get_mut(&mut self) -> &mut Option { - &mut self.value - } + fn update(&mut self, value: String) { + self.is_dirty = true; + self.value = Some(value) + } +} - fn set(&mut self, value: Option) { - self.value = value - } +impl AttrValue for AttrVoteId { + fn dat_type() -> &'static DatType { + static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); + ONCE_LOCK.get_or_init(|| Self::attr_dat_type()) + } - fn update(&mut self, value: String) { - self.is_dirty = true; - self.value = Some(value) - } + fn datum_desc() -> &'static DatumDesc { + static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); + ONCE_LOCK.get_or_init(|| Self::attr_datum_desc()) } - impl AttrValue for AttrVoteId { - fn dat_type() -> &'static DatType { - static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); - ONCE_LOCK.get_or_init(|| Self::attr_dat_type()) - } + fn object_name() -> &'static str { + VOTE_RESULT + } - fn datum_desc() -> &'static DatumDesc { - static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); - ONCE_LOCK.get_or_init(|| Self::attr_datum_desc()) - } + fn attr_name() -> &'static str { + VOTE_ID + } +} - fn object_name() -> &'static str { - VOTE_RESULT - } +// attribute struct definition +#[derive(Default, Clone, Debug)] +pub struct AttrTopic { + is_dirty:bool, + value: Option +} - fn attr_name() -> &'static str { - VOTE_ID +impl AttrTopic { + fn from(value:Option) -> Self { + Self { + is_dirty: false, + value } } - // attribute struct definition - #[derive(Default, Clone, Debug)] - pub struct AttrTopic { - is_dirty: bool, - value: Option, + fn get(&self) -> &Option { + &self.value } - impl AttrTopic { - fn from(value: Option) -> Self { - Self { - is_dirty: false, - value, - } - } + fn get_mut(&mut self) -> &mut Option { + &mut self.value + } - fn get(&self) -> &Option { - &self.value - } + fn set(&mut self, value:Option) { + self.value = value + } - fn get_mut(&mut self) -> &mut Option { - &mut self.value - } + fn update(&mut self, value: String) { + self.is_dirty = true; + self.value = Some(value) + } +} - fn set(&mut self, value: Option) { - self.value = value - } +impl AttrValue for AttrTopic { + fn dat_type() -> &'static DatType { + static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); + ONCE_LOCK.get_or_init(|| Self::attr_dat_type()) + } - fn update(&mut self, value: String) { - self.is_dirty = true; - self.value = Some(value) - } + fn datum_desc() -> &'static DatumDesc { + static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); + ONCE_LOCK.get_or_init(|| Self::attr_datum_desc()) } - impl AttrValue for AttrTopic { - fn dat_type() -> &'static DatType { - static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); - ONCE_LOCK.get_or_init(|| Self::attr_dat_type()) - } + fn object_name() -> &'static str { + VOTE_RESULT + } - fn datum_desc() -> &'static DatumDesc { - static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); - ONCE_LOCK.get_or_init(|| Self::attr_datum_desc()) - } + fn attr_name() -> &'static str { + TOPIC + } +} - fn object_name() -> &'static str { - VOTE_RESULT - } +// attribute struct definition +#[derive(Default, Clone, Debug)] +pub struct AttrVoteEnded { + is_dirty:bool, + value: Option +} - fn attr_name() -> &'static str { - TOPIC +impl AttrVoteEnded { + fn from(value:Option) -> Self { + Self { + is_dirty: false, + value } } - // attribute struct definition - #[derive(Default, Clone, Debug)] - pub struct AttrVoteEnded { - is_dirty: bool, - value: Option, + fn get(&self) -> &Option { + &self.value } - impl AttrVoteEnded { - fn from(value: Option) -> Self { - Self { - is_dirty: false, - value, - } - } + fn get_mut(&mut self) -> &mut Option { + &mut self.value + } - fn get(&self) -> &Option { - &self.value - } + fn set(&mut self, value:Option) { + self.value = value + } - fn get_mut(&mut self) -> &mut Option { - &mut self.value - } + fn update(&mut self, value: i32) { + self.is_dirty = true; + self.value = Some(value) + } +} - fn set(&mut self, value: Option) { - self.value = value - } +impl AttrValue for AttrVoteEnded { + fn dat_type() -> &'static DatType { + static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); + ONCE_LOCK.get_or_init(|| Self::attr_dat_type()) + } - fn update(&mut self, value: i32) { - self.is_dirty = true; - self.value = Some(value) - } + fn datum_desc() -> &'static DatumDesc { + static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); + ONCE_LOCK.get_or_init(|| Self::attr_datum_desc()) } - impl AttrValue for AttrVoteEnded { - fn dat_type() -> &'static DatType { - static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); - ONCE_LOCK.get_or_init(|| Self::attr_dat_type()) - } + fn object_name() -> &'static str { + VOTE_RESULT + } - fn datum_desc() -> &'static DatumDesc { - static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); - ONCE_LOCK.get_or_init(|| Self::attr_datum_desc()) - } + fn attr_name() -> &'static str { + VOTE_ENDED + } +} - fn object_name() -> &'static str { - VOTE_RESULT - } +// attribute struct definition +#[derive(Default, Clone, Debug)] +pub struct AttrTotalVotes { + is_dirty:bool, + value: Option +} - fn attr_name() -> &'static str { - VOTE_ENDED +impl AttrTotalVotes { + fn from(value:Option) -> Self { + Self { + is_dirty: false, + value } } - // attribute struct definition - #[derive(Default, Clone, Debug)] - pub struct AttrTotalVotes { - is_dirty: bool, - value: Option, + fn get(&self) -> &Option { + &self.value } - impl AttrTotalVotes { - fn from(value: Option) -> Self { - Self { - is_dirty: false, - value, - } - } + fn get_mut(&mut self) -> &mut Option { + &mut self.value + } - fn get(&self) -> &Option { - &self.value - } + fn set(&mut self, value:Option) { + self.value = value + } - fn get_mut(&mut self) -> &mut Option { - &mut self.value - } + fn update(&mut self, value: i32) { + self.is_dirty = true; + self.value = Some(value) + } +} - fn set(&mut self, value: Option) { - self.value = value - } +impl AttrValue for AttrTotalVotes { + fn dat_type() -> &'static DatType { + static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); + ONCE_LOCK.get_or_init(|| Self::attr_dat_type()) + } - fn update(&mut self, value: i32) { - self.is_dirty = true; - self.value = Some(value) - } + fn datum_desc() -> &'static DatumDesc { + static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); + ONCE_LOCK.get_or_init(|| Self::attr_datum_desc()) } - impl AttrValue for AttrTotalVotes { - fn dat_type() -> &'static DatType { - static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); - ONCE_LOCK.get_or_init(|| Self::attr_dat_type()) - } + fn object_name() -> &'static str { + VOTE_RESULT + } - fn datum_desc() -> &'static DatumDesc { - static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); - ONCE_LOCK.get_or_init(|| Self::attr_datum_desc()) - } + fn attr_name() -> &'static str { + TOTAL_VOTES + } +} - fn object_name() -> &'static str { - VOTE_RESULT - } +// attribute struct definition +#[derive(Default, Clone, Debug)] +pub struct AttrOptions { + is_dirty:bool, + value: Option +} - fn attr_name() -> &'static str { - TOTAL_VOTES +impl AttrOptions { + fn from(value:Option) -> Self { + Self { + is_dirty: false, + value } } - // attribute struct definition - #[derive(Default, Clone, Debug)] - pub struct AttrOptions { - is_dirty: bool, - value: Option, + fn get(&self) -> &Option { + &self.value } - impl AttrOptions { - fn from(value: Option) -> Self { - Self { - is_dirty: false, - value, - } - } - - fn get(&self) -> &Option { - &self.value - } - - fn get_mut(&mut self) -> &mut Option { - &mut self.value - } + fn get_mut(&mut self) -> &mut Option { + &mut self.value + } - fn set(&mut self, value: Option) { - self.value = value - } + fn set(&mut self, value:Option) { + self.value = value + } - fn update(&mut self, value: String) { - self.is_dirty = true; - self.value = Some(value) - } + fn update(&mut self, value: String) { + self.is_dirty = true; + self.value = Some(value) } +} - impl AttrValue for AttrOptions { - fn dat_type() -> &'static DatType { - static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); - ONCE_LOCK.get_or_init(|| Self::attr_dat_type()) - } +impl AttrValue for AttrOptions { + fn dat_type() -> &'static DatType { + static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); + ONCE_LOCK.get_or_init(|| Self::attr_dat_type()) + } - fn datum_desc() -> &'static DatumDesc { - static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); - ONCE_LOCK.get_or_init(|| Self::attr_datum_desc()) - } + fn datum_desc() -> &'static DatumDesc { + static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); + ONCE_LOCK.get_or_init(|| Self::attr_datum_desc()) + } - fn object_name() -> &'static str { - VOTE_RESULT - } + fn object_name() -> &'static str { + VOTE_RESULT + } - fn attr_name() -> &'static str { - OPTIONS - } + fn attr_name() -> &'static str { + OPTIONS } } + + +} \ No newline at end of file diff --git a/example/vote/src/generated/votes.rs b/example/vote/src/generated/votes.rs index 6f1a657..4471934 100644 --- a/example/vote/src/generated/votes.rs +++ b/example/vote/src/generated/votes.rs @@ -1,731 +1,781 @@ pub mod object { - use lazy_static::lazy_static; - use mudu::common::result::RS; - use mudu_contract::database::attr_field_access; - use mudu_contract::database::attr_value::AttrValue; - use mudu_contract::database::entity::Entity; - use mudu_contract::database::entity_utils; - use mudu_contract::database::sql_params::SQLParamMarker; - use mudu_contract::tuple::datum_desc::DatumDesc; - use mudu_contract::tuple::tuple_datum::TupleDatumMarker; - use mudu_contract::tuple::tuple_field_desc::TupleFieldDesc; - use mudu_type::dat_binary::DatBinary; - use mudu_type::dat_textual::DatTextual; - use mudu_type::dat_type::DatType; - use mudu_type::dat_type_id::DatTypeID; - use mudu_type::dat_value::DatValue; - use mudu_type::datum::{Datum, DatumDyn}; - - // constant definition - const VOTES: &str = "votes"; - - const VOTE_ID: &str = "vote_id"; - - const CREATOR_ID: &str = "creator_id"; - - const TOPIC: &str = "topic"; - - const VOTE_TYPE: &str = "vote_type"; - - const MAX_CHOICES: &str = "max_choices"; - - const END_TIME: &str = "end_time"; - - const VISIBILITY_RULE: &str = "visibility_rule"; - - // entity struct definition - #[derive(Debug, Clone, Default)] - pub struct Votes { - vote_id: AttrVoteId, - - creator_id: AttrCreatorId, - - topic: AttrTopic, - - vote_type: AttrVoteType, - - max_choices: AttrMaxChoices, - - end_time: AttrEndTime, +use lazy_static::lazy_static; +use mududb::common::result::RS; +use mududb::contract::database::attr_field_access; +use mududb::contract::database::attr_value::AttrValue; +use mududb::contract::database::entity::Entity; +use mududb::contract::database::entity_utils; +use mududb::contract::database::sql_params::SQLParamMarker; +use mududb::contract::tuple::datum_desc::DatumDesc; +use mududb::contract::tuple::tuple_field_desc::TupleFieldDesc; +use mududb::contract::tuple::tuple_datum::TupleDatumMarker; +use mududb::types::dat_binary::DatBinary; +use mududb::types::dat_textual::DatTextual; +use mududb::types::dat_type::DatType; +use mududb::types::dat_type_id::DatTypeID; +use mududb::types::dat_value::DatValue; +use mududb::types::datum::{Datum, DatumDyn}; + +// constant definition +const VOTES:&str = "votes"; + +const VOTE_ID:&str = "vote_id"; + +const CREATOR_ID:&str = "creator_id"; + +const TOPIC:&str = "topic"; + +const VOTE_TYPE:&str = "vote_type"; + +const MAX_CHOICES:&str = "max_choices"; + +const END_TIME:&str = "end_time"; + +const VISIBILITY_RULE:&str = "visibility_rule"; + + +// entity struct definition +#[derive(Debug, Clone, Default)] +pub struct Votes { + + vote_id: AttrVoteId, + + creator_id: AttrCreatorId, + + topic: AttrTopic, + + vote_type: AttrVoteType, + + max_choices: AttrMaxChoices, + + end_time: AttrEndTime, + + visibility_rule: AttrVisibilityRule, + +} - visibility_rule: AttrVisibilityRule, +impl TupleDatumMarker for Votes {} + +impl SQLParamMarker for Votes {} + +impl Votes { + pub fn new( + vote_id: Option, + creator_id: Option, + topic: Option, + vote_type: Option, + max_choices: Option, + end_time: Option, + visibility_rule: Option, + + ) -> Self { + let s = Self { + + vote_id : AttrVoteId::from(vote_id), + + creator_id : AttrCreatorId::from(creator_id), + + topic : AttrTopic::from(topic), + + vote_type : AttrVoteType::from(vote_type), + + max_choices : AttrMaxChoices::from(max_choices), + + end_time : AttrEndTime::from(end_time), + + visibility_rule : AttrVisibilityRule::from(visibility_rule), + + }; + s } - impl TupleDatumMarker for Votes {} - - impl SQLParamMarker for Votes {} - - impl Votes { - pub fn new( - vote_id: Option, - creator_id: Option, - topic: Option, - vote_type: Option, - max_choices: Option, - end_time: Option, - visibility_rule: Option, - ) -> Self { - let s = Self { - vote_id: AttrVoteId::from(vote_id), - - creator_id: AttrCreatorId::from(creator_id), + pub fn new_empty() -> Self { + Self::default() + } - topic: AttrTopic::from(topic), + + pub fn set_vote_id( + &mut self, + vote_id: String, + ) { + self.vote_id.update(vote_id) + } - vote_type: AttrVoteType::from(vote_type), + pub fn get_vote_id( + &self, + ) -> &Option { + self.vote_id.get() + } + + pub fn set_creator_id( + &mut self, + creator_id: String, + ) { + self.creator_id.update(creator_id) + } - max_choices: AttrMaxChoices::from(max_choices), + pub fn get_creator_id( + &self, + ) -> &Option { + self.creator_id.get() + } + + pub fn set_topic( + &mut self, + topic: String, + ) { + self.topic.update(topic) + } - end_time: AttrEndTime::from(end_time), + pub fn get_topic( + &self, + ) -> &Option { + self.topic.get() + } + + pub fn set_vote_type( + &mut self, + vote_type: String, + ) { + self.vote_type.update(vote_type) + } - visibility_rule: AttrVisibilityRule::from(visibility_rule), - }; - s - } + pub fn get_vote_type( + &self, + ) -> &Option { + self.vote_type.get() + } + + pub fn set_max_choices( + &mut self, + max_choices: i32, + ) { + self.max_choices.update(max_choices) + } - pub fn new_empty() -> Self { - Self::default() - } + pub fn get_max_choices( + &self, + ) -> &Option { + self.max_choices.get() + } + + pub fn set_end_time( + &mut self, + end_time: i32, + ) { + self.end_time.update(end_time) + } - pub fn set_vote_id(&mut self, vote_id: String) { - self.vote_id.update(vote_id) - } + pub fn get_end_time( + &self, + ) -> &Option { + self.end_time.get() + } + + pub fn set_visibility_rule( + &mut self, + visibility_rule: String, + ) { + self.visibility_rule.update(visibility_rule) + } - pub fn get_vote_id(&self) -> &Option { - self.vote_id.get() - } + pub fn get_visibility_rule( + &self, + ) -> &Option { + self.visibility_rule.get() + } + +} - pub fn set_creator_id(&mut self, creator_id: String) { - self.creator_id.update(creator_id) +impl Datum for Votes { + fn dat_type() -> &'static DatType { + lazy_static! { + static ref DAT_TYPE: DatType = entity_utils::entity_dat_type::(); } + &DAT_TYPE + } - pub fn get_creator_id(&self) -> &Option { - self.creator_id.get() - } + fn from_binary(binary: &[u8]) -> RS { + entity_utils::entity_from_binary(binary) + } - pub fn set_topic(&mut self, topic: String) { - self.topic.update(topic) - } + fn from_value(value: &DatValue) -> RS { + entity_utils::entity_from_value(value) + } - pub fn get_topic(&self) -> &Option { - self.topic.get() - } + fn from_textual(textual: &str) -> RS { + entity_utils::entity_from_textual(textual) + } +} - pub fn set_vote_type(&mut self, vote_type: String) { - self.vote_type.update(vote_type) - } +impl DatumDyn for Votes { + fn dat_type_id(&self) -> RS { + entity_utils::entity_dat_type_id() + } - pub fn get_vote_type(&self) -> &Option { - self.vote_type.get() - } + fn to_binary(&self, dat_type: &DatType) -> RS { + entity_utils::entity_to_binary(self, dat_type) + } - pub fn set_max_choices(&mut self, max_choices: i32) { - self.max_choices.update(max_choices) - } + fn to_textual(&self, dat_type: &DatType) -> RS { + entity_utils::entity_to_textual(self, dat_type) + } - pub fn get_max_choices(&self) -> &Option { - self.max_choices.get() - } + fn to_value(&self, dat_type: &DatType) -> RS { + entity_utils::entity_to_value(self, dat_type) + } - pub fn set_end_time(&mut self, end_time: i32) { - self.end_time.update(end_time) - } + fn clone_boxed(&self) -> Box { + entity_utils::entity_clone_boxed(self) + } +} - pub fn get_end_time(&self) -> &Option { - self.end_time.get() - } +impl Entity for Votes { + fn new_empty() -> Self { + Self::new_empty() + } - pub fn set_visibility_rule(&mut self, visibility_rule: String) { - self.visibility_rule.update(visibility_rule) - } + fn tuple_desc() -> &'static TupleFieldDesc { + lazy_static! { + static ref TUPLE_DESC: TupleFieldDesc = TupleFieldDesc::new(vec![ + + AttrVoteId::datum_desc().clone(), + + AttrCreatorId::datum_desc().clone(), + + AttrTopic::datum_desc().clone(), + + AttrVoteType::datum_desc().clone(), + + AttrMaxChoices::datum_desc().clone(), + + AttrEndTime::datum_desc().clone(), + + AttrVisibilityRule::datum_desc().clone(), + + ]); + } + &TUPLE_DESC + } - pub fn get_visibility_rule(&self) -> &Option { - self.visibility_rule.get() - } + fn object_name() -> &'static str { + VOTES } - impl Datum for Votes { - fn dat_type() -> &'static DatType { - lazy_static! { - static ref DAT_TYPE: DatType = entity_utils::entity_dat_type::(); + fn get_field_binary(&self, field: &str) -> RS>> { + match field { + + VOTE_ID => { + attr_field_access::attr_get_binary::<_>(self.vote_id.get()) } - &DAT_TYPE - } - - fn from_binary(binary: &[u8]) -> RS { - entity_utils::entity_from_binary(binary) - } - - fn from_value(value: &DatValue) -> RS { - entity_utils::entity_from_value(value) - } - - fn from_textual(textual: &str) -> RS { - entity_utils::entity_from_textual(textual) + + CREATOR_ID => { + attr_field_access::attr_get_binary::<_>(self.creator_id.get()) + } + + TOPIC => { + attr_field_access::attr_get_binary::<_>(self.topic.get()) + } + + VOTE_TYPE => { + attr_field_access::attr_get_binary::<_>(self.vote_type.get()) + } + + MAX_CHOICES => { + attr_field_access::attr_get_binary::<_>(self.max_choices.get()) + } + + END_TIME => { + attr_field_access::attr_get_binary::<_>(self.end_time.get()) + } + + VISIBILITY_RULE => { + attr_field_access::attr_get_binary::<_>(self.visibility_rule.get()) + } + + _ => { panic!("unknown name"); } } } - impl DatumDyn for Votes { - fn dat_type_id(&self) -> RS { - entity_utils::entity_dat_type_id() - } - - fn to_binary(&self, dat_type: &DatType) -> RS { - entity_utils::entity_to_binary(self, dat_type) - } - - fn to_textual(&self, dat_type: &DatType) -> RS { - entity_utils::entity_to_textual(self, dat_type) - } - - fn to_value(&self, dat_type: &DatType) -> RS { - entity_utils::entity_to_value(self, dat_type) - } - - fn clone_boxed(&self) -> Box { - entity_utils::entity_clone_boxed(self) + fn set_field_binary>(&mut self, field: &str, binary: B) -> RS<()> { + match field { + + VOTE_ID => { + attr_field_access::attr_set_binary::<_, _>(self.vote_id.get_mut(), binary.as_ref())?; + } + + CREATOR_ID => { + attr_field_access::attr_set_binary::<_, _>(self.creator_id.get_mut(), binary.as_ref())?; + } + + TOPIC => { + attr_field_access::attr_set_binary::<_, _>(self.topic.get_mut(), binary.as_ref())?; + } + + VOTE_TYPE => { + attr_field_access::attr_set_binary::<_, _>(self.vote_type.get_mut(), binary.as_ref())?; + } + + MAX_CHOICES => { + attr_field_access::attr_set_binary::<_, _>(self.max_choices.get_mut(), binary.as_ref())?; + } + + END_TIME => { + attr_field_access::attr_set_binary::<_, _>(self.end_time.get_mut(), binary.as_ref())?; + } + + VISIBILITY_RULE => { + attr_field_access::attr_set_binary::<_, _>(self.visibility_rule.get_mut(), binary.as_ref())?; + } + + _ => { panic!("unknown name"); } } + Ok(()) } - impl Entity for Votes { - fn new_empty() -> Self { - Self::new_empty() - } - - fn tuple_desc() -> &'static TupleFieldDesc { - lazy_static! { - static ref TUPLE_DESC: TupleFieldDesc = TupleFieldDesc::new(vec![ - AttrVoteId::datum_desc().clone(), - AttrCreatorId::datum_desc().clone(), - AttrTopic::datum_desc().clone(), - AttrVoteType::datum_desc().clone(), - AttrMaxChoices::datum_desc().clone(), - AttrEndTime::datum_desc().clone(), - AttrVisibilityRule::datum_desc().clone(), - ]); + fn get_field_value(&self, field: &str) -> RS> { + match field { + + VOTE_ID => { + attr_field_access::attr_get_value::<_>(self.vote_id.get()) } - &TUPLE_DESC - } - - fn object_name() -> &'static str { - VOTES - } - - fn get_field_binary(&self, field: &str) -> RS>> { - match field { - VOTE_ID => attr_field_access::attr_get_binary::<_>(self.vote_id.get()), - - CREATOR_ID => attr_field_access::attr_get_binary::<_>(self.creator_id.get()), - - TOPIC => attr_field_access::attr_get_binary::<_>(self.topic.get()), - - VOTE_TYPE => attr_field_access::attr_get_binary::<_>(self.vote_type.get()), - - MAX_CHOICES => attr_field_access::attr_get_binary::<_>(self.max_choices.get()), - - END_TIME => attr_field_access::attr_get_binary::<_>(self.end_time.get()), - - VISIBILITY_RULE => { - attr_field_access::attr_get_binary::<_>(self.visibility_rule.get()) - } - - _ => { - panic!("unknown name"); - } + + CREATOR_ID => { + attr_field_access::attr_get_value::<_>(self.creator_id.get()) } - } - - fn set_field_binary>(&mut self, field: &str, binary: B) -> RS<()> { - match field { - VOTE_ID => { - attr_field_access::attr_set_binary::<_, _>( - self.vote_id.get_mut(), - binary.as_ref(), - )?; - } - - CREATOR_ID => { - attr_field_access::attr_set_binary::<_, _>( - self.creator_id.get_mut(), - binary.as_ref(), - )?; - } - - TOPIC => { - attr_field_access::attr_set_binary::<_, _>( - self.topic.get_mut(), - binary.as_ref(), - )?; - } - - VOTE_TYPE => { - attr_field_access::attr_set_binary::<_, _>( - self.vote_type.get_mut(), - binary.as_ref(), - )?; - } - - MAX_CHOICES => { - attr_field_access::attr_set_binary::<_, _>( - self.max_choices.get_mut(), - binary.as_ref(), - )?; - } - - END_TIME => { - attr_field_access::attr_set_binary::<_, _>( - self.end_time.get_mut(), - binary.as_ref(), - )?; - } - - VISIBILITY_RULE => { - attr_field_access::attr_set_binary::<_, _>( - self.visibility_rule.get_mut(), - binary.as_ref(), - )?; - } - - _ => { - panic!("unknown name"); - } + + TOPIC => { + attr_field_access::attr_get_value::<_>(self.topic.get()) } - Ok(()) - } - - fn get_field_value(&self, field: &str) -> RS> { - match field { - VOTE_ID => attr_field_access::attr_get_value::<_>(self.vote_id.get()), - - CREATOR_ID => attr_field_access::attr_get_value::<_>(self.creator_id.get()), - - TOPIC => attr_field_access::attr_get_value::<_>(self.topic.get()), - - VOTE_TYPE => attr_field_access::attr_get_value::<_>(self.vote_type.get()), - - MAX_CHOICES => attr_field_access::attr_get_value::<_>(self.max_choices.get()), - - END_TIME => attr_field_access::attr_get_value::<_>(self.end_time.get()), - - VISIBILITY_RULE => { - attr_field_access::attr_get_value::<_>(self.visibility_rule.get()) - } - - _ => { - panic!("unknown name"); - } + + VOTE_TYPE => { + attr_field_access::attr_get_value::<_>(self.vote_type.get()) + } + + MAX_CHOICES => { + attr_field_access::attr_get_value::<_>(self.max_choices.get()) + } + + END_TIME => { + attr_field_access::attr_get_value::<_>(self.end_time.get()) + } + + VISIBILITY_RULE => { + attr_field_access::attr_get_value::<_>(self.visibility_rule.get()) } + + _ => { panic!("unknown name"); } } + } - fn set_field_value>(&mut self, field: &str, value: B) -> RS<()> { - match field { - VOTE_ID => { - attr_field_access::attr_set_value::<_, _>(self.vote_id.get_mut(), value)?; - } - - CREATOR_ID => { - attr_field_access::attr_set_value::<_, _>(self.creator_id.get_mut(), value)?; - } - - TOPIC => { - attr_field_access::attr_set_value::<_, _>(self.topic.get_mut(), value)?; - } - - VOTE_TYPE => { - attr_field_access::attr_set_value::<_, _>(self.vote_type.get_mut(), value)?; - } - - MAX_CHOICES => { - attr_field_access::attr_set_value::<_, _>(self.max_choices.get_mut(), value)?; - } - - END_TIME => { - attr_field_access::attr_set_value::<_, _>(self.end_time.get_mut(), value)?; - } - - VISIBILITY_RULE => { - attr_field_access::attr_set_value::<_, _>( - self.visibility_rule.get_mut(), - value, - )?; - } - - _ => { - panic!("unknown name"); - } + fn set_field_value>(&mut self, field: &str, value: B) -> RS<()> { + match field { + + VOTE_ID => { + attr_field_access::attr_set_value::<_, _>(self.vote_id.get_mut(), value)?; + } + + CREATOR_ID => { + attr_field_access::attr_set_value::<_, _>(self.creator_id.get_mut(), value)?; + } + + TOPIC => { + attr_field_access::attr_set_value::<_, _>(self.topic.get_mut(), value)?; + } + + VOTE_TYPE => { + attr_field_access::attr_set_value::<_, _>(self.vote_type.get_mut(), value)?; } - Ok(()) + + MAX_CHOICES => { + attr_field_access::attr_set_value::<_, _>(self.max_choices.get_mut(), value)?; + } + + END_TIME => { + attr_field_access::attr_set_value::<_, _>(self.end_time.get_mut(), value)?; + } + + VISIBILITY_RULE => { + attr_field_access::attr_set_value::<_, _>(self.visibility_rule.get_mut(), value)?; + } + + _ => { panic!("unknown name"); } } + Ok(()) } +} - // attribute struct definition - #[derive(Default, Clone, Debug)] - pub struct AttrVoteId { - is_dirty: bool, - value: Option, - } - impl AttrVoteId { - fn from(value: Option) -> Self { - Self { - is_dirty: false, - value, - } - } +// attribute struct definition +#[derive(Default, Clone, Debug)] +pub struct AttrVoteId { + is_dirty:bool, + value: Option +} - fn get(&self) -> &Option { - &self.value +impl AttrVoteId { + fn from(value:Option) -> Self { + Self { + is_dirty: false, + value } + } - fn get_mut(&mut self) -> &mut Option { - &mut self.value - } + fn get(&self) -> &Option { + &self.value + } - fn set(&mut self, value: Option) { - self.value = value - } + fn get_mut(&mut self) -> &mut Option { + &mut self.value + } - fn update(&mut self, value: String) { - self.is_dirty = true; - self.value = Some(value) - } + fn set(&mut self, value:Option) { + self.value = value } - impl AttrValue for AttrVoteId { - fn dat_type() -> &'static DatType { - static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); - ONCE_LOCK.get_or_init(|| Self::attr_dat_type()) - } + fn update(&mut self, value: String) { + self.is_dirty = true; + self.value = Some(value) + } +} - fn datum_desc() -> &'static DatumDesc { - static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); - ONCE_LOCK.get_or_init(|| Self::attr_datum_desc()) - } +impl AttrValue for AttrVoteId { + fn dat_type() -> &'static DatType { + static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); + ONCE_LOCK.get_or_init(|| Self::attr_dat_type()) + } - fn object_name() -> &'static str { - VOTES - } + fn datum_desc() -> &'static DatumDesc { + static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); + ONCE_LOCK.get_or_init(|| Self::attr_datum_desc()) + } - fn attr_name() -> &'static str { - VOTE_ID - } + fn object_name() -> &'static str { + VOTES } - // attribute struct definition - #[derive(Default, Clone, Debug)] - pub struct AttrCreatorId { - is_dirty: bool, - value: Option, + fn attr_name() -> &'static str { + VOTE_ID } +} - impl AttrCreatorId { - fn from(value: Option) -> Self { - Self { - is_dirty: false, - value, - } - } +// attribute struct definition +#[derive(Default, Clone, Debug)] +pub struct AttrCreatorId { + is_dirty:bool, + value: Option +} - fn get(&self) -> &Option { - &self.value +impl AttrCreatorId { + fn from(value:Option) -> Self { + Self { + is_dirty: false, + value } + } - fn get_mut(&mut self) -> &mut Option { - &mut self.value - } + fn get(&self) -> &Option { + &self.value + } - fn set(&mut self, value: Option) { - self.value = value - } + fn get_mut(&mut self) -> &mut Option { + &mut self.value + } - fn update(&mut self, value: String) { - self.is_dirty = true; - self.value = Some(value) - } + fn set(&mut self, value:Option) { + self.value = value } - impl AttrValue for AttrCreatorId { - fn dat_type() -> &'static DatType { - static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); - ONCE_LOCK.get_or_init(|| Self::attr_dat_type()) - } + fn update(&mut self, value: String) { + self.is_dirty = true; + self.value = Some(value) + } +} - fn datum_desc() -> &'static DatumDesc { - static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); - ONCE_LOCK.get_or_init(|| Self::attr_datum_desc()) - } +impl AttrValue for AttrCreatorId { + fn dat_type() -> &'static DatType { + static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); + ONCE_LOCK.get_or_init(|| Self::attr_dat_type()) + } - fn object_name() -> &'static str { - VOTES - } + fn datum_desc() -> &'static DatumDesc { + static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); + ONCE_LOCK.get_or_init(|| Self::attr_datum_desc()) + } - fn attr_name() -> &'static str { - CREATOR_ID - } + fn object_name() -> &'static str { + VOTES } - // attribute struct definition - #[derive(Default, Clone, Debug)] - pub struct AttrTopic { - is_dirty: bool, - value: Option, + fn attr_name() -> &'static str { + CREATOR_ID } +} - impl AttrTopic { - fn from(value: Option) -> Self { - Self { - is_dirty: false, - value, - } - } +// attribute struct definition +#[derive(Default, Clone, Debug)] +pub struct AttrTopic { + is_dirty:bool, + value: Option +} - fn get(&self) -> &Option { - &self.value +impl AttrTopic { + fn from(value:Option) -> Self { + Self { + is_dirty: false, + value } + } - fn get_mut(&mut self) -> &mut Option { - &mut self.value - } + fn get(&self) -> &Option { + &self.value + } - fn set(&mut self, value: Option) { - self.value = value - } + fn get_mut(&mut self) -> &mut Option { + &mut self.value + } - fn update(&mut self, value: String) { - self.is_dirty = true; - self.value = Some(value) - } + fn set(&mut self, value:Option) { + self.value = value } - impl AttrValue for AttrTopic { - fn dat_type() -> &'static DatType { - static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); - ONCE_LOCK.get_or_init(|| Self::attr_dat_type()) - } + fn update(&mut self, value: String) { + self.is_dirty = true; + self.value = Some(value) + } +} - fn datum_desc() -> &'static DatumDesc { - static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); - ONCE_LOCK.get_or_init(|| Self::attr_datum_desc()) - } +impl AttrValue for AttrTopic { + fn dat_type() -> &'static DatType { + static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); + ONCE_LOCK.get_or_init(|| Self::attr_dat_type()) + } - fn object_name() -> &'static str { - VOTES - } + fn datum_desc() -> &'static DatumDesc { + static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); + ONCE_LOCK.get_or_init(|| Self::attr_datum_desc()) + } - fn attr_name() -> &'static str { - TOPIC - } + fn object_name() -> &'static str { + VOTES } - // attribute struct definition - #[derive(Default, Clone, Debug)] - pub struct AttrVoteType { - is_dirty: bool, - value: Option, + fn attr_name() -> &'static str { + TOPIC } +} - impl AttrVoteType { - fn from(value: Option) -> Self { - Self { - is_dirty: false, - value, - } - } +// attribute struct definition +#[derive(Default, Clone, Debug)] +pub struct AttrVoteType { + is_dirty:bool, + value: Option +} - fn get(&self) -> &Option { - &self.value +impl AttrVoteType { + fn from(value:Option) -> Self { + Self { + is_dirty: false, + value } + } - fn get_mut(&mut self) -> &mut Option { - &mut self.value - } + fn get(&self) -> &Option { + &self.value + } - fn set(&mut self, value: Option) { - self.value = value - } + fn get_mut(&mut self) -> &mut Option { + &mut self.value + } - fn update(&mut self, value: String) { - self.is_dirty = true; - self.value = Some(value) - } + fn set(&mut self, value:Option) { + self.value = value } - impl AttrValue for AttrVoteType { - fn dat_type() -> &'static DatType { - static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); - ONCE_LOCK.get_or_init(|| Self::attr_dat_type()) - } + fn update(&mut self, value: String) { + self.is_dirty = true; + self.value = Some(value) + } +} - fn datum_desc() -> &'static DatumDesc { - static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); - ONCE_LOCK.get_or_init(|| Self::attr_datum_desc()) - } +impl AttrValue for AttrVoteType { + fn dat_type() -> &'static DatType { + static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); + ONCE_LOCK.get_or_init(|| Self::attr_dat_type()) + } - fn object_name() -> &'static str { - VOTES - } + fn datum_desc() -> &'static DatumDesc { + static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); + ONCE_LOCK.get_or_init(|| Self::attr_datum_desc()) + } - fn attr_name() -> &'static str { - VOTE_TYPE - } + fn object_name() -> &'static str { + VOTES } - // attribute struct definition - #[derive(Default, Clone, Debug)] - pub struct AttrMaxChoices { - is_dirty: bool, - value: Option, + fn attr_name() -> &'static str { + VOTE_TYPE } +} - impl AttrMaxChoices { - fn from(value: Option) -> Self { - Self { - is_dirty: false, - value, - } - } +// attribute struct definition +#[derive(Default, Clone, Debug)] +pub struct AttrMaxChoices { + is_dirty:bool, + value: Option +} - fn get(&self) -> &Option { - &self.value +impl AttrMaxChoices { + fn from(value:Option) -> Self { + Self { + is_dirty: false, + value } + } - fn get_mut(&mut self) -> &mut Option { - &mut self.value - } + fn get(&self) -> &Option { + &self.value + } - fn set(&mut self, value: Option) { - self.value = value - } + fn get_mut(&mut self) -> &mut Option { + &mut self.value + } - fn update(&mut self, value: i32) { - self.is_dirty = true; - self.value = Some(value) - } + fn set(&mut self, value:Option) { + self.value = value } - impl AttrValue for AttrMaxChoices { - fn dat_type() -> &'static DatType { - static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); - ONCE_LOCK.get_or_init(|| Self::attr_dat_type()) - } + fn update(&mut self, value: i32) { + self.is_dirty = true; + self.value = Some(value) + } +} - fn datum_desc() -> &'static DatumDesc { - static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); - ONCE_LOCK.get_or_init(|| Self::attr_datum_desc()) - } +impl AttrValue for AttrMaxChoices { + fn dat_type() -> &'static DatType { + static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); + ONCE_LOCK.get_or_init(|| Self::attr_dat_type()) + } - fn object_name() -> &'static str { - VOTES - } + fn datum_desc() -> &'static DatumDesc { + static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); + ONCE_LOCK.get_or_init(|| Self::attr_datum_desc()) + } - fn attr_name() -> &'static str { - MAX_CHOICES - } + fn object_name() -> &'static str { + VOTES } - // attribute struct definition - #[derive(Default, Clone, Debug)] - pub struct AttrEndTime { - is_dirty: bool, - value: Option, + fn attr_name() -> &'static str { + MAX_CHOICES } +} - impl AttrEndTime { - fn from(value: Option) -> Self { - Self { - is_dirty: false, - value, - } - } +// attribute struct definition +#[derive(Default, Clone, Debug)] +pub struct AttrEndTime { + is_dirty:bool, + value: Option +} - fn get(&self) -> &Option { - &self.value +impl AttrEndTime { + fn from(value:Option) -> Self { + Self { + is_dirty: false, + value } + } - fn get_mut(&mut self) -> &mut Option { - &mut self.value - } + fn get(&self) -> &Option { + &self.value + } - fn set(&mut self, value: Option) { - self.value = value - } + fn get_mut(&mut self) -> &mut Option { + &mut self.value + } - fn update(&mut self, value: i32) { - self.is_dirty = true; - self.value = Some(value) - } + fn set(&mut self, value:Option) { + self.value = value } - impl AttrValue for AttrEndTime { - fn dat_type() -> &'static DatType { - static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); - ONCE_LOCK.get_or_init(|| Self::attr_dat_type()) - } + fn update(&mut self, value: i32) { + self.is_dirty = true; + self.value = Some(value) + } +} - fn datum_desc() -> &'static DatumDesc { - static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); - ONCE_LOCK.get_or_init(|| Self::attr_datum_desc()) - } +impl AttrValue for AttrEndTime { + fn dat_type() -> &'static DatType { + static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); + ONCE_LOCK.get_or_init(|| Self::attr_dat_type()) + } - fn object_name() -> &'static str { - VOTES - } + fn datum_desc() -> &'static DatumDesc { + static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); + ONCE_LOCK.get_or_init(|| Self::attr_datum_desc()) + } - fn attr_name() -> &'static str { - END_TIME - } + fn object_name() -> &'static str { + VOTES } - // attribute struct definition - #[derive(Default, Clone, Debug)] - pub struct AttrVisibilityRule { - is_dirty: bool, - value: Option, + fn attr_name() -> &'static str { + END_TIME } +} - impl AttrVisibilityRule { - fn from(value: Option) -> Self { - Self { - is_dirty: false, - value, - } - } +// attribute struct definition +#[derive(Default, Clone, Debug)] +pub struct AttrVisibilityRule { + is_dirty:bool, + value: Option +} - fn get(&self) -> &Option { - &self.value +impl AttrVisibilityRule { + fn from(value:Option) -> Self { + Self { + is_dirty: false, + value } + } - fn get_mut(&mut self) -> &mut Option { - &mut self.value - } + fn get(&self) -> &Option { + &self.value + } - fn set(&mut self, value: Option) { - self.value = value - } + fn get_mut(&mut self) -> &mut Option { + &mut self.value + } - fn update(&mut self, value: String) { - self.is_dirty = true; - self.value = Some(value) - } + fn set(&mut self, value:Option) { + self.value = value } - impl AttrValue for AttrVisibilityRule { - fn dat_type() -> &'static DatType { - static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); - ONCE_LOCK.get_or_init(|| Self::attr_dat_type()) - } + fn update(&mut self, value: String) { + self.is_dirty = true; + self.value = Some(value) + } +} - fn datum_desc() -> &'static DatumDesc { - static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); - ONCE_LOCK.get_or_init(|| Self::attr_datum_desc()) - } +impl AttrValue for AttrVisibilityRule { + fn dat_type() -> &'static DatType { + static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); + ONCE_LOCK.get_or_init(|| Self::attr_dat_type()) + } - fn object_name() -> &'static str { - VOTES - } + fn datum_desc() -> &'static DatumDesc { + static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); + ONCE_LOCK.get_or_init(|| Self::attr_datum_desc()) + } - fn attr_name() -> &'static str { - VISIBILITY_RULE - } + fn object_name() -> &'static str { + VOTES + } + + fn attr_name() -> &'static str { + VISIBILITY_RULE } } + + +} \ No newline at end of file diff --git a/example/vote/src/rust/options.rs b/example/vote/src/rust/options.rs index 9769dec..b3107c9 100644 --- a/example/vote/src/rust/options.rs +++ b/example/vote/src/rust/options.rs @@ -1,439 +1,417 @@ pub mod object { - use lazy_static::lazy_static; - use mudu::common::result::RS; - use mudu_contract::database::attr_field_access; - use mudu_contract::database::attr_value::AttrValue; - use mudu_contract::database::entity::Entity; - use mudu_contract::database::entity_utils; - use mudu_contract::database::sql_params::SQLParamMarker; - use mudu_contract::tuple::datum_desc::DatumDesc; - use mudu_contract::tuple::tuple_datum::TupleDatumMarker; - use mudu_contract::tuple::tuple_field_desc::TupleFieldDesc; - use mudu_type::dat_binary::DatBinary; - use mudu_type::dat_textual::DatTextual; - use mudu_type::dat_type::DatType; - use mudu_type::dat_type_id::DatTypeID; - use mudu_type::dat_value::DatValue; - use mudu_type::datum::{Datum, DatumDyn}; - - // constant definition - const OPTIONS: &str = "options"; - - const OPTION_ID: &str = "option_id"; - - const VOTE_ID: &str = "vote_id"; - - const OPTION_TEXT: &str = "option_text"; - - // entity struct definition - #[derive(Debug, Clone, Default)] - pub struct Options { - option_id: AttrOptionId, - - vote_id: AttrVoteId, +use lazy_static::lazy_static; +use mududb::common::result::RS; +use mududb::contract::database::attr_field_access; +use mududb::contract::database::attr_value::AttrValue; +use mududb::contract::database::entity::Entity; +use mududb::contract::database::entity_utils; +use mududb::contract::database::sql_params::SQLParamMarker; +use mududb::contract::tuple::datum_desc::DatumDesc; +use mududb::contract::tuple::tuple_field_desc::TupleFieldDesc; +use mududb::contract::tuple::tuple_datum::TupleDatumMarker; +use mududb::types::dat_binary::DatBinary; +use mududb::types::dat_textual::DatTextual; +use mududb::types::dat_type::DatType; +use mududb::types::dat_type_id::DatTypeID; +use mududb::types::dat_value::DatValue; +use mududb::types::datum::{Datum, DatumDyn}; + +// constant definition +const OPTIONS:&str = "options"; + +const OPTION_ID:&str = "option_id"; + +const VOTE_ID:&str = "vote_id"; + +const OPTION_TEXT:&str = "option_text"; + + +// entity struct definition +#[derive(Debug, Clone, Default)] +pub struct Options { + + option_id: AttrOptionId, + + vote_id: AttrVoteId, + + option_text: AttrOptionText, + +} - option_text: AttrOptionText, +impl TupleDatumMarker for Options {} + +impl SQLParamMarker for Options {} + +impl Options { + pub fn new( + option_id: Option, + vote_id: Option, + option_text: Option, + + ) -> Self { + let s = Self { + + option_id : AttrOptionId::from(option_id), + + vote_id : AttrVoteId::from(vote_id), + + option_text : AttrOptionText::from(option_text), + + }; + s } - impl TupleDatumMarker for Options {} - - impl SQLParamMarker for Options {} - - impl Options { - pub fn new( - option_id: Option, - vote_id: Option, - option_text: Option, - ) -> Self { - let s = Self { - option_id: AttrOptionId::from(option_id), - - vote_id: AttrVoteId::from(vote_id), - - option_text: AttrOptionText::from(option_text), - }; - s - } - - pub fn new_empty() -> Self { - Self::default() - } + pub fn new_empty() -> Self { + Self::default() + } - pub fn set_option_id(&mut self, option_id: String) { - self.option_id.update(option_id) - } + + pub fn set_option_id( + &mut self, + option_id: String, + ) { + self.option_id.update(option_id) + } - pub fn get_option_id(&self) -> &Option { - self.option_id.get() - } + pub fn get_option_id( + &self, + ) -> &Option { + self.option_id.get() + } + + pub fn set_vote_id( + &mut self, + vote_id: String, + ) { + self.vote_id.update(vote_id) + } - pub fn set_vote_id(&mut self, vote_id: String) { - self.vote_id.update(vote_id) - } + pub fn get_vote_id( + &self, + ) -> &Option { + self.vote_id.get() + } + + pub fn set_option_text( + &mut self, + option_text: String, + ) { + self.option_text.update(option_text) + } - pub fn get_vote_id(&self) -> &Option { - self.vote_id.get() - } + pub fn get_option_text( + &self, + ) -> &Option { + self.option_text.get() + } + +} - pub fn set_option_text(&mut self, option_text: String) { - self.option_text.update(option_text) +impl Datum for Options { + fn dat_type() -> &'static DatType { + lazy_static! { + static ref DAT_TYPE: DatType = entity_utils::entity_dat_type::(); } + &DAT_TYPE + } - pub fn get_option_text(&self) -> &Option { - self.option_text.get() - } + fn from_binary(binary: &[u8]) -> RS { + entity_utils::entity_from_binary(binary) } - impl Datum for Options { - fn dat_type() -> &'static DatType { - lazy_static! { - static ref DAT_TYPE: DatType = entity_utils::entity_dat_type::(); - } - &DAT_TYPE - } + fn from_value(value: &DatValue) -> RS { + entity_utils::entity_from_value(value) + } - fn from_binary(binary: &[u8]) -> RS { - entity_utils::entity_from_binary(binary) - } + fn from_textual(textual: &str) -> RS { + entity_utils::entity_from_textual(textual) + } +} - fn from_value(value: &DatValue) -> RS { - entity_utils::entity_from_value(value) - } +impl DatumDyn for Options { + fn dat_type_id(&self) -> RS { + entity_utils::entity_dat_type_id() + } - fn from_textual(textual: &str) -> RS { - entity_utils::entity_from_textual(textual) - } + fn to_binary(&self, dat_type: &DatType) -> RS { + entity_utils::entity_to_binary(self, dat_type) } - impl DatumDyn for Options { - fn dat_type_id(&self) -> RS { - entity_utils::entity_dat_type_id() - } + fn to_textual(&self, dat_type: &DatType) -> RS { + entity_utils::entity_to_textual(self, dat_type) + } - fn to_binary(&self, dat_type: &DatType) -> RS { - entity_utils::entity_to_binary(self, dat_type) - } + fn to_value(&self, dat_type: &DatType) -> RS { + entity_utils::entity_to_value(self, dat_type) + } - fn to_textual(&self, dat_type: &DatType) -> RS { - entity_utils::entity_to_textual(self, dat_type) - } + fn clone_boxed(&self) -> Box { + entity_utils::entity_clone_boxed(self) + } +} - fn to_value(&self, dat_type: &DatType) -> RS { - entity_utils::entity_to_value(self, dat_type) - } +impl Entity for Options { + fn new_empty() -> Self { + Self::new_empty() + } - fn clone_boxed(&self) -> Box { - entity_utils::entity_clone_boxed(self) - } + fn tuple_desc() -> &'static TupleFieldDesc { + lazy_static! { + static ref TUPLE_DESC: TupleFieldDesc = TupleFieldDesc::new(vec![ + + AttrOptionId::datum_desc().clone(), + + AttrVoteId::datum_desc().clone(), + + AttrOptionText::datum_desc().clone(), + + ]); + } + &TUPLE_DESC } - impl Entity for Options { - fn new_empty() -> Self { - Self::new_empty() - } + fn object_name() -> &'static str { + OPTIONS + } - fn tuple_desc() -> &'static TupleFieldDesc { - lazy_static! { - static ref TUPLE_DESC: TupleFieldDesc = TupleFieldDesc::new(vec![ - AttrOptionId::datum_desc().clone(), - AttrVoteId::datum_desc().clone(), - AttrOptionText::datum_desc().clone(), - ]); + fn get_field_binary(&self, field: &str) -> RS>> { + match field { + + OPTION_ID => { + attr_field_access::attr_get_binary::<_>(self.option_id.get()) } - &TUPLE_DESC - } - - fn object_name() -> &'static str { - OPTIONS - } - - fn get_field_binary(&self, field: &str) -> RS>> { - match field { - OPTION_ID => attr_field_access::attr_get_binary::<_>(self.option_id.get()), - - VOTE_ID => attr_field_access::attr_get_binary::<_>(self.vote_id.get()), - - OPTION_TEXT => attr_field_access::attr_get_binary::<_>(self.option_text.get()), - - _ => { - panic!("unknown name"); - } + + VOTE_ID => { + attr_field_access::attr_get_binary::<_>(self.vote_id.get()) } + + OPTION_TEXT => { + attr_field_access::attr_get_binary::<_>(self.option_text.get()) + } + + _ => { panic!("unknown name"); } } + } - fn set_field_binary>(&mut self, field: &str, binary: B) -> RS<()> { - match field { - OPTION_ID => { - attr_field_access::attr_set_binary::<_, _>( - self.option_id.get_mut(), - binary.as_ref(), - )?; - } - - VOTE_ID => { - attr_field_access::attr_set_binary::<_, _>( - self.vote_id.get_mut(), - binary.as_ref(), - )?; - } - - OPTION_TEXT => { - attr_field_access::attr_set_binary::<_, _>( - self.option_text.get_mut(), - binary.as_ref(), - )?; - } - - _ => { - panic!("unknown name"); - } + fn set_field_binary>(&mut self, field: &str, binary: B) -> RS<()> { + match field { + + OPTION_ID => { + attr_field_access::attr_set_binary::<_, _>(self.option_id.get_mut(), binary.as_ref())?; } - Ok(()) + + VOTE_ID => { + attr_field_access::attr_set_binary::<_, _>(self.vote_id.get_mut(), binary.as_ref())?; + } + + OPTION_TEXT => { + attr_field_access::attr_set_binary::<_, _>(self.option_text.get_mut(), binary.as_ref())?; + } + + _ => { panic!("unknown name"); } } + Ok(()) + } - fn get_field_value(&self, field: &str) -> RS> { - match field { - OPTION_ID => attr_field_access::attr_get_value::<_>(self.option_id.get()), - - VOTE_ID => attr_field_access::attr_get_value::<_>(self.vote_id.get()), - - OPTION_TEXT => attr_field_access::attr_get_value::<_>(self.option_text.get()), - - _ => { - panic!("unknown name"); - } + fn get_field_value(&self, field: &str) -> RS> { + match field { + + OPTION_ID => { + attr_field_access::attr_get_value::<_>(self.option_id.get()) + } + + VOTE_ID => { + attr_field_access::attr_get_value::<_>(self.vote_id.get()) + } + + OPTION_TEXT => { + attr_field_access::attr_get_value::<_>(self.option_text.get()) } + + _ => { panic!("unknown name"); } } + } - fn set_field_value>(&mut self, field: &str, value: B) -> RS<()> { - match field { - OPTION_ID => { - attr_field_access::attr_set_value::<_, _>(self.option_id.get_mut(), value)?; - } - - VOTE_ID => { - attr_field_access::attr_set_value::<_, _>(self.vote_id.get_mut(), value)?; - } - - OPTION_TEXT => { - attr_field_access::attr_set_value::<_, _>(self.option_text.get_mut(), value)?; - } - - _ => { - panic!("unknown name"); - } + fn set_field_value>(&mut self, field: &str, value: B) -> RS<()> { + match field { + + OPTION_ID => { + attr_field_access::attr_set_value::<_, _>(self.option_id.get_mut(), value)?; + } + + VOTE_ID => { + attr_field_access::attr_set_value::<_, _>(self.vote_id.get_mut(), value)?; } - Ok(()) + + OPTION_TEXT => { + attr_field_access::attr_set_value::<_, _>(self.option_text.get_mut(), value)?; + } + + _ => { panic!("unknown name"); } } + Ok(()) } +} - // attribute struct definition - #[derive(Default, Clone, Debug)] - pub struct AttrOptionId { - is_dirty: bool, - value: Option, - } - impl AttrOptionId { - fn from(value: Option) -> Self { - Self { - is_dirty: false, - value, - } - } +// attribute struct definition +#[derive(Default, Clone, Debug)] +pub struct AttrOptionId { + is_dirty:bool, + value: Option +} - fn get(&self) -> &Option { - &self.value +impl AttrOptionId { + fn from(value:Option) -> Self { + Self { + is_dirty: false, + value } + } - fn get_mut(&mut self) -> &mut Option { - &mut self.value - } + fn get(&self) -> &Option { + &self.value + } - fn set(&mut self, value: Option) { - self.value = value - } + fn get_mut(&mut self) -> &mut Option { + &mut self.value + } - fn update(&mut self, value: String) { - self.is_dirty = true; - self.value = Some(value) - } + fn set(&mut self, value:Option) { + self.value = value } - impl AttrValue for AttrOptionId { - fn dat_type() -> &'static DatType { - static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); - ONCE_LOCK.get_or_init(|| Self::attr_dat_type()) - } + fn update(&mut self, value: String) { + self.is_dirty = true; + self.value = Some(value) + } +} - fn datum_desc() -> &'static DatumDesc { - static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); - ONCE_LOCK.get_or_init(|| Self::attr_datum_desc()) - } +impl AttrValue for AttrOptionId { + fn dat_type() -> &'static DatType { + static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); + ONCE_LOCK.get_or_init(|| Self::attr_dat_type()) + } - fn object_name() -> &'static str { - OPTIONS - } + fn datum_desc() -> &'static DatumDesc { + static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); + ONCE_LOCK.get_or_init(|| Self::attr_datum_desc()) + } - fn attr_name() -> &'static str { - OPTION_ID - } + fn object_name() -> &'static str { + OPTIONS } - // attribute struct definition - #[derive(Default, Clone, Debug)] - pub struct AttrVoteId { - is_dirty: bool, - value: Option, + fn attr_name() -> &'static str { + OPTION_ID } +} - impl AttrVoteId { - fn from(value: Option) -> Self { - Self { - is_dirty: false, - value, - } - } +// attribute struct definition +#[derive(Default, Clone, Debug)] +pub struct AttrVoteId { + is_dirty:bool, + value: Option +} - fn get(&self) -> &Option { - &self.value +impl AttrVoteId { + fn from(value:Option) -> Self { + Self { + is_dirty: false, + value } + } - fn get_mut(&mut self) -> &mut Option { - &mut self.value - } + fn get(&self) -> &Option { + &self.value + } - fn set(&mut self, value: Option) { - self.value = value - } + fn get_mut(&mut self) -> &mut Option { + &mut self.value + } - fn update(&mut self, value: String) { - self.is_dirty = true; - self.value = Some(value) - } + fn set(&mut self, value:Option) { + self.value = value } - impl AttrValue for AttrVoteId { - fn dat_type() -> &'static DatType { - static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); - ONCE_LOCK.get_or_init(|| Self::attr_dat_type()) - } + fn update(&mut self, value: String) { + self.is_dirty = true; + self.value = Some(value) + } +} - fn datum_desc() -> &'static DatumDesc { - static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); - ONCE_LOCK.get_or_init(|| Self::attr_datum_desc()) - } +impl AttrValue for AttrVoteId { + fn dat_type() -> &'static DatType { + static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); + ONCE_LOCK.get_or_init(|| Self::attr_dat_type()) + } - fn object_name() -> &'static str { - OPTIONS - } + fn datum_desc() -> &'static DatumDesc { + static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); + ONCE_LOCK.get_or_init(|| Self::attr_datum_desc()) + } - fn attr_name() -> &'static str { - VOTE_ID - } + fn object_name() -> &'static str { + OPTIONS } - // attribute struct definition - #[derive(Default, Clone, Debug)] - pub struct AttrOptionText { - is_dirty: bool, - value: Option, + fn attr_name() -> &'static str { + VOTE_ID } +} - impl AttrOptionText { - fn from(value: Option) -> Self { - Self { - is_dirty: false, - value, - } - } +// attribute struct definition +#[derive(Default, Clone, Debug)] +pub struct AttrOptionText { + is_dirty:bool, + value: Option +} - fn get(&self) -> &Option { - &self.value +impl AttrOptionText { + fn from(value:Option) -> Self { + Self { + is_dirty: false, + value } + } - fn get_mut(&mut self) -> &mut Option { - &mut self.value - } + fn get(&self) -> &Option { + &self.value + } - fn set(&mut self, value: Option) { - self.value = value - } + fn get_mut(&mut self) -> &mut Option { + &mut self.value + } - fn update(&mut self, value: String) { - self.is_dirty = true; - self.value = Some(value) - } + fn set(&mut self, value:Option) { + self.value = value } - impl AttrValue for AttrOptionText { - fn dat_type() -> &'static DatType { - static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); - ONCE_LOCK.get_or_init(|| Self::attr_dat_type()) - } + fn update(&mut self, value: String) { + self.is_dirty = true; + self.value = Some(value) + } +} - fn datum_desc() -> &'static DatumDesc { - static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); - ONCE_LOCK.get_or_init(|| Self::attr_datum_desc()) - } +impl AttrValue for AttrOptionText { + fn dat_type() -> &'static DatType { + static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); + ONCE_LOCK.get_or_init(|| Self::attr_dat_type()) + } - fn object_name() -> &'static str { - OPTIONS - } + fn datum_desc() -> &'static DatumDesc { + static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); + ONCE_LOCK.get_or_init(|| Self::attr_datum_desc()) + } - fn attr_name() -> &'static str { - OPTION_TEXT - } + fn object_name() -> &'static str { + OPTIONS } - #[cfg(test)] - mod tests { - use super::Options; - use mudu_contract::database::entity::Entity; - use mudu_type::datum::{Datum, DatumDyn}; - - #[test] - fn options_roundtrip_value_binary_and_textual() { - let option = Options::new( - Some("opt-1".to_string()), - Some("vote-1".to_string()), - Some("Alpha".to_string()), - ); - - let value = option.to_value(Options::dat_type()).unwrap(); - let from_value = Options::from_value(&value).unwrap(); - assert_eq!(from_value.get_option_id().as_deref(), Some("opt-1")); - assert_eq!(from_value.get_vote_id().as_deref(), Some("vote-1")); - assert_eq!(from_value.get_option_text().as_deref(), Some("Alpha")); - - let binary = option.to_binary(Options::dat_type()).unwrap(); - let from_binary = Options::from_binary(binary.as_ref()).unwrap(); - assert_eq!(from_binary.get_option_text().as_deref(), Some("Alpha")); - - let textual = option.to_textual(Options::dat_type()).unwrap(); - let from_textual = Options::from_textual(textual.as_ref()).unwrap(); - assert_eq!(from_textual.get_vote_id().as_deref(), Some("vote-1")); - - let mut updated = Options::new_empty(); - updated - .set_field_value( - "option_id", - mudu_type::dat_value::DatValue::from_string("opt-2".to_string()), - ) - .unwrap(); - updated - .set_field_value( - "vote_id", - mudu_type::dat_value::DatValue::from_string("vote-2".to_string()), - ) - .unwrap(); - updated - .set_field_value( - "option_text", - mudu_type::dat_value::DatValue::from_string("Beta".to_string()), - ) - .unwrap(); - assert_eq!(updated.get_option_text().as_deref(), Some("Beta")); - } + fn attr_name() -> &'static str { + OPTION_TEXT } } + + +} diff --git a/example/vote/src/rust/procedure.rs b/example/vote/src/rust/procedure.rs index 9f82558..ed1cd55 100644 --- a/example/vote/src/rust/procedure.rs +++ b/example/vote/src/rust/procedure.rs @@ -4,18 +4,18 @@ use crate::rust::vote_history_item::object::VoteHistoryItem; use crate::rust::vote_result::object::VoteResult; use crate::rust::votes::object::Votes; use fallible_iterator::FallibleIterator; -use mudu::common::result::RS; -use mudu::common::xid::XID; -use mudu::error::ec::EC::MuduError; -use mudu::m_error; -use mudu_contract::database::entity_set::RecordSet; -use mudu_contract::{sql_params, sql_stmt}; -use sys_interface::sync_api::{mudu_command, mudu_query}; +use mududb::common::result::RS; +use mududb::common::xid::XID; +use mududb::error::ec::EC::MuduError; +use mududb::m_error; +use mududb::contract::database::entity_set::RecordSet; +use mududb::contract::{sql_params, sql_stmt}; +use mududb::sys_interface::sync_api::{mudu_command, mudu_query}; // User management /**mudu-proc**/ pub fn create_user(xid: XID, phone: String) -> RS { - let user_id = mudu_sys::random::next_uuid_v4_string(); + let user_id = mududb::sys::random::next_uuid_v4_string(); mudu_command( xid, sql_stmt!(&"INSERT INTO users (user_id, phone) VALUES (?, ?)"), @@ -36,7 +36,7 @@ pub fn create_vote( visibility_rule: String, ) -> RS { // Validate input - if end_time <= mudu_sys::time::utc_now().timestamp() { + if end_time <= mududb::sys::time::utc_now().timestamp() { return Err(m_error!( MuduError, "End time must be in future".to_string() @@ -61,7 +61,7 @@ pub fn create_vote( )); } - let vote_id = mudu_sys::random::next_uuid_v4_string(); + let vote_id = mududb::sys::random::next_uuid_v4_string(); mudu_command( xid, sql_stmt!( @@ -76,7 +76,7 @@ pub fn create_vote( // Add option to vote /**mudu-proc**/ pub fn add_option(xid: XID, vote_id: String, option_text: String) -> RS { - let option_id = mudu_sys::random::next_uuid_v4_string(); + let option_id = mududb::sys::random::next_uuid_v4_string(); mudu_command( xid, sql_stmt!(&"INSERT INTO options (option_id, vote_id, option_text) VALUES (?, ?, ?)"), @@ -97,7 +97,7 @@ pub fn cast_vote(xid: XID, user_id: String, vote_id: String, option_ids: Vec vote.get_end_time().unwrap() as i64 { + if mududb::sys::time::utc_now().timestamp() > vote.get_end_time().unwrap() as i64 { return Err(m_error!(MuduError, "Voting has ended".to_string())); } @@ -130,8 +130,8 @@ pub fn cast_vote(xid: XID, user_id: String, vote_id: String, option_ids: Vec RS<()> { .next()? .ok_or_else(|| m_error!(MuduError, "Vote not found".to_string()))?; - if mudu_sys::time::utc_now().timestamp() > vote.get_end_time().unwrap() as i64 { + if mududb::sys::time::utc_now().timestamp() > vote.get_end_time().unwrap() as i64 { return Err(m_error!( MuduError, "Voting has ended, cannot withdraw".to_string() @@ -209,7 +209,7 @@ pub fn get_vote_result(xid: XID, vote_id: String) -> RS { .next()? .ok_or_else(|| m_error!(MuduError, "Vote not found".to_string()))?; - let now = mudu_sys::time::utc_now().timestamp(); + let now = mududb::sys::time::utc_now().timestamp(); let vote_ended = now > vote.get_end_time().unwrap() as i64; // Check visibility rules @@ -284,7 +284,7 @@ pub fn get_voting_history(xid: XID, user_id: String) -> RS> let mut history = Vec::new(); for action in actions { - let vote_ended = (mudu_sys::time::utc_now().timestamp() + let vote_ended = (mududb::sys::time::utc_now().timestamp() > action.get_action_time().unwrap() as i64) as i32; history.push(VoteHistoryItem::new( Some(action.get_vote_id().as_ref().unwrap().to_string()), @@ -319,7 +319,7 @@ mod tests { #[test] fn create_vote_rejects_invalid_vote_type_and_single_choice_mismatch() { - let future = mudu_sys::time::utc_now().timestamp() + 3600; + let future = mududb::sys::time::utc_now().timestamp() + 3600; let vote_type_err = create_vote( 1, @@ -356,7 +356,7 @@ mod tests { #[test] fn create_vote_rejects_invalid_visibility_rule() { - let future = mudu_sys::time::utc_now().timestamp() + 3600; + let future = mududb::sys::time::utc_now().timestamp() + 3600; let err = create_vote( 1, "creator".to_string(), diff --git a/example/vote/src/rust/users.rs b/example/vote/src/rust/users.rs index 2e38ea4..3491721 100644 --- a/example/vote/src/rust/users.rs +++ b/example/vote/src/rust/users.rs @@ -1,338 +1,326 @@ pub mod object { - use lazy_static::lazy_static; - use mudu::common::result::RS; - use mudu_contract::database::attr_field_access; - use mudu_contract::database::attr_value::AttrValue; - use mudu_contract::database::entity::Entity; - use mudu_contract::database::entity_utils; - use mudu_contract::database::sql_params::SQLParamMarker; - use mudu_contract::tuple::datum_desc::DatumDesc; - use mudu_contract::tuple::tuple_datum::TupleDatumMarker; - use mudu_contract::tuple::tuple_field_desc::TupleFieldDesc; - use mudu_type::dat_binary::DatBinary; - use mudu_type::dat_textual::DatTextual; - use mudu_type::dat_type::DatType; - use mudu_type::dat_type_id::DatTypeID; - use mudu_type::dat_value::DatValue; - use mudu_type::datum::{Datum, DatumDyn}; - - // constant definition - const USERS: &str = "users"; - - const USER_ID: &str = "user_id"; - - const PHONE: &str = "phone"; - - // entity struct definition - #[derive(Debug, Clone, Default)] - pub struct Users { - user_id: AttrUserId, - - phone: AttrPhone, - } - - impl TupleDatumMarker for Users {} - - impl SQLParamMarker for Users {} - - impl Users { - pub fn new(user_id: Option, phone: Option) -> Self { - let s = Self { - user_id: AttrUserId::from(user_id), - - phone: AttrPhone::from(phone), - }; - s - } - - pub fn new_empty() -> Self { - Self::default() - } - - pub fn set_user_id(&mut self, user_id: String) { - self.user_id.update(user_id) - } +use lazy_static::lazy_static; +use mududb::common::result::RS; +use mududb::contract::database::attr_field_access; +use mududb::contract::database::attr_value::AttrValue; +use mududb::contract::database::entity::Entity; +use mududb::contract::database::entity_utils; +use mududb::contract::database::sql_params::SQLParamMarker; +use mududb::contract::tuple::datum_desc::DatumDesc; +use mududb::contract::tuple::tuple_field_desc::TupleFieldDesc; +use mududb::contract::tuple::tuple_datum::TupleDatumMarker; +use mududb::types::dat_binary::DatBinary; +use mududb::types::dat_textual::DatTextual; +use mududb::types::dat_type::DatType; +use mududb::types::dat_type_id::DatTypeID; +use mududb::types::dat_value::DatValue; +use mududb::types::datum::{Datum, DatumDyn}; + +// constant definition +const USERS:&str = "users"; + +const USER_ID:&str = "user_id"; + +const PHONE:&str = "phone"; + + +// entity struct definition +#[derive(Debug, Clone, Default)] +pub struct Users { + + user_id: AttrUserId, + + phone: AttrPhone, + +} - pub fn get_user_id(&self) -> &Option { - self.user_id.get() - } +impl TupleDatumMarker for Users {} + +impl SQLParamMarker for Users {} + +impl Users { + pub fn new( + user_id: Option, + phone: Option, + + ) -> Self { + let s = Self { + + user_id : AttrUserId::from(user_id), + + phone : AttrPhone::from(phone), + + }; + s + } - pub fn set_phone(&mut self, phone: String) { - self.phone.update(phone) - } + pub fn new_empty() -> Self { + Self::default() + } - pub fn get_phone(&self) -> &Option { - self.phone.get() - } + + pub fn set_user_id( + &mut self, + user_id: String, + ) { + self.user_id.update(user_id) } - impl Datum for Users { - fn dat_type() -> &'static DatType { - lazy_static! { - static ref DAT_TYPE: DatType = entity_utils::entity_dat_type::(); - } - &DAT_TYPE - } + pub fn get_user_id( + &self, + ) -> &Option { + self.user_id.get() + } + + pub fn set_phone( + &mut self, + phone: String, + ) { + self.phone.update(phone) + } - fn from_binary(binary: &[u8]) -> RS { - entity_utils::entity_from_binary(binary) - } + pub fn get_phone( + &self, + ) -> &Option { + self.phone.get() + } + +} - fn from_value(value: &DatValue) -> RS { - entity_utils::entity_from_value(value) +impl Datum for Users { + fn dat_type() -> &'static DatType { + lazy_static! { + static ref DAT_TYPE: DatType = entity_utils::entity_dat_type::(); } + &DAT_TYPE + } - fn from_textual(textual: &str) -> RS { - entity_utils::entity_from_textual(textual) - } + fn from_binary(binary: &[u8]) -> RS { + entity_utils::entity_from_binary(binary) } - impl DatumDyn for Users { - fn dat_type_id(&self) -> RS { - entity_utils::entity_dat_type_id() - } + fn from_value(value: &DatValue) -> RS { + entity_utils::entity_from_value(value) + } - fn to_binary(&self, dat_type: &DatType) -> RS { - entity_utils::entity_to_binary(self, dat_type) - } + fn from_textual(textual: &str) -> RS { + entity_utils::entity_from_textual(textual) + } +} - fn to_textual(&self, dat_type: &DatType) -> RS { - entity_utils::entity_to_textual(self, dat_type) - } +impl DatumDyn for Users { + fn dat_type_id(&self) -> RS { + entity_utils::entity_dat_type_id() + } - fn to_value(&self, dat_type: &DatType) -> RS { - entity_utils::entity_to_value(self, dat_type) - } + fn to_binary(&self, dat_type: &DatType) -> RS { + entity_utils::entity_to_binary(self, dat_type) + } - fn clone_boxed(&self) -> Box { - entity_utils::entity_clone_boxed(self) - } + fn to_textual(&self, dat_type: &DatType) -> RS { + entity_utils::entity_to_textual(self, dat_type) } - impl Entity for Users { - fn new_empty() -> Self { - Self::new_empty() - } + fn to_value(&self, dat_type: &DatType) -> RS { + entity_utils::entity_to_value(self, dat_type) + } - fn tuple_desc() -> &'static TupleFieldDesc { - lazy_static! { - static ref TUPLE_DESC: TupleFieldDesc = TupleFieldDesc::new(vec![ - AttrUserId::datum_desc().clone(), - AttrPhone::datum_desc().clone(), - ]); - } - &TUPLE_DESC - } + fn clone_boxed(&self) -> Box { + entity_utils::entity_clone_boxed(self) + } +} - fn object_name() -> &'static str { - USERS - } +impl Entity for Users { + fn new_empty() -> Self { + Self::new_empty() + } - fn get_field_binary(&self, field: &str) -> RS>> { - match field { - USER_ID => attr_field_access::attr_get_binary::<_>(self.user_id.get()), + fn tuple_desc() -> &'static TupleFieldDesc { + lazy_static! { + static ref TUPLE_DESC: TupleFieldDesc = TupleFieldDesc::new(vec![ + + AttrUserId::datum_desc().clone(), + + AttrPhone::datum_desc().clone(), + + ]); + } + &TUPLE_DESC + } - PHONE => attr_field_access::attr_get_binary::<_>(self.phone.get()), + fn object_name() -> &'static str { + USERS + } - _ => { - panic!("unknown name"); - } + fn get_field_binary(&self, field: &str) -> RS>> { + match field { + + USER_ID => { + attr_field_access::attr_get_binary::<_>(self.user_id.get()) + } + + PHONE => { + attr_field_access::attr_get_binary::<_>(self.phone.get()) } + + _ => { panic!("unknown name"); } } + } - fn set_field_binary>(&mut self, field: &str, binary: B) -> RS<()> { - match field { - USER_ID => { - attr_field_access::attr_set_binary::<_, _>( - self.user_id.get_mut(), - binary.as_ref(), - )?; - } - - PHONE => { - attr_field_access::attr_set_binary::<_, _>( - self.phone.get_mut(), - binary.as_ref(), - )?; - } - - _ => { - panic!("unknown name"); - } + fn set_field_binary>(&mut self, field: &str, binary: B) -> RS<()> { + match field { + + USER_ID => { + attr_field_access::attr_set_binary::<_, _>(self.user_id.get_mut(), binary.as_ref())?; + } + + PHONE => { + attr_field_access::attr_set_binary::<_, _>(self.phone.get_mut(), binary.as_ref())?; } - Ok(()) + + _ => { panic!("unknown name"); } } + Ok(()) + } - fn get_field_value(&self, field: &str) -> RS> { - match field { - USER_ID => attr_field_access::attr_get_value::<_>(self.user_id.get()), - - PHONE => attr_field_access::attr_get_value::<_>(self.phone.get()), - - _ => { - panic!("unknown name"); - } + fn get_field_value(&self, field: &str) -> RS> { + match field { + + USER_ID => { + attr_field_access::attr_get_value::<_>(self.user_id.get()) } + + PHONE => { + attr_field_access::attr_get_value::<_>(self.phone.get()) + } + + _ => { panic!("unknown name"); } } + } - fn set_field_value>(&mut self, field: &str, value: B) -> RS<()> { - match field { - USER_ID => { - attr_field_access::attr_set_value::<_, _>(self.user_id.get_mut(), value)?; - } - - PHONE => { - attr_field_access::attr_set_value::<_, _>(self.phone.get_mut(), value)?; - } - - _ => { - panic!("unknown name"); - } + fn set_field_value>(&mut self, field: &str, value: B) -> RS<()> { + match field { + + USER_ID => { + attr_field_access::attr_set_value::<_, _>(self.user_id.get_mut(), value)?; + } + + PHONE => { + attr_field_access::attr_set_value::<_, _>(self.phone.get_mut(), value)?; } - Ok(()) + + _ => { panic!("unknown name"); } } + Ok(()) } +} - // attribute struct definition - #[derive(Default, Clone, Debug)] - pub struct AttrUserId { - is_dirty: bool, - value: Option, - } - impl AttrUserId { - fn from(value: Option) -> Self { - Self { - is_dirty: false, - value, - } - } +// attribute struct definition +#[derive(Default, Clone, Debug)] +pub struct AttrUserId { + is_dirty:bool, + value: Option +} - fn get(&self) -> &Option { - &self.value +impl AttrUserId { + fn from(value:Option) -> Self { + Self { + is_dirty: false, + value } + } - fn get_mut(&mut self) -> &mut Option { - &mut self.value - } + fn get(&self) -> &Option { + &self.value + } - fn set(&mut self, value: Option) { - self.value = value - } + fn get_mut(&mut self) -> &mut Option { + &mut self.value + } - fn update(&mut self, value: String) { - self.is_dirty = true; - self.value = Some(value) - } + fn set(&mut self, value:Option) { + self.value = value } - impl AttrValue for AttrUserId { - fn dat_type() -> &'static DatType { - static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); - ONCE_LOCK.get_or_init(|| Self::attr_dat_type()) - } + fn update(&mut self, value: String) { + self.is_dirty = true; + self.value = Some(value) + } +} - fn datum_desc() -> &'static DatumDesc { - static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); - ONCE_LOCK.get_or_init(|| Self::attr_datum_desc()) - } +impl AttrValue for AttrUserId { + fn dat_type() -> &'static DatType { + static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); + ONCE_LOCK.get_or_init(|| Self::attr_dat_type()) + } - fn object_name() -> &'static str { - USERS - } + fn datum_desc() -> &'static DatumDesc { + static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); + ONCE_LOCK.get_or_init(|| Self::attr_datum_desc()) + } - fn attr_name() -> &'static str { - USER_ID - } + fn object_name() -> &'static str { + USERS } - // attribute struct definition - #[derive(Default, Clone, Debug)] - pub struct AttrPhone { - is_dirty: bool, - value: Option, + fn attr_name() -> &'static str { + USER_ID } +} - impl AttrPhone { - fn from(value: Option) -> Self { - Self { - is_dirty: false, - value, - } - } +// attribute struct definition +#[derive(Default, Clone, Debug)] +pub struct AttrPhone { + is_dirty:bool, + value: Option +} - fn get(&self) -> &Option { - &self.value +impl AttrPhone { + fn from(value:Option) -> Self { + Self { + is_dirty: false, + value } + } - fn get_mut(&mut self) -> &mut Option { - &mut self.value - } + fn get(&self) -> &Option { + &self.value + } - fn set(&mut self, value: Option) { - self.value = value - } + fn get_mut(&mut self) -> &mut Option { + &mut self.value + } - fn update(&mut self, value: String) { - self.is_dirty = true; - self.value = Some(value) - } + fn set(&mut self, value:Option) { + self.value = value } - impl AttrValue for AttrPhone { - fn dat_type() -> &'static DatType { - static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); - ONCE_LOCK.get_or_init(|| Self::attr_dat_type()) - } + fn update(&mut self, value: String) { + self.is_dirty = true; + self.value = Some(value) + } +} - fn datum_desc() -> &'static DatumDesc { - static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); - ONCE_LOCK.get_or_init(|| Self::attr_datum_desc()) - } +impl AttrValue for AttrPhone { + fn dat_type() -> &'static DatType { + static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); + ONCE_LOCK.get_or_init(|| Self::attr_dat_type()) + } - fn object_name() -> &'static str { - USERS - } + fn datum_desc() -> &'static DatumDesc { + static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); + ONCE_LOCK.get_or_init(|| Self::attr_datum_desc()) + } - fn attr_name() -> &'static str { - PHONE - } + fn object_name() -> &'static str { + USERS } - #[cfg(test)] - mod tests { - use super::Users; - use mudu_contract::database::entity::Entity; - use mudu_type::datum::{Datum, DatumDyn}; - - #[test] - fn users_roundtrip_value_binary_and_field_access() { - let user = Users::new(Some("u-1".to_string()), Some("13800138000".to_string())); - - let value = user.to_value(Users::dat_type()).unwrap(); - let from_value = Users::from_value(&value).unwrap(); - assert_eq!(from_value.get_user_id().as_deref(), Some("u-1")); - assert_eq!(from_value.get_phone().as_deref(), Some("13800138000")); - - let binary = user.to_binary(Users::dat_type()).unwrap(); - let from_binary = Users::from_binary(binary.as_ref()).unwrap(); - assert_eq!(from_binary.get_phone().as_deref(), Some("13800138000")); - - let mut updated = Users::new_empty(); - updated - .set_field_value( - "user_id", - mudu_type::dat_value::DatValue::from_string("u-2".to_string()), - ) - .unwrap(); - updated - .set_field_value( - "phone", - mudu_type::dat_value::DatValue::from_string("13900139000".to_string()), - ) - .unwrap(); - assert_eq!(updated.get_user_id().as_deref(), Some("u-2")); - assert_eq!(updated.get_phone().as_deref(), Some("13900139000")); - } + fn attr_name() -> &'static str { + PHONE } } + + +} diff --git a/example/vote/src/rust/vote_actions.rs b/example/vote/src/rust/vote_actions.rs index 087e395..1331086 100644 --- a/example/vote/src/rust/vote_actions.rs +++ b/example/vote/src/rust/vote_actions.rs @@ -1,599 +1,599 @@ pub mod object { - use lazy_static::lazy_static; - use mudu::common::result::RS; - use mudu_contract::database::attr_field_access; - use mudu_contract::database::attr_value::AttrValue; - use mudu_contract::database::entity::Entity; - use mudu_contract::database::entity_utils; - use mudu_contract::database::sql_params::SQLParamMarker; - use mudu_contract::tuple::datum_desc::DatumDesc; - use mudu_contract::tuple::tuple_datum::TupleDatumMarker; - use mudu_contract::tuple::tuple_field_desc::TupleFieldDesc; - use mudu_type::dat_binary::DatBinary; - use mudu_type::dat_textual::DatTextual; - use mudu_type::dat_type::DatType; - use mudu_type::dat_type_id::DatTypeID; - use mudu_type::dat_value::DatValue; - use mudu_type::datum::{Datum, DatumDyn}; - - // constant definition - const VOTE_ACTIONS: &str = "vote_actions"; - - const ACTION_ID: &str = "action_id"; - - const USER_ID: &str = "user_id"; - - const VOTE_ID: &str = "vote_id"; - - const ACTION_TIME: &str = "action_time"; - - const IS_WITHDRAWN: &str = "is_withdrawn"; - - // entity struct definition - #[derive(Debug, Clone, Default)] - pub struct VoteActions { - action_id: AttrActionId, - - user_id: AttrUserId, - - vote_id: AttrVoteId, +use lazy_static::lazy_static; +use mududb::common::result::RS; +use mududb::contract::database::attr_field_access; +use mududb::contract::database::attr_value::AttrValue; +use mududb::contract::database::entity::Entity; +use mududb::contract::database::entity_utils; +use mududb::contract::database::sql_params::SQLParamMarker; +use mududb::contract::tuple::datum_desc::DatumDesc; +use mududb::contract::tuple::tuple_field_desc::TupleFieldDesc; +use mududb::contract::tuple::tuple_datum::TupleDatumMarker; +use mududb::types::dat_binary::DatBinary; +use mududb::types::dat_textual::DatTextual; +use mududb::types::dat_type::DatType; +use mududb::types::dat_type_id::DatTypeID; +use mududb::types::dat_value::DatValue; +use mududb::types::datum::{Datum, DatumDyn}; + +// constant definition +const VOTE_ACTIONS:&str = "vote_actions"; + +const ACTION_ID:&str = "action_id"; + +const USER_ID:&str = "user_id"; + +const VOTE_ID:&str = "vote_id"; + +const ACTION_TIME:&str = "action_time"; + +const IS_WITHDRAWN:&str = "is_withdrawn"; + + +// entity struct definition +#[derive(Debug, Clone, Default)] +pub struct VoteActions { + + action_id: AttrActionId, + + user_id: AttrUserId, + + vote_id: AttrVoteId, + + action_time: AttrActionTime, + + is_withdrawn: AttrIsWithdrawn, + +} - action_time: AttrActionTime, +impl TupleDatumMarker for VoteActions {} + +impl SQLParamMarker for VoteActions {} + +impl VoteActions { + pub fn new( + action_id: Option, + user_id: Option, + vote_id: Option, + action_time: Option, + is_withdrawn: Option, + + ) -> Self { + let s = Self { + + action_id : AttrActionId::from(action_id), + + user_id : AttrUserId::from(user_id), + + vote_id : AttrVoteId::from(vote_id), + + action_time : AttrActionTime::from(action_time), + + is_withdrawn : AttrIsWithdrawn::from(is_withdrawn), + + }; + s + } - is_withdrawn: AttrIsWithdrawn, + pub fn new_empty() -> Self { + Self::default() } - impl TupleDatumMarker for VoteActions {} + + pub fn set_action_id( + &mut self, + action_id: String, + ) { + self.action_id.update(action_id) + } - impl SQLParamMarker for VoteActions {} + pub fn get_action_id( + &self, + ) -> &Option { + self.action_id.get() + } + + pub fn set_user_id( + &mut self, + user_id: String, + ) { + self.user_id.update(user_id) + } - impl VoteActions { - pub fn new( - action_id: Option, - user_id: Option, - vote_id: Option, - action_time: Option, - is_withdrawn: Option, - ) -> Self { - let s = Self { - action_id: AttrActionId::from(action_id), + pub fn get_user_id( + &self, + ) -> &Option { + self.user_id.get() + } + + pub fn set_vote_id( + &mut self, + vote_id: String, + ) { + self.vote_id.update(vote_id) + } - user_id: AttrUserId::from(user_id), + pub fn get_vote_id( + &self, + ) -> &Option { + self.vote_id.get() + } + + pub fn set_action_time( + &mut self, + action_time: i32, + ) { + self.action_time.update(action_time) + } - vote_id: AttrVoteId::from(vote_id), + pub fn get_action_time( + &self, + ) -> &Option { + self.action_time.get() + } + + pub fn set_is_withdrawn( + &mut self, + is_withdrawn: i32, + ) { + self.is_withdrawn.update(is_withdrawn) + } - action_time: AttrActionTime::from(action_time), + pub fn get_is_withdrawn( + &self, + ) -> &Option { + self.is_withdrawn.get() + } + +} - is_withdrawn: AttrIsWithdrawn::from(is_withdrawn), - }; - s +impl Datum for VoteActions { + fn dat_type() -> &'static DatType { + lazy_static! { + static ref DAT_TYPE: DatType = entity_utils::entity_dat_type::(); } + &DAT_TYPE + } - pub fn new_empty() -> Self { - Self::default() - } + fn from_binary(binary: &[u8]) -> RS { + entity_utils::entity_from_binary(binary) + } - pub fn set_action_id(&mut self, action_id: String) { - self.action_id.update(action_id) - } + fn from_value(value: &DatValue) -> RS { + entity_utils::entity_from_value(value) + } - pub fn get_action_id(&self) -> &Option { - self.action_id.get() - } + fn from_textual(textual: &str) -> RS { + entity_utils::entity_from_textual(textual) + } +} - pub fn set_user_id(&mut self, user_id: String) { - self.user_id.update(user_id) - } +impl DatumDyn for VoteActions { + fn dat_type_id(&self) -> RS { + entity_utils::entity_dat_type_id() + } - pub fn get_user_id(&self) -> &Option { - self.user_id.get() - } + fn to_binary(&self, dat_type: &DatType) -> RS { + entity_utils::entity_to_binary(self, dat_type) + } - pub fn set_vote_id(&mut self, vote_id: String) { - self.vote_id.update(vote_id) - } + fn to_textual(&self, dat_type: &DatType) -> RS { + entity_utils::entity_to_textual(self, dat_type) + } - pub fn get_vote_id(&self) -> &Option { - self.vote_id.get() - } + fn to_value(&self, dat_type: &DatType) -> RS { + entity_utils::entity_to_value(self, dat_type) + } - pub fn set_action_time(&mut self, action_time: i32) { - self.action_time.update(action_time) - } + fn clone_boxed(&self) -> Box { + entity_utils::entity_clone_boxed(self) + } +} - pub fn get_action_time(&self) -> &Option { - self.action_time.get() - } +impl Entity for VoteActions { + fn new_empty() -> Self { + Self::new_empty() + } - pub fn set_is_withdrawn(&mut self, is_withdrawn: i32) { - self.is_withdrawn.update(is_withdrawn) - } + fn tuple_desc() -> &'static TupleFieldDesc { + lazy_static! { + static ref TUPLE_DESC: TupleFieldDesc = TupleFieldDesc::new(vec![ + + AttrActionId::datum_desc().clone(), + + AttrUserId::datum_desc().clone(), + + AttrVoteId::datum_desc().clone(), + + AttrActionTime::datum_desc().clone(), + + AttrIsWithdrawn::datum_desc().clone(), + + ]); + } + &TUPLE_DESC + } - pub fn get_is_withdrawn(&self) -> &Option { - self.is_withdrawn.get() - } + fn object_name() -> &'static str { + VOTE_ACTIONS } - impl Datum for VoteActions { - fn dat_type() -> &'static DatType { - lazy_static! { - static ref DAT_TYPE: DatType = entity_utils::entity_dat_type::(); + fn get_field_binary(&self, field: &str) -> RS>> { + match field { + + ACTION_ID => { + attr_field_access::attr_get_binary::<_>(self.action_id.get()) } - &DAT_TYPE - } - - fn from_binary(binary: &[u8]) -> RS { - entity_utils::entity_from_binary(binary) - } - - fn from_value(value: &DatValue) -> RS { - entity_utils::entity_from_value(value) - } - - fn from_textual(textual: &str) -> RS { - entity_utils::entity_from_textual(textual) + + USER_ID => { + attr_field_access::attr_get_binary::<_>(self.user_id.get()) + } + + VOTE_ID => { + attr_field_access::attr_get_binary::<_>(self.vote_id.get()) + } + + ACTION_TIME => { + attr_field_access::attr_get_binary::<_>(self.action_time.get()) + } + + IS_WITHDRAWN => { + attr_field_access::attr_get_binary::<_>(self.is_withdrawn.get()) + } + + _ => { panic!("unknown name"); } } } - impl DatumDyn for VoteActions { - fn dat_type_id(&self) -> RS { - entity_utils::entity_dat_type_id() - } - - fn to_binary(&self, dat_type: &DatType) -> RS { - entity_utils::entity_to_binary(self, dat_type) - } - - fn to_textual(&self, dat_type: &DatType) -> RS { - entity_utils::entity_to_textual(self, dat_type) - } - - fn to_value(&self, dat_type: &DatType) -> RS { - entity_utils::entity_to_value(self, dat_type) - } - - fn clone_boxed(&self) -> Box { - entity_utils::entity_clone_boxed(self) + fn set_field_binary>(&mut self, field: &str, binary: B) -> RS<()> { + match field { + + ACTION_ID => { + attr_field_access::attr_set_binary::<_, _>(self.action_id.get_mut(), binary.as_ref())?; + } + + USER_ID => { + attr_field_access::attr_set_binary::<_, _>(self.user_id.get_mut(), binary.as_ref())?; + } + + VOTE_ID => { + attr_field_access::attr_set_binary::<_, _>(self.vote_id.get_mut(), binary.as_ref())?; + } + + ACTION_TIME => { + attr_field_access::attr_set_binary::<_, _>(self.action_time.get_mut(), binary.as_ref())?; + } + + IS_WITHDRAWN => { + attr_field_access::attr_set_binary::<_, _>(self.is_withdrawn.get_mut(), binary.as_ref())?; + } + + _ => { panic!("unknown name"); } } + Ok(()) } - impl Entity for VoteActions { - fn new_empty() -> Self { - Self::new_empty() - } - - fn tuple_desc() -> &'static TupleFieldDesc { - lazy_static! { - static ref TUPLE_DESC: TupleFieldDesc = TupleFieldDesc::new(vec![ - AttrActionId::datum_desc().clone(), - AttrUserId::datum_desc().clone(), - AttrVoteId::datum_desc().clone(), - AttrActionTime::datum_desc().clone(), - AttrIsWithdrawn::datum_desc().clone(), - ]); + fn get_field_value(&self, field: &str) -> RS> { + match field { + + ACTION_ID => { + attr_field_access::attr_get_value::<_>(self.action_id.get()) } - &TUPLE_DESC - } - - fn object_name() -> &'static str { - VOTE_ACTIONS - } - - fn get_field_binary(&self, field: &str) -> RS>> { - match field { - ACTION_ID => attr_field_access::attr_get_binary::<_>(self.action_id.get()), - - USER_ID => attr_field_access::attr_get_binary::<_>(self.user_id.get()), - - VOTE_ID => attr_field_access::attr_get_binary::<_>(self.vote_id.get()), - - ACTION_TIME => attr_field_access::attr_get_binary::<_>(self.action_time.get()), - - IS_WITHDRAWN => attr_field_access::attr_get_binary::<_>(self.is_withdrawn.get()), - - _ => { - panic!("unknown name"); - } + + USER_ID => { + attr_field_access::attr_get_value::<_>(self.user_id.get()) } - } - - fn set_field_binary>(&mut self, field: &str, binary: B) -> RS<()> { - match field { - ACTION_ID => { - attr_field_access::attr_set_binary::<_, _>( - self.action_id.get_mut(), - binary.as_ref(), - )?; - } - - USER_ID => { - attr_field_access::attr_set_binary::<_, _>( - self.user_id.get_mut(), - binary.as_ref(), - )?; - } - - VOTE_ID => { - attr_field_access::attr_set_binary::<_, _>( - self.vote_id.get_mut(), - binary.as_ref(), - )?; - } - - ACTION_TIME => { - attr_field_access::attr_set_binary::<_, _>( - self.action_time.get_mut(), - binary.as_ref(), - )?; - } - - IS_WITHDRAWN => { - attr_field_access::attr_set_binary::<_, _>( - self.is_withdrawn.get_mut(), - binary.as_ref(), - )?; - } - - _ => { - panic!("unknown name"); - } + + VOTE_ID => { + attr_field_access::attr_get_value::<_>(self.vote_id.get()) } - Ok(()) - } - - fn get_field_value(&self, field: &str) -> RS> { - match field { - ACTION_ID => attr_field_access::attr_get_value::<_>(self.action_id.get()), - - USER_ID => attr_field_access::attr_get_value::<_>(self.user_id.get()), - - VOTE_ID => attr_field_access::attr_get_value::<_>(self.vote_id.get()), - - ACTION_TIME => attr_field_access::attr_get_value::<_>(self.action_time.get()), - - IS_WITHDRAWN => attr_field_access::attr_get_value::<_>(self.is_withdrawn.get()), - - _ => { - panic!("unknown name"); - } + + ACTION_TIME => { + attr_field_access::attr_get_value::<_>(self.action_time.get()) } + + IS_WITHDRAWN => { + attr_field_access::attr_get_value::<_>(self.is_withdrawn.get()) + } + + _ => { panic!("unknown name"); } } + } - fn set_field_value>(&mut self, field: &str, value: B) -> RS<()> { - match field { - ACTION_ID => { - attr_field_access::attr_set_value::<_, _>(self.action_id.get_mut(), value)?; - } - - USER_ID => { - attr_field_access::attr_set_value::<_, _>(self.user_id.get_mut(), value)?; - } - - VOTE_ID => { - attr_field_access::attr_set_value::<_, _>(self.vote_id.get_mut(), value)?; - } - - ACTION_TIME => { - attr_field_access::attr_set_value::<_, _>(self.action_time.get_mut(), value)?; - } - - IS_WITHDRAWN => { - attr_field_access::attr_set_value::<_, _>(self.is_withdrawn.get_mut(), value)?; - } - - _ => { - panic!("unknown name"); - } + fn set_field_value>(&mut self, field: &str, value: B) -> RS<()> { + match field { + + ACTION_ID => { + attr_field_access::attr_set_value::<_, _>(self.action_id.get_mut(), value)?; + } + + USER_ID => { + attr_field_access::attr_set_value::<_, _>(self.user_id.get_mut(), value)?; + } + + VOTE_ID => { + attr_field_access::attr_set_value::<_, _>(self.vote_id.get_mut(), value)?; } - Ok(()) + + ACTION_TIME => { + attr_field_access::attr_set_value::<_, _>(self.action_time.get_mut(), value)?; + } + + IS_WITHDRAWN => { + attr_field_access::attr_set_value::<_, _>(self.is_withdrawn.get_mut(), value)?; + } + + _ => { panic!("unknown name"); } } + Ok(()) } +} - // attribute struct definition - #[derive(Default, Clone, Debug)] - pub struct AttrActionId { - is_dirty: bool, - value: Option, - } - impl AttrActionId { - fn from(value: Option) -> Self { - Self { - is_dirty: false, - value, - } - } +// attribute struct definition +#[derive(Default, Clone, Debug)] +pub struct AttrActionId { + is_dirty:bool, + value: Option +} - fn get(&self) -> &Option { - &self.value +impl AttrActionId { + fn from(value:Option) -> Self { + Self { + is_dirty: false, + value } + } - fn get_mut(&mut self) -> &mut Option { - &mut self.value - } + fn get(&self) -> &Option { + &self.value + } - fn set(&mut self, value: Option) { - self.value = value - } + fn get_mut(&mut self) -> &mut Option { + &mut self.value + } - fn update(&mut self, value: String) { - self.is_dirty = true; - self.value = Some(value) - } + fn set(&mut self, value:Option) { + self.value = value } - impl AttrValue for AttrActionId { - fn dat_type() -> &'static DatType { - static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); - ONCE_LOCK.get_or_init(|| Self::attr_dat_type()) - } + fn update(&mut self, value: String) { + self.is_dirty = true; + self.value = Some(value) + } +} - fn datum_desc() -> &'static DatumDesc { - static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); - ONCE_LOCK.get_or_init(|| Self::attr_datum_desc()) - } +impl AttrValue for AttrActionId { + fn dat_type() -> &'static DatType { + static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); + ONCE_LOCK.get_or_init(|| Self::attr_dat_type()) + } - fn object_name() -> &'static str { - VOTE_ACTIONS - } + fn datum_desc() -> &'static DatumDesc { + static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); + ONCE_LOCK.get_or_init(|| Self::attr_datum_desc()) + } - fn attr_name() -> &'static str { - ACTION_ID - } + fn object_name() -> &'static str { + VOTE_ACTIONS } - // attribute struct definition - #[derive(Default, Clone, Debug)] - pub struct AttrUserId { - is_dirty: bool, - value: Option, + fn attr_name() -> &'static str { + ACTION_ID } +} - impl AttrUserId { - fn from(value: Option) -> Self { - Self { - is_dirty: false, - value, - } - } +// attribute struct definition +#[derive(Default, Clone, Debug)] +pub struct AttrUserId { + is_dirty:bool, + value: Option +} - fn get(&self) -> &Option { - &self.value +impl AttrUserId { + fn from(value:Option) -> Self { + Self { + is_dirty: false, + value } + } - fn get_mut(&mut self) -> &mut Option { - &mut self.value - } + fn get(&self) -> &Option { + &self.value + } - fn set(&mut self, value: Option) { - self.value = value - } + fn get_mut(&mut self) -> &mut Option { + &mut self.value + } - fn update(&mut self, value: String) { - self.is_dirty = true; - self.value = Some(value) - } + fn set(&mut self, value:Option) { + self.value = value } - impl AttrValue for AttrUserId { - fn dat_type() -> &'static DatType { - static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); - ONCE_LOCK.get_or_init(|| Self::attr_dat_type()) - } + fn update(&mut self, value: String) { + self.is_dirty = true; + self.value = Some(value) + } +} - fn datum_desc() -> &'static DatumDesc { - static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); - ONCE_LOCK.get_or_init(|| Self::attr_datum_desc()) - } +impl AttrValue for AttrUserId { + fn dat_type() -> &'static DatType { + static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); + ONCE_LOCK.get_or_init(|| Self::attr_dat_type()) + } - fn object_name() -> &'static str { - VOTE_ACTIONS - } + fn datum_desc() -> &'static DatumDesc { + static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); + ONCE_LOCK.get_or_init(|| Self::attr_datum_desc()) + } - fn attr_name() -> &'static str { - USER_ID - } + fn object_name() -> &'static str { + VOTE_ACTIONS } - // attribute struct definition - #[derive(Default, Clone, Debug)] - pub struct AttrVoteId { - is_dirty: bool, - value: Option, + fn attr_name() -> &'static str { + USER_ID } +} - impl AttrVoteId { - fn from(value: Option) -> Self { - Self { - is_dirty: false, - value, - } - } +// attribute struct definition +#[derive(Default, Clone, Debug)] +pub struct AttrVoteId { + is_dirty:bool, + value: Option +} - fn get(&self) -> &Option { - &self.value +impl AttrVoteId { + fn from(value:Option) -> Self { + Self { + is_dirty: false, + value } + } - fn get_mut(&mut self) -> &mut Option { - &mut self.value - } + fn get(&self) -> &Option { + &self.value + } - fn set(&mut self, value: Option) { - self.value = value - } + fn get_mut(&mut self) -> &mut Option { + &mut self.value + } - fn update(&mut self, value: String) { - self.is_dirty = true; - self.value = Some(value) - } + fn set(&mut self, value:Option) { + self.value = value } - impl AttrValue for AttrVoteId { - fn dat_type() -> &'static DatType { - static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); - ONCE_LOCK.get_or_init(|| Self::attr_dat_type()) - } + fn update(&mut self, value: String) { + self.is_dirty = true; + self.value = Some(value) + } +} - fn datum_desc() -> &'static DatumDesc { - static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); - ONCE_LOCK.get_or_init(|| Self::attr_datum_desc()) - } +impl AttrValue for AttrVoteId { + fn dat_type() -> &'static DatType { + static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); + ONCE_LOCK.get_or_init(|| Self::attr_dat_type()) + } - fn object_name() -> &'static str { - VOTE_ACTIONS - } + fn datum_desc() -> &'static DatumDesc { + static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); + ONCE_LOCK.get_or_init(|| Self::attr_datum_desc()) + } - fn attr_name() -> &'static str { - VOTE_ID - } + fn object_name() -> &'static str { + VOTE_ACTIONS } - // attribute struct definition - #[derive(Default, Clone, Debug)] - pub struct AttrActionTime { - is_dirty: bool, - value: Option, + fn attr_name() -> &'static str { + VOTE_ID } +} - impl AttrActionTime { - fn from(value: Option) -> Self { - Self { - is_dirty: false, - value, - } - } +// attribute struct definition +#[derive(Default, Clone, Debug)] +pub struct AttrActionTime { + is_dirty:bool, + value: Option +} - fn get(&self) -> &Option { - &self.value +impl AttrActionTime { + fn from(value:Option) -> Self { + Self { + is_dirty: false, + value } + } - fn get_mut(&mut self) -> &mut Option { - &mut self.value - } + fn get(&self) -> &Option { + &self.value + } - fn set(&mut self, value: Option) { - self.value = value - } + fn get_mut(&mut self) -> &mut Option { + &mut self.value + } - fn update(&mut self, value: i32) { - self.is_dirty = true; - self.value = Some(value) - } + fn set(&mut self, value:Option) { + self.value = value } - impl AttrValue for AttrActionTime { - fn dat_type() -> &'static DatType { - static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); - ONCE_LOCK.get_or_init(|| Self::attr_dat_type()) - } + fn update(&mut self, value: i32) { + self.is_dirty = true; + self.value = Some(value) + } +} - fn datum_desc() -> &'static DatumDesc { - static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); - ONCE_LOCK.get_or_init(|| Self::attr_datum_desc()) - } +impl AttrValue for AttrActionTime { + fn dat_type() -> &'static DatType { + static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); + ONCE_LOCK.get_or_init(|| Self::attr_dat_type()) + } - fn object_name() -> &'static str { - VOTE_ACTIONS - } + fn datum_desc() -> &'static DatumDesc { + static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); + ONCE_LOCK.get_or_init(|| Self::attr_datum_desc()) + } - fn attr_name() -> &'static str { - ACTION_TIME - } + fn object_name() -> &'static str { + VOTE_ACTIONS } - // attribute struct definition - #[derive(Default, Clone, Debug)] - pub struct AttrIsWithdrawn { - is_dirty: bool, - value: Option, + fn attr_name() -> &'static str { + ACTION_TIME } +} - impl AttrIsWithdrawn { - fn from(value: Option) -> Self { - Self { - is_dirty: false, - value, - } - } +// attribute struct definition +#[derive(Default, Clone, Debug)] +pub struct AttrIsWithdrawn { + is_dirty:bool, + value: Option +} - fn get(&self) -> &Option { - &self.value +impl AttrIsWithdrawn { + fn from(value:Option) -> Self { + Self { + is_dirty: false, + value } + } - fn get_mut(&mut self) -> &mut Option { - &mut self.value - } + fn get(&self) -> &Option { + &self.value + } - fn set(&mut self, value: Option) { - self.value = value - } + fn get_mut(&mut self) -> &mut Option { + &mut self.value + } - fn update(&mut self, value: i32) { - self.is_dirty = true; - self.value = Some(value) - } + fn set(&mut self, value:Option) { + self.value = value } - impl AttrValue for AttrIsWithdrawn { - fn dat_type() -> &'static DatType { - static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); - ONCE_LOCK.get_or_init(|| Self::attr_dat_type()) - } + fn update(&mut self, value: i32) { + self.is_dirty = true; + self.value = Some(value) + } +} - fn datum_desc() -> &'static DatumDesc { - static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); - ONCE_LOCK.get_or_init(|| Self::attr_datum_desc()) - } +impl AttrValue for AttrIsWithdrawn { + fn dat_type() -> &'static DatType { + static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); + ONCE_LOCK.get_or_init(|| Self::attr_dat_type()) + } - fn object_name() -> &'static str { - VOTE_ACTIONS - } + fn datum_desc() -> &'static DatumDesc { + static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); + ONCE_LOCK.get_or_init(|| Self::attr_datum_desc()) + } - fn attr_name() -> &'static str { - IS_WITHDRAWN - } + fn object_name() -> &'static str { + VOTE_ACTIONS } - #[cfg(test)] - mod tests { - use super::VoteActions; - use mudu_contract::database::entity::Entity; - use mudu_type::datum::{Datum, DatumDyn}; - - #[test] - fn vote_actions_roundtrip_and_field_updates() { - let action = VoteActions::new( - Some("a1".to_string()), - Some("u1".to_string()), - Some("v1".to_string()), - Some(10), - Some(0), - ); - - let from_value = - VoteActions::from_value(&action.to_value(VoteActions::dat_type()).unwrap()) - .unwrap(); - assert_eq!(from_value.get_action_id().as_deref(), Some("a1")); - assert_eq!(from_value.get_action_time(), &Some(10)); - - let from_binary = VoteActions::from_binary( - action.to_binary(VoteActions::dat_type()).unwrap().as_ref(), - ) - .unwrap(); - assert_eq!(from_binary.get_is_withdrawn(), &Some(0)); - - let mut updated = VoteActions::new_empty(); - updated - .set_field_value( - "action_id", - mudu_type::dat_value::DatValue::from_string("a2".to_string()), - ) - .unwrap(); - updated - .set_field_value("is_withdrawn", mudu_type::dat_value::DatValue::from_i32(1)) - .unwrap(); - assert_eq!(updated.get_action_id().as_deref(), Some("a2")); - assert_eq!(updated.get_is_withdrawn(), &Some(1)); - } + fn attr_name() -> &'static str { + IS_WITHDRAWN } } + + +} diff --git a/example/vote/src/rust/vote_choices.rs b/example/vote/src/rust/vote_choices.rs index fc73a77..238591a 100644 --- a/example/vote/src/rust/vote_choices.rs +++ b/example/vote/src/rust/vote_choices.rs @@ -1,388 +1,417 @@ pub mod object { - use lazy_static::lazy_static; - use mudu::common::result::RS; - use mudu_contract::database::attr_field_access; - use mudu_contract::database::attr_value::AttrValue; - use mudu_contract::database::entity::Entity; - use mudu_contract::database::entity_utils; - use mudu_contract::database::sql_params::SQLParamMarker; - use mudu_contract::tuple::datum_desc::DatumDesc; - use mudu_contract::tuple::tuple_datum::TupleDatumMarker; - use mudu_contract::tuple::tuple_field_desc::TupleFieldDesc; - use mudu_type::dat_binary::DatBinary; - use mudu_type::dat_textual::DatTextual; - use mudu_type::dat_type::DatType; - use mudu_type::dat_type_id::DatTypeID; - use mudu_type::dat_value::DatValue; - use mudu_type::datum::{Datum, DatumDyn}; - - // constant definition - const VOTE_CHOICES: &str = "vote_choices"; - - const CHOICE_ID: &str = "choice_id"; - - const ACTION_ID: &str = "action_id"; - - const OPTION_ID: &str = "option_id"; - - // entity struct definition - #[derive(Debug, Clone, Default)] - pub struct VoteChoices { - choice_id: AttrChoiceId, - - action_id: AttrActionId, +use lazy_static::lazy_static; +use mududb::common::result::RS; +use mududb::contract::database::attr_field_access; +use mududb::contract::database::attr_value::AttrValue; +use mududb::contract::database::entity::Entity; +use mududb::contract::database::entity_utils; +use mududb::contract::database::sql_params::SQLParamMarker; +use mududb::contract::tuple::datum_desc::DatumDesc; +use mududb::contract::tuple::tuple_field_desc::TupleFieldDesc; +use mududb::contract::tuple::tuple_datum::TupleDatumMarker; +use mududb::types::dat_binary::DatBinary; +use mududb::types::dat_textual::DatTextual; +use mududb::types::dat_type::DatType; +use mududb::types::dat_type_id::DatTypeID; +use mududb::types::dat_value::DatValue; +use mududb::types::datum::{Datum, DatumDyn}; + +// constant definition +const VOTE_CHOICES:&str = "vote_choices"; + +const CHOICE_ID:&str = "choice_id"; + +const ACTION_ID:&str = "action_id"; + +const OPTION_ID:&str = "option_id"; + + +// entity struct definition +#[derive(Debug, Clone, Default)] +pub struct VoteChoices { + + choice_id: AttrChoiceId, + + action_id: AttrActionId, + + option_id: AttrOptionId, + +} - option_id: AttrOptionId, +impl TupleDatumMarker for VoteChoices {} + +impl SQLParamMarker for VoteChoices {} + +impl VoteChoices { + pub fn new( + choice_id: Option, + action_id: Option, + option_id: Option, + + ) -> Self { + let s = Self { + + choice_id : AttrChoiceId::from(choice_id), + + action_id : AttrActionId::from(action_id), + + option_id : AttrOptionId::from(option_id), + + }; + s } - impl TupleDatumMarker for VoteChoices {} - - impl SQLParamMarker for VoteChoices {} - - impl VoteChoices { - pub fn new( - choice_id: Option, - action_id: Option, - option_id: Option, - ) -> Self { - let s = Self { - choice_id: AttrChoiceId::from(choice_id), - - action_id: AttrActionId::from(action_id), - - option_id: AttrOptionId::from(option_id), - }; - s - } - - pub fn new_empty() -> Self { - Self::default() - } + pub fn new_empty() -> Self { + Self::default() + } - pub fn set_choice_id(&mut self, choice_id: String) { - self.choice_id.update(choice_id) - } + + pub fn set_choice_id( + &mut self, + choice_id: String, + ) { + self.choice_id.update(choice_id) + } - pub fn get_choice_id(&self) -> &Option { - self.choice_id.get() - } + pub fn get_choice_id( + &self, + ) -> &Option { + self.choice_id.get() + } + + pub fn set_action_id( + &mut self, + action_id: String, + ) { + self.action_id.update(action_id) + } - pub fn set_action_id(&mut self, action_id: String) { - self.action_id.update(action_id) - } + pub fn get_action_id( + &self, + ) -> &Option { + self.action_id.get() + } + + pub fn set_option_id( + &mut self, + option_id: String, + ) { + self.option_id.update(option_id) + } - pub fn get_action_id(&self) -> &Option { - self.action_id.get() - } + pub fn get_option_id( + &self, + ) -> &Option { + self.option_id.get() + } + +} - pub fn set_option_id(&mut self, option_id: String) { - self.option_id.update(option_id) +impl Datum for VoteChoices { + fn dat_type() -> &'static DatType { + lazy_static! { + static ref DAT_TYPE: DatType = entity_utils::entity_dat_type::(); } + &DAT_TYPE + } - pub fn get_option_id(&self) -> &Option { - self.option_id.get() - } + fn from_binary(binary: &[u8]) -> RS { + entity_utils::entity_from_binary(binary) } - impl Datum for VoteChoices { - fn dat_type() -> &'static DatType { - lazy_static! { - static ref DAT_TYPE: DatType = entity_utils::entity_dat_type::(); - } - &DAT_TYPE - } + fn from_value(value: &DatValue) -> RS { + entity_utils::entity_from_value(value) + } - fn from_binary(binary: &[u8]) -> RS { - entity_utils::entity_from_binary(binary) - } + fn from_textual(textual: &str) -> RS { + entity_utils::entity_from_textual(textual) + } +} - fn from_value(value: &DatValue) -> RS { - entity_utils::entity_from_value(value) - } +impl DatumDyn for VoteChoices { + fn dat_type_id(&self) -> RS { + entity_utils::entity_dat_type_id() + } - fn from_textual(textual: &str) -> RS { - entity_utils::entity_from_textual(textual) - } + fn to_binary(&self, dat_type: &DatType) -> RS { + entity_utils::entity_to_binary(self, dat_type) } - impl DatumDyn for VoteChoices { - fn dat_type_id(&self) -> RS { - entity_utils::entity_dat_type_id() - } + fn to_textual(&self, dat_type: &DatType) -> RS { + entity_utils::entity_to_textual(self, dat_type) + } - fn to_binary(&self, dat_type: &DatType) -> RS { - entity_utils::entity_to_binary(self, dat_type) - } + fn to_value(&self, dat_type: &DatType) -> RS { + entity_utils::entity_to_value(self, dat_type) + } - fn to_textual(&self, dat_type: &DatType) -> RS { - entity_utils::entity_to_textual(self, dat_type) - } + fn clone_boxed(&self) -> Box { + entity_utils::entity_clone_boxed(self) + } +} - fn to_value(&self, dat_type: &DatType) -> RS { - entity_utils::entity_to_value(self, dat_type) - } +impl Entity for VoteChoices { + fn new_empty() -> Self { + Self::new_empty() + } - fn clone_boxed(&self) -> Box { - entity_utils::entity_clone_boxed(self) - } + fn tuple_desc() -> &'static TupleFieldDesc { + lazy_static! { + static ref TUPLE_DESC: TupleFieldDesc = TupleFieldDesc::new(vec![ + + AttrChoiceId::datum_desc().clone(), + + AttrActionId::datum_desc().clone(), + + AttrOptionId::datum_desc().clone(), + + ]); + } + &TUPLE_DESC } - impl Entity for VoteChoices { - fn new_empty() -> Self { - Self::new_empty() - } + fn object_name() -> &'static str { + VOTE_CHOICES + } - fn tuple_desc() -> &'static TupleFieldDesc { - lazy_static! { - static ref TUPLE_DESC: TupleFieldDesc = TupleFieldDesc::new(vec![ - AttrChoiceId::datum_desc().clone(), - AttrActionId::datum_desc().clone(), - AttrOptionId::datum_desc().clone(), - ]); + fn get_field_binary(&self, field: &str) -> RS>> { + match field { + + CHOICE_ID => { + attr_field_access::attr_get_binary::<_>(self.choice_id.get()) } - &TUPLE_DESC - } - - fn object_name() -> &'static str { - VOTE_CHOICES + + ACTION_ID => { + attr_field_access::attr_get_binary::<_>(self.action_id.get()) + } + + OPTION_ID => { + attr_field_access::attr_get_binary::<_>(self.option_id.get()) + } + + _ => { panic!("unknown name"); } } + } - fn get_field_binary(&self, field: &str) -> RS>> { - match field { - CHOICE_ID => attr_field_access::attr_get_binary::<_>(self.choice_id.get()), - - ACTION_ID => attr_field_access::attr_get_binary::<_>(self.action_id.get()), - - OPTION_ID => attr_field_access::attr_get_binary::<_>(self.option_id.get()), - - _ => { - panic!("unknown name"); - } + fn set_field_binary>(&mut self, field: &str, binary: B) -> RS<()> { + match field { + + CHOICE_ID => { + attr_field_access::attr_set_binary::<_, _>(self.choice_id.get_mut(), binary.as_ref())?; + } + + ACTION_ID => { + attr_field_access::attr_set_binary::<_, _>(self.action_id.get_mut(), binary.as_ref())?; } + + OPTION_ID => { + attr_field_access::attr_set_binary::<_, _>(self.option_id.get_mut(), binary.as_ref())?; + } + + _ => { panic!("unknown name"); } } + Ok(()) + } - fn set_field_binary>(&mut self, field: &str, binary: B) -> RS<()> { - match field { - CHOICE_ID => { - attr_field_access::attr_set_binary::<_, _>( - self.choice_id.get_mut(), - binary.as_ref(), - )?; - } - - ACTION_ID => { - attr_field_access::attr_set_binary::<_, _>( - self.action_id.get_mut(), - binary.as_ref(), - )?; - } - - OPTION_ID => { - attr_field_access::attr_set_binary::<_, _>( - self.option_id.get_mut(), - binary.as_ref(), - )?; - } - - _ => { - panic!("unknown name"); - } + fn get_field_value(&self, field: &str) -> RS> { + match field { + + CHOICE_ID => { + attr_field_access::attr_get_value::<_>(self.choice_id.get()) } - Ok(()) + + ACTION_ID => { + attr_field_access::attr_get_value::<_>(self.action_id.get()) + } + + OPTION_ID => { + attr_field_access::attr_get_value::<_>(self.option_id.get()) + } + + _ => { panic!("unknown name"); } } + } - fn get_field_value(&self, field: &str) -> RS> { - match field { - CHOICE_ID => attr_field_access::attr_get_value::<_>(self.choice_id.get()), - - ACTION_ID => attr_field_access::attr_get_value::<_>(self.action_id.get()), - - OPTION_ID => attr_field_access::attr_get_value::<_>(self.option_id.get()), - - _ => { - panic!("unknown name"); - } + fn set_field_value>(&mut self, field: &str, value: B) -> RS<()> { + match field { + + CHOICE_ID => { + attr_field_access::attr_set_value::<_, _>(self.choice_id.get_mut(), value)?; + } + + ACTION_ID => { + attr_field_access::attr_set_value::<_, _>(self.action_id.get_mut(), value)?; + } + + OPTION_ID => { + attr_field_access::attr_set_value::<_, _>(self.option_id.get_mut(), value)?; } + + _ => { panic!("unknown name"); } } + Ok(()) + } +} - fn set_field_value>(&mut self, field: &str, value: B) -> RS<()> { - match field { - CHOICE_ID => { - attr_field_access::attr_set_value::<_, _>(self.choice_id.get_mut(), value)?; - } - - ACTION_ID => { - attr_field_access::attr_set_value::<_, _>(self.action_id.get_mut(), value)?; - } - OPTION_ID => { - attr_field_access::attr_set_value::<_, _>(self.option_id.get_mut(), value)?; - } +// attribute struct definition +#[derive(Default, Clone, Debug)] +pub struct AttrChoiceId { + is_dirty:bool, + value: Option +} - _ => { - panic!("unknown name"); - } - } - Ok(()) +impl AttrChoiceId { + fn from(value:Option) -> Self { + Self { + is_dirty: false, + value } } - // attribute struct definition - #[derive(Default, Clone, Debug)] - pub struct AttrChoiceId { - is_dirty: bool, - value: Option, + fn get(&self) -> &Option { + &self.value } - impl AttrChoiceId { - fn from(value: Option) -> Self { - Self { - is_dirty: false, - value, - } - } + fn get_mut(&mut self) -> &mut Option { + &mut self.value + } - fn get(&self) -> &Option { - &self.value - } + fn set(&mut self, value:Option) { + self.value = value + } - fn get_mut(&mut self) -> &mut Option { - &mut self.value - } + fn update(&mut self, value: String) { + self.is_dirty = true; + self.value = Some(value) + } +} - fn set(&mut self, value: Option) { - self.value = value - } +impl AttrValue for AttrChoiceId { + fn dat_type() -> &'static DatType { + static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); + ONCE_LOCK.get_or_init(|| Self::attr_dat_type()) + } - fn update(&mut self, value: String) { - self.is_dirty = true; - self.value = Some(value) - } + fn datum_desc() -> &'static DatumDesc { + static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); + ONCE_LOCK.get_or_init(|| Self::attr_datum_desc()) } - impl AttrValue for AttrChoiceId { - fn dat_type() -> &'static DatType { - static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); - ONCE_LOCK.get_or_init(|| Self::attr_dat_type()) - } + fn object_name() -> &'static str { + VOTE_CHOICES + } - fn datum_desc() -> &'static DatumDesc { - static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); - ONCE_LOCK.get_or_init(|| Self::attr_datum_desc()) - } + fn attr_name() -> &'static str { + CHOICE_ID + } +} - fn object_name() -> &'static str { - VOTE_CHOICES - } +// attribute struct definition +#[derive(Default, Clone, Debug)] +pub struct AttrActionId { + is_dirty:bool, + value: Option +} - fn attr_name() -> &'static str { - CHOICE_ID +impl AttrActionId { + fn from(value:Option) -> Self { + Self { + is_dirty: false, + value } } - // attribute struct definition - #[derive(Default, Clone, Debug)] - pub struct AttrActionId { - is_dirty: bool, - value: Option, + fn get(&self) -> &Option { + &self.value } - impl AttrActionId { - fn from(value: Option) -> Self { - Self { - is_dirty: false, - value, - } - } + fn get_mut(&mut self) -> &mut Option { + &mut self.value + } - fn get(&self) -> &Option { - &self.value - } + fn set(&mut self, value:Option) { + self.value = value + } - fn get_mut(&mut self) -> &mut Option { - &mut self.value - } + fn update(&mut self, value: String) { + self.is_dirty = true; + self.value = Some(value) + } +} - fn set(&mut self, value: Option) { - self.value = value - } +impl AttrValue for AttrActionId { + fn dat_type() -> &'static DatType { + static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); + ONCE_LOCK.get_or_init(|| Self::attr_dat_type()) + } - fn update(&mut self, value: String) { - self.is_dirty = true; - self.value = Some(value) - } + fn datum_desc() -> &'static DatumDesc { + static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); + ONCE_LOCK.get_or_init(|| Self::attr_datum_desc()) } - impl AttrValue for AttrActionId { - fn dat_type() -> &'static DatType { - static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); - ONCE_LOCK.get_or_init(|| Self::attr_dat_type()) - } + fn object_name() -> &'static str { + VOTE_CHOICES + } - fn datum_desc() -> &'static DatumDesc { - static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); - ONCE_LOCK.get_or_init(|| Self::attr_datum_desc()) - } + fn attr_name() -> &'static str { + ACTION_ID + } +} - fn object_name() -> &'static str { - VOTE_CHOICES - } +// attribute struct definition +#[derive(Default, Clone, Debug)] +pub struct AttrOptionId { + is_dirty:bool, + value: Option +} - fn attr_name() -> &'static str { - ACTION_ID +impl AttrOptionId { + fn from(value:Option) -> Self { + Self { + is_dirty: false, + value } } - // attribute struct definition - #[derive(Default, Clone, Debug)] - pub struct AttrOptionId { - is_dirty: bool, - value: Option, + fn get(&self) -> &Option { + &self.value } - impl AttrOptionId { - fn from(value: Option) -> Self { - Self { - is_dirty: false, - value, - } - } + fn get_mut(&mut self) -> &mut Option { + &mut self.value + } - fn get(&self) -> &Option { - &self.value - } + fn set(&mut self, value:Option) { + self.value = value + } - fn get_mut(&mut self) -> &mut Option { - &mut self.value - } + fn update(&mut self, value: String) { + self.is_dirty = true; + self.value = Some(value) + } +} - fn set(&mut self, value: Option) { - self.value = value - } +impl AttrValue for AttrOptionId { + fn dat_type() -> &'static DatType { + static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); + ONCE_LOCK.get_or_init(|| Self::attr_dat_type()) + } - fn update(&mut self, value: String) { - self.is_dirty = true; - self.value = Some(value) - } + fn datum_desc() -> &'static DatumDesc { + static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); + ONCE_LOCK.get_or_init(|| Self::attr_datum_desc()) } - impl AttrValue for AttrOptionId { - fn dat_type() -> &'static DatType { - static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); - ONCE_LOCK.get_or_init(|| Self::attr_dat_type()) - } + fn object_name() -> &'static str { + VOTE_CHOICES + } - fn datum_desc() -> &'static DatumDesc { - static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); - ONCE_LOCK.get_or_init(|| Self::attr_datum_desc()) - } + fn attr_name() -> &'static str { + OPTION_ID + } +} - fn object_name() -> &'static str { - VOTE_CHOICES - } - fn attr_name() -> &'static str { - OPTION_ID - } - } } diff --git a/example/vote/src/rust/vote_history_item.rs b/example/vote/src/rust/vote_history_item.rs index 46471c6..18dc428 100644 --- a/example/vote/src/rust/vote_history_item.rs +++ b/example/vote/src/rust/vote_history_item.rs @@ -1,601 +1,599 @@ pub mod object { - use lazy_static::lazy_static; - use mudu::common::result::RS; - use mudu_contract::database::attr_field_access; - use mudu_contract::database::attr_value::AttrValue; - use mudu_contract::database::entity::Entity; - use mudu_contract::database::entity_utils; - use mudu_contract::database::sql_params::SQLParamMarker; - use mudu_contract::tuple::datum_desc::DatumDesc; - use mudu_contract::tuple::tuple_datum::TupleDatumMarker; - use mudu_contract::tuple::tuple_field_desc::TupleFieldDesc; - use mudu_type::dat_binary::DatBinary; - use mudu_type::dat_textual::DatTextual; - use mudu_type::dat_type::DatType; - use mudu_type::dat_type_id::DatTypeID; - use mudu_type::dat_value::DatValue; - use mudu_type::datum::{Datum, DatumDyn}; - - // constant definition - const VOTE_HISTORY_ITEM: &str = "vote_history_item"; - - const VOTE_ID: &str = "vote_id"; - - const TOPIC: &str = "topic"; - - const ACTION_TIME: &str = "action_time"; - - const IS_WITHDRAWN: &str = "is_withdrawn"; - - const VOTE_ENDED: &str = "vote_ended"; - - // entity struct definition - #[derive(Debug, Clone, Default)] - pub struct VoteHistoryItem { - vote_id: AttrVoteId, - - topic: AttrTopic, - - action_time: AttrActionTime, +use lazy_static::lazy_static; +use mududb::common::result::RS; +use mududb::contract::database::attr_field_access; +use mududb::contract::database::attr_value::AttrValue; +use mududb::contract::database::entity::Entity; +use mududb::contract::database::entity_utils; +use mududb::contract::database::sql_params::SQLParamMarker; +use mududb::contract::tuple::datum_desc::DatumDesc; +use mududb::contract::tuple::tuple_field_desc::TupleFieldDesc; +use mududb::contract::tuple::tuple_datum::TupleDatumMarker; +use mududb::types::dat_binary::DatBinary; +use mududb::types::dat_textual::DatTextual; +use mududb::types::dat_type::DatType; +use mududb::types::dat_type_id::DatTypeID; +use mududb::types::dat_value::DatValue; +use mududb::types::datum::{Datum, DatumDyn}; + +// constant definition +const VOTE_HISTORY_ITEM:&str = "vote_history_item"; + +const VOTE_ID:&str = "vote_id"; + +const TOPIC:&str = "topic"; + +const ACTION_TIME:&str = "action_time"; + +const IS_WITHDRAWN:&str = "is_withdrawn"; + +const VOTE_ENDED:&str = "vote_ended"; + + +// entity struct definition +#[derive(Debug, Clone, Default)] +pub struct VoteHistoryItem { + + vote_id: AttrVoteId, + + topic: AttrTopic, + + action_time: AttrActionTime, + + is_withdrawn: AttrIsWithdrawn, + + vote_ended: AttrVoteEnded, + +} - is_withdrawn: AttrIsWithdrawn, +impl TupleDatumMarker for VoteHistoryItem {} + +impl SQLParamMarker for VoteHistoryItem {} + +impl VoteHistoryItem { + pub fn new( + vote_id: Option, + topic: Option, + action_time: Option, + is_withdrawn: Option, + vote_ended: Option, + + ) -> Self { + let s = Self { + + vote_id : AttrVoteId::from(vote_id), + + topic : AttrTopic::from(topic), + + action_time : AttrActionTime::from(action_time), + + is_withdrawn : AttrIsWithdrawn::from(is_withdrawn), + + vote_ended : AttrVoteEnded::from(vote_ended), + + }; + s + } - vote_ended: AttrVoteEnded, + pub fn new_empty() -> Self { + Self::default() } - impl TupleDatumMarker for VoteHistoryItem {} + + pub fn set_vote_id( + &mut self, + vote_id: String, + ) { + self.vote_id.update(vote_id) + } - impl SQLParamMarker for VoteHistoryItem {} + pub fn get_vote_id( + &self, + ) -> &Option { + self.vote_id.get() + } + + pub fn set_topic( + &mut self, + topic: String, + ) { + self.topic.update(topic) + } - impl VoteHistoryItem { - pub fn new( - vote_id: Option, - topic: Option, - action_time: Option, - is_withdrawn: Option, - vote_ended: Option, - ) -> Self { - let s = Self { - vote_id: AttrVoteId::from(vote_id), + pub fn get_topic( + &self, + ) -> &Option { + self.topic.get() + } + + pub fn set_action_time( + &mut self, + action_time: i32, + ) { + self.action_time.update(action_time) + } - topic: AttrTopic::from(topic), + pub fn get_action_time( + &self, + ) -> &Option { + self.action_time.get() + } + + pub fn set_is_withdrawn( + &mut self, + is_withdrawn: i32, + ) { + self.is_withdrawn.update(is_withdrawn) + } - action_time: AttrActionTime::from(action_time), + pub fn get_is_withdrawn( + &self, + ) -> &Option { + self.is_withdrawn.get() + } + + pub fn set_vote_ended( + &mut self, + vote_ended: i32, + ) { + self.vote_ended.update(vote_ended) + } - is_withdrawn: AttrIsWithdrawn::from(is_withdrawn), + pub fn get_vote_ended( + &self, + ) -> &Option { + self.vote_ended.get() + } + +} - vote_ended: AttrVoteEnded::from(vote_ended), - }; - s +impl Datum for VoteHistoryItem { + fn dat_type() -> &'static DatType { + lazy_static! { + static ref DAT_TYPE: DatType = entity_utils::entity_dat_type::(); } + &DAT_TYPE + } - pub fn new_empty() -> Self { - Self::default() - } + fn from_binary(binary: &[u8]) -> RS { + entity_utils::entity_from_binary(binary) + } - pub fn set_vote_id(&mut self, vote_id: String) { - self.vote_id.update(vote_id) - } + fn from_value(value: &DatValue) -> RS { + entity_utils::entity_from_value(value) + } - pub fn get_vote_id(&self) -> &Option { - self.vote_id.get() - } + fn from_textual(textual: &str) -> RS { + entity_utils::entity_from_textual(textual) + } +} - pub fn set_topic(&mut self, topic: String) { - self.topic.update(topic) - } +impl DatumDyn for VoteHistoryItem { + fn dat_type_id(&self) -> RS { + entity_utils::entity_dat_type_id() + } - pub fn get_topic(&self) -> &Option { - self.topic.get() - } + fn to_binary(&self, dat_type: &DatType) -> RS { + entity_utils::entity_to_binary(self, dat_type) + } - pub fn set_action_time(&mut self, action_time: i32) { - self.action_time.update(action_time) - } + fn to_textual(&self, dat_type: &DatType) -> RS { + entity_utils::entity_to_textual(self, dat_type) + } - pub fn get_action_time(&self) -> &Option { - self.action_time.get() - } + fn to_value(&self, dat_type: &DatType) -> RS { + entity_utils::entity_to_value(self, dat_type) + } - pub fn set_is_withdrawn(&mut self, is_withdrawn: i32) { - self.is_withdrawn.update(is_withdrawn) - } + fn clone_boxed(&self) -> Box { + entity_utils::entity_clone_boxed(self) + } +} - pub fn get_is_withdrawn(&self) -> &Option { - self.is_withdrawn.get() - } +impl Entity for VoteHistoryItem { + fn new_empty() -> Self { + Self::new_empty() + } - pub fn set_vote_ended(&mut self, vote_ended: i32) { - self.vote_ended.update(vote_ended) - } + fn tuple_desc() -> &'static TupleFieldDesc { + lazy_static! { + static ref TUPLE_DESC: TupleFieldDesc = TupleFieldDesc::new(vec![ + + AttrVoteId::datum_desc().clone(), + + AttrTopic::datum_desc().clone(), + + AttrActionTime::datum_desc().clone(), + + AttrIsWithdrawn::datum_desc().clone(), + + AttrVoteEnded::datum_desc().clone(), + + ]); + } + &TUPLE_DESC + } - pub fn get_vote_ended(&self) -> &Option { - self.vote_ended.get() - } + fn object_name() -> &'static str { + VOTE_HISTORY_ITEM } - impl Datum for VoteHistoryItem { - fn dat_type() -> &'static DatType { - lazy_static! { - static ref DAT_TYPE: DatType = entity_utils::entity_dat_type::(); + fn get_field_binary(&self, field: &str) -> RS>> { + match field { + + VOTE_ID => { + attr_field_access::attr_get_binary::<_>(self.vote_id.get()) } - &DAT_TYPE - } - - fn from_binary(binary: &[u8]) -> RS { - entity_utils::entity_from_binary(binary) - } - - fn from_value(value: &DatValue) -> RS { - entity_utils::entity_from_value(value) - } - - fn from_textual(textual: &str) -> RS { - entity_utils::entity_from_textual(textual) + + TOPIC => { + attr_field_access::attr_get_binary::<_>(self.topic.get()) + } + + ACTION_TIME => { + attr_field_access::attr_get_binary::<_>(self.action_time.get()) + } + + IS_WITHDRAWN => { + attr_field_access::attr_get_binary::<_>(self.is_withdrawn.get()) + } + + VOTE_ENDED => { + attr_field_access::attr_get_binary::<_>(self.vote_ended.get()) + } + + _ => { panic!("unknown name"); } } } - impl DatumDyn for VoteHistoryItem { - fn dat_type_id(&self) -> RS { - entity_utils::entity_dat_type_id() - } - - fn to_binary(&self, dat_type: &DatType) -> RS { - entity_utils::entity_to_binary(self, dat_type) - } - - fn to_textual(&self, dat_type: &DatType) -> RS { - entity_utils::entity_to_textual(self, dat_type) - } - - fn to_value(&self, dat_type: &DatType) -> RS { - entity_utils::entity_to_value(self, dat_type) - } - - fn clone_boxed(&self) -> Box { - entity_utils::entity_clone_boxed(self) + fn set_field_binary>(&mut self, field: &str, binary: B) -> RS<()> { + match field { + + VOTE_ID => { + attr_field_access::attr_set_binary::<_, _>(self.vote_id.get_mut(), binary.as_ref())?; + } + + TOPIC => { + attr_field_access::attr_set_binary::<_, _>(self.topic.get_mut(), binary.as_ref())?; + } + + ACTION_TIME => { + attr_field_access::attr_set_binary::<_, _>(self.action_time.get_mut(), binary.as_ref())?; + } + + IS_WITHDRAWN => { + attr_field_access::attr_set_binary::<_, _>(self.is_withdrawn.get_mut(), binary.as_ref())?; + } + + VOTE_ENDED => { + attr_field_access::attr_set_binary::<_, _>(self.vote_ended.get_mut(), binary.as_ref())?; + } + + _ => { panic!("unknown name"); } } + Ok(()) } - impl Entity for VoteHistoryItem { - fn new_empty() -> Self { - Self::new_empty() - } - - fn tuple_desc() -> &'static TupleFieldDesc { - lazy_static! { - static ref TUPLE_DESC: TupleFieldDesc = TupleFieldDesc::new(vec![ - AttrVoteId::datum_desc().clone(), - AttrTopic::datum_desc().clone(), - AttrActionTime::datum_desc().clone(), - AttrIsWithdrawn::datum_desc().clone(), - AttrVoteEnded::datum_desc().clone(), - ]); + fn get_field_value(&self, field: &str) -> RS> { + match field { + + VOTE_ID => { + attr_field_access::attr_get_value::<_>(self.vote_id.get()) } - &TUPLE_DESC - } - - fn object_name() -> &'static str { - VOTE_HISTORY_ITEM - } - - fn get_field_binary(&self, field: &str) -> RS>> { - match field { - VOTE_ID => attr_field_access::attr_get_binary::<_>(self.vote_id.get()), - - TOPIC => attr_field_access::attr_get_binary::<_>(self.topic.get()), - - ACTION_TIME => attr_field_access::attr_get_binary::<_>(self.action_time.get()), - - IS_WITHDRAWN => attr_field_access::attr_get_binary::<_>(self.is_withdrawn.get()), - - VOTE_ENDED => attr_field_access::attr_get_binary::<_>(self.vote_ended.get()), - - _ => { - panic!("unknown name"); - } + + TOPIC => { + attr_field_access::attr_get_value::<_>(self.topic.get()) } - } - - fn set_field_binary>(&mut self, field: &str, binary: B) -> RS<()> { - match field { - VOTE_ID => { - attr_field_access::attr_set_binary::<_, _>( - self.vote_id.get_mut(), - binary.as_ref(), - )?; - } - - TOPIC => { - attr_field_access::attr_set_binary::<_, _>( - self.topic.get_mut(), - binary.as_ref(), - )?; - } - - ACTION_TIME => { - attr_field_access::attr_set_binary::<_, _>( - self.action_time.get_mut(), - binary.as_ref(), - )?; - } - - IS_WITHDRAWN => { - attr_field_access::attr_set_binary::<_, _>( - self.is_withdrawn.get_mut(), - binary.as_ref(), - )?; - } - - VOTE_ENDED => { - attr_field_access::attr_set_binary::<_, _>( - self.vote_ended.get_mut(), - binary.as_ref(), - )?; - } - - _ => { - panic!("unknown name"); - } + + ACTION_TIME => { + attr_field_access::attr_get_value::<_>(self.action_time.get()) } - Ok(()) - } - - fn get_field_value(&self, field: &str) -> RS> { - match field { - VOTE_ID => attr_field_access::attr_get_value::<_>(self.vote_id.get()), - - TOPIC => attr_field_access::attr_get_value::<_>(self.topic.get()), - - ACTION_TIME => attr_field_access::attr_get_value::<_>(self.action_time.get()), - - IS_WITHDRAWN => attr_field_access::attr_get_value::<_>(self.is_withdrawn.get()), - - VOTE_ENDED => attr_field_access::attr_get_value::<_>(self.vote_ended.get()), - - _ => { - panic!("unknown name"); - } + + IS_WITHDRAWN => { + attr_field_access::attr_get_value::<_>(self.is_withdrawn.get()) } + + VOTE_ENDED => { + attr_field_access::attr_get_value::<_>(self.vote_ended.get()) + } + + _ => { panic!("unknown name"); } } + } - fn set_field_value>(&mut self, field: &str, value: B) -> RS<()> { - match field { - VOTE_ID => { - attr_field_access::attr_set_value::<_, _>(self.vote_id.get_mut(), value)?; - } - - TOPIC => { - attr_field_access::attr_set_value::<_, _>(self.topic.get_mut(), value)?; - } - - ACTION_TIME => { - attr_field_access::attr_set_value::<_, _>(self.action_time.get_mut(), value)?; - } - - IS_WITHDRAWN => { - attr_field_access::attr_set_value::<_, _>(self.is_withdrawn.get_mut(), value)?; - } - - VOTE_ENDED => { - attr_field_access::attr_set_value::<_, _>(self.vote_ended.get_mut(), value)?; - } - - _ => { - panic!("unknown name"); - } + fn set_field_value>(&mut self, field: &str, value: B) -> RS<()> { + match field { + + VOTE_ID => { + attr_field_access::attr_set_value::<_, _>(self.vote_id.get_mut(), value)?; + } + + TOPIC => { + attr_field_access::attr_set_value::<_, _>(self.topic.get_mut(), value)?; + } + + ACTION_TIME => { + attr_field_access::attr_set_value::<_, _>(self.action_time.get_mut(), value)?; } - Ok(()) + + IS_WITHDRAWN => { + attr_field_access::attr_set_value::<_, _>(self.is_withdrawn.get_mut(), value)?; + } + + VOTE_ENDED => { + attr_field_access::attr_set_value::<_, _>(self.vote_ended.get_mut(), value)?; + } + + _ => { panic!("unknown name"); } } + Ok(()) } +} - // attribute struct definition - #[derive(Default, Clone, Debug)] - pub struct AttrVoteId { - is_dirty: bool, - value: Option, - } - impl AttrVoteId { - fn from(value: Option) -> Self { - Self { - is_dirty: false, - value, - } - } +// attribute struct definition +#[derive(Default, Clone, Debug)] +pub struct AttrVoteId { + is_dirty:bool, + value: Option +} - fn get(&self) -> &Option { - &self.value +impl AttrVoteId { + fn from(value:Option) -> Self { + Self { + is_dirty: false, + value } + } - fn get_mut(&mut self) -> &mut Option { - &mut self.value - } + fn get(&self) -> &Option { + &self.value + } - fn set(&mut self, value: Option) { - self.value = value - } + fn get_mut(&mut self) -> &mut Option { + &mut self.value + } - fn update(&mut self, value: String) { - self.is_dirty = true; - self.value = Some(value) - } + fn set(&mut self, value:Option) { + self.value = value } - impl AttrValue for AttrVoteId { - fn dat_type() -> &'static DatType { - static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); - ONCE_LOCK.get_or_init(|| Self::attr_dat_type()) - } + fn update(&mut self, value: String) { + self.is_dirty = true; + self.value = Some(value) + } +} - fn datum_desc() -> &'static DatumDesc { - static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); - ONCE_LOCK.get_or_init(|| Self::attr_datum_desc()) - } +impl AttrValue for AttrVoteId { + fn dat_type() -> &'static DatType { + static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); + ONCE_LOCK.get_or_init(|| Self::attr_dat_type()) + } - fn object_name() -> &'static str { - VOTE_HISTORY_ITEM - } + fn datum_desc() -> &'static DatumDesc { + static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); + ONCE_LOCK.get_or_init(|| Self::attr_datum_desc()) + } - fn attr_name() -> &'static str { - VOTE_ID - } + fn object_name() -> &'static str { + VOTE_HISTORY_ITEM } - // attribute struct definition - #[derive(Default, Clone, Debug)] - pub struct AttrTopic { - is_dirty: bool, - value: Option, + fn attr_name() -> &'static str { + VOTE_ID } +} - impl AttrTopic { - fn from(value: Option) -> Self { - Self { - is_dirty: false, - value, - } - } +// attribute struct definition +#[derive(Default, Clone, Debug)] +pub struct AttrTopic { + is_dirty:bool, + value: Option +} - fn get(&self) -> &Option { - &self.value +impl AttrTopic { + fn from(value:Option) -> Self { + Self { + is_dirty: false, + value } + } - fn get_mut(&mut self) -> &mut Option { - &mut self.value - } + fn get(&self) -> &Option { + &self.value + } - fn set(&mut self, value: Option) { - self.value = value - } + fn get_mut(&mut self) -> &mut Option { + &mut self.value + } - fn update(&mut self, value: String) { - self.is_dirty = true; - self.value = Some(value) - } + fn set(&mut self, value:Option) { + self.value = value } - impl AttrValue for AttrTopic { - fn dat_type() -> &'static DatType { - static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); - ONCE_LOCK.get_or_init(|| Self::attr_dat_type()) - } + fn update(&mut self, value: String) { + self.is_dirty = true; + self.value = Some(value) + } +} - fn datum_desc() -> &'static DatumDesc { - static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); - ONCE_LOCK.get_or_init(|| Self::attr_datum_desc()) - } +impl AttrValue for AttrTopic { + fn dat_type() -> &'static DatType { + static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); + ONCE_LOCK.get_or_init(|| Self::attr_dat_type()) + } - fn object_name() -> &'static str { - VOTE_HISTORY_ITEM - } + fn datum_desc() -> &'static DatumDesc { + static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); + ONCE_LOCK.get_or_init(|| Self::attr_datum_desc()) + } - fn attr_name() -> &'static str { - TOPIC - } + fn object_name() -> &'static str { + VOTE_HISTORY_ITEM } - // attribute struct definition - #[derive(Default, Clone, Debug)] - pub struct AttrActionTime { - is_dirty: bool, - value: Option, + fn attr_name() -> &'static str { + TOPIC } +} - impl AttrActionTime { - fn from(value: Option) -> Self { - Self { - is_dirty: false, - value, - } - } +// attribute struct definition +#[derive(Default, Clone, Debug)] +pub struct AttrActionTime { + is_dirty:bool, + value: Option +} - fn get(&self) -> &Option { - &self.value +impl AttrActionTime { + fn from(value:Option) -> Self { + Self { + is_dirty: false, + value } + } - fn get_mut(&mut self) -> &mut Option { - &mut self.value - } + fn get(&self) -> &Option { + &self.value + } - fn set(&mut self, value: Option) { - self.value = value - } + fn get_mut(&mut self) -> &mut Option { + &mut self.value + } - fn update(&mut self, value: i32) { - self.is_dirty = true; - self.value = Some(value) - } + fn set(&mut self, value:Option) { + self.value = value } - impl AttrValue for AttrActionTime { - fn dat_type() -> &'static DatType { - static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); - ONCE_LOCK.get_or_init(|| Self::attr_dat_type()) - } + fn update(&mut self, value: i32) { + self.is_dirty = true; + self.value = Some(value) + } +} - fn datum_desc() -> &'static DatumDesc { - static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); - ONCE_LOCK.get_or_init(|| Self::attr_datum_desc()) - } +impl AttrValue for AttrActionTime { + fn dat_type() -> &'static DatType { + static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); + ONCE_LOCK.get_or_init(|| Self::attr_dat_type()) + } - fn object_name() -> &'static str { - VOTE_HISTORY_ITEM - } + fn datum_desc() -> &'static DatumDesc { + static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); + ONCE_LOCK.get_or_init(|| Self::attr_datum_desc()) + } - fn attr_name() -> &'static str { - ACTION_TIME - } + fn object_name() -> &'static str { + VOTE_HISTORY_ITEM } - // attribute struct definition - #[derive(Default, Clone, Debug)] - pub struct AttrIsWithdrawn { - is_dirty: bool, - value: Option, + fn attr_name() -> &'static str { + ACTION_TIME } +} - impl AttrIsWithdrawn { - fn from(value: Option) -> Self { - Self { - is_dirty: false, - value, - } - } +// attribute struct definition +#[derive(Default, Clone, Debug)] +pub struct AttrIsWithdrawn { + is_dirty:bool, + value: Option +} - fn get(&self) -> &Option { - &self.value +impl AttrIsWithdrawn { + fn from(value:Option) -> Self { + Self { + is_dirty: false, + value } + } - fn get_mut(&mut self) -> &mut Option { - &mut self.value - } + fn get(&self) -> &Option { + &self.value + } - fn set(&mut self, value: Option) { - self.value = value - } + fn get_mut(&mut self) -> &mut Option { + &mut self.value + } - fn update(&mut self, value: i32) { - self.is_dirty = true; - self.value = Some(value) - } + fn set(&mut self, value:Option) { + self.value = value } - impl AttrValue for AttrIsWithdrawn { - fn dat_type() -> &'static DatType { - static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); - ONCE_LOCK.get_or_init(|| Self::attr_dat_type()) - } + fn update(&mut self, value: i32) { + self.is_dirty = true; + self.value = Some(value) + } +} - fn datum_desc() -> &'static DatumDesc { - static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); - ONCE_LOCK.get_or_init(|| Self::attr_datum_desc()) - } +impl AttrValue for AttrIsWithdrawn { + fn dat_type() -> &'static DatType { + static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); + ONCE_LOCK.get_or_init(|| Self::attr_dat_type()) + } - fn object_name() -> &'static str { - VOTE_HISTORY_ITEM - } + fn datum_desc() -> &'static DatumDesc { + static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); + ONCE_LOCK.get_or_init(|| Self::attr_datum_desc()) + } - fn attr_name() -> &'static str { - IS_WITHDRAWN - } + fn object_name() -> &'static str { + VOTE_HISTORY_ITEM } - // attribute struct definition - #[derive(Default, Clone, Debug)] - pub struct AttrVoteEnded { - is_dirty: bool, - value: Option, + fn attr_name() -> &'static str { + IS_WITHDRAWN } +} - impl AttrVoteEnded { - fn from(value: Option) -> Self { - Self { - is_dirty: false, - value, - } - } +// attribute struct definition +#[derive(Default, Clone, Debug)] +pub struct AttrVoteEnded { + is_dirty:bool, + value: Option +} - fn get(&self) -> &Option { - &self.value +impl AttrVoteEnded { + fn from(value:Option) -> Self { + Self { + is_dirty: false, + value } + } - fn get_mut(&mut self) -> &mut Option { - &mut self.value - } + fn get(&self) -> &Option { + &self.value + } - fn set(&mut self, value: Option) { - self.value = value - } + fn get_mut(&mut self) -> &mut Option { + &mut self.value + } - fn update(&mut self, value: i32) { - self.is_dirty = true; - self.value = Some(value) - } + fn set(&mut self, value:Option) { + self.value = value } - impl AttrValue for AttrVoteEnded { - fn dat_type() -> &'static DatType { - static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); - ONCE_LOCK.get_or_init(|| Self::attr_dat_type()) - } + fn update(&mut self, value: i32) { + self.is_dirty = true; + self.value = Some(value) + } +} - fn datum_desc() -> &'static DatumDesc { - static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); - ONCE_LOCK.get_or_init(|| Self::attr_datum_desc()) - } +impl AttrValue for AttrVoteEnded { + fn dat_type() -> &'static DatType { + static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); + ONCE_LOCK.get_or_init(|| Self::attr_dat_type()) + } - fn object_name() -> &'static str { - VOTE_HISTORY_ITEM - } + fn datum_desc() -> &'static DatumDesc { + static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); + ONCE_LOCK.get_or_init(|| Self::attr_datum_desc()) + } - fn attr_name() -> &'static str { - VOTE_ENDED - } + fn object_name() -> &'static str { + VOTE_HISTORY_ITEM } - #[cfg(test)] - mod tests { - use super::VoteHistoryItem; - use mudu_contract::database::entity::Entity; - use mudu_type::datum::{Datum, DatumDyn}; - - #[test] - fn vote_history_item_roundtrip_and_field_updates() { - let item = VoteHistoryItem::new( - Some("v1".to_string()), - Some("topic".to_string()), - Some(11), - Some(0), - Some(1), - ); - - let from_value = - VoteHistoryItem::from_value(&item.to_value(VoteHistoryItem::dat_type()).unwrap()) - .unwrap(); - assert_eq!(from_value.get_topic().as_deref(), Some("topic")); - assert_eq!(from_value.get_vote_ended(), &Some(1)); - - let from_binary = VoteHistoryItem::from_binary( - item.to_binary(VoteHistoryItem::dat_type()) - .unwrap() - .as_ref(), - ) - .unwrap(); - assert_eq!(from_binary.get_action_time(), &Some(11)); - - let mut updated = VoteHistoryItem::new_empty(); - updated - .set_field_value( - "topic", - mudu_type::dat_value::DatValue::from_string("t2".to_string()), - ) - .unwrap(); - updated - .set_field_value("vote_ended", mudu_type::dat_value::DatValue::from_i32(0)) - .unwrap(); - assert_eq!(updated.get_topic().as_deref(), Some("t2")); - assert_eq!(updated.get_vote_ended(), &Some(0)); - } + fn attr_name() -> &'static str { + VOTE_ENDED } } + + +} diff --git a/example/vote/src/rust/vote_result.rs b/example/vote/src/rust/vote_result.rs index 980ccee..032265d 100644 --- a/example/vote/src/rust/vote_result.rs +++ b/example/vote/src/rust/vote_result.rs @@ -1,597 +1,599 @@ pub mod object { - use lazy_static::lazy_static; - use mudu::common::result::RS; - use mudu_contract::database::attr_field_access; - use mudu_contract::database::attr_value::AttrValue; - use mudu_contract::database::entity::Entity; - use mudu_contract::database::entity_utils; - use mudu_contract::database::sql_params::SQLParamMarker; - use mudu_contract::tuple::datum_desc::DatumDesc; - use mudu_contract::tuple::tuple_datum::TupleDatumMarker; - use mudu_contract::tuple::tuple_field_desc::TupleFieldDesc; - use mudu_type::dat_binary::DatBinary; - use mudu_type::dat_textual::DatTextual; - use mudu_type::dat_type::DatType; - use mudu_type::dat_type_id::DatTypeID; - use mudu_type::dat_value::DatValue; - use mudu_type::datum::{Datum, DatumDyn}; - - // constant definition - const VOTE_RESULT: &str = "vote_result"; - - const VOTE_ID: &str = "vote_id"; - - const TOPIC: &str = "topic"; - - const VOTE_ENDED: &str = "vote_ended"; - - const TOTAL_VOTES: &str = "total_votes"; - - const OPTIONS: &str = "options"; - - // entity struct definition - #[derive(Debug, Clone, Default)] - pub struct VoteResult { - vote_id: AttrVoteId, - - topic: AttrTopic, - - vote_ended: AttrVoteEnded, +use lazy_static::lazy_static; +use mududb::common::result::RS; +use mududb::contract::database::attr_field_access; +use mududb::contract::database::attr_value::AttrValue; +use mududb::contract::database::entity::Entity; +use mududb::contract::database::entity_utils; +use mududb::contract::database::sql_params::SQLParamMarker; +use mududb::contract::tuple::datum_desc::DatumDesc; +use mududb::contract::tuple::tuple_field_desc::TupleFieldDesc; +use mududb::contract::tuple::tuple_datum::TupleDatumMarker; +use mududb::types::dat_binary::DatBinary; +use mududb::types::dat_textual::DatTextual; +use mududb::types::dat_type::DatType; +use mududb::types::dat_type_id::DatTypeID; +use mududb::types::dat_value::DatValue; +use mududb::types::datum::{Datum, DatumDyn}; + +// constant definition +const VOTE_RESULT:&str = "vote_result"; + +const VOTE_ID:&str = "vote_id"; + +const TOPIC:&str = "topic"; + +const VOTE_ENDED:&str = "vote_ended"; + +const TOTAL_VOTES:&str = "total_votes"; + +const OPTIONS:&str = "options"; + + +// entity struct definition +#[derive(Debug, Clone, Default)] +pub struct VoteResult { + + vote_id: AttrVoteId, + + topic: AttrTopic, + + vote_ended: AttrVoteEnded, + + total_votes: AttrTotalVotes, + + options: AttrOptions, + +} - total_votes: AttrTotalVotes, +impl TupleDatumMarker for VoteResult {} + +impl SQLParamMarker for VoteResult {} + +impl VoteResult { + pub fn new( + vote_id: Option, + topic: Option, + vote_ended: Option, + total_votes: Option, + options: Option, + + ) -> Self { + let s = Self { + + vote_id : AttrVoteId::from(vote_id), + + topic : AttrTopic::from(topic), + + vote_ended : AttrVoteEnded::from(vote_ended), + + total_votes : AttrTotalVotes::from(total_votes), + + options : AttrOptions::from(options), + + }; + s + } - options: AttrOptions, + pub fn new_empty() -> Self { + Self::default() } - impl TupleDatumMarker for VoteResult {} + + pub fn set_vote_id( + &mut self, + vote_id: String, + ) { + self.vote_id.update(vote_id) + } - impl SQLParamMarker for VoteResult {} + pub fn get_vote_id( + &self, + ) -> &Option { + self.vote_id.get() + } + + pub fn set_topic( + &mut self, + topic: String, + ) { + self.topic.update(topic) + } - impl VoteResult { - pub fn new( - vote_id: Option, - topic: Option, - vote_ended: Option, - total_votes: Option, - options: Option, - ) -> Self { - let s = Self { - vote_id: AttrVoteId::from(vote_id), + pub fn get_topic( + &self, + ) -> &Option { + self.topic.get() + } + + pub fn set_vote_ended( + &mut self, + vote_ended: i32, + ) { + self.vote_ended.update(vote_ended) + } - topic: AttrTopic::from(topic), + pub fn get_vote_ended( + &self, + ) -> &Option { + self.vote_ended.get() + } + + pub fn set_total_votes( + &mut self, + total_votes: i32, + ) { + self.total_votes.update(total_votes) + } - vote_ended: AttrVoteEnded::from(vote_ended), + pub fn get_total_votes( + &self, + ) -> &Option { + self.total_votes.get() + } + + pub fn set_options( + &mut self, + options: String, + ) { + self.options.update(options) + } - total_votes: AttrTotalVotes::from(total_votes), + pub fn get_options( + &self, + ) -> &Option { + self.options.get() + } + +} - options: AttrOptions::from(options), - }; - s +impl Datum for VoteResult { + fn dat_type() -> &'static DatType { + lazy_static! { + static ref DAT_TYPE: DatType = entity_utils::entity_dat_type::(); } + &DAT_TYPE + } - pub fn new_empty() -> Self { - Self::default() - } + fn from_binary(binary: &[u8]) -> RS { + entity_utils::entity_from_binary(binary) + } - pub fn set_vote_id(&mut self, vote_id: String) { - self.vote_id.update(vote_id) - } + fn from_value(value: &DatValue) -> RS { + entity_utils::entity_from_value(value) + } - pub fn get_vote_id(&self) -> &Option { - self.vote_id.get() - } + fn from_textual(textual: &str) -> RS { + entity_utils::entity_from_textual(textual) + } +} - pub fn set_topic(&mut self, topic: String) { - self.topic.update(topic) - } +impl DatumDyn for VoteResult { + fn dat_type_id(&self) -> RS { + entity_utils::entity_dat_type_id() + } - pub fn get_topic(&self) -> &Option { - self.topic.get() - } + fn to_binary(&self, dat_type: &DatType) -> RS { + entity_utils::entity_to_binary(self, dat_type) + } - pub fn set_vote_ended(&mut self, vote_ended: i32) { - self.vote_ended.update(vote_ended) - } + fn to_textual(&self, dat_type: &DatType) -> RS { + entity_utils::entity_to_textual(self, dat_type) + } - pub fn get_vote_ended(&self) -> &Option { - self.vote_ended.get() - } + fn to_value(&self, dat_type: &DatType) -> RS { + entity_utils::entity_to_value(self, dat_type) + } - pub fn set_total_votes(&mut self, total_votes: i32) { - self.total_votes.update(total_votes) - } + fn clone_boxed(&self) -> Box { + entity_utils::entity_clone_boxed(self) + } +} - pub fn get_total_votes(&self) -> &Option { - self.total_votes.get() - } +impl Entity for VoteResult { + fn new_empty() -> Self { + Self::new_empty() + } - pub fn set_options(&mut self, options: String) { - self.options.update(options) - } + fn tuple_desc() -> &'static TupleFieldDesc { + lazy_static! { + static ref TUPLE_DESC: TupleFieldDesc = TupleFieldDesc::new(vec![ + + AttrVoteId::datum_desc().clone(), + + AttrTopic::datum_desc().clone(), + + AttrVoteEnded::datum_desc().clone(), + + AttrTotalVotes::datum_desc().clone(), + + AttrOptions::datum_desc().clone(), + + ]); + } + &TUPLE_DESC + } - pub fn get_options(&self) -> &Option { - self.options.get() - } + fn object_name() -> &'static str { + VOTE_RESULT } - impl Datum for VoteResult { - fn dat_type() -> &'static DatType { - lazy_static! { - static ref DAT_TYPE: DatType = entity_utils::entity_dat_type::(); + fn get_field_binary(&self, field: &str) -> RS>> { + match field { + + VOTE_ID => { + attr_field_access::attr_get_binary::<_>(self.vote_id.get()) } - &DAT_TYPE - } - - fn from_binary(binary: &[u8]) -> RS { - entity_utils::entity_from_binary(binary) - } - - fn from_value(value: &DatValue) -> RS { - entity_utils::entity_from_value(value) - } - - fn from_textual(textual: &str) -> RS { - entity_utils::entity_from_textual(textual) + + TOPIC => { + attr_field_access::attr_get_binary::<_>(self.topic.get()) + } + + VOTE_ENDED => { + attr_field_access::attr_get_binary::<_>(self.vote_ended.get()) + } + + TOTAL_VOTES => { + attr_field_access::attr_get_binary::<_>(self.total_votes.get()) + } + + OPTIONS => { + attr_field_access::attr_get_binary::<_>(self.options.get()) + } + + _ => { panic!("unknown name"); } } } - impl DatumDyn for VoteResult { - fn dat_type_id(&self) -> RS { - entity_utils::entity_dat_type_id() - } - - fn to_binary(&self, dat_type: &DatType) -> RS { - entity_utils::entity_to_binary(self, dat_type) - } - - fn to_textual(&self, dat_type: &DatType) -> RS { - entity_utils::entity_to_textual(self, dat_type) - } - - fn to_value(&self, dat_type: &DatType) -> RS { - entity_utils::entity_to_value(self, dat_type) - } - - fn clone_boxed(&self) -> Box { - entity_utils::entity_clone_boxed(self) + fn set_field_binary>(&mut self, field: &str, binary: B) -> RS<()> { + match field { + + VOTE_ID => { + attr_field_access::attr_set_binary::<_, _>(self.vote_id.get_mut(), binary.as_ref())?; + } + + TOPIC => { + attr_field_access::attr_set_binary::<_, _>(self.topic.get_mut(), binary.as_ref())?; + } + + VOTE_ENDED => { + attr_field_access::attr_set_binary::<_, _>(self.vote_ended.get_mut(), binary.as_ref())?; + } + + TOTAL_VOTES => { + attr_field_access::attr_set_binary::<_, _>(self.total_votes.get_mut(), binary.as_ref())?; + } + + OPTIONS => { + attr_field_access::attr_set_binary::<_, _>(self.options.get_mut(), binary.as_ref())?; + } + + _ => { panic!("unknown name"); } } + Ok(()) } - impl Entity for VoteResult { - fn new_empty() -> Self { - Self::new_empty() - } - - fn tuple_desc() -> &'static TupleFieldDesc { - lazy_static! { - static ref TUPLE_DESC: TupleFieldDesc = TupleFieldDesc::new(vec![ - AttrVoteId::datum_desc().clone(), - AttrTopic::datum_desc().clone(), - AttrVoteEnded::datum_desc().clone(), - AttrTotalVotes::datum_desc().clone(), - AttrOptions::datum_desc().clone(), - ]); + fn get_field_value(&self, field: &str) -> RS> { + match field { + + VOTE_ID => { + attr_field_access::attr_get_value::<_>(self.vote_id.get()) } - &TUPLE_DESC - } - - fn object_name() -> &'static str { - VOTE_RESULT - } - - fn get_field_binary(&self, field: &str) -> RS>> { - match field { - VOTE_ID => attr_field_access::attr_get_binary::<_>(self.vote_id.get()), - - TOPIC => attr_field_access::attr_get_binary::<_>(self.topic.get()), - - VOTE_ENDED => attr_field_access::attr_get_binary::<_>(self.vote_ended.get()), - - TOTAL_VOTES => attr_field_access::attr_get_binary::<_>(self.total_votes.get()), - - OPTIONS => attr_field_access::attr_get_binary::<_>(self.options.get()), - - _ => { - panic!("unknown name"); - } + + TOPIC => { + attr_field_access::attr_get_value::<_>(self.topic.get()) } - } - - fn set_field_binary>(&mut self, field: &str, binary: B) -> RS<()> { - match field { - VOTE_ID => { - attr_field_access::attr_set_binary::<_, _>( - self.vote_id.get_mut(), - binary.as_ref(), - )?; - } - - TOPIC => { - attr_field_access::attr_set_binary::<_, _>( - self.topic.get_mut(), - binary.as_ref(), - )?; - } - - VOTE_ENDED => { - attr_field_access::attr_set_binary::<_, _>( - self.vote_ended.get_mut(), - binary.as_ref(), - )?; - } - - TOTAL_VOTES => { - attr_field_access::attr_set_binary::<_, _>( - self.total_votes.get_mut(), - binary.as_ref(), - )?; - } - - OPTIONS => { - attr_field_access::attr_set_binary::<_, _>( - self.options.get_mut(), - binary.as_ref(), - )?; - } - - _ => { - panic!("unknown name"); - } + + VOTE_ENDED => { + attr_field_access::attr_get_value::<_>(self.vote_ended.get()) } - Ok(()) - } - - fn get_field_value(&self, field: &str) -> RS> { - match field { - VOTE_ID => attr_field_access::attr_get_value::<_>(self.vote_id.get()), - - TOPIC => attr_field_access::attr_get_value::<_>(self.topic.get()), - - VOTE_ENDED => attr_field_access::attr_get_value::<_>(self.vote_ended.get()), - - TOTAL_VOTES => attr_field_access::attr_get_value::<_>(self.total_votes.get()), - - OPTIONS => attr_field_access::attr_get_value::<_>(self.options.get()), - - _ => { - panic!("unknown name"); - } + + TOTAL_VOTES => { + attr_field_access::attr_get_value::<_>(self.total_votes.get()) } + + OPTIONS => { + attr_field_access::attr_get_value::<_>(self.options.get()) + } + + _ => { panic!("unknown name"); } } + } - fn set_field_value>(&mut self, field: &str, value: B) -> RS<()> { - match field { - VOTE_ID => { - attr_field_access::attr_set_value::<_, _>(self.vote_id.get_mut(), value)?; - } - - TOPIC => { - attr_field_access::attr_set_value::<_, _>(self.topic.get_mut(), value)?; - } - - VOTE_ENDED => { - attr_field_access::attr_set_value::<_, _>(self.vote_ended.get_mut(), value)?; - } - - TOTAL_VOTES => { - attr_field_access::attr_set_value::<_, _>(self.total_votes.get_mut(), value)?; - } - - OPTIONS => { - attr_field_access::attr_set_value::<_, _>(self.options.get_mut(), value)?; - } - - _ => { - panic!("unknown name"); - } + fn set_field_value>(&mut self, field: &str, value: B) -> RS<()> { + match field { + + VOTE_ID => { + attr_field_access::attr_set_value::<_, _>(self.vote_id.get_mut(), value)?; + } + + TOPIC => { + attr_field_access::attr_set_value::<_, _>(self.topic.get_mut(), value)?; + } + + VOTE_ENDED => { + attr_field_access::attr_set_value::<_, _>(self.vote_ended.get_mut(), value)?; } - Ok(()) + + TOTAL_VOTES => { + attr_field_access::attr_set_value::<_, _>(self.total_votes.get_mut(), value)?; + } + + OPTIONS => { + attr_field_access::attr_set_value::<_, _>(self.options.get_mut(), value)?; + } + + _ => { panic!("unknown name"); } } + Ok(()) } +} - // attribute struct definition - #[derive(Default, Clone, Debug)] - pub struct AttrVoteId { - is_dirty: bool, - value: Option, - } - impl AttrVoteId { - fn from(value: Option) -> Self { - Self { - is_dirty: false, - value, - } - } +// attribute struct definition +#[derive(Default, Clone, Debug)] +pub struct AttrVoteId { + is_dirty:bool, + value: Option +} - fn get(&self) -> &Option { - &self.value +impl AttrVoteId { + fn from(value:Option) -> Self { + Self { + is_dirty: false, + value } + } - fn get_mut(&mut self) -> &mut Option { - &mut self.value - } + fn get(&self) -> &Option { + &self.value + } - fn set(&mut self, value: Option) { - self.value = value - } + fn get_mut(&mut self) -> &mut Option { + &mut self.value + } - fn update(&mut self, value: String) { - self.is_dirty = true; - self.value = Some(value) - } + fn set(&mut self, value:Option) { + self.value = value } - impl AttrValue for AttrVoteId { - fn dat_type() -> &'static DatType { - static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); - ONCE_LOCK.get_or_init(|| Self::attr_dat_type()) - } + fn update(&mut self, value: String) { + self.is_dirty = true; + self.value = Some(value) + } +} - fn datum_desc() -> &'static DatumDesc { - static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); - ONCE_LOCK.get_or_init(|| Self::attr_datum_desc()) - } +impl AttrValue for AttrVoteId { + fn dat_type() -> &'static DatType { + static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); + ONCE_LOCK.get_or_init(|| Self::attr_dat_type()) + } - fn object_name() -> &'static str { - VOTE_RESULT - } + fn datum_desc() -> &'static DatumDesc { + static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); + ONCE_LOCK.get_or_init(|| Self::attr_datum_desc()) + } - fn attr_name() -> &'static str { - VOTE_ID - } + fn object_name() -> &'static str { + VOTE_RESULT } - // attribute struct definition - #[derive(Default, Clone, Debug)] - pub struct AttrTopic { - is_dirty: bool, - value: Option, + fn attr_name() -> &'static str { + VOTE_ID } +} - impl AttrTopic { - fn from(value: Option) -> Self { - Self { - is_dirty: false, - value, - } - } +// attribute struct definition +#[derive(Default, Clone, Debug)] +pub struct AttrTopic { + is_dirty:bool, + value: Option +} - fn get(&self) -> &Option { - &self.value +impl AttrTopic { + fn from(value:Option) -> Self { + Self { + is_dirty: false, + value } + } - fn get_mut(&mut self) -> &mut Option { - &mut self.value - } + fn get(&self) -> &Option { + &self.value + } - fn set(&mut self, value: Option) { - self.value = value - } + fn get_mut(&mut self) -> &mut Option { + &mut self.value + } - fn update(&mut self, value: String) { - self.is_dirty = true; - self.value = Some(value) - } + fn set(&mut self, value:Option) { + self.value = value } - impl AttrValue for AttrTopic { - fn dat_type() -> &'static DatType { - static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); - ONCE_LOCK.get_or_init(|| Self::attr_dat_type()) - } + fn update(&mut self, value: String) { + self.is_dirty = true; + self.value = Some(value) + } +} - fn datum_desc() -> &'static DatumDesc { - static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); - ONCE_LOCK.get_or_init(|| Self::attr_datum_desc()) - } +impl AttrValue for AttrTopic { + fn dat_type() -> &'static DatType { + static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); + ONCE_LOCK.get_or_init(|| Self::attr_dat_type()) + } - fn object_name() -> &'static str { - VOTE_RESULT - } + fn datum_desc() -> &'static DatumDesc { + static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); + ONCE_LOCK.get_or_init(|| Self::attr_datum_desc()) + } - fn attr_name() -> &'static str { - TOPIC - } + fn object_name() -> &'static str { + VOTE_RESULT } - // attribute struct definition - #[derive(Default, Clone, Debug)] - pub struct AttrVoteEnded { - is_dirty: bool, - value: Option, + fn attr_name() -> &'static str { + TOPIC } +} - impl AttrVoteEnded { - fn from(value: Option) -> Self { - Self { - is_dirty: false, - value, - } - } +// attribute struct definition +#[derive(Default, Clone, Debug)] +pub struct AttrVoteEnded { + is_dirty:bool, + value: Option +} - fn get(&self) -> &Option { - &self.value +impl AttrVoteEnded { + fn from(value:Option) -> Self { + Self { + is_dirty: false, + value } + } - fn get_mut(&mut self) -> &mut Option { - &mut self.value - } + fn get(&self) -> &Option { + &self.value + } - fn set(&mut self, value: Option) { - self.value = value - } + fn get_mut(&mut self) -> &mut Option { + &mut self.value + } - fn update(&mut self, value: i32) { - self.is_dirty = true; - self.value = Some(value) - } + fn set(&mut self, value:Option) { + self.value = value } - impl AttrValue for AttrVoteEnded { - fn dat_type() -> &'static DatType { - static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); - ONCE_LOCK.get_or_init(|| Self::attr_dat_type()) - } + fn update(&mut self, value: i32) { + self.is_dirty = true; + self.value = Some(value) + } +} - fn datum_desc() -> &'static DatumDesc { - static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); - ONCE_LOCK.get_or_init(|| Self::attr_datum_desc()) - } +impl AttrValue for AttrVoteEnded { + fn dat_type() -> &'static DatType { + static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); + ONCE_LOCK.get_or_init(|| Self::attr_dat_type()) + } - fn object_name() -> &'static str { - VOTE_RESULT - } + fn datum_desc() -> &'static DatumDesc { + static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); + ONCE_LOCK.get_or_init(|| Self::attr_datum_desc()) + } - fn attr_name() -> &'static str { - VOTE_ENDED - } + fn object_name() -> &'static str { + VOTE_RESULT } - // attribute struct definition - #[derive(Default, Clone, Debug)] - pub struct AttrTotalVotes { - is_dirty: bool, - value: Option, + fn attr_name() -> &'static str { + VOTE_ENDED } +} - impl AttrTotalVotes { - fn from(value: Option) -> Self { - Self { - is_dirty: false, - value, - } - } +// attribute struct definition +#[derive(Default, Clone, Debug)] +pub struct AttrTotalVotes { + is_dirty:bool, + value: Option +} - fn get(&self) -> &Option { - &self.value +impl AttrTotalVotes { + fn from(value:Option) -> Self { + Self { + is_dirty: false, + value } + } - fn get_mut(&mut self) -> &mut Option { - &mut self.value - } + fn get(&self) -> &Option { + &self.value + } - fn set(&mut self, value: Option) { - self.value = value - } + fn get_mut(&mut self) -> &mut Option { + &mut self.value + } - fn update(&mut self, value: i32) { - self.is_dirty = true; - self.value = Some(value) - } + fn set(&mut self, value:Option) { + self.value = value } - impl AttrValue for AttrTotalVotes { - fn dat_type() -> &'static DatType { - static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); - ONCE_LOCK.get_or_init(|| Self::attr_dat_type()) - } + fn update(&mut self, value: i32) { + self.is_dirty = true; + self.value = Some(value) + } +} - fn datum_desc() -> &'static DatumDesc { - static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); - ONCE_LOCK.get_or_init(|| Self::attr_datum_desc()) - } +impl AttrValue for AttrTotalVotes { + fn dat_type() -> &'static DatType { + static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); + ONCE_LOCK.get_or_init(|| Self::attr_dat_type()) + } - fn object_name() -> &'static str { - VOTE_RESULT - } + fn datum_desc() -> &'static DatumDesc { + static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); + ONCE_LOCK.get_or_init(|| Self::attr_datum_desc()) + } - fn attr_name() -> &'static str { - TOTAL_VOTES - } + fn object_name() -> &'static str { + VOTE_RESULT } - // attribute struct definition - #[derive(Default, Clone, Debug)] - pub struct AttrOptions { - is_dirty: bool, - value: Option, + fn attr_name() -> &'static str { + TOTAL_VOTES } +} - impl AttrOptions { - fn from(value: Option) -> Self { - Self { - is_dirty: false, - value, - } - } +// attribute struct definition +#[derive(Default, Clone, Debug)] +pub struct AttrOptions { + is_dirty:bool, + value: Option +} - fn get(&self) -> &Option { - &self.value +impl AttrOptions { + fn from(value:Option) -> Self { + Self { + is_dirty: false, + value } + } - fn get_mut(&mut self) -> &mut Option { - &mut self.value - } + fn get(&self) -> &Option { + &self.value + } - fn set(&mut self, value: Option) { - self.value = value - } + fn get_mut(&mut self) -> &mut Option { + &mut self.value + } - fn update(&mut self, value: String) { - self.is_dirty = true; - self.value = Some(value) - } + fn set(&mut self, value:Option) { + self.value = value } - impl AttrValue for AttrOptions { - fn dat_type() -> &'static DatType { - static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); - ONCE_LOCK.get_or_init(|| Self::attr_dat_type()) - } + fn update(&mut self, value: String) { + self.is_dirty = true; + self.value = Some(value) + } +} - fn datum_desc() -> &'static DatumDesc { - static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); - ONCE_LOCK.get_or_init(|| Self::attr_datum_desc()) - } +impl AttrValue for AttrOptions { + fn dat_type() -> &'static DatType { + static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); + ONCE_LOCK.get_or_init(|| Self::attr_dat_type()) + } - fn object_name() -> &'static str { - VOTE_RESULT - } + fn datum_desc() -> &'static DatumDesc { + static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); + ONCE_LOCK.get_or_init(|| Self::attr_datum_desc()) + } - fn attr_name() -> &'static str { - OPTIONS - } + fn object_name() -> &'static str { + VOTE_RESULT } - #[cfg(test)] - mod tests { - use super::VoteResult; - use mudu_contract::database::entity::Entity; - use mudu_type::datum::{Datum, DatumDyn}; - - #[test] - fn vote_result_roundtrip_and_field_updates() { - let result = VoteResult::new( - Some("v1".to_string()), - Some("topic".to_string()), - Some(1), - Some(9), - Some("[]".to_string()), - ); - - let from_value = - VoteResult::from_value(&result.to_value(VoteResult::dat_type()).unwrap()).unwrap(); - assert_eq!(from_value.get_total_votes(), &Some(9)); - assert_eq!(from_value.get_options().as_deref(), Some("[]")); - - let from_binary = - VoteResult::from_binary(result.to_binary(VoteResult::dat_type()).unwrap().as_ref()) - .unwrap(); - assert_eq!(from_binary.get_vote_ended(), &Some(1)); - - let mut updated = VoteResult::new_empty(); - updated - .set_field_value( - "topic", - mudu_type::dat_value::DatValue::from_string("t2".to_string()), - ) - .unwrap(); - updated - .set_field_value("total_votes", mudu_type::dat_value::DatValue::from_i32(12)) - .unwrap(); - assert_eq!(updated.get_topic().as_deref(), Some("t2")); - assert_eq!(updated.get_total_votes(), &Some(12)); - } + fn attr_name() -> &'static str { + OPTIONS } } + + +} diff --git a/example/vote/src/rust/votes.rs b/example/vote/src/rust/votes.rs index d3d3769..1b8c4db 100644 --- a/example/vote/src/rust/votes.rs +++ b/example/vote/src/rust/votes.rs @@ -1,772 +1,781 @@ pub mod object { - use lazy_static::lazy_static; - use mudu::common::result::RS; - use mudu_contract::database::attr_field_access; - use mudu_contract::database::attr_value::AttrValue; - use mudu_contract::database::entity::Entity; - use mudu_contract::database::entity_utils; - use mudu_contract::database::sql_params::SQLParamMarker; - use mudu_contract::tuple::datum_desc::DatumDesc; - use mudu_contract::tuple::tuple_datum::TupleDatumMarker; - use mudu_contract::tuple::tuple_field_desc::TupleFieldDesc; - use mudu_type::dat_binary::DatBinary; - use mudu_type::dat_textual::DatTextual; - use mudu_type::dat_type::DatType; - use mudu_type::dat_type_id::DatTypeID; - use mudu_type::dat_value::DatValue; - use mudu_type::datum::{Datum, DatumDyn}; - - // constant definition - const VOTES: &str = "votes"; - - const VOTE_ID: &str = "vote_id"; - - const CREATOR_ID: &str = "creator_id"; - - const TOPIC: &str = "topic"; - - const VOTE_TYPE: &str = "vote_type"; - - const MAX_CHOICES: &str = "max_choices"; - - const END_TIME: &str = "end_time"; - - const VISIBILITY_RULE: &str = "visibility_rule"; - - // entity struct definition - #[derive(Debug, Clone, Default)] - pub struct Votes { - vote_id: AttrVoteId, - - creator_id: AttrCreatorId, - - topic: AttrTopic, - - vote_type: AttrVoteType, - - max_choices: AttrMaxChoices, - - end_time: AttrEndTime, +use lazy_static::lazy_static; +use mududb::common::result::RS; +use mududb::contract::database::attr_field_access; +use mududb::contract::database::attr_value::AttrValue; +use mududb::contract::database::entity::Entity; +use mududb::contract::database::entity_utils; +use mududb::contract::database::sql_params::SQLParamMarker; +use mududb::contract::tuple::datum_desc::DatumDesc; +use mududb::contract::tuple::tuple_field_desc::TupleFieldDesc; +use mududb::contract::tuple::tuple_datum::TupleDatumMarker; +use mududb::types::dat_binary::DatBinary; +use mududb::types::dat_textual::DatTextual; +use mududb::types::dat_type::DatType; +use mududb::types::dat_type_id::DatTypeID; +use mududb::types::dat_value::DatValue; +use mududb::types::datum::{Datum, DatumDyn}; + +// constant definition +const VOTES:&str = "votes"; + +const VOTE_ID:&str = "vote_id"; + +const CREATOR_ID:&str = "creator_id"; + +const TOPIC:&str = "topic"; + +const VOTE_TYPE:&str = "vote_type"; + +const MAX_CHOICES:&str = "max_choices"; + +const END_TIME:&str = "end_time"; + +const VISIBILITY_RULE:&str = "visibility_rule"; + + +// entity struct definition +#[derive(Debug, Clone, Default)] +pub struct Votes { + + vote_id: AttrVoteId, + + creator_id: AttrCreatorId, + + topic: AttrTopic, + + vote_type: AttrVoteType, + + max_choices: AttrMaxChoices, + + end_time: AttrEndTime, + + visibility_rule: AttrVisibilityRule, + +} - visibility_rule: AttrVisibilityRule, +impl TupleDatumMarker for Votes {} + +impl SQLParamMarker for Votes {} + +impl Votes { + pub fn new( + vote_id: Option, + creator_id: Option, + topic: Option, + vote_type: Option, + max_choices: Option, + end_time: Option, + visibility_rule: Option, + + ) -> Self { + let s = Self { + + vote_id : AttrVoteId::from(vote_id), + + creator_id : AttrCreatorId::from(creator_id), + + topic : AttrTopic::from(topic), + + vote_type : AttrVoteType::from(vote_type), + + max_choices : AttrMaxChoices::from(max_choices), + + end_time : AttrEndTime::from(end_time), + + visibility_rule : AttrVisibilityRule::from(visibility_rule), + + }; + s } - impl TupleDatumMarker for Votes {} - - impl SQLParamMarker for Votes {} - - impl Votes { - pub fn new( - vote_id: Option, - creator_id: Option, - topic: Option, - vote_type: Option, - max_choices: Option, - end_time: Option, - visibility_rule: Option, - ) -> Self { - let s = Self { - vote_id: AttrVoteId::from(vote_id), - - creator_id: AttrCreatorId::from(creator_id), + pub fn new_empty() -> Self { + Self::default() + } - topic: AttrTopic::from(topic), + + pub fn set_vote_id( + &mut self, + vote_id: String, + ) { + self.vote_id.update(vote_id) + } - vote_type: AttrVoteType::from(vote_type), + pub fn get_vote_id( + &self, + ) -> &Option { + self.vote_id.get() + } + + pub fn set_creator_id( + &mut self, + creator_id: String, + ) { + self.creator_id.update(creator_id) + } - max_choices: AttrMaxChoices::from(max_choices), + pub fn get_creator_id( + &self, + ) -> &Option { + self.creator_id.get() + } + + pub fn set_topic( + &mut self, + topic: String, + ) { + self.topic.update(topic) + } - end_time: AttrEndTime::from(end_time), + pub fn get_topic( + &self, + ) -> &Option { + self.topic.get() + } + + pub fn set_vote_type( + &mut self, + vote_type: String, + ) { + self.vote_type.update(vote_type) + } - visibility_rule: AttrVisibilityRule::from(visibility_rule), - }; - s - } + pub fn get_vote_type( + &self, + ) -> &Option { + self.vote_type.get() + } + + pub fn set_max_choices( + &mut self, + max_choices: i32, + ) { + self.max_choices.update(max_choices) + } - pub fn new_empty() -> Self { - Self::default() - } + pub fn get_max_choices( + &self, + ) -> &Option { + self.max_choices.get() + } + + pub fn set_end_time( + &mut self, + end_time: i32, + ) { + self.end_time.update(end_time) + } - pub fn set_vote_id(&mut self, vote_id: String) { - self.vote_id.update(vote_id) - } + pub fn get_end_time( + &self, + ) -> &Option { + self.end_time.get() + } + + pub fn set_visibility_rule( + &mut self, + visibility_rule: String, + ) { + self.visibility_rule.update(visibility_rule) + } - pub fn get_vote_id(&self) -> &Option { - self.vote_id.get() - } + pub fn get_visibility_rule( + &self, + ) -> &Option { + self.visibility_rule.get() + } + +} - pub fn set_creator_id(&mut self, creator_id: String) { - self.creator_id.update(creator_id) +impl Datum for Votes { + fn dat_type() -> &'static DatType { + lazy_static! { + static ref DAT_TYPE: DatType = entity_utils::entity_dat_type::(); } + &DAT_TYPE + } - pub fn get_creator_id(&self) -> &Option { - self.creator_id.get() - } + fn from_binary(binary: &[u8]) -> RS { + entity_utils::entity_from_binary(binary) + } - pub fn set_topic(&mut self, topic: String) { - self.topic.update(topic) - } + fn from_value(value: &DatValue) -> RS { + entity_utils::entity_from_value(value) + } - pub fn get_topic(&self) -> &Option { - self.topic.get() - } + fn from_textual(textual: &str) -> RS { + entity_utils::entity_from_textual(textual) + } +} - pub fn set_vote_type(&mut self, vote_type: String) { - self.vote_type.update(vote_type) - } +impl DatumDyn for Votes { + fn dat_type_id(&self) -> RS { + entity_utils::entity_dat_type_id() + } - pub fn get_vote_type(&self) -> &Option { - self.vote_type.get() - } + fn to_binary(&self, dat_type: &DatType) -> RS { + entity_utils::entity_to_binary(self, dat_type) + } - pub fn set_max_choices(&mut self, max_choices: i32) { - self.max_choices.update(max_choices) - } + fn to_textual(&self, dat_type: &DatType) -> RS { + entity_utils::entity_to_textual(self, dat_type) + } - pub fn get_max_choices(&self) -> &Option { - self.max_choices.get() - } + fn to_value(&self, dat_type: &DatType) -> RS { + entity_utils::entity_to_value(self, dat_type) + } - pub fn set_end_time(&mut self, end_time: i32) { - self.end_time.update(end_time) - } + fn clone_boxed(&self) -> Box { + entity_utils::entity_clone_boxed(self) + } +} - pub fn get_end_time(&self) -> &Option { - self.end_time.get() - } +impl Entity for Votes { + fn new_empty() -> Self { + Self::new_empty() + } - pub fn set_visibility_rule(&mut self, visibility_rule: String) { - self.visibility_rule.update(visibility_rule) - } + fn tuple_desc() -> &'static TupleFieldDesc { + lazy_static! { + static ref TUPLE_DESC: TupleFieldDesc = TupleFieldDesc::new(vec![ + + AttrVoteId::datum_desc().clone(), + + AttrCreatorId::datum_desc().clone(), + + AttrTopic::datum_desc().clone(), + + AttrVoteType::datum_desc().clone(), + + AttrMaxChoices::datum_desc().clone(), + + AttrEndTime::datum_desc().clone(), + + AttrVisibilityRule::datum_desc().clone(), + + ]); + } + &TUPLE_DESC + } - pub fn get_visibility_rule(&self) -> &Option { - self.visibility_rule.get() - } + fn object_name() -> &'static str { + VOTES } - impl Datum for Votes { - fn dat_type() -> &'static DatType { - lazy_static! { - static ref DAT_TYPE: DatType = entity_utils::entity_dat_type::(); + fn get_field_binary(&self, field: &str) -> RS>> { + match field { + + VOTE_ID => { + attr_field_access::attr_get_binary::<_>(self.vote_id.get()) } - &DAT_TYPE - } - - fn from_binary(binary: &[u8]) -> RS { - entity_utils::entity_from_binary(binary) - } - - fn from_value(value: &DatValue) -> RS { - entity_utils::entity_from_value(value) - } - - fn from_textual(textual: &str) -> RS { - entity_utils::entity_from_textual(textual) + + CREATOR_ID => { + attr_field_access::attr_get_binary::<_>(self.creator_id.get()) + } + + TOPIC => { + attr_field_access::attr_get_binary::<_>(self.topic.get()) + } + + VOTE_TYPE => { + attr_field_access::attr_get_binary::<_>(self.vote_type.get()) + } + + MAX_CHOICES => { + attr_field_access::attr_get_binary::<_>(self.max_choices.get()) + } + + END_TIME => { + attr_field_access::attr_get_binary::<_>(self.end_time.get()) + } + + VISIBILITY_RULE => { + attr_field_access::attr_get_binary::<_>(self.visibility_rule.get()) + } + + _ => { panic!("unknown name"); } } } - impl DatumDyn for Votes { - fn dat_type_id(&self) -> RS { - entity_utils::entity_dat_type_id() - } - - fn to_binary(&self, dat_type: &DatType) -> RS { - entity_utils::entity_to_binary(self, dat_type) - } - - fn to_textual(&self, dat_type: &DatType) -> RS { - entity_utils::entity_to_textual(self, dat_type) - } - - fn to_value(&self, dat_type: &DatType) -> RS { - entity_utils::entity_to_value(self, dat_type) - } - - fn clone_boxed(&self) -> Box { - entity_utils::entity_clone_boxed(self) + fn set_field_binary>(&mut self, field: &str, binary: B) -> RS<()> { + match field { + + VOTE_ID => { + attr_field_access::attr_set_binary::<_, _>(self.vote_id.get_mut(), binary.as_ref())?; + } + + CREATOR_ID => { + attr_field_access::attr_set_binary::<_, _>(self.creator_id.get_mut(), binary.as_ref())?; + } + + TOPIC => { + attr_field_access::attr_set_binary::<_, _>(self.topic.get_mut(), binary.as_ref())?; + } + + VOTE_TYPE => { + attr_field_access::attr_set_binary::<_, _>(self.vote_type.get_mut(), binary.as_ref())?; + } + + MAX_CHOICES => { + attr_field_access::attr_set_binary::<_, _>(self.max_choices.get_mut(), binary.as_ref())?; + } + + END_TIME => { + attr_field_access::attr_set_binary::<_, _>(self.end_time.get_mut(), binary.as_ref())?; + } + + VISIBILITY_RULE => { + attr_field_access::attr_set_binary::<_, _>(self.visibility_rule.get_mut(), binary.as_ref())?; + } + + _ => { panic!("unknown name"); } } + Ok(()) } - impl Entity for Votes { - fn new_empty() -> Self { - Self::new_empty() - } - - fn tuple_desc() -> &'static TupleFieldDesc { - lazy_static! { - static ref TUPLE_DESC: TupleFieldDesc = TupleFieldDesc::new(vec![ - AttrVoteId::datum_desc().clone(), - AttrCreatorId::datum_desc().clone(), - AttrTopic::datum_desc().clone(), - AttrVoteType::datum_desc().clone(), - AttrMaxChoices::datum_desc().clone(), - AttrEndTime::datum_desc().clone(), - AttrVisibilityRule::datum_desc().clone(), - ]); + fn get_field_value(&self, field: &str) -> RS> { + match field { + + VOTE_ID => { + attr_field_access::attr_get_value::<_>(self.vote_id.get()) } - &TUPLE_DESC - } - - fn object_name() -> &'static str { - VOTES - } - - fn get_field_binary(&self, field: &str) -> RS>> { - match field { - VOTE_ID => attr_field_access::attr_get_binary::<_>(self.vote_id.get()), - - CREATOR_ID => attr_field_access::attr_get_binary::<_>(self.creator_id.get()), - - TOPIC => attr_field_access::attr_get_binary::<_>(self.topic.get()), - - VOTE_TYPE => attr_field_access::attr_get_binary::<_>(self.vote_type.get()), - - MAX_CHOICES => attr_field_access::attr_get_binary::<_>(self.max_choices.get()), - - END_TIME => attr_field_access::attr_get_binary::<_>(self.end_time.get()), - - VISIBILITY_RULE => { - attr_field_access::attr_get_binary::<_>(self.visibility_rule.get()) - } - - _ => { - panic!("unknown name"); - } + + CREATOR_ID => { + attr_field_access::attr_get_value::<_>(self.creator_id.get()) } - } - - fn set_field_binary>(&mut self, field: &str, binary: B) -> RS<()> { - match field { - VOTE_ID => { - attr_field_access::attr_set_binary::<_, _>( - self.vote_id.get_mut(), - binary.as_ref(), - )?; - } - - CREATOR_ID => { - attr_field_access::attr_set_binary::<_, _>( - self.creator_id.get_mut(), - binary.as_ref(), - )?; - } - - TOPIC => { - attr_field_access::attr_set_binary::<_, _>( - self.topic.get_mut(), - binary.as_ref(), - )?; - } - - VOTE_TYPE => { - attr_field_access::attr_set_binary::<_, _>( - self.vote_type.get_mut(), - binary.as_ref(), - )?; - } - - MAX_CHOICES => { - attr_field_access::attr_set_binary::<_, _>( - self.max_choices.get_mut(), - binary.as_ref(), - )?; - } - - END_TIME => { - attr_field_access::attr_set_binary::<_, _>( - self.end_time.get_mut(), - binary.as_ref(), - )?; - } - - VISIBILITY_RULE => { - attr_field_access::attr_set_binary::<_, _>( - self.visibility_rule.get_mut(), - binary.as_ref(), - )?; - } - - _ => { - panic!("unknown name"); - } + + TOPIC => { + attr_field_access::attr_get_value::<_>(self.topic.get()) } - Ok(()) - } - - fn get_field_value(&self, field: &str) -> RS> { - match field { - VOTE_ID => attr_field_access::attr_get_value::<_>(self.vote_id.get()), - - CREATOR_ID => attr_field_access::attr_get_value::<_>(self.creator_id.get()), - - TOPIC => attr_field_access::attr_get_value::<_>(self.topic.get()), - - VOTE_TYPE => attr_field_access::attr_get_value::<_>(self.vote_type.get()), - - MAX_CHOICES => attr_field_access::attr_get_value::<_>(self.max_choices.get()), - - END_TIME => attr_field_access::attr_get_value::<_>(self.end_time.get()), - - VISIBILITY_RULE => { - attr_field_access::attr_get_value::<_>(self.visibility_rule.get()) - } - - _ => { - panic!("unknown name"); - } + + VOTE_TYPE => { + attr_field_access::attr_get_value::<_>(self.vote_type.get()) + } + + MAX_CHOICES => { + attr_field_access::attr_get_value::<_>(self.max_choices.get()) + } + + END_TIME => { + attr_field_access::attr_get_value::<_>(self.end_time.get()) + } + + VISIBILITY_RULE => { + attr_field_access::attr_get_value::<_>(self.visibility_rule.get()) } + + _ => { panic!("unknown name"); } } + } - fn set_field_value>(&mut self, field: &str, value: B) -> RS<()> { - match field { - VOTE_ID => { - attr_field_access::attr_set_value::<_, _>(self.vote_id.get_mut(), value)?; - } - - CREATOR_ID => { - attr_field_access::attr_set_value::<_, _>(self.creator_id.get_mut(), value)?; - } - - TOPIC => { - attr_field_access::attr_set_value::<_, _>(self.topic.get_mut(), value)?; - } - - VOTE_TYPE => { - attr_field_access::attr_set_value::<_, _>(self.vote_type.get_mut(), value)?; - } - - MAX_CHOICES => { - attr_field_access::attr_set_value::<_, _>(self.max_choices.get_mut(), value)?; - } - - END_TIME => { - attr_field_access::attr_set_value::<_, _>(self.end_time.get_mut(), value)?; - } - - VISIBILITY_RULE => { - attr_field_access::attr_set_value::<_, _>( - self.visibility_rule.get_mut(), - value, - )?; - } - - _ => { - panic!("unknown name"); - } + fn set_field_value>(&mut self, field: &str, value: B) -> RS<()> { + match field { + + VOTE_ID => { + attr_field_access::attr_set_value::<_, _>(self.vote_id.get_mut(), value)?; + } + + CREATOR_ID => { + attr_field_access::attr_set_value::<_, _>(self.creator_id.get_mut(), value)?; + } + + TOPIC => { + attr_field_access::attr_set_value::<_, _>(self.topic.get_mut(), value)?; + } + + VOTE_TYPE => { + attr_field_access::attr_set_value::<_, _>(self.vote_type.get_mut(), value)?; } - Ok(()) + + MAX_CHOICES => { + attr_field_access::attr_set_value::<_, _>(self.max_choices.get_mut(), value)?; + } + + END_TIME => { + attr_field_access::attr_set_value::<_, _>(self.end_time.get_mut(), value)?; + } + + VISIBILITY_RULE => { + attr_field_access::attr_set_value::<_, _>(self.visibility_rule.get_mut(), value)?; + } + + _ => { panic!("unknown name"); } } + Ok(()) } +} - // attribute struct definition - #[derive(Default, Clone, Debug)] - pub struct AttrVoteId { - is_dirty: bool, - value: Option, - } - impl AttrVoteId { - fn from(value: Option) -> Self { - Self { - is_dirty: false, - value, - } - } +// attribute struct definition +#[derive(Default, Clone, Debug)] +pub struct AttrVoteId { + is_dirty:bool, + value: Option +} - fn get(&self) -> &Option { - &self.value +impl AttrVoteId { + fn from(value:Option) -> Self { + Self { + is_dirty: false, + value } + } - fn get_mut(&mut self) -> &mut Option { - &mut self.value - } + fn get(&self) -> &Option { + &self.value + } - fn set(&mut self, value: Option) { - self.value = value - } + fn get_mut(&mut self) -> &mut Option { + &mut self.value + } - fn update(&mut self, value: String) { - self.is_dirty = true; - self.value = Some(value) - } + fn set(&mut self, value:Option) { + self.value = value } - impl AttrValue for AttrVoteId { - fn dat_type() -> &'static DatType { - static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); - ONCE_LOCK.get_or_init(|| Self::attr_dat_type()) - } + fn update(&mut self, value: String) { + self.is_dirty = true; + self.value = Some(value) + } +} - fn datum_desc() -> &'static DatumDesc { - static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); - ONCE_LOCK.get_or_init(|| Self::attr_datum_desc()) - } +impl AttrValue for AttrVoteId { + fn dat_type() -> &'static DatType { + static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); + ONCE_LOCK.get_or_init(|| Self::attr_dat_type()) + } - fn object_name() -> &'static str { - VOTES - } + fn datum_desc() -> &'static DatumDesc { + static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); + ONCE_LOCK.get_or_init(|| Self::attr_datum_desc()) + } - fn attr_name() -> &'static str { - VOTE_ID - } + fn object_name() -> &'static str { + VOTES } - // attribute struct definition - #[derive(Default, Clone, Debug)] - pub struct AttrCreatorId { - is_dirty: bool, - value: Option, + fn attr_name() -> &'static str { + VOTE_ID } +} - impl AttrCreatorId { - fn from(value: Option) -> Self { - Self { - is_dirty: false, - value, - } - } +// attribute struct definition +#[derive(Default, Clone, Debug)] +pub struct AttrCreatorId { + is_dirty:bool, + value: Option +} - fn get(&self) -> &Option { - &self.value +impl AttrCreatorId { + fn from(value:Option) -> Self { + Self { + is_dirty: false, + value } + } - fn get_mut(&mut self) -> &mut Option { - &mut self.value - } + fn get(&self) -> &Option { + &self.value + } - fn set(&mut self, value: Option) { - self.value = value - } + fn get_mut(&mut self) -> &mut Option { + &mut self.value + } - fn update(&mut self, value: String) { - self.is_dirty = true; - self.value = Some(value) - } + fn set(&mut self, value:Option) { + self.value = value } - impl AttrValue for AttrCreatorId { - fn dat_type() -> &'static DatType { - static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); - ONCE_LOCK.get_or_init(|| Self::attr_dat_type()) - } + fn update(&mut self, value: String) { + self.is_dirty = true; + self.value = Some(value) + } +} - fn datum_desc() -> &'static DatumDesc { - static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); - ONCE_LOCK.get_or_init(|| Self::attr_datum_desc()) - } +impl AttrValue for AttrCreatorId { + fn dat_type() -> &'static DatType { + static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); + ONCE_LOCK.get_or_init(|| Self::attr_dat_type()) + } - fn object_name() -> &'static str { - VOTES - } + fn datum_desc() -> &'static DatumDesc { + static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); + ONCE_LOCK.get_or_init(|| Self::attr_datum_desc()) + } - fn attr_name() -> &'static str { - CREATOR_ID - } + fn object_name() -> &'static str { + VOTES } - // attribute struct definition - #[derive(Default, Clone, Debug)] - pub struct AttrTopic { - is_dirty: bool, - value: Option, + fn attr_name() -> &'static str { + CREATOR_ID } +} - impl AttrTopic { - fn from(value: Option) -> Self { - Self { - is_dirty: false, - value, - } - } +// attribute struct definition +#[derive(Default, Clone, Debug)] +pub struct AttrTopic { + is_dirty:bool, + value: Option +} - fn get(&self) -> &Option { - &self.value +impl AttrTopic { + fn from(value:Option) -> Self { + Self { + is_dirty: false, + value } + } - fn get_mut(&mut self) -> &mut Option { - &mut self.value - } + fn get(&self) -> &Option { + &self.value + } - fn set(&mut self, value: Option) { - self.value = value - } + fn get_mut(&mut self) -> &mut Option { + &mut self.value + } - fn update(&mut self, value: String) { - self.is_dirty = true; - self.value = Some(value) - } + fn set(&mut self, value:Option) { + self.value = value } - impl AttrValue for AttrTopic { - fn dat_type() -> &'static DatType { - static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); - ONCE_LOCK.get_or_init(|| Self::attr_dat_type()) - } + fn update(&mut self, value: String) { + self.is_dirty = true; + self.value = Some(value) + } +} - fn datum_desc() -> &'static DatumDesc { - static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); - ONCE_LOCK.get_or_init(|| Self::attr_datum_desc()) - } +impl AttrValue for AttrTopic { + fn dat_type() -> &'static DatType { + static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); + ONCE_LOCK.get_or_init(|| Self::attr_dat_type()) + } - fn object_name() -> &'static str { - VOTES - } + fn datum_desc() -> &'static DatumDesc { + static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); + ONCE_LOCK.get_or_init(|| Self::attr_datum_desc()) + } - fn attr_name() -> &'static str { - TOPIC - } + fn object_name() -> &'static str { + VOTES } - // attribute struct definition - #[derive(Default, Clone, Debug)] - pub struct AttrVoteType { - is_dirty: bool, - value: Option, + fn attr_name() -> &'static str { + TOPIC } +} - impl AttrVoteType { - fn from(value: Option) -> Self { - Self { - is_dirty: false, - value, - } - } +// attribute struct definition +#[derive(Default, Clone, Debug)] +pub struct AttrVoteType { + is_dirty:bool, + value: Option +} - fn get(&self) -> &Option { - &self.value +impl AttrVoteType { + fn from(value:Option) -> Self { + Self { + is_dirty: false, + value } + } - fn get_mut(&mut self) -> &mut Option { - &mut self.value - } + fn get(&self) -> &Option { + &self.value + } - fn set(&mut self, value: Option) { - self.value = value - } + fn get_mut(&mut self) -> &mut Option { + &mut self.value + } - fn update(&mut self, value: String) { - self.is_dirty = true; - self.value = Some(value) - } + fn set(&mut self, value:Option) { + self.value = value } - impl AttrValue for AttrVoteType { - fn dat_type() -> &'static DatType { - static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); - ONCE_LOCK.get_or_init(|| Self::attr_dat_type()) - } + fn update(&mut self, value: String) { + self.is_dirty = true; + self.value = Some(value) + } +} - fn datum_desc() -> &'static DatumDesc { - static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); - ONCE_LOCK.get_or_init(|| Self::attr_datum_desc()) - } +impl AttrValue for AttrVoteType { + fn dat_type() -> &'static DatType { + static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); + ONCE_LOCK.get_or_init(|| Self::attr_dat_type()) + } - fn object_name() -> &'static str { - VOTES - } + fn datum_desc() -> &'static DatumDesc { + static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); + ONCE_LOCK.get_or_init(|| Self::attr_datum_desc()) + } - fn attr_name() -> &'static str { - VOTE_TYPE - } + fn object_name() -> &'static str { + VOTES } - // attribute struct definition - #[derive(Default, Clone, Debug)] - pub struct AttrMaxChoices { - is_dirty: bool, - value: Option, + fn attr_name() -> &'static str { + VOTE_TYPE } +} - impl AttrMaxChoices { - fn from(value: Option) -> Self { - Self { - is_dirty: false, - value, - } - } +// attribute struct definition +#[derive(Default, Clone, Debug)] +pub struct AttrMaxChoices { + is_dirty:bool, + value: Option +} - fn get(&self) -> &Option { - &self.value +impl AttrMaxChoices { + fn from(value:Option) -> Self { + Self { + is_dirty: false, + value } + } - fn get_mut(&mut self) -> &mut Option { - &mut self.value - } + fn get(&self) -> &Option { + &self.value + } - fn set(&mut self, value: Option) { - self.value = value - } + fn get_mut(&mut self) -> &mut Option { + &mut self.value + } - fn update(&mut self, value: i32) { - self.is_dirty = true; - self.value = Some(value) - } + fn set(&mut self, value:Option) { + self.value = value } - impl AttrValue for AttrMaxChoices { - fn dat_type() -> &'static DatType { - static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); - ONCE_LOCK.get_or_init(|| Self::attr_dat_type()) - } + fn update(&mut self, value: i32) { + self.is_dirty = true; + self.value = Some(value) + } +} - fn datum_desc() -> &'static DatumDesc { - static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); - ONCE_LOCK.get_or_init(|| Self::attr_datum_desc()) - } +impl AttrValue for AttrMaxChoices { + fn dat_type() -> &'static DatType { + static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); + ONCE_LOCK.get_or_init(|| Self::attr_dat_type()) + } - fn object_name() -> &'static str { - VOTES - } + fn datum_desc() -> &'static DatumDesc { + static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); + ONCE_LOCK.get_or_init(|| Self::attr_datum_desc()) + } - fn attr_name() -> &'static str { - MAX_CHOICES - } + fn object_name() -> &'static str { + VOTES } - // attribute struct definition - #[derive(Default, Clone, Debug)] - pub struct AttrEndTime { - is_dirty: bool, - value: Option, + fn attr_name() -> &'static str { + MAX_CHOICES } +} - impl AttrEndTime { - fn from(value: Option) -> Self { - Self { - is_dirty: false, - value, - } - } +// attribute struct definition +#[derive(Default, Clone, Debug)] +pub struct AttrEndTime { + is_dirty:bool, + value: Option +} - fn get(&self) -> &Option { - &self.value +impl AttrEndTime { + fn from(value:Option) -> Self { + Self { + is_dirty: false, + value } + } - fn get_mut(&mut self) -> &mut Option { - &mut self.value - } + fn get(&self) -> &Option { + &self.value + } - fn set(&mut self, value: Option) { - self.value = value - } + fn get_mut(&mut self) -> &mut Option { + &mut self.value + } - fn update(&mut self, value: i32) { - self.is_dirty = true; - self.value = Some(value) - } + fn set(&mut self, value:Option) { + self.value = value } - impl AttrValue for AttrEndTime { - fn dat_type() -> &'static DatType { - static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); - ONCE_LOCK.get_or_init(|| Self::attr_dat_type()) - } + fn update(&mut self, value: i32) { + self.is_dirty = true; + self.value = Some(value) + } +} - fn datum_desc() -> &'static DatumDesc { - static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); - ONCE_LOCK.get_or_init(|| Self::attr_datum_desc()) - } +impl AttrValue for AttrEndTime { + fn dat_type() -> &'static DatType { + static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); + ONCE_LOCK.get_or_init(|| Self::attr_dat_type()) + } - fn object_name() -> &'static str { - VOTES - } + fn datum_desc() -> &'static DatumDesc { + static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); + ONCE_LOCK.get_or_init(|| Self::attr_datum_desc()) + } - fn attr_name() -> &'static str { - END_TIME - } + fn object_name() -> &'static str { + VOTES } - // attribute struct definition - #[derive(Default, Clone, Debug)] - pub struct AttrVisibilityRule { - is_dirty: bool, - value: Option, + fn attr_name() -> &'static str { + END_TIME } +} - impl AttrVisibilityRule { - fn from(value: Option) -> Self { - Self { - is_dirty: false, - value, - } - } +// attribute struct definition +#[derive(Default, Clone, Debug)] +pub struct AttrVisibilityRule { + is_dirty:bool, + value: Option +} - fn get(&self) -> &Option { - &self.value +impl AttrVisibilityRule { + fn from(value:Option) -> Self { + Self { + is_dirty: false, + value } + } - fn get_mut(&mut self) -> &mut Option { - &mut self.value - } + fn get(&self) -> &Option { + &self.value + } - fn set(&mut self, value: Option) { - self.value = value - } + fn get_mut(&mut self) -> &mut Option { + &mut self.value + } - fn update(&mut self, value: String) { - self.is_dirty = true; - self.value = Some(value) - } + fn set(&mut self, value:Option) { + self.value = value } - impl AttrValue for AttrVisibilityRule { - fn dat_type() -> &'static DatType { - static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); - ONCE_LOCK.get_or_init(|| Self::attr_dat_type()) - } + fn update(&mut self, value: String) { + self.is_dirty = true; + self.value = Some(value) + } +} - fn datum_desc() -> &'static DatumDesc { - static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); - ONCE_LOCK.get_or_init(|| Self::attr_datum_desc()) - } +impl AttrValue for AttrVisibilityRule { + fn dat_type() -> &'static DatType { + static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); + ONCE_LOCK.get_or_init(|| Self::attr_dat_type()) + } - fn object_name() -> &'static str { - VOTES - } + fn datum_desc() -> &'static DatumDesc { + static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); + ONCE_LOCK.get_or_init(|| Self::attr_datum_desc()) + } - fn attr_name() -> &'static str { - VISIBILITY_RULE - } + fn object_name() -> &'static str { + VOTES } - #[cfg(test)] - mod tests { - use super::Votes; - use mudu_contract::database::entity::Entity; - use mudu_type::datum::{Datum, DatumDyn}; - - #[test] - fn votes_roundtrip_and_field_updates() { - let vote = Votes::new( - Some("v1".to_string()), - Some("u1".to_string()), - Some("topic".to_string()), - Some("single".to_string()), - Some(1), - Some(100), - Some("always".to_string()), - ); - - let from_value = Votes::from_value(&vote.to_value(Votes::dat_type()).unwrap()).unwrap(); - assert_eq!(from_value.get_vote_type().as_deref(), Some("single")); - assert_eq!(from_value.get_end_time(), &Some(100)); - - let from_binary = - Votes::from_binary(vote.to_binary(Votes::dat_type()).unwrap().as_ref()).unwrap(); - assert_eq!(from_binary.get_visibility_rule().as_deref(), Some("always")); - - let mut updated = Votes::new_empty(); - updated - .set_field_value("max_choices", mudu_type::dat_value::DatValue::from_i32(3)) - .unwrap(); - updated - .set_field_value( - "vote_type", - mudu_type::dat_value::DatValue::from_string("multiple".to_string()), - ) - .unwrap(); - assert_eq!(updated.get_max_choices(), &Some(3)); - assert_eq!(updated.get_vote_type().as_deref(), Some("multiple")); - } + fn attr_name() -> &'static str { + VISIBILITY_RULE } } + + +} diff --git a/example/wallet/Cargo.toml b/example/wallet/Cargo.toml index 31e899b..80ca7ba 100644 --- a/example/wallet/Cargo.toml +++ b/example/wallet/Cargo.toml @@ -8,21 +8,11 @@ crate-type = ["cdylib"] [dependencies] -mudu = { workspace = true } -mudu_sys = { workspace = true } -mudu_type = { workspace = true } -mudu_contract = { workspace = true } -mudu_binding = { workspace = true } -uuid = { workspace = true } lazy_static = { workspace = true } wit-bindgen = { workspace = true } - -[target.'cfg(target_arch = "wasm32")'.dependencies] -sys_interface = { workspace = true, features = ["async"] } - -[target.'cfg(not(target_arch = "wasm32"))'.dependencies] -sys_interface = { workspace = true, features = ["async"] } +mududb = { workspace = true, features = ["async"] } [dev-dependencies] [target.'cfg(not(target_arch = "wasm32"))'.dev-dependencies] -sys_interface = { workspace = true, features = ["async", "standalone-adapter"] } +# Enables standalone local adapter mode for integration-style native tests. +mududb = { workspace = true, features = ["async", "standalone-adapter"] } diff --git a/example/wallet/package/package.desc.json b/example/wallet/package/package.desc.json index f4d5327..73a734d 100644 --- a/example/wallet/package/package.desc.json +++ b/example/wallet/package/package.desc.json @@ -3,7 +3,32 @@ "wallet": [ { "module_name": "wallet", - "proc_name": "update_user", + "proc_name": "withdraw", + "param_desc": { + "fields": [ + { + "dat_type": { + "id": "I32", + "param": null + }, + "name": "user_id" + }, + { + "dat_type": { + "id": "I32", + "param": null + }, + "name": "amount" + } + ] + }, + "return_desc": { + "fields": [] + } + }, + { + "module_name": "wallet", + "proc_name": "create_user", "param_desc": { "fields": [ { @@ -43,25 +68,7 @@ }, { "module_name": "wallet", - "proc_name": "delete_user", - "param_desc": { - "fields": [ - { - "dat_type": { - "id": "I32", - "param": null - }, - "name": "user_id" - } - ] - }, - "return_desc": { - "fields": [] - } - }, - { - "module_name": "wallet", - "proc_name": "transfer", + "proc_name": "transfer_funds", "param_desc": { "fields": [ { @@ -93,7 +100,7 @@ }, { "module_name": "wallet", - "proc_name": "purchase", + "proc_name": "delete_user", "param_desc": { "fields": [ { @@ -102,24 +109,6 @@ "param": null }, "name": "user_id" - }, - { - "dat_type": { - "id": "I32", - "param": null - }, - "name": "amount" - }, - { - "dat_type": { - "id": "String", - "param": { - "String": { - "length": 65536 - } - } - }, - "name": "description" } ] }, @@ -129,7 +118,7 @@ }, { "module_name": "wallet", - "proc_name": "deposit", + "proc_name": "update_user", "param_desc": { "fields": [ { @@ -141,10 +130,25 @@ }, { "dat_type": { - "id": "I32", - "param": null + "id": "String", + "param": { + "String": { + "length": 65536 + } + } }, - "name": "amount" + "name": "name" + }, + { + "dat_type": { + "id": "String", + "param": { + "String": { + "length": 65536 + } + } + }, + "name": "email" } ] }, @@ -154,7 +158,7 @@ }, { "module_name": "wallet", - "proc_name": "transfer_funds", + "proc_name": "purchase", "param_desc": { "fields": [ { @@ -162,21 +166,25 @@ "id": "I32", "param": null }, - "name": "from_user_id" + "name": "user_id" }, { "dat_type": { "id": "I32", "param": null }, - "name": "to_user_id" + "name": "amount" }, { "dat_type": { - "id": "I32", - "param": null + "id": "String", + "param": { + "String": { + "length": 65536 + } + } }, - "name": "amount" + "name": "description" } ] }, @@ -186,7 +194,7 @@ }, { "module_name": "wallet", - "proc_name": "create_user", + "proc_name": "transfer", "param_desc": { "fields": [ { @@ -194,29 +202,21 @@ "id": "I32", "param": null }, - "name": "user_id" + "name": "from_user_id" }, { "dat_type": { - "id": "String", - "param": { - "String": { - "length": 65536 - } - } + "id": "I32", + "param": null }, - "name": "name" + "name": "to_user_id" }, { "dat_type": { - "id": "String", - "param": { - "String": { - "length": 65536 - } - } + "id": "I32", + "param": null }, - "name": "email" + "name": "amount" } ] }, @@ -226,7 +226,7 @@ }, { "module_name": "wallet", - "proc_name": "withdraw", + "proc_name": "deposit", "param_desc": { "fields": [ { diff --git a/example/wallet/package/type.desc.json b/example/wallet/package/type.desc.json index d57be1e..5caa3e1 100644 --- a/example/wallet/package/type.desc.json +++ b/example/wallet/package/type.desc.json @@ -1,48 +1,5 @@ { "types": { - "Orders": [ - 2, - { - "record_name": "orders", - "record_fields": [ - { - "field_name": "order_id", - "field_type": [ - 0, - 6 - ] - }, - { - "field_name": "user_id", - "field_type": [ - 0, - 6 - ] - }, - { - "field_name": "merch_id", - "field_type": [ - 0, - 6 - ] - }, - { - "field_name": "amount", - "field_type": [ - 0, - 6 - ] - }, - { - "field_name": "created_at", - "field_type": [ - 0, - 6 - ] - } - ] - } - ], "Users": [ 2, { @@ -100,11 +57,18 @@ ] } ], - "Wallets": [ + "Orders": [ 2, { - "record_name": "wallets", + "record_name": "orders", "record_fields": [ + { + "field_name": "order_id", + "field_type": [ + 0, + 6 + ] + }, { "field_name": "user_id", "field_type": [ @@ -113,14 +77,21 @@ ] }, { - "field_name": "balance", + "field_name": "merch_id", "field_type": [ 0, 6 ] }, { - "field_name": "updated_at", + "field_name": "amount", + "field_type": [ + 0, + 6 + ] + }, + { + "field_name": "created_at", "field_type": [ 0, 6 @@ -178,6 +149,35 @@ } ] } + ], + "Wallets": [ + 2, + { + "record_name": "wallets", + "record_fields": [ + { + "field_name": "user_id", + "field_type": [ + 0, + 6 + ] + }, + { + "field_name": "balance", + "field_type": [ + 0, + 6 + ] + }, + { + "field_name": "updated_at", + "field_type": [ + 0, + 6 + ] + } + ] + } ] } } \ No newline at end of file diff --git a/example/wallet/src/generated/orders.rs b/example/wallet/src/generated/orders.rs index bc43169..504b351 100644 --- a/example/wallet/src/generated/orders.rs +++ b/example/wallet/src/generated/orders.rs @@ -1,20 +1,20 @@ pub mod object { use lazy_static::lazy_static; -use mudu::common::result::RS; -use mudu_type::dat_binary::DatBinary; -use mudu_type::dat_textual::DatTextual; -use mudu_type::dat_type::DatType; -use mudu_type::dat_type_id::DatTypeID; -use mudu_type::dat_value::DatValue; -use mudu_type::datum::{Datum, DatumDyn}; -use mudu_contract::database::attr_field_access; -use mudu_contract::database::attr_value::AttrValue; -use mudu_contract::database::entity::Entity; -use mudu_contract::database::entity_utils; -use mudu_contract::tuple::datum_desc::DatumDesc; -use mudu_contract::tuple::tuple_field_desc::TupleFieldDesc; -use mudu_contract::tuple::tuple_datum::TupleDatumMarker; -use mudu_contract::database::sql_params::SQLParamMarker; +use mududb::common::result::RS; +use mududb::contract::database::attr_field_access; +use mududb::contract::database::attr_value::AttrValue; +use mududb::contract::database::entity::Entity; +use mududb::contract::database::entity_utils; +use mududb::contract::database::sql_params::SQLParamMarker; +use mududb::contract::tuple::datum_desc::DatumDesc; +use mududb::contract::tuple::tuple_field_desc::TupleFieldDesc; +use mududb::contract::tuple::tuple_datum::TupleDatumMarker; +use mududb::types::dat_binary::DatBinary; +use mududb::types::dat_textual::DatTextual; +use mududb::types::dat_type::DatType; +use mududb::types::dat_type_id::DatTypeID; +use mududb::types::dat_value::DatValue; +use mududb::types::datum::{Datum, DatumDyn}; // constant definition const ORDERS:&str = "orders"; diff --git a/example/wallet/src/generated/procedures.rs b/example/wallet/src/generated/procedures.rs index 3f9fe3c..96168f1 100644 --- a/example/wallet/src/generated/procedures.rs +++ b/example/wallet/src/generated/procedures.rs @@ -1,16 +1,16 @@ use crate::generated::wallets::object::Wallets; -use mudu::common::result::RS; -use mudu::common::xid::XID; -use mudu::error::ec::EC::MuduError; -use mudu::m_error; -use mudu_contract::database::attr_value::AttrValue; -use mudu_contract::{sql_params, sql_stmt}; -use mudu_type::datum::DatumDyn; +use mududb::common::result::RS; +use mududb::common::xid::XID; +use mududb::error::ec::EC::MuduError; +use mududb::m_error; +use mududb::contract::database::attr_value::AttrValue; +use mududb::contract::{sql_params, sql_stmt}; +use mududb::types::datum::DatumDyn; use std::time::UNIX_EPOCH; -use sys_interface::async_api::{mudu_command, mudu_query}; +use mududb::sys_interface::async_api::{mudu_command, mudu_query}; fn current_timestamp() -> i64 { - let now = mudu_sys::time::system_time_now(); + let now = mududb::sys::time::system_time_now(); let duration_since_epoch = now .duration_since(UNIX_EPOCH) .expect("SystemTime before UNIX EPOCH!"); @@ -94,7 +94,7 @@ pub async fn transfer_funds(xid: XID, from_user_id: i32, to_user_id: i32, amount } // 3. Entity the transaction - let id = mudu_sys::random::next_uuid_v4_string(); + let id = mududb::sys::random::next_uuid_v4_string(); let insert_rows = mudu_command( xid, sql_stmt!( @@ -217,7 +217,7 @@ pub async fn deposit(xid: XID, user_id: i32, amount: i32) -> RS<()> { } let now = current_timestamp(); - let tx_id = mudu_sys::random::next_uuid_v4_string(); + let tx_id = mududb::sys::random::next_uuid_v4_string(); let wallet = mudu_query::( xid, sql_stmt!(&"SELECT user_id, balance, updated_at FROM wallets WHERE user_id = ?"), @@ -272,7 +272,7 @@ pub async fn withdraw(xid: XID, user_id: i32, amount: i32) -> RS<()> { } let now = current_timestamp(); - let tx_id = mudu_sys::random::next_uuid_v4_string(); + let tx_id = mududb::sys::random::next_uuid_v4_string(); let next_balance = required_balance(&wallet)? - amount; // Update wallet balance @@ -330,7 +330,7 @@ pub async fn transfer(xid: XID, from_user_id: i32, to_user_id: i32, amount: i32) let receiver_balance = required_balance(&receiver_wallet)?; let now = current_timestamp(); - let tx_id = mudu_sys::random::next_uuid_v4_string(); + let tx_id = mududb::sys::random::next_uuid_v4_string(); // Debit sender mudu_command( @@ -386,7 +386,7 @@ pub async fn purchase(xid: XID, user_id: i32, amount: i32, description: String) } let now = current_timestamp(); - let tx_id = mudu_sys::random::next_uuid_v4_string(); + let tx_id = mududb::sys::random::next_uuid_v4_string(); let next_balance = required_balance(&wallet)? - amount; // Deduct amount @@ -407,41 +407,33 @@ pub async fn purchase(xid: XID, user_id: i32, amount: i32, description: String) Ok(()) } -async fn mp2_update_user(param:Vec) -> Vec { - ::mudu_binding::procedure::procedure_invoke::invoke_procedure_async( +async fn mp2_withdraw(param:Vec) -> Vec { + ::mududb::binding::procedure::procedure_invoke::invoke_procedure_async( param, - mudu_inner_p2_update_user, + mudu_inner_p2_withdraw, ).await } -pub async fn mudu_inner_p2_update_user( - param: ::mudu_contract::procedure::procedure_param::ProcedureParam, -) -> ::mudu::common::result::RS< - ::mudu_contract::procedure::procedure_result::ProcedureResult, +pub async fn mudu_inner_p2_withdraw( + param: ::mududb::contract::procedure::procedure_param::ProcedureParam, +) -> ::mududb::common::result::RS< + ::mududb::contract::procedure::procedure_result::ProcedureResult, > { - let return_desc = mudu_result_desc_update_user().clone(); - let res = update_user( + let res = withdraw( param.session_id(), - ::mudu_type::datum::value_to_typed::< + ::mududb::types::datum::value_to_typed::< i32, _, >(¶m.param_list()[0], "i32")?, - ::mudu_type::datum::value_to_typed::< - String, - _, - >(¶m.param_list()[1], "String")?, - - - - ::mudu_type::datum::value_to_typed::< - String, + ::mududb::types::datum::value_to_typed::< + i32, _, - >(¶m.param_list()[2], "String")?, + >(¶m.param_list()[1], "i32")?, ).await; @@ -452,37 +444,30 @@ pub async fn mudu_inner_p2_update_user( vec![] }; - Ok(::mudu_contract::procedure::procedure_result::ProcedureResult::new(return_list)) + Ok(::mududb::contract::procedure::procedure_result::ProcedureResult::new(return_list)) } Err(e) => Err(e), } } -pub fn mudu_argv_desc_update_user() -> &'static ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc { - static ARGV_DESC: std::sync::OnceLock<::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc> = +pub fn mudu_argv_desc_withdraw() -> &'static ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc { + static ARGV_DESC: std::sync::OnceLock<::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc> = std::sync::OnceLock::new(); ARGV_DESC.get_or_init(|| { - ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc::new(vec![ + ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc::new(vec![ - ::mudu_contract::tuple::datum_desc::DatumDesc::new( + ::mududb::contract::tuple::datum_desc::DatumDesc::new( "user_id".to_string(), - ::dat_type().clone() - - ), - - ::mudu_contract::tuple::datum_desc::DatumDesc::new( - "name".to_string(), - - ::dat_type().clone() + ::dat_type().clone() ), - ::mudu_contract::tuple::datum_desc::DatumDesc::new( - "email".to_string(), + ::mududb::contract::tuple::datum_desc::DatumDesc::new( + "amount".to_string(), - ::dat_type().clone() + ::dat_type().clone() ), @@ -491,40 +476,40 @@ pub fn mudu_argv_desc_update_user() -> &'static ::mudu_contract::tuple::tuple_f ) } -pub fn mudu_result_desc_update_user() -> &'static ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc { - static RESULT_DESC: std::sync::OnceLock<::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc> = +pub fn mudu_result_desc_withdraw() -> &'static ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc { + static RESULT_DESC: std::sync::OnceLock<::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc> = std::sync::OnceLock::new(); RESULT_DESC.get_or_init(|| { - ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc::new(vec![ + ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc::new(vec![ ]) } ) } -pub fn mudu_proc_desc_update_user() -> &'static ::mudu_contract::procedure::proc_desc::ProcDesc { +pub fn mudu_proc_desc_withdraw() -> &'static ::mududb::contract::procedure::proc_desc::ProcDesc { static _PROC_DESC: std::sync::OnceLock< - ::mudu_contract::procedure::proc_desc::ProcDesc, + ::mududb::contract::procedure::proc_desc::ProcDesc, > = std::sync::OnceLock::new(); _PROC_DESC .get_or_init(|| { - ::mudu_contract::procedure::proc_desc::ProcDesc::new( + ::mududb::contract::procedure::proc_desc::ProcDesc::new( "wallet".to_string(), - "update_user".to_string(), - mudu_argv_desc_update_user().clone(), - mudu_result_desc_update_user().clone(), + "withdraw".to_string(), + mudu_argv_desc_withdraw().clone(), + mudu_result_desc_withdraw().clone(), false ) }) } -mod mod_update_user { +mod mod_withdraw { wit_bindgen::generate!({ inline: - r##"package mudu:mp2-update-user; - world mudu-app-mp2-update-user { - export mp2-update-user: func(param:list) -> list; + r##"package mudu:mp2-withdraw; + world mudu-app-mp2-withdraw { + export mp2-withdraw: func(param:list) -> list; } "##, async: true @@ -532,39 +517,52 @@ mod mod_update_user { #[allow(non_camel_case_types)] #[allow(unused)] - struct GuestUpdateUser {} + struct GuestWithdraw {} - impl Guest for GuestUpdateUser { - async fn mp2_update_user(param:Vec) -> Vec { - super::mp2_update_user(param).await + impl Guest for GuestWithdraw { + async fn mp2_withdraw(param:Vec) -> Vec { + super::mp2_withdraw(param).await } } - export!(GuestUpdateUser); + export!(GuestWithdraw); } -async fn mp2_delete_user(param:Vec) -> Vec { - ::mudu_binding::procedure::procedure_invoke::invoke_procedure_async( +async fn mp2_create_user(param:Vec) -> Vec { + ::mududb::binding::procedure::procedure_invoke::invoke_procedure_async( param, - mudu_inner_p2_delete_user, + mudu_inner_p2_create_user, ).await } -pub async fn mudu_inner_p2_delete_user( - param: ::mudu_contract::procedure::procedure_param::ProcedureParam, -) -> ::mudu::common::result::RS< - ::mudu_contract::procedure::procedure_result::ProcedureResult, +pub async fn mudu_inner_p2_create_user( + param: ::mududb::contract::procedure::procedure_param::ProcedureParam, +) -> ::mududb::common::result::RS< + ::mududb::contract::procedure::procedure_result::ProcedureResult, > { - let return_desc = mudu_result_desc_delete_user().clone(); - let res = delete_user( + let res = create_user( param.session_id(), - ::mudu_type::datum::value_to_typed::< + ::mududb::types::datum::value_to_typed::< i32, _, >(¶m.param_list()[0], "i32")?, + + ::mududb::types::datum::value_to_typed::< + String, + _, + >(¶m.param_list()[1], "String")?, + + + + ::mududb::types::datum::value_to_typed::< + String, + _, + >(¶m.param_list()[2], "String")?, + + ).await; match res { Ok(tuple) => { @@ -573,23 +571,37 @@ pub async fn mudu_inner_p2_delete_user( vec![] }; - Ok(::mudu_contract::procedure::procedure_result::ProcedureResult::new(return_list)) + Ok(::mududb::contract::procedure::procedure_result::ProcedureResult::new(return_list)) } Err(e) => Err(e), } } -pub fn mudu_argv_desc_delete_user() -> &'static ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc { - static ARGV_DESC: std::sync::OnceLock<::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc> = +pub fn mudu_argv_desc_create_user() -> &'static ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc { + static ARGV_DESC: std::sync::OnceLock<::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc> = std::sync::OnceLock::new(); ARGV_DESC.get_or_init(|| { - ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc::new(vec![ + ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc::new(vec![ - ::mudu_contract::tuple::datum_desc::DatumDesc::new( + ::mududb::contract::tuple::datum_desc::DatumDesc::new( "user_id".to_string(), - ::dat_type().clone() + ::dat_type().clone() + + ), + + ::mududb::contract::tuple::datum_desc::DatumDesc::new( + "name".to_string(), + + ::dat_type().clone() + + ), + + ::mududb::contract::tuple::datum_desc::DatumDesc::new( + "email".to_string(), + + ::dat_type().clone() ), @@ -598,40 +610,40 @@ pub fn mudu_argv_desc_delete_user() -> &'static ::mudu_contract::tuple::tuple_f ) } -pub fn mudu_result_desc_delete_user() -> &'static ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc { - static RESULT_DESC: std::sync::OnceLock<::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc> = +pub fn mudu_result_desc_create_user() -> &'static ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc { + static RESULT_DESC: std::sync::OnceLock<::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc> = std::sync::OnceLock::new(); RESULT_DESC.get_or_init(|| { - ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc::new(vec![ + ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc::new(vec![ ]) } ) } -pub fn mudu_proc_desc_delete_user() -> &'static ::mudu_contract::procedure::proc_desc::ProcDesc { +pub fn mudu_proc_desc_create_user() -> &'static ::mududb::contract::procedure::proc_desc::ProcDesc { static _PROC_DESC: std::sync::OnceLock< - ::mudu_contract::procedure::proc_desc::ProcDesc, + ::mududb::contract::procedure::proc_desc::ProcDesc, > = std::sync::OnceLock::new(); _PROC_DESC .get_or_init(|| { - ::mudu_contract::procedure::proc_desc::ProcDesc::new( + ::mududb::contract::procedure::proc_desc::ProcDesc::new( "wallet".to_string(), - "delete_user".to_string(), - mudu_argv_desc_delete_user().clone(), - mudu_result_desc_delete_user().clone(), + "create_user".to_string(), + mudu_argv_desc_create_user().clone(), + mudu_result_desc_create_user().clone(), false ) }) } -mod mod_delete_user { +mod mod_create_user { wit_bindgen::generate!({ inline: - r##"package mudu:mp2-delete-user; - world mudu-app-mp2-delete-user { - export mp2-delete-user: func(param:list) -> list; + r##"package mudu:mp2-create-user; + world mudu-app-mp2-create-user { + export mp2-create-user: func(param:list) -> list; } "##, async: true @@ -639,48 +651,47 @@ mod mod_delete_user { #[allow(non_camel_case_types)] #[allow(unused)] - struct GuestDeleteUser {} + struct GuestCreateUser {} - impl Guest for GuestDeleteUser { - async fn mp2_delete_user(param:Vec) -> Vec { - super::mp2_delete_user(param).await + impl Guest for GuestCreateUser { + async fn mp2_create_user(param:Vec) -> Vec { + super::mp2_create_user(param).await } } - export!(GuestDeleteUser); + export!(GuestCreateUser); } -async fn mp2_transfer(param:Vec) -> Vec { - ::mudu_binding::procedure::procedure_invoke::invoke_procedure_async( +async fn mp2_transfer_funds(param:Vec) -> Vec { + ::mududb::binding::procedure::procedure_invoke::invoke_procedure_async( param, - mudu_inner_p2_transfer, + mudu_inner_p2_transfer_funds, ).await } -pub async fn mudu_inner_p2_transfer( - param: ::mudu_contract::procedure::procedure_param::ProcedureParam, -) -> ::mudu::common::result::RS< - ::mudu_contract::procedure::procedure_result::ProcedureResult, +pub async fn mudu_inner_p2_transfer_funds( + param: ::mududb::contract::procedure::procedure_param::ProcedureParam, +) -> ::mududb::common::result::RS< + ::mududb::contract::procedure::procedure_result::ProcedureResult, > { - let return_desc = mudu_result_desc_transfer().clone(); - let res = transfer( + let res = transfer_funds( param.session_id(), - ::mudu_type::datum::value_to_typed::< + ::mududb::types::datum::value_to_typed::< i32, _, >(¶m.param_list()[0], "i32")?, - ::mudu_type::datum::value_to_typed::< + ::mududb::types::datum::value_to_typed::< i32, _, >(¶m.param_list()[1], "i32")?, - ::mudu_type::datum::value_to_typed::< + ::mududb::types::datum::value_to_typed::< i32, _, >(¶m.param_list()[2], "i32")?, @@ -694,37 +705,37 @@ pub async fn mudu_inner_p2_transfer( vec![] }; - Ok(::mudu_contract::procedure::procedure_result::ProcedureResult::new(return_list)) + Ok(::mududb::contract::procedure::procedure_result::ProcedureResult::new(return_list)) } Err(e) => Err(e), } } -pub fn mudu_argv_desc_transfer() -> &'static ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc { - static ARGV_DESC: std::sync::OnceLock<::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc> = +pub fn mudu_argv_desc_transfer_funds() -> &'static ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc { + static ARGV_DESC: std::sync::OnceLock<::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc> = std::sync::OnceLock::new(); ARGV_DESC.get_or_init(|| { - ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc::new(vec![ + ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc::new(vec![ - ::mudu_contract::tuple::datum_desc::DatumDesc::new( + ::mududb::contract::tuple::datum_desc::DatumDesc::new( "from_user_id".to_string(), - ::dat_type().clone() + ::dat_type().clone() ), - ::mudu_contract::tuple::datum_desc::DatumDesc::new( + ::mududb::contract::tuple::datum_desc::DatumDesc::new( "to_user_id".to_string(), - ::dat_type().clone() + ::dat_type().clone() ), - ::mudu_contract::tuple::datum_desc::DatumDesc::new( + ::mududb::contract::tuple::datum_desc::DatumDesc::new( "amount".to_string(), - ::dat_type().clone() + ::dat_type().clone() ), @@ -733,40 +744,40 @@ pub fn mudu_argv_desc_transfer() -> &'static ::mudu_contract::tuple::tuple_fiel ) } -pub fn mudu_result_desc_transfer() -> &'static ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc { - static RESULT_DESC: std::sync::OnceLock<::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc> = +pub fn mudu_result_desc_transfer_funds() -> &'static ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc { + static RESULT_DESC: std::sync::OnceLock<::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc> = std::sync::OnceLock::new(); RESULT_DESC.get_or_init(|| { - ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc::new(vec![ + ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc::new(vec![ ]) } ) } -pub fn mudu_proc_desc_transfer() -> &'static ::mudu_contract::procedure::proc_desc::ProcDesc { +pub fn mudu_proc_desc_transfer_funds() -> &'static ::mududb::contract::procedure::proc_desc::ProcDesc { static _PROC_DESC: std::sync::OnceLock< - ::mudu_contract::procedure::proc_desc::ProcDesc, + ::mududb::contract::procedure::proc_desc::ProcDesc, > = std::sync::OnceLock::new(); _PROC_DESC .get_or_init(|| { - ::mudu_contract::procedure::proc_desc::ProcDesc::new( + ::mududb::contract::procedure::proc_desc::ProcDesc::new( "wallet".to_string(), - "transfer".to_string(), - mudu_argv_desc_transfer().clone(), - mudu_result_desc_transfer().clone(), + "transfer_funds".to_string(), + mudu_argv_desc_transfer_funds().clone(), + mudu_result_desc_transfer_funds().clone(), false ) }) } -mod mod_transfer { +mod mod_transfer_funds { wit_bindgen::generate!({ inline: - r##"package mudu:mp2-transfer; - world mudu-app-mp2-transfer { - export mp2-transfer: func(param:list) -> list; + r##"package mudu:mp2-transfer-funds; + world mudu-app-mp2-transfer-funds { + export mp2-transfer-funds: func(param:list) -> list; } "##, async: true @@ -774,53 +785,38 @@ mod mod_transfer { #[allow(non_camel_case_types)] #[allow(unused)] - struct GuestTransfer {} + struct GuestTransferFunds {} - impl Guest for GuestTransfer { - async fn mp2_transfer(param:Vec) -> Vec { - super::mp2_transfer(param).await + impl Guest for GuestTransferFunds { + async fn mp2_transfer_funds(param:Vec) -> Vec { + super::mp2_transfer_funds(param).await } } - export!(GuestTransfer); + export!(GuestTransferFunds); } -async fn mp2_purchase(param:Vec) -> Vec { - ::mudu_binding::procedure::procedure_invoke::invoke_procedure_async( +async fn mp2_delete_user(param:Vec) -> Vec { + ::mududb::binding::procedure::procedure_invoke::invoke_procedure_async( param, - mudu_inner_p2_purchase, + mudu_inner_p2_delete_user, ).await } -pub async fn mudu_inner_p2_purchase( - param: ::mudu_contract::procedure::procedure_param::ProcedureParam, -) -> ::mudu::common::result::RS< - ::mudu_contract::procedure::procedure_result::ProcedureResult, +pub async fn mudu_inner_p2_delete_user( + param: ::mududb::contract::procedure::procedure_param::ProcedureParam, +) -> ::mududb::common::result::RS< + ::mududb::contract::procedure::procedure_result::ProcedureResult, > { - let return_desc = mudu_result_desc_purchase().clone(); - let res = purchase( + let res = delete_user( param.session_id(), - ::mudu_type::datum::value_to_typed::< + ::mududb::types::datum::value_to_typed::< i32, _, >(¶m.param_list()[0], "i32")?, - - ::mudu_type::datum::value_to_typed::< - i32, - _, - >(¶m.param_list()[1], "i32")?, - - - - ::mudu_type::datum::value_to_typed::< - String, - _, - >(¶m.param_list()[2], "String")?, - - ).await; match res { Ok(tuple) => { @@ -829,37 +825,23 @@ pub async fn mudu_inner_p2_purchase( vec![] }; - Ok(::mudu_contract::procedure::procedure_result::ProcedureResult::new(return_list)) + Ok(::mududb::contract::procedure::procedure_result::ProcedureResult::new(return_list)) } Err(e) => Err(e), } } -pub fn mudu_argv_desc_purchase() -> &'static ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc { - static ARGV_DESC: std::sync::OnceLock<::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc> = +pub fn mudu_argv_desc_delete_user() -> &'static ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc { + static ARGV_DESC: std::sync::OnceLock<::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc> = std::sync::OnceLock::new(); ARGV_DESC.get_or_init(|| { - ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc::new(vec![ + ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc::new(vec![ - ::mudu_contract::tuple::datum_desc::DatumDesc::new( + ::mududb::contract::tuple::datum_desc::DatumDesc::new( "user_id".to_string(), - ::dat_type().clone() - - ), - - ::mudu_contract::tuple::datum_desc::DatumDesc::new( - "amount".to_string(), - - ::dat_type().clone() - - ), - - ::mudu_contract::tuple::datum_desc::DatumDesc::new( - "description".to_string(), - - ::dat_type().clone() + ::dat_type().clone() ), @@ -868,40 +850,40 @@ pub fn mudu_argv_desc_purchase() -> &'static ::mudu_contract::tuple::tuple_fiel ) } -pub fn mudu_result_desc_purchase() -> &'static ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc { - static RESULT_DESC: std::sync::OnceLock<::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc> = +pub fn mudu_result_desc_delete_user() -> &'static ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc { + static RESULT_DESC: std::sync::OnceLock<::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc> = std::sync::OnceLock::new(); RESULT_DESC.get_or_init(|| { - ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc::new(vec![ + ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc::new(vec![ ]) } ) } -pub fn mudu_proc_desc_purchase() -> &'static ::mudu_contract::procedure::proc_desc::ProcDesc { +pub fn mudu_proc_desc_delete_user() -> &'static ::mududb::contract::procedure::proc_desc::ProcDesc { static _PROC_DESC: std::sync::OnceLock< - ::mudu_contract::procedure::proc_desc::ProcDesc, + ::mududb::contract::procedure::proc_desc::ProcDesc, > = std::sync::OnceLock::new(); _PROC_DESC .get_or_init(|| { - ::mudu_contract::procedure::proc_desc::ProcDesc::new( + ::mududb::contract::procedure::proc_desc::ProcDesc::new( "wallet".to_string(), - "purchase".to_string(), - mudu_argv_desc_purchase().clone(), - mudu_result_desc_purchase().clone(), + "delete_user".to_string(), + mudu_argv_desc_delete_user().clone(), + mudu_result_desc_delete_user().clone(), false ) }) } -mod mod_purchase { +mod mod_delete_user { wit_bindgen::generate!({ inline: - r##"package mudu:mp2-purchase; - world mudu-app-mp2-purchase { - export mp2-purchase: func(param:list) -> list; + r##"package mudu:mp2-delete-user; + world mudu-app-mp2-delete-user { + export mp2-delete-user: func(param:list) -> list; } "##, async: true @@ -909,44 +891,50 @@ mod mod_purchase { #[allow(non_camel_case_types)] #[allow(unused)] - struct GuestPurchase {} + struct GuestDeleteUser {} - impl Guest for GuestPurchase { - async fn mp2_purchase(param:Vec) -> Vec { - super::mp2_purchase(param).await + impl Guest for GuestDeleteUser { + async fn mp2_delete_user(param:Vec) -> Vec { + super::mp2_delete_user(param).await } } - export!(GuestPurchase); + export!(GuestDeleteUser); } -async fn mp2_deposit(param:Vec) -> Vec { - ::mudu_binding::procedure::procedure_invoke::invoke_procedure_async( +async fn mp2_update_user(param:Vec) -> Vec { + ::mududb::binding::procedure::procedure_invoke::invoke_procedure_async( param, - mudu_inner_p2_deposit, + mudu_inner_p2_update_user, ).await } -pub async fn mudu_inner_p2_deposit( - param: ::mudu_contract::procedure::procedure_param::ProcedureParam, -) -> ::mudu::common::result::RS< - ::mudu_contract::procedure::procedure_result::ProcedureResult, +pub async fn mudu_inner_p2_update_user( + param: ::mududb::contract::procedure::procedure_param::ProcedureParam, +) -> ::mududb::common::result::RS< + ::mududb::contract::procedure::procedure_result::ProcedureResult, > { - let return_desc = mudu_result_desc_deposit().clone(); - let res = deposit( + let res = update_user( param.session_id(), - ::mudu_type::datum::value_to_typed::< + ::mududb::types::datum::value_to_typed::< i32, _, >(¶m.param_list()[0], "i32")?, - ::mudu_type::datum::value_to_typed::< - i32, + ::mududb::types::datum::value_to_typed::< + String, _, - >(¶m.param_list()[1], "i32")?, + >(¶m.param_list()[1], "String")?, + + + + ::mududb::types::datum::value_to_typed::< + String, + _, + >(¶m.param_list()[2], "String")?, ).await; @@ -957,30 +945,37 @@ pub async fn mudu_inner_p2_deposit( vec![] }; - Ok(::mudu_contract::procedure::procedure_result::ProcedureResult::new(return_list)) + Ok(::mududb::contract::procedure::procedure_result::ProcedureResult::new(return_list)) } Err(e) => Err(e), } } -pub fn mudu_argv_desc_deposit() -> &'static ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc { - static ARGV_DESC: std::sync::OnceLock<::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc> = +pub fn mudu_argv_desc_update_user() -> &'static ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc { + static ARGV_DESC: std::sync::OnceLock<::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc> = std::sync::OnceLock::new(); ARGV_DESC.get_or_init(|| { - ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc::new(vec![ + ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc::new(vec![ - ::mudu_contract::tuple::datum_desc::DatumDesc::new( + ::mududb::contract::tuple::datum_desc::DatumDesc::new( "user_id".to_string(), - ::dat_type().clone() + ::dat_type().clone() ), - ::mudu_contract::tuple::datum_desc::DatumDesc::new( - "amount".to_string(), + ::mududb::contract::tuple::datum_desc::DatumDesc::new( + "name".to_string(), + + ::dat_type().clone() + + ), + + ::mududb::contract::tuple::datum_desc::DatumDesc::new( + "email".to_string(), - ::dat_type().clone() + ::dat_type().clone() ), @@ -989,40 +984,40 @@ pub fn mudu_argv_desc_deposit() -> &'static ::mudu_contract::tuple::tuple_field ) } -pub fn mudu_result_desc_deposit() -> &'static ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc { - static RESULT_DESC: std::sync::OnceLock<::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc> = +pub fn mudu_result_desc_update_user() -> &'static ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc { + static RESULT_DESC: std::sync::OnceLock<::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc> = std::sync::OnceLock::new(); RESULT_DESC.get_or_init(|| { - ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc::new(vec![ + ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc::new(vec![ ]) } ) } -pub fn mudu_proc_desc_deposit() -> &'static ::mudu_contract::procedure::proc_desc::ProcDesc { +pub fn mudu_proc_desc_update_user() -> &'static ::mududb::contract::procedure::proc_desc::ProcDesc { static _PROC_DESC: std::sync::OnceLock< - ::mudu_contract::procedure::proc_desc::ProcDesc, + ::mududb::contract::procedure::proc_desc::ProcDesc, > = std::sync::OnceLock::new(); _PROC_DESC .get_or_init(|| { - ::mudu_contract::procedure::proc_desc::ProcDesc::new( + ::mududb::contract::procedure::proc_desc::ProcDesc::new( "wallet".to_string(), - "deposit".to_string(), - mudu_argv_desc_deposit().clone(), - mudu_result_desc_deposit().clone(), + "update_user".to_string(), + mudu_argv_desc_update_user().clone(), + mudu_result_desc_update_user().clone(), false ) }) } -mod mod_deposit { +mod mod_update_user { wit_bindgen::generate!({ inline: - r##"package mudu:mp2-deposit; - world mudu-app-mp2-deposit { - export mp2-deposit: func(param:list) -> list; + r##"package mudu:mp2-update-user; + world mudu-app-mp2-update-user { + export mp2-update-user: func(param:list) -> list; } "##, async: true @@ -1030,51 +1025,50 @@ mod mod_deposit { #[allow(non_camel_case_types)] #[allow(unused)] - struct GuestDeposit {} + struct GuestUpdateUser {} - impl Guest for GuestDeposit { - async fn mp2_deposit(param:Vec) -> Vec { - super::mp2_deposit(param).await + impl Guest for GuestUpdateUser { + async fn mp2_update_user(param:Vec) -> Vec { + super::mp2_update_user(param).await } } - export!(GuestDeposit); + export!(GuestUpdateUser); } -async fn mp2_transfer_funds(param:Vec) -> Vec { - ::mudu_binding::procedure::procedure_invoke::invoke_procedure_async( +async fn mp2_purchase(param:Vec) -> Vec { + ::mududb::binding::procedure::procedure_invoke::invoke_procedure_async( param, - mudu_inner_p2_transfer_funds, + mudu_inner_p2_purchase, ).await } -pub async fn mudu_inner_p2_transfer_funds( - param: ::mudu_contract::procedure::procedure_param::ProcedureParam, -) -> ::mudu::common::result::RS< - ::mudu_contract::procedure::procedure_result::ProcedureResult, +pub async fn mudu_inner_p2_purchase( + param: ::mududb::contract::procedure::procedure_param::ProcedureParam, +) -> ::mududb::common::result::RS< + ::mududb::contract::procedure::procedure_result::ProcedureResult, > { - let return_desc = mudu_result_desc_transfer_funds().clone(); - let res = transfer_funds( + let res = purchase( param.session_id(), - ::mudu_type::datum::value_to_typed::< + ::mududb::types::datum::value_to_typed::< i32, _, >(¶m.param_list()[0], "i32")?, - ::mudu_type::datum::value_to_typed::< + ::mududb::types::datum::value_to_typed::< i32, _, >(¶m.param_list()[1], "i32")?, - ::mudu_type::datum::value_to_typed::< - i32, + ::mududb::types::datum::value_to_typed::< + String, _, - >(¶m.param_list()[2], "i32")?, + >(¶m.param_list()[2], "String")?, ).await; @@ -1085,37 +1079,37 @@ pub async fn mudu_inner_p2_transfer_funds( vec![] }; - Ok(::mudu_contract::procedure::procedure_result::ProcedureResult::new(return_list)) + Ok(::mududb::contract::procedure::procedure_result::ProcedureResult::new(return_list)) } Err(e) => Err(e), } } -pub fn mudu_argv_desc_transfer_funds() -> &'static ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc { - static ARGV_DESC: std::sync::OnceLock<::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc> = +pub fn mudu_argv_desc_purchase() -> &'static ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc { + static ARGV_DESC: std::sync::OnceLock<::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc> = std::sync::OnceLock::new(); ARGV_DESC.get_or_init(|| { - ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc::new(vec![ + ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc::new(vec![ - ::mudu_contract::tuple::datum_desc::DatumDesc::new( - "from_user_id".to_string(), + ::mududb::contract::tuple::datum_desc::DatumDesc::new( + "user_id".to_string(), - ::dat_type().clone() + ::dat_type().clone() ), - ::mudu_contract::tuple::datum_desc::DatumDesc::new( - "to_user_id".to_string(), + ::mududb::contract::tuple::datum_desc::DatumDesc::new( + "amount".to_string(), - ::dat_type().clone() + ::dat_type().clone() ), - ::mudu_contract::tuple::datum_desc::DatumDesc::new( - "amount".to_string(), + ::mududb::contract::tuple::datum_desc::DatumDesc::new( + "description".to_string(), - ::dat_type().clone() + ::dat_type().clone() ), @@ -1124,40 +1118,40 @@ pub fn mudu_argv_desc_transfer_funds() -> &'static ::mudu_contract::tuple::tupl ) } -pub fn mudu_result_desc_transfer_funds() -> &'static ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc { - static RESULT_DESC: std::sync::OnceLock<::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc> = +pub fn mudu_result_desc_purchase() -> &'static ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc { + static RESULT_DESC: std::sync::OnceLock<::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc> = std::sync::OnceLock::new(); RESULT_DESC.get_or_init(|| { - ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc::new(vec![ + ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc::new(vec![ ]) } ) } -pub fn mudu_proc_desc_transfer_funds() -> &'static ::mudu_contract::procedure::proc_desc::ProcDesc { +pub fn mudu_proc_desc_purchase() -> &'static ::mududb::contract::procedure::proc_desc::ProcDesc { static _PROC_DESC: std::sync::OnceLock< - ::mudu_contract::procedure::proc_desc::ProcDesc, + ::mududb::contract::procedure::proc_desc::ProcDesc, > = std::sync::OnceLock::new(); _PROC_DESC .get_or_init(|| { - ::mudu_contract::procedure::proc_desc::ProcDesc::new( + ::mududb::contract::procedure::proc_desc::ProcDesc::new( "wallet".to_string(), - "transfer_funds".to_string(), - mudu_argv_desc_transfer_funds().clone(), - mudu_result_desc_transfer_funds().clone(), + "purchase".to_string(), + mudu_argv_desc_purchase().clone(), + mudu_result_desc_purchase().clone(), false ) }) } -mod mod_transfer_funds { +mod mod_purchase { wit_bindgen::generate!({ inline: - r##"package mudu:mp2-transfer-funds; - world mudu-app-mp2-transfer-funds { - export mp2-transfer-funds: func(param:list) -> list; + r##"package mudu:mp2-purchase; + world mudu-app-mp2-purchase { + export mp2-purchase: func(param:list) -> list; } "##, async: true @@ -1165,51 +1159,50 @@ mod mod_transfer_funds { #[allow(non_camel_case_types)] #[allow(unused)] - struct GuestTransferFunds {} + struct GuestPurchase {} - impl Guest for GuestTransferFunds { - async fn mp2_transfer_funds(param:Vec) -> Vec { - super::mp2_transfer_funds(param).await + impl Guest for GuestPurchase { + async fn mp2_purchase(param:Vec) -> Vec { + super::mp2_purchase(param).await } } - export!(GuestTransferFunds); + export!(GuestPurchase); } -async fn mp2_create_user(param:Vec) -> Vec { - ::mudu_binding::procedure::procedure_invoke::invoke_procedure_async( +async fn mp2_transfer(param:Vec) -> Vec { + ::mududb::binding::procedure::procedure_invoke::invoke_procedure_async( param, - mudu_inner_p2_create_user, + mudu_inner_p2_transfer, ).await } -pub async fn mudu_inner_p2_create_user( - param: ::mudu_contract::procedure::procedure_param::ProcedureParam, -) -> ::mudu::common::result::RS< - ::mudu_contract::procedure::procedure_result::ProcedureResult, +pub async fn mudu_inner_p2_transfer( + param: ::mududb::contract::procedure::procedure_param::ProcedureParam, +) -> ::mududb::common::result::RS< + ::mududb::contract::procedure::procedure_result::ProcedureResult, > { - let return_desc = mudu_result_desc_create_user().clone(); - let res = create_user( + let res = transfer( param.session_id(), - ::mudu_type::datum::value_to_typed::< + ::mududb::types::datum::value_to_typed::< i32, _, >(¶m.param_list()[0], "i32")?, - ::mudu_type::datum::value_to_typed::< - String, + ::mududb::types::datum::value_to_typed::< + i32, _, - >(¶m.param_list()[1], "String")?, + >(¶m.param_list()[1], "i32")?, - ::mudu_type::datum::value_to_typed::< - String, + ::mududb::types::datum::value_to_typed::< + i32, _, - >(¶m.param_list()[2], "String")?, + >(¶m.param_list()[2], "i32")?, ).await; @@ -1220,37 +1213,37 @@ pub async fn mudu_inner_p2_create_user( vec![] }; - Ok(::mudu_contract::procedure::procedure_result::ProcedureResult::new(return_list)) + Ok(::mududb::contract::procedure::procedure_result::ProcedureResult::new(return_list)) } Err(e) => Err(e), } } -pub fn mudu_argv_desc_create_user() -> &'static ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc { - static ARGV_DESC: std::sync::OnceLock<::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc> = +pub fn mudu_argv_desc_transfer() -> &'static ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc { + static ARGV_DESC: std::sync::OnceLock<::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc> = std::sync::OnceLock::new(); ARGV_DESC.get_or_init(|| { - ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc::new(vec![ + ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc::new(vec![ - ::mudu_contract::tuple::datum_desc::DatumDesc::new( - "user_id".to_string(), + ::mududb::contract::tuple::datum_desc::DatumDesc::new( + "from_user_id".to_string(), - ::dat_type().clone() + ::dat_type().clone() ), - ::mudu_contract::tuple::datum_desc::DatumDesc::new( - "name".to_string(), + ::mududb::contract::tuple::datum_desc::DatumDesc::new( + "to_user_id".to_string(), - ::dat_type().clone() + ::dat_type().clone() ), - ::mudu_contract::tuple::datum_desc::DatumDesc::new( - "email".to_string(), + ::mududb::contract::tuple::datum_desc::DatumDesc::new( + "amount".to_string(), - ::dat_type().clone() + ::dat_type().clone() ), @@ -1259,40 +1252,40 @@ pub fn mudu_argv_desc_create_user() -> &'static ::mudu_contract::tuple::tuple_f ) } -pub fn mudu_result_desc_create_user() -> &'static ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc { - static RESULT_DESC: std::sync::OnceLock<::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc> = +pub fn mudu_result_desc_transfer() -> &'static ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc { + static RESULT_DESC: std::sync::OnceLock<::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc> = std::sync::OnceLock::new(); RESULT_DESC.get_or_init(|| { - ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc::new(vec![ + ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc::new(vec![ ]) } ) } -pub fn mudu_proc_desc_create_user() -> &'static ::mudu_contract::procedure::proc_desc::ProcDesc { +pub fn mudu_proc_desc_transfer() -> &'static ::mududb::contract::procedure::proc_desc::ProcDesc { static _PROC_DESC: std::sync::OnceLock< - ::mudu_contract::procedure::proc_desc::ProcDesc, + ::mududb::contract::procedure::proc_desc::ProcDesc, > = std::sync::OnceLock::new(); _PROC_DESC .get_or_init(|| { - ::mudu_contract::procedure::proc_desc::ProcDesc::new( + ::mududb::contract::procedure::proc_desc::ProcDesc::new( "wallet".to_string(), - "create_user".to_string(), - mudu_argv_desc_create_user().clone(), - mudu_result_desc_create_user().clone(), + "transfer".to_string(), + mudu_argv_desc_transfer().clone(), + mudu_result_desc_transfer().clone(), false ) }) } -mod mod_create_user { +mod mod_transfer { wit_bindgen::generate!({ inline: - r##"package mudu:mp2-create-user; - world mudu-app-mp2-create-user { - export mp2-create-user: func(param:list) -> list; + r##"package mudu:mp2-transfer; + world mudu-app-mp2-transfer { + export mp2-transfer: func(param:list) -> list; } "##, async: true @@ -1300,41 +1293,40 @@ mod mod_create_user { #[allow(non_camel_case_types)] #[allow(unused)] - struct GuestCreateUser {} + struct GuestTransfer {} - impl Guest for GuestCreateUser { - async fn mp2_create_user(param:Vec) -> Vec { - super::mp2_create_user(param).await + impl Guest for GuestTransfer { + async fn mp2_transfer(param:Vec) -> Vec { + super::mp2_transfer(param).await } } - export!(GuestCreateUser); + export!(GuestTransfer); } -async fn mp2_withdraw(param:Vec) -> Vec { - ::mudu_binding::procedure::procedure_invoke::invoke_procedure_async( +async fn mp2_deposit(param:Vec) -> Vec { + ::mududb::binding::procedure::procedure_invoke::invoke_procedure_async( param, - mudu_inner_p2_withdraw, + mudu_inner_p2_deposit, ).await } -pub async fn mudu_inner_p2_withdraw( - param: ::mudu_contract::procedure::procedure_param::ProcedureParam, -) -> ::mudu::common::result::RS< - ::mudu_contract::procedure::procedure_result::ProcedureResult, +pub async fn mudu_inner_p2_deposit( + param: ::mududb::contract::procedure::procedure_param::ProcedureParam, +) -> ::mududb::common::result::RS< + ::mududb::contract::procedure::procedure_result::ProcedureResult, > { - let return_desc = mudu_result_desc_withdraw().clone(); - let res = withdraw( + let res = deposit( param.session_id(), - ::mudu_type::datum::value_to_typed::< + ::mududb::types::datum::value_to_typed::< i32, _, >(¶m.param_list()[0], "i32")?, - ::mudu_type::datum::value_to_typed::< + ::mududb::types::datum::value_to_typed::< i32, _, >(¶m.param_list()[1], "i32")?, @@ -1348,30 +1340,30 @@ pub async fn mudu_inner_p2_withdraw( vec![] }; - Ok(::mudu_contract::procedure::procedure_result::ProcedureResult::new(return_list)) + Ok(::mududb::contract::procedure::procedure_result::ProcedureResult::new(return_list)) } Err(e) => Err(e), } } -pub fn mudu_argv_desc_withdraw() -> &'static ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc { - static ARGV_DESC: std::sync::OnceLock<::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc> = +pub fn mudu_argv_desc_deposit() -> &'static ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc { + static ARGV_DESC: std::sync::OnceLock<::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc> = std::sync::OnceLock::new(); ARGV_DESC.get_or_init(|| { - ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc::new(vec![ + ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc::new(vec![ - ::mudu_contract::tuple::datum_desc::DatumDesc::new( + ::mududb::contract::tuple::datum_desc::DatumDesc::new( "user_id".to_string(), - ::dat_type().clone() + ::dat_type().clone() ), - ::mudu_contract::tuple::datum_desc::DatumDesc::new( + ::mududb::contract::tuple::datum_desc::DatumDesc::new( "amount".to_string(), - ::dat_type().clone() + ::dat_type().clone() ), @@ -1380,40 +1372,40 @@ pub fn mudu_argv_desc_withdraw() -> &'static ::mudu_contract::tuple::tuple_fiel ) } -pub fn mudu_result_desc_withdraw() -> &'static ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc { - static RESULT_DESC: std::sync::OnceLock<::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc> = +pub fn mudu_result_desc_deposit() -> &'static ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc { + static RESULT_DESC: std::sync::OnceLock<::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc> = std::sync::OnceLock::new(); RESULT_DESC.get_or_init(|| { - ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc::new(vec![ + ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc::new(vec![ ]) } ) } -pub fn mudu_proc_desc_withdraw() -> &'static ::mudu_contract::procedure::proc_desc::ProcDesc { +pub fn mudu_proc_desc_deposit() -> &'static ::mududb::contract::procedure::proc_desc::ProcDesc { static _PROC_DESC: std::sync::OnceLock< - ::mudu_contract::procedure::proc_desc::ProcDesc, + ::mududb::contract::procedure::proc_desc::ProcDesc, > = std::sync::OnceLock::new(); _PROC_DESC .get_or_init(|| { - ::mudu_contract::procedure::proc_desc::ProcDesc::new( + ::mududb::contract::procedure::proc_desc::ProcDesc::new( "wallet".to_string(), - "withdraw".to_string(), - mudu_argv_desc_withdraw().clone(), - mudu_result_desc_withdraw().clone(), + "deposit".to_string(), + mudu_argv_desc_deposit().clone(), + mudu_result_desc_deposit().clone(), false ) }) } -mod mod_withdraw { +mod mod_deposit { wit_bindgen::generate!({ inline: - r##"package mudu:mp2-withdraw; - world mudu-app-mp2-withdraw { - export mp2-withdraw: func(param:list) -> list; + r##"package mudu:mp2-deposit; + world mudu-app-mp2-deposit { + export mp2-deposit: func(param:list) -> list; } "##, async: true @@ -1421,13 +1413,13 @@ mod mod_withdraw { #[allow(non_camel_case_types)] #[allow(unused)] - struct GuestWithdraw {} + struct GuestDeposit {} - impl Guest for GuestWithdraw { - async fn mp2_withdraw(param:Vec) -> Vec { - super::mp2_withdraw(param).await + impl Guest for GuestDeposit { + async fn mp2_deposit(param:Vec) -> Vec { + super::mp2_deposit(param).await } } - export!(GuestWithdraw); + export!(GuestDeposit); } \ No newline at end of file diff --git a/example/wallet/src/generated/transactions.rs b/example/wallet/src/generated/transactions.rs index 947cc0f..ac35640 100644 --- a/example/wallet/src/generated/transactions.rs +++ b/example/wallet/src/generated/transactions.rs @@ -1,20 +1,20 @@ pub mod object { use lazy_static::lazy_static; -use mudu::common::result::RS; -use mudu_type::dat_binary::DatBinary; -use mudu_type::dat_textual::DatTextual; -use mudu_type::dat_type::DatType; -use mudu_type::dat_type_id::DatTypeID; -use mudu_type::dat_value::DatValue; -use mudu_type::datum::{Datum, DatumDyn}; -use mudu_contract::database::attr_field_access; -use mudu_contract::database::attr_value::AttrValue; -use mudu_contract::database::entity::Entity; -use mudu_contract::database::entity_utils; -use mudu_contract::tuple::datum_desc::DatumDesc; -use mudu_contract::tuple::tuple_field_desc::TupleFieldDesc; -use mudu_contract::tuple::tuple_datum::TupleDatumMarker; -use mudu_contract::database::sql_params::SQLParamMarker; +use mududb::common::result::RS; +use mududb::contract::database::attr_field_access; +use mududb::contract::database::attr_value::AttrValue; +use mududb::contract::database::entity::Entity; +use mududb::contract::database::entity_utils; +use mududb::contract::database::sql_params::SQLParamMarker; +use mududb::contract::tuple::datum_desc::DatumDesc; +use mududb::contract::tuple::tuple_field_desc::TupleFieldDesc; +use mududb::contract::tuple::tuple_datum::TupleDatumMarker; +use mududb::types::dat_binary::DatBinary; +use mududb::types::dat_textual::DatTextual; +use mududb::types::dat_type::DatType; +use mududb::types::dat_type_id::DatTypeID; +use mududb::types::dat_value::DatValue; +use mududb::types::datum::{Datum, DatumDyn}; // constant definition const TRANSACTIONS:&str = "transactions"; diff --git a/example/wallet/src/generated/users.rs b/example/wallet/src/generated/users.rs index 0f02ddc..f08e8fe 100644 --- a/example/wallet/src/generated/users.rs +++ b/example/wallet/src/generated/users.rs @@ -1,20 +1,20 @@ pub mod object { use lazy_static::lazy_static; -use mudu::common::result::RS; -use mudu_type::dat_binary::DatBinary; -use mudu_type::dat_textual::DatTextual; -use mudu_type::dat_type::DatType; -use mudu_type::dat_type_id::DatTypeID; -use mudu_type::dat_value::DatValue; -use mudu_type::datum::{Datum, DatumDyn}; -use mudu_contract::database::attr_field_access; -use mudu_contract::database::attr_value::AttrValue; -use mudu_contract::database::entity::Entity; -use mudu_contract::database::entity_utils; -use mudu_contract::tuple::datum_desc::DatumDesc; -use mudu_contract::tuple::tuple_field_desc::TupleFieldDesc; -use mudu_contract::tuple::tuple_datum::TupleDatumMarker; -use mudu_contract::database::sql_params::SQLParamMarker; +use mududb::common::result::RS; +use mududb::contract::database::attr_field_access; +use mududb::contract::database::attr_value::AttrValue; +use mududb::contract::database::entity::Entity; +use mududb::contract::database::entity_utils; +use mududb::contract::database::sql_params::SQLParamMarker; +use mududb::contract::tuple::datum_desc::DatumDesc; +use mududb::contract::tuple::tuple_field_desc::TupleFieldDesc; +use mududb::contract::tuple::tuple_datum::TupleDatumMarker; +use mududb::types::dat_binary::DatBinary; +use mududb::types::dat_textual::DatTextual; +use mududb::types::dat_type::DatType; +use mududb::types::dat_type_id::DatTypeID; +use mududb::types::dat_value::DatValue; +use mududb::types::datum::{Datum, DatumDyn}; // constant definition const USERS:&str = "users"; diff --git a/example/wallet/src/generated/wallets.rs b/example/wallet/src/generated/wallets.rs index b0aa482..cc1a953 100644 --- a/example/wallet/src/generated/wallets.rs +++ b/example/wallet/src/generated/wallets.rs @@ -1,20 +1,20 @@ pub mod object { use lazy_static::lazy_static; -use mudu::common::result::RS; -use mudu_type::dat_binary::DatBinary; -use mudu_type::dat_textual::DatTextual; -use mudu_type::dat_type::DatType; -use mudu_type::dat_type_id::DatTypeID; -use mudu_type::dat_value::DatValue; -use mudu_type::datum::{Datum, DatumDyn}; -use mudu_contract::database::attr_field_access; -use mudu_contract::database::attr_value::AttrValue; -use mudu_contract::database::entity::Entity; -use mudu_contract::database::entity_utils; -use mudu_contract::tuple::datum_desc::DatumDesc; -use mudu_contract::tuple::tuple_field_desc::TupleFieldDesc; -use mudu_contract::tuple::tuple_datum::TupleDatumMarker; -use mudu_contract::database::sql_params::SQLParamMarker; +use mududb::common::result::RS; +use mududb::contract::database::attr_field_access; +use mududb::contract::database::attr_value::AttrValue; +use mududb::contract::database::entity::Entity; +use mududb::contract::database::entity_utils; +use mududb::contract::database::sql_params::SQLParamMarker; +use mududb::contract::tuple::datum_desc::DatumDesc; +use mududb::contract::tuple::tuple_field_desc::TupleFieldDesc; +use mududb::contract::tuple::tuple_datum::TupleDatumMarker; +use mududb::types::dat_binary::DatBinary; +use mududb::types::dat_textual::DatTextual; +use mududb::types::dat_type::DatType; +use mududb::types::dat_type_id::DatTypeID; +use mududb::types::dat_value::DatValue; +use mududb::types::datum::{Datum, DatumDyn}; // constant definition const WALLETS:&str = "wallets"; diff --git a/example/wallet/src/generated/warehouse.rs b/example/wallet/src/generated/warehouse.rs index 2b8a182..93ac5dc 100644 --- a/example/wallet/src/generated/warehouse.rs +++ b/example/wallet/src/generated/warehouse.rs @@ -1,18 +1,18 @@ pub mod object { use lazy_static::lazy_static; - use mudu::common::result::RS; - use mudu_contract::database::attr_field_access; - use mudu_contract::database::attr_value::AttrValue; - use mudu_contract::database::entity::Entity; - use mudu_contract::database::entity_utils; - use mudu_contract::tuple::datum_desc::DatumDesc; - use mudu_contract::tuple::tuple_field_desc::TupleFieldDesc; - use mudu_type::dat_binary::DatBinary; - use mudu_type::dat_textual::DatTextual; - use mudu_type::dat_type::DatType; - use mudu_type::dat_type_id::DatTypeID; - use mudu_type::dat_value::DatValue; - use mudu_type::datum::{Datum, DatumDyn}; + use mududb::common::result::RS; + use mududb::contract::database::attr_field_access; + use mududb::contract::database::attr_value::AttrValue; + use mududb::contract::database::entity::Entity; + use mududb::contract::database::entity_utils; + use mududb::contract::tuple::datum_desc::DatumDesc; + use mududb::contract::tuple::tuple_field_desc::TupleFieldDesc; + use mududb::types::dat_binary::DatBinary; + use mududb::types::dat_textual::DatTextual; + use mududb::types::dat_type::DatType; + use mududb::types::dat_type_id::DatTypeID; + use mududb::types::dat_value::DatValue; + use mududb::types::datum::{Datum, DatumDyn}; const TABLE_WAREHOUSE: &str = "warehouse"; const COLUMN_W_ID: &str = "w_id"; @@ -183,7 +183,7 @@ pub mod object { #[cfg(test)] mod tests { use super::Warehouse; - use mudu_type::datum::{Datum, DatumDyn}; + use mududb::types::datum::{Datum, DatumDyn}; #[test] fn warehouse_roundtrip_and_setters_work() { diff --git a/example/wallet/src/rust/orders.rs b/example/wallet/src/rust/orders.rs index 51c38e4..55403b7 100644 --- a/example/wallet/src/rust/orders.rs +++ b/example/wallet/src/rust/orders.rs @@ -1,20 +1,20 @@ pub mod object { use lazy_static::lazy_static; -use mudu::common::result::RS; -use mudu_type::dat_binary::DatBinary; -use mudu_type::dat_textual::DatTextual; -use mudu_type::dat_type::DatType; -use mudu_type::dat_type_id::DatTypeID; -use mudu_type::dat_value::DatValue; -use mudu_type::datum::{Datum, DatumDyn}; -use mudu_contract::database::attr_field_access; -use mudu_contract::database::attr_value::AttrValue; -use mudu_contract::database::entity::Entity; -use mudu_contract::database::entity_utils; -use mudu_contract::tuple::datum_desc::DatumDesc; -use mudu_contract::tuple::tuple_field_desc::TupleFieldDesc; -use mudu_contract::tuple::tuple_datum::TupleDatumMarker; -use mudu_contract::database::sql_params::SQLParamMarker; +use mududb::common::result::RS; +use mududb::contract::database::attr_field_access; +use mududb::contract::database::attr_value::AttrValue; +use mududb::contract::database::entity::Entity; +use mududb::contract::database::entity_utils; +use mududb::contract::database::sql_params::SQLParamMarker; +use mududb::contract::tuple::datum_desc::DatumDesc; +use mududb::contract::tuple::tuple_field_desc::TupleFieldDesc; +use mududb::contract::tuple::tuple_datum::TupleDatumMarker; +use mududb::types::dat_binary::DatBinary; +use mududb::types::dat_textual::DatTextual; +use mududb::types::dat_type::DatType; +use mududb::types::dat_type_id::DatTypeID; +use mududb::types::dat_value::DatValue; +use mududb::types::datum::{Datum, DatumDyn}; // constant definition const ORDERS:&str = "orders"; diff --git a/example/wallet/src/rust/procedures.rs b/example/wallet/src/rust/procedures.rs index a8890d2..f6cee5e 100644 --- a/example/wallet/src/rust/procedures.rs +++ b/example/wallet/src/rust/procedures.rs @@ -1,16 +1,16 @@ use crate::rust::wallets::object::Wallets; -use mudu::common::result::RS; -use mudu::common::xid::XID; -use mudu::error::ec::EC::MuduError; -use mudu::m_error; -use mudu_contract::database::attr_value::AttrValue; -use mudu_contract::{sql_params, sql_stmt}; -use mudu_type::datum::DatumDyn; +use mududb::common::result::RS; +use mududb::common::xid::XID; +use mududb::error::ec::EC::MuduError; +use mududb::m_error; +use mududb::contract::database::attr_value::AttrValue; +use mududb::contract::{sql_params, sql_stmt}; +use mududb::types::datum::DatumDyn; use std::time::UNIX_EPOCH; -use sys_interface::sync_api::{mudu_command, mudu_query}; +use mududb::sys_interface::sync_api::{mudu_command, mudu_query}; fn current_timestamp() -> i64 { - let now = mudu_sys::time::system_time_now(); + let now = mududb::sys::time::system_time_now(); let duration_since_epoch = now .duration_since(UNIX_EPOCH) .expect("SystemTime before UNIX EPOCH!"); @@ -94,7 +94,7 @@ pub fn transfer_funds(xid: XID, from_user_id: i32, to_user_id: i32, amount: i32) } // 3. Entity the transaction - let id = mudu_sys::random::next_uuid_v4_string(); + let id = mududb::sys::random::next_uuid_v4_string(); let insert_rows = mudu_command( xid, sql_stmt!( @@ -217,7 +217,7 @@ pub fn deposit(xid: XID, user_id: i32, amount: i32) -> RS<()> { } let now = current_timestamp(); - let tx_id = mudu_sys::random::next_uuid_v4_string(); + let tx_id = mududb::sys::random::next_uuid_v4_string(); let wallet = mudu_query::( xid, sql_stmt!(&"SELECT user_id, balance, updated_at FROM wallets WHERE user_id = ?"), @@ -272,7 +272,7 @@ pub fn withdraw(xid: XID, user_id: i32, amount: i32) -> RS<()> { } let now = current_timestamp(); - let tx_id = mudu_sys::random::next_uuid_v4_string(); + let tx_id = mududb::sys::random::next_uuid_v4_string(); let next_balance = required_balance(&wallet)? - amount; // Update wallet balance @@ -330,7 +330,7 @@ pub fn transfer(xid: XID, from_user_id: i32, to_user_id: i32, amount: i32) -> RS let receiver_balance = required_balance(&receiver_wallet)?; let now = current_timestamp(); - let tx_id = mudu_sys::random::next_uuid_v4_string(); + let tx_id = mududb::sys::random::next_uuid_v4_string(); // Debit sender mudu_command( @@ -386,7 +386,7 @@ pub fn purchase(xid: XID, user_id: i32, amount: i32, description: String) -> RS< } let now = current_timestamp(); - let tx_id = mudu_sys::random::next_uuid_v4_string(); + let tx_id = mududb::sys::random::next_uuid_v4_string(); let next_balance = required_balance(&wallet)? - amount; // Deduct amount diff --git a/example/wallet/src/rust/transactions.rs b/example/wallet/src/rust/transactions.rs index 448414c..f9c1a8e 100644 --- a/example/wallet/src/rust/transactions.rs +++ b/example/wallet/src/rust/transactions.rs @@ -1,20 +1,20 @@ pub mod object { use lazy_static::lazy_static; -use mudu::common::result::RS; -use mudu_type::dat_binary::DatBinary; -use mudu_type::dat_textual::DatTextual; -use mudu_type::dat_type::DatType; -use mudu_type::dat_type_id::DatTypeID; -use mudu_type::dat_value::DatValue; -use mudu_type::datum::{Datum, DatumDyn}; -use mudu_contract::database::attr_field_access; -use mudu_contract::database::attr_value::AttrValue; -use mudu_contract::database::entity::Entity; -use mudu_contract::database::entity_utils; -use mudu_contract::tuple::datum_desc::DatumDesc; -use mudu_contract::tuple::tuple_field_desc::TupleFieldDesc; -use mudu_contract::tuple::tuple_datum::TupleDatumMarker; -use mudu_contract::database::sql_params::SQLParamMarker; +use mududb::common::result::RS; +use mududb::contract::database::attr_field_access; +use mududb::contract::database::attr_value::AttrValue; +use mududb::contract::database::entity::Entity; +use mududb::contract::database::entity_utils; +use mududb::contract::database::sql_params::SQLParamMarker; +use mududb::contract::tuple::datum_desc::DatumDesc; +use mududb::contract::tuple::tuple_field_desc::TupleFieldDesc; +use mududb::contract::tuple::tuple_datum::TupleDatumMarker; +use mududb::types::dat_binary::DatBinary; +use mududb::types::dat_textual::DatTextual; +use mududb::types::dat_type::DatType; +use mududb::types::dat_type_id::DatTypeID; +use mududb::types::dat_value::DatValue; +use mududb::types::datum::{Datum, DatumDyn}; // constant definition const TRANSACTIONS:&str = "transactions"; diff --git a/example/wallet/src/rust/users.rs b/example/wallet/src/rust/users.rs index e84a9cf..c22f147 100644 --- a/example/wallet/src/rust/users.rs +++ b/example/wallet/src/rust/users.rs @@ -1,20 +1,20 @@ pub mod object { use lazy_static::lazy_static; -use mudu::common::result::RS; -use mudu_type::dat_binary::DatBinary; -use mudu_type::dat_textual::DatTextual; -use mudu_type::dat_type::DatType; -use mudu_type::dat_type_id::DatTypeID; -use mudu_type::dat_value::DatValue; -use mudu_type::datum::{Datum, DatumDyn}; -use mudu_contract::database::attr_field_access; -use mudu_contract::database::attr_value::AttrValue; -use mudu_contract::database::entity::Entity; -use mudu_contract::database::entity_utils; -use mudu_contract::tuple::datum_desc::DatumDesc; -use mudu_contract::tuple::tuple_field_desc::TupleFieldDesc; -use mudu_contract::tuple::tuple_datum::TupleDatumMarker; -use mudu_contract::database::sql_params::SQLParamMarker; +use mududb::common::result::RS; +use mududb::contract::database::attr_field_access; +use mududb::contract::database::attr_value::AttrValue; +use mududb::contract::database::entity::Entity; +use mududb::contract::database::entity_utils; +use mududb::contract::database::sql_params::SQLParamMarker; +use mududb::contract::tuple::datum_desc::DatumDesc; +use mududb::contract::tuple::tuple_field_desc::TupleFieldDesc; +use mududb::contract::tuple::tuple_datum::TupleDatumMarker; +use mududb::types::dat_binary::DatBinary; +use mududb::types::dat_textual::DatTextual; +use mududb::types::dat_type::DatType; +use mududb::types::dat_type_id::DatTypeID; +use mududb::types::dat_value::DatValue; +use mududb::types::datum::{Datum, DatumDyn}; // constant definition const USERS:&str = "users"; diff --git a/example/wallet/src/rust/wallets.rs b/example/wallet/src/rust/wallets.rs index dd775bc..6adb3e9 100644 --- a/example/wallet/src/rust/wallets.rs +++ b/example/wallet/src/rust/wallets.rs @@ -1,20 +1,20 @@ pub mod object { use lazy_static::lazy_static; -use mudu::common::result::RS; -use mudu_type::dat_binary::DatBinary; -use mudu_type::dat_textual::DatTextual; -use mudu_type::dat_type::DatType; -use mudu_type::dat_type_id::DatTypeID; -use mudu_type::dat_value::DatValue; -use mudu_type::datum::{Datum, DatumDyn}; -use mudu_contract::database::attr_field_access; -use mudu_contract::database::attr_value::AttrValue; -use mudu_contract::database::entity::Entity; -use mudu_contract::database::entity_utils; -use mudu_contract::tuple::datum_desc::DatumDesc; -use mudu_contract::tuple::tuple_field_desc::TupleFieldDesc; -use mudu_contract::tuple::tuple_datum::TupleDatumMarker; -use mudu_contract::database::sql_params::SQLParamMarker; +use mududb::common::result::RS; +use mududb::contract::database::attr_field_access; +use mududb::contract::database::attr_value::AttrValue; +use mududb::contract::database::entity::Entity; +use mududb::contract::database::entity_utils; +use mududb::contract::database::sql_params::SQLParamMarker; +use mududb::contract::tuple::datum_desc::DatumDesc; +use mududb::contract::tuple::tuple_field_desc::TupleFieldDesc; +use mududb::contract::tuple::tuple_datum::TupleDatumMarker; +use mududb::types::dat_binary::DatBinary; +use mududb::types::dat_textual::DatTextual; +use mududb::types::dat_type::DatType; +use mududb::types::dat_type_id::DatTypeID; +use mududb::types::dat_value::DatValue; +use mududb::types::datum::{Datum, DatumDyn}; // constant definition const WALLETS:&str = "wallets"; diff --git a/example/wallet/src/rust/warehouse.rs b/example/wallet/src/rust/warehouse.rs index 2ba0b12..fa389fc 100644 --- a/example/wallet/src/rust/warehouse.rs +++ b/example/wallet/src/rust/warehouse.rs @@ -1,18 +1,18 @@ pub mod object { use lazy_static::lazy_static; - use mudu::common::result::RS; - use mudu_contract::database::attr_field_access; - use mudu_contract::database::attr_value::AttrValue; - use mudu_contract::database::entity::Entity; - use mudu_contract::database::entity_utils; - use mudu_contract::tuple::datum_desc::DatumDesc; - use mudu_contract::tuple::tuple_field_desc::TupleFieldDesc; - use mudu_type::dat_binary::DatBinary; - use mudu_type::dat_textual::DatTextual; - use mudu_type::dat_type::DatType; - use mudu_type::dat_type_id::DatTypeID; - use mudu_type::dat_value::DatValue; - use mudu_type::datum::{Datum, DatumDyn}; + use mududb::common::result::RS; + use mududb::contract::database::attr_field_access; + use mududb::contract::database::attr_value::AttrValue; + use mududb::contract::database::entity::Entity; + use mududb::contract::database::entity_utils; + use mududb::contract::tuple::datum_desc::DatumDesc; + use mududb::contract::tuple::tuple_field_desc::TupleFieldDesc; + use mududb::types::dat_binary::DatBinary; + use mududb::types::dat_textual::DatTextual; + use mududb::types::dat_type::DatType; + use mududb::types::dat_type_id::DatTypeID; + use mududb::types::dat_value::DatValue; + use mududb::types::datum::{Datum, DatumDyn}; const TABLE_WAREHOUSE: &str = "warehouse"; const COLUMN_W_ID: &str = "w_id"; @@ -183,7 +183,7 @@ pub mod object { #[cfg(test)] mod tests { use super::Warehouse; - use mudu_type::datum::{Datum, DatumDyn}; + use mududb::types::datum::{Datum, DatumDyn}; #[test] fn warehouse_roundtrip_and_setters_work() { diff --git a/example/wallet/src/testing/procedure.rs b/example/wallet/src/testing/procedure.rs index 28a2c08..56d5368 100644 --- a/example/wallet/src/testing/procedure.rs +++ b/example/wallet/src/testing/procedure.rs @@ -1,13 +1,13 @@ use crate::rust::procedures; use crate::rust::transactions::object::Transactions; use crate::rust::wallets::object::Wallets; -use mudu::common::id::OID; -use mudu_contract::database::entity_set::RecordSet; -use mudu_contract::{sql_params, sql_stmt}; +use mududb::common::id::OID; +use mududb::contract::database::entity_set::RecordSet; +use mududb::contract::{sql_params, sql_stmt}; use std::path::PathBuf; use std::sync::{Mutex, OnceLock}; use std::time::UNIX_EPOCH; -use sys_interface::sync_api::{mudu_batch, mudu_close, mudu_open, mudu_query}; +use mududb::sys_interface::sync_api::{mudu_batch, mudu_close, mudu_open, mudu_query}; static TEST_MUTEX: OnceLock> = OnceLock::new(); @@ -205,7 +205,7 @@ impl TestDb { rs.next_record().unwrap() } - fn query_count( + fn query_count( &self, sql: &str, params: &P, @@ -214,7 +214,7 @@ impl TestDb { rs.next_record().unwrap().unwrap() } - fn query_string( + fn query_string( &self, sql: &str, params: &P, @@ -224,13 +224,13 @@ impl TestDb { } fn query_records< - R: mudu_contract::database::entity::Entity, - P: mudu_contract::database::sql_params::SQLParams, + R: mududb::contract::database::entity::Entity, + P: mududb::contract::database::sql_params::SQLParams, >( &self, sql: &str, params: &P, - ) -> mudu_contract::database::entity_set::RecordSet { + ) -> mududb::contract::database::entity_set::RecordSet { mudu_query::(self.current_session(), sql_stmt!(&sql), params).unwrap() } @@ -252,7 +252,7 @@ impl Drop for TestDb { } fn unique_db_path() -> PathBuf { - let nanos = mudu_sys::time::system_time_now() + let nanos = mududb::sys::time::system_time_now() .duration_since(UNIX_EPOCH) .unwrap() .as_nanos(); diff --git a/example/ycsb/Cargo.toml b/example/ycsb/Cargo.toml index 1b50880..b00289d 100644 --- a/example/ycsb/Cargo.toml +++ b/example/ycsb/Cargo.toml @@ -18,19 +18,14 @@ benchmark-runner = [ "dep:mudu_utils", "dep:tokio", "debug_trace", - "sys_interface/standalone-adapter", + "mududb/standalone-adapter", ] [dependencies] -mudu = { workspace = true } -mudu_sys = { workspace = true } -mudu_type = { workspace = true } -mudu_contract = { workspace = true } -mudu_binding = { workspace = true } +mududb = { workspace = true, features = ["async"] } mudu_adapter = { workspace = true, optional = true } mudu_cli = { workspace = true, optional = true } mudu_utils = { workspace = true, optional = true, features = ["debug_trace"] } -sys_interface = { workspace = true, features = ["async"] } wit-bindgen = { workspace = true } clap = { workspace = true, optional = true, features = ["derive"] } tokio = { workspace = true, optional = true } @@ -38,7 +33,7 @@ async-backtrace = { workspace = true, optional = true } [target.'cfg(not(target_arch = "wasm32"))'.dev-dependencies] mudu_adapter = { workspace = true } -sys_interface = { workspace = true, features = ["async", "standalone-adapter"] } +mududb = { workspace = true, features = ["async", "standalone-adapter"] } tokio = { workspace = true, features = ["rt-multi-thread"] } [[bin]] diff --git a/example/ycsb/package/package.desc.json b/example/ycsb/package/package.desc.json index 83bad2f..570b78b 100644 --- a/example/ycsb/package/package.desc.json +++ b/example/ycsb/package/package.desc.json @@ -3,7 +3,7 @@ "ycsb": [ { "module_name": "ycsb", - "proc_name": "ycsb_read_modify_write", + "proc_name": "ycsb_read", "param_desc": { "fields": [ { @@ -16,17 +16,6 @@ } }, "name": "user_key" - }, - { - "dat_type": { - "id": "String", - "param": { - "String": { - "length": 65536 - } - } - }, - "name": "append_value" } ] }, @@ -48,7 +37,7 @@ }, { "module_name": "ycsb", - "proc_name": "ycsb_read", + "proc_name": "ycsb_update", "param_desc": { "fields": [ { @@ -61,11 +50,7 @@ } }, "name": "user_key" - } - ] - }, - "return_desc": { - "fields": [ + }, { "dat_type": { "id": "String", @@ -75,14 +60,17 @@ } } }, - "name": "0" + "name": "value" } ] + }, + "return_desc": { + "fields": [] } }, { "module_name": "ycsb", - "proc_name": "ycsb_update", + "proc_name": "ycsb_scan", "param_desc": { "fields": [ { @@ -94,7 +82,7 @@ } } }, - "name": "user_key" + "name": "start_user_key" }, { "dat_type": { @@ -105,17 +93,37 @@ } } }, - "name": "value" + "name": "end_user_key" } ] }, "return_desc": { - "fields": [] + "fields": [ + { + "dat_type": { + "id": "Array", + "param": { + "Array": { + "dat_type": { + "id": "String", + "param": { + "String": { + "length": 65536 + } + } + }, + "max_size": null + } + } + }, + "name": "0" + } + ] } }, { "module_name": "ycsb", - "proc_name": "ycsb_scan", + "proc_name": "ycsb_read_modify_write", "param_desc": { "fields": [ { @@ -127,7 +135,7 @@ } } }, - "name": "start_user_key" + "name": "user_key" }, { "dat_type": { @@ -138,7 +146,7 @@ } } }, - "name": "end_user_key" + "name": "append_value" } ] }, @@ -146,18 +154,10 @@ "fields": [ { "dat_type": { - "id": "Array", + "id": "String", "param": { - "Array": { - "dat_type": { - "id": "String", - "param": { - "String": { - "length": 65536 - } - } - }, - "max_size": null + "String": { + "length": 65536 } } }, diff --git a/example/ycsb/src/bin/ycsb_benchmark.rs b/example/ycsb/src/bin/ycsb_benchmark.rs index 716434e..0f90fca 100644 --- a/example/ycsb/src/bin/ycsb_benchmark.rs +++ b/example/ycsb/src/bin/ycsb_benchmark.rs @@ -1,9 +1,9 @@ use clap::Parser; -use mudu::common::result::RS; -use mudu::common::xid::XID; -use mudu_binding::universal::uni_session_open_argv::UniSessionOpenArgv; +use mududb::common::result::RS; +use mududb::common::xid::XID; +use mududb::binding::universal::uni_session_open_argv::UniSessionOpenArgv; use mudu_cli::management::{ServerTopology, fetch_server_topology}; -use mudu_contract::database::sql_stmt_text::SQLStmtText; +use mududb::contract::database::sql_stmt_text::SQLStmtText; use mudu_utils::debug::debug_serve; use mudu_utils::notifier::NotifyWait; use mudu_utils::task::spawn_task; @@ -13,11 +13,11 @@ use std::sync::Barrier as StdBarrier; use std::sync::atomic::{AtomicUsize, Ordering}; use std::thread; use std::time::{Duration, Instant}; -use sys_interface::async_api::{ +use mududb::sys_interface::async_api::{ mudu_close as mudu_close_async, mudu_command as mudu_command_async, mudu_open_argv as mudu_open_argv_async, }; -use sys_interface::sync_api::{mudu_close, mudu_command as mudu_command_sync, mudu_open_argv}; +use mududb::sys_interface::sync_api::{mudu_close, mudu_command as mudu_command_sync, mudu_open_argv}; use tokio::runtime::Builder; use tokio::sync::{Barrier as TokioBarrier, Semaphore}; use ycsb::rust::procedure::{ @@ -133,8 +133,8 @@ impl DebugHttpServer { .name("ycsb-debug-http".to_string()) .spawn(move || debug_serve(thread_canceler, port)) .map_err(|e| { - mudu::m_error!( - mudu::error::ec::EC::ThreadErr, + mududb::m_error!( + mududb::error::ec::EC::ThreadErr, "spawn ycsb debug http server error", e ) @@ -161,14 +161,14 @@ impl ProgressReporter { let handle = thread::Builder::new() .name(format!("ycsb-progress-{}", phase.as_str())) .spawn(move || { - let start = mudu_sys::time::instant_now(); + let start = mududb::sys::time::instant_now(); let mut last_completed = 0; let mut last_report = start; loop { - mudu_sys::task::sleep_blocking(PROGRESS_REPORT_INTERVAL); + mududb::sys::task::sleep_blocking(PROGRESS_REPORT_INTERVAL); let started = thread_tracker.started.load(Ordering::Relaxed).min(total); let completed = thread_tracker.completed.load(Ordering::Relaxed).min(total); - let now = mudu_sys::time::instant_now(); + let now = mududb::sys::time::instant_now(); let delta = completed.saturating_sub(last_completed); let delta_secs = now.duration_since(last_report).as_secs_f64().max(0.000_001); let total_secs = now.duration_since(start).as_secs_f64().max(0.000_001); @@ -230,8 +230,8 @@ impl Drop for DebugHttpServer { impl PartitionRouting { fn slot(&self, partition_index: usize) -> RS { self.slots.get(partition_index).copied().ok_or_else(|| { - mudu::m_error!( - mudu::error::ec::EC::NoSuchElement, + mududb::m_error!( + mududb::error::ec::EC::NoSuchElement, format!("no routing slot for partition index {}", partition_index) ) }) @@ -286,8 +286,8 @@ fn run_async_mode(args: Args) -> RS<()> { .enable_all() .build() .map_err(|e| { - mudu::m_error!( - mudu::error::ec::EC::TokioErr, + mududb::m_error!( + mududb::error::ec::EC::TokioErr, "build ycsb benchmark runtime error", e ) @@ -298,15 +298,15 @@ fn run_async_mode(args: Args) -> RS<()> { run_async(args).await })?; let output = join.await.map_err(|e| { - mudu::m_error!( - mudu::error::ec::EC::ThreadErr, + mududb::m_error!( + mududb::error::ec::EC::ThreadErr, "join ycsb benchmark root task error", e ) })?; output.ok_or_else(|| { - mudu::m_error!( - mudu::error::ec::EC::ThreadErr, + mududb::m_error!( + mududb::error::ec::EC::ThreadErr, "ycsb benchmark root task canceled" ) })? @@ -319,7 +319,7 @@ fn run_sync_mode(args: Args) -> RS<()> { let value_template = Arc::new(build_value(args.field_length)); let routing = Arc::new(load_partition_routing_sync(partition_count)?); - let load_start = mudu_sys::time::instant_now(); + let load_start = mududb::sys::time::instant_now(); run_workers_sync( &args, connection_count, @@ -329,7 +329,7 @@ fn run_sync_mode(args: Args) -> RS<()> { )?; let load_elapsed = load_start.elapsed(); - let run_start = mudu_sys::time::instant_now(); + let run_start = mududb::sys::time::instant_now(); let counters = run_workers_sync( &args, connection_count, @@ -356,7 +356,7 @@ async fn run_async(args: Args) -> RS<()> { let value_template = Arc::new(build_value(args.field_length)); let routing = Arc::new(load_partition_routing_async(partition_count).await?); - let load_start = mudu_sys::time::instant_now(); + let load_start = mududb::sys::time::instant_now(); run_workers_async( &args, connection_count, @@ -367,7 +367,7 @@ async fn run_async(args: Args) -> RS<()> { .await?; let load_elapsed = load_start.elapsed(); - let run_start = mudu_sys::time::instant_now(); + let run_start = mududb::sys::time::instant_now(); let counters = run_workers_async( &args, connection_count, @@ -471,8 +471,8 @@ fn run_workers_sync( let mut total = Counters::default(); for handle in handles { let counters = handle.join().map_err(|_| { - mudu::m_error!( - mudu::error::ec::EC::ThreadErr, + mududb::m_error!( + mududb::error::ec::EC::ThreadErr, "ycsb worker thread panicked" ) })??; @@ -542,15 +542,15 @@ async fn run_workers_async( let mut total = Counters::default(); for handle in handles { let counters = handle.await.map_err(|e| { - mudu::m_error!( - mudu::error::ec::EC::ThreadErr, + mududb::m_error!( + mududb::error::ec::EC::ThreadErr, "ycsb async worker task failed", e ) })?; let counters = counters.ok_or_else(|| { - mudu::m_error!( - mudu::error::ec::EC::ThreadErr, + mududb::m_error!( + mududb::error::ec::EC::ThreadErr, "ycsb async worker task canceled" ) })??; @@ -632,8 +632,8 @@ async fn run_worker_async( let worker_id = slot.worker_id; let xid = { let _permit = open_limit.acquire_owned().await.map_err(|e| { - mudu::m_error!( - mudu::error::ec::EC::ThreadErr, + mududb::m_error!( + mududb::error::ec::EC::ThreadErr, "acquire ycsb async open permit error", e ) @@ -691,8 +691,8 @@ fn load_partition_routing_sync(partition_count: usize) -> RS { .enable_all() .build() .map_err(|e| { - mudu::m_error!( - mudu::error::ec::EC::TokioErr, + mududb::m_error!( + mududb::error::ec::EC::TokioErr, "build ycsb topology runtime error", e ) @@ -702,7 +702,7 @@ fn load_partition_routing_sync(partition_count: usize) -> RS { Err(err) if topology_is_unsupported(&err) => { return Ok(default_partition_routing(partition_count)); } - Err(err) => return Err(mudu::m_error!(mudu::error::ec::EC::NetErr, err)), + Err(err) => return Err(mududb::m_error!(mududb::error::ec::EC::NetErr, err)), }; build_partition_routing(partition_count, topology) } @@ -716,7 +716,7 @@ async fn load_partition_routing_async(partition_count: usize) -> RS { return Ok(default_partition_routing(partition_count)); } - Err(err) => return Err(mudu::m_error!(mudu::error::ec::EC::NetErr, err)), + Err(err) => return Err(mududb::m_error!(mududb::error::ec::EC::NetErr, err)), }; build_partition_routing(partition_count, topology) } @@ -751,8 +751,8 @@ fn build_partition_routing( } slots.sort_by_key(|slot| slot.partition_id); if slots.len() < partition_count { - return Err(mudu::m_error!( - mudu::error::ec::EC::NoneErr, + return Err(mududb::m_error!( + mududb::error::ec::EC::NoneErr, format!( "requested {} partitions but topology only exposes {}", partition_count, diff --git a/example/ycsb/src/generated/mod.rs b/example/ycsb/src/generated/mod.rs index b3c780a..5dcbb7f 100644 --- a/example/ycsb/src/generated/mod.rs +++ b/example/ycsb/src/generated/mod.rs @@ -1 +1,2 @@ pub mod procedure; +mod procedure_common; \ No newline at end of file diff --git a/example/ycsb/src/generated/procedure.rs b/example/ycsb/src/generated/procedure.rs index 8855d08..df5b580 100644 --- a/example/ycsb/src/generated/procedure.rs +++ b/example/ycsb/src/generated/procedure.rs @@ -1,27 +1,13 @@ -use mudu::common::result::RS; -use mudu::common::xid::XID; -use mudu::error::ec::EC; -use mudu::m_error; -use sys_interface::async_api::{mudu_get, mudu_put, mudu_range}; - -fn kv_data_key(user_key: &str) -> String { - format!("user/{user_key}") -} - -fn decode_utf8(label: &str, bytes: Vec) -> RS { - String::from_utf8(bytes).map_err(|e| { - m_error!( - EC::DecodeErr, - format!("invalid utf8 in ycsb {label}"), - e.to_string() - ) - }) -} +use crate::generated::procedure_common::{decode_utf8, kv_data_key}; +use mududb::common::result::RS; +use mududb::common::xid::XID; +use mududb::error::ec::EC; +use mududb::m_error; +use mududb::sys_interface::async_api::{mudu_get, mudu_put, mudu_range}; async fn read_value(session_id: XID, user_key: &str) -> RS { let key = kv_data_key(user_key); - let value = mudu_get(session_id, key.as_bytes()) - .await? + let value = mudu_get(session_id, key.as_bytes()).await? .ok_or_else(|| m_error!(EC::NoneErr, format!("ycsb key not found: {user_key}")))?; decode_utf8("value", value) } @@ -40,8 +26,7 @@ pub async fn ycsb_read(xid: XID, user_key: String) -> RS { /**mudu-proc**/ pub async fn ycsb_update(xid: XID, user_key: String, value: String) -> RS<()> { let key = kv_data_key(&user_key); - let _ = mudu_get(xid, key.as_bytes()) - .await? + let _ = mudu_get(xid, key.as_bytes()).await? .ok_or_else(|| m_error!(EC::NoneErr, format!("ycsb key not found: {user_key}")))?; mudu_put(xid, key.as_bytes(), value.as_bytes()).await } @@ -61,11 +46,7 @@ pub async fn ycsb_scan(xid: XID, start_user_key: String, end_user_key: String) - } /**mudu-proc**/ -pub async fn ycsb_read_modify_write( - xid: XID, - user_key: String, - append_value: String, -) -> RS { +pub async fn ycsb_read_modify_write(xid: XID, user_key: String, append_value: String) -> RS { let key = kv_data_key(&user_key); let mut current = match mudu_get(xid, key.as_bytes()).await? { Some(value) => decode_utf8("value", value)?, @@ -75,152 +56,144 @@ pub async fn ycsb_read_modify_write( mudu_put(xid, key.as_bytes(), current.as_bytes()).await?; Ok(current) } -async fn mp2_ycsb_read_modify_write(param: Vec) -> Vec { - ::mudu_binding::procedure::procedure_invoke::invoke_procedure_async( - param, - mudu_inner_p2_ycsb_read_modify_write, - ) - .await -} -pub async fn mudu_inner_p2_ycsb_read_modify_write( - param: ::mudu_contract::procedure::procedure_param::ProcedureParam, -) -> ::mudu::common::result::RS<::mudu_contract::procedure::procedure_result::ProcedureResult> { - let return_desc = mudu_result_desc_ycsb_read_modify_write().clone(); - let res = ycsb_read_modify_write( - param.session_id(), - ::mudu_type::datum::value_to_typed::(¶m.param_list()[0], "String")?, - ::mudu_type::datum::value_to_typed::(¶m.param_list()[1], "String")?, - ) - .await; - let tuple = res; - Ok(::mudu_contract::procedure::procedure_result::ProcedureResult::from(tuple, &return_desc)?) -} +#[cfg(test)] +mod tests { + use super::{ycsb_insert, ycsb_read, ycsb_read_modify_write, ycsb_scan, ycsb_update}; + use crate::test_lock; + use std::path::PathBuf; + use std::time::{SystemTime, UNIX_EPOCH}; + use mududb::sys_interface::async_api::{mudu_close, mudu_open}; + + fn temp_db_path(name: &str) -> PathBuf { + let suffix = SystemTime::now() + .duration_since(UNIX_EPOCH) + .expect("system time before unix epoch") + .as_nanos(); + std::env::temp_dir().join(format!("ycsb_{name}_{suffix}.db")) + } -pub fn mudu_argv_desc_ycsb_read_modify_write() --> &'static ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc { - static ARGV_DESC: std::sync::OnceLock< - ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc, - > = std::sync::OnceLock::new(); - ARGV_DESC.get_or_init(|| { - <(String, String) as ::mudu_contract::tuple::tuple_datum::TupleDatum>::tuple_desc_static(&{ - let _vec: Vec = - <[_]>::into_vec(std::boxed::Box::new(["user_key", "append_value"])) - .iter() - .map(|s| s.to_string()) - .collect(); - _vec - }) - }) -} + #[test] + async fn ycsb_sync_procedures_roundtrip_against_standalone_adapter() { + let _guard = test_lock().lock().unwrap_or_else(|err| err.into_inner()); + let db_path = temp_db_path("sync"); + mudu_adapter::config::reset_db_path_override_for_test(); + mudu_adapter::syscall::set_db_path(&db_path); -pub fn mudu_result_desc_ycsb_read_modify_write() --> &'static ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc { - static RESULT_DESC: std::sync::OnceLock< - ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc, - > = std::sync::OnceLock::new(); - RESULT_DESC.get_or_init(|| { - <(String,) as ::mudu_contract::tuple::tuple_datum::TupleDatum>::tuple_desc_static(&[]) - }) -} + let xid = mudu_open().await.unwrap(); + ycsb_insert(xid, "u1".to_string(), "v1".to_string()).await.unwrap(); + ycsb_insert(xid, "u2".to_string(), "v2".to_string()).await.unwrap(); -pub fn mudu_proc_desc_ycsb_read_modify_write() --> &'static ::mudu_contract::procedure::proc_desc::ProcDesc { - static _PROC_DESC: std::sync::OnceLock<::mudu_contract::procedure::proc_desc::ProcDesc> = - std::sync::OnceLock::new(); - _PROC_DESC.get_or_init(|| { - ::mudu_contract::procedure::proc_desc::ProcDesc::new( - "ycsb".to_string(), - "ycsb_read_modify_write".to_string(), - mudu_argv_desc_ycsb_read_modify_write().clone(), - mudu_result_desc_ycsb_read_modify_write().clone(), - false, - ) - }) -} + assert_eq!(ycsb_read(xid, "u1".to_string()).unwrap(), "v1"); -mod mod_ycsb_read_modify_write { - wit_bindgen::generate!({ - inline: - r##"package mudu:mp2-ycsb-read-modify-write; - world mudu-app-mp2-ycsb-read-modify-write { - export mp2-ycsb-read-modify-write: func(param:list) -> list; - } - "##, - async: true - }); + ycsb_update(xid, "u1".to_string(), "v3".to_string()).await.unwrap(); + assert_eq!(ycsb_read(xid, "u1".to_string()).unwrap(), "v3"); - #[allow(non_camel_case_types)] - #[allow(unused)] - struct GuestYcsbReadModifyWrite {} + assert_eq!( + ycsb_scan(xid, "u1".to_string(), "uz".to_string()).unwrap(), + vec!["user/u1=v3".to_string(), "user/u2=v2".to_string()] + ); - impl Guest for GuestYcsbReadModifyWrite { - async fn mp2_ycsb_read_modify_write(param: Vec) -> Vec { - super::mp2_ycsb_read_modify_write(param).await - } - } + assert_eq!( + ycsb_read_modify_write(xid, "u1".to_string(), "-x".to_string()).unwrap(), + "v3-x" + ); - export!(GuestYcsbReadModifyWrite); + mudu_close(xid).await.unwrap(); + } } -async fn mp2_ycsb_read(param: Vec) -> Vec { - ::mudu_binding::procedure::procedure_invoke::invoke_procedure_async( +async fn mp2_ycsb_read(param:Vec) -> Vec { + ::mududb::binding::procedure::procedure_invoke::invoke_procedure_async( param, mudu_inner_p2_ycsb_read, - ) - .await + ).await } pub async fn mudu_inner_p2_ycsb_read( - param: ::mudu_contract::procedure::procedure_param::ProcedureParam, -) -> ::mudu::common::result::RS<::mudu_contract::procedure::procedure_result::ProcedureResult> { - let return_desc = mudu_result_desc_ycsb_read().clone(); + param: ::mududb::contract::procedure::procedure_param::ProcedureParam, +) -> ::mududb::common::result::RS< + ::mududb::contract::procedure::procedure_result::ProcedureResult, +> { let res = ycsb_read( param.session_id(), - ::mudu_type::datum::value_to_typed::(¶m.param_list()[0], "String")?, - ) - .await; - let tuple = res; - Ok(::mudu_contract::procedure::procedure_result::ProcedureResult::from(tuple, &return_desc)?) + + + ::mududb::types::datum::value_to_typed::< + String, + _, + >(¶m.param_list()[0], "String")?, + + + ).await; + match res { + Ok(tuple) => { + let return_list = { + + vec![ + + ::mududb::types::datum::value_from_typed(&tuple, "String")? + + ] + + }; + Ok(::mududb::contract::procedure::procedure_result::ProcedureResult::new(return_list)) + } + Err(e) => Err(e), + } } -pub fn mudu_argv_desc_ycsb_read() --> &'static ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc { - static ARGV_DESC: std::sync::OnceLock< - ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc, - > = std::sync::OnceLock::new(); - ARGV_DESC.get_or_init(|| { - <(String,) as ::mudu_contract::tuple::tuple_datum::TupleDatum>::tuple_desc_static(&{ - let _vec: Vec = <[_]>::into_vec(std::boxed::Box::new(["user_key"])) - .iter() - .map(|s| s.to_string()) - .collect(); - _vec - }) - }) +pub fn mudu_argv_desc_ycsb_read() -> &'static ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc { + static ARGV_DESC: std::sync::OnceLock<::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc> = + std::sync::OnceLock::new(); + ARGV_DESC.get_or_init(|| + { + ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc::new(vec![ + + ::mududb::contract::tuple::datum_desc::DatumDesc::new( + "user_key".to_string(), + + ::dat_type().clone() + + ), + + ]) + } + ) } -pub fn mudu_result_desc_ycsb_read() --> &'static ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc { - static RESULT_DESC: std::sync::OnceLock< - ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc, - > = std::sync::OnceLock::new(); - RESULT_DESC.get_or_init(|| { - <(String,) as ::mudu_contract::tuple::tuple_datum::TupleDatum>::tuple_desc_static(&[]) - }) +pub fn mudu_result_desc_ycsb_read() -> &'static ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc { + static RESULT_DESC: std::sync::OnceLock<::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc> = + std::sync::OnceLock::new(); + RESULT_DESC.get_or_init(|| + { + ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc::new(vec![ + + ::mududb::contract::tuple::datum_desc::DatumDesc::new( + "0".to_string(), + + ::dat_type().clone() + + ), + + ]) + } + ) } -pub fn mudu_proc_desc_ycsb_read() -> &'static ::mudu_contract::procedure::proc_desc::ProcDesc { - static _PROC_DESC: std::sync::OnceLock<::mudu_contract::procedure::proc_desc::ProcDesc> = - std::sync::OnceLock::new(); - _PROC_DESC.get_or_init(|| { - ::mudu_contract::procedure::proc_desc::ProcDesc::new( - "ycsb".to_string(), - "ycsb_read".to_string(), - mudu_argv_desc_ycsb_read().clone(), - mudu_result_desc_ycsb_read().clone(), - false, - ) - }) +pub fn mudu_proc_desc_ycsb_read() -> &'static ::mududb::contract::procedure::proc_desc::ProcDesc { + static _PROC_DESC: std::sync::OnceLock< + ::mududb::contract::procedure::proc_desc::ProcDesc, + > = std::sync::OnceLock::new(); + _PROC_DESC + .get_or_init(|| { + ::mududb::contract::procedure::proc_desc::ProcDesc::new( + "ycsb".to_string(), + "ycsb_read".to_string(), + mudu_argv_desc_ycsb_read().clone(), + mudu_result_desc_ycsb_read().clone(), + false + ) + }) } mod mod_ycsb_read { @@ -239,73 +212,108 @@ mod mod_ycsb_read { struct GuestYcsbRead {} impl Guest for GuestYcsbRead { - async fn mp2_ycsb_read(param: Vec) -> Vec { + async fn mp2_ycsb_read(param:Vec) -> Vec { super::mp2_ycsb_read(param).await } } export!(GuestYcsbRead); } -async fn mp2_ycsb_update(param: Vec) -> Vec { - ::mudu_binding::procedure::procedure_invoke::invoke_procedure_async( +async fn mp2_ycsb_update(param:Vec) -> Vec { + ::mududb::binding::procedure::procedure_invoke::invoke_procedure_async( param, mudu_inner_p2_ycsb_update, - ) - .await + ).await } pub async fn mudu_inner_p2_ycsb_update( - param: ::mudu_contract::procedure::procedure_param::ProcedureParam, -) -> ::mudu::common::result::RS<::mudu_contract::procedure::procedure_result::ProcedureResult> { - let return_desc = mudu_result_desc_ycsb_update().clone(); + param: ::mududb::contract::procedure::procedure_param::ProcedureParam, +) -> ::mududb::common::result::RS< + ::mududb::contract::procedure::procedure_result::ProcedureResult, +> { let res = ycsb_update( param.session_id(), - ::mudu_type::datum::value_to_typed::(¶m.param_list()[0], "String")?, - ::mudu_type::datum::value_to_typed::(¶m.param_list()[1], "String")?, - ) - .await; - let tuple = res; - Ok(::mudu_contract::procedure::procedure_result::ProcedureResult::from(tuple, &return_desc)?) + + + ::mududb::types::datum::value_to_typed::< + String, + _, + >(¶m.param_list()[0], "String")?, + + + + ::mududb::types::datum::value_to_typed::< + String, + _, + >(¶m.param_list()[1], "String")?, + + + ).await; + match res { + Ok(tuple) => { + let return_list = { + + vec![] + + }; + Ok(::mududb::contract::procedure::procedure_result::ProcedureResult::new(return_list)) + } + Err(e) => Err(e), + } } -pub fn mudu_argv_desc_ycsb_update() --> &'static ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc { - static ARGV_DESC: std::sync::OnceLock< - ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc, - > = std::sync::OnceLock::new(); - ARGV_DESC.get_or_init(|| { - <(String, String) as ::mudu_contract::tuple::tuple_datum::TupleDatum>::tuple_desc_static(&{ - let _vec: Vec = <[_]>::into_vec(std::boxed::Box::new(["user_key", "value"])) - .iter() - .map(|s| s.to_string()) - .collect(); - _vec - }) - }) +pub fn mudu_argv_desc_ycsb_update() -> &'static ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc { + static ARGV_DESC: std::sync::OnceLock<::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc> = + std::sync::OnceLock::new(); + ARGV_DESC.get_or_init(|| + { + ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc::new(vec![ + + ::mududb::contract::tuple::datum_desc::DatumDesc::new( + "user_key".to_string(), + + ::dat_type().clone() + + ), + + ::mududb::contract::tuple::datum_desc::DatumDesc::new( + "value".to_string(), + + ::dat_type().clone() + + ), + + ]) + } + ) } -pub fn mudu_result_desc_ycsb_update() --> &'static ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc { - static RESULT_DESC: std::sync::OnceLock< - ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc, - > = std::sync::OnceLock::new(); - RESULT_DESC.get_or_init(|| { - <() as ::mudu_contract::tuple::tuple_datum::TupleDatum>::tuple_desc_static(&[]) - }) +pub fn mudu_result_desc_ycsb_update() -> &'static ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc { + static RESULT_DESC: std::sync::OnceLock<::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc> = + std::sync::OnceLock::new(); + RESULT_DESC.get_or_init(|| + { + ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc::new(vec![ + + ]) + } + ) } -pub fn mudu_proc_desc_ycsb_update() -> &'static ::mudu_contract::procedure::proc_desc::ProcDesc { - static _PROC_DESC: std::sync::OnceLock<::mudu_contract::procedure::proc_desc::ProcDesc> = - std::sync::OnceLock::new(); - _PROC_DESC.get_or_init(|| { - ::mudu_contract::procedure::proc_desc::ProcDesc::new( - "ycsb".to_string(), - "ycsb_update".to_string(), - mudu_argv_desc_ycsb_update().clone(), - mudu_result_desc_ycsb_update().clone(), - false, - ) - }) +pub fn mudu_proc_desc_ycsb_update() -> &'static ::mududb::contract::procedure::proc_desc::ProcDesc { + static _PROC_DESC: std::sync::OnceLock< + ::mududb::contract::procedure::proc_desc::ProcDesc, + > = std::sync::OnceLock::new(); + _PROC_DESC + .get_or_init(|| { + ::mududb::contract::procedure::proc_desc::ProcDesc::new( + "ycsb".to_string(), + "ycsb_update".to_string(), + mudu_argv_desc_ycsb_update().clone(), + mudu_result_desc_ycsb_update().clone(), + false + ) + }) } mod mod_ycsb_update { @@ -324,74 +332,119 @@ mod mod_ycsb_update { struct GuestYcsbUpdate {} impl Guest for GuestYcsbUpdate { - async fn mp2_ycsb_update(param: Vec) -> Vec { + async fn mp2_ycsb_update(param:Vec) -> Vec { super::mp2_ycsb_update(param).await } } export!(GuestYcsbUpdate); } -async fn mp2_ycsb_scan(param: Vec) -> Vec { - ::mudu_binding::procedure::procedure_invoke::invoke_procedure_async( +async fn mp2_ycsb_scan(param:Vec) -> Vec { + ::mududb::binding::procedure::procedure_invoke::invoke_procedure_async( param, mudu_inner_p2_ycsb_scan, - ) - .await + ).await } pub async fn mudu_inner_p2_ycsb_scan( - param: ::mudu_contract::procedure::procedure_param::ProcedureParam, -) -> ::mudu::common::result::RS<::mudu_contract::procedure::procedure_result::ProcedureResult> { - let return_desc = mudu_result_desc_ycsb_scan().clone(); + param: ::mududb::contract::procedure::procedure_param::ProcedureParam, +) -> ::mududb::common::result::RS< + ::mududb::contract::procedure::procedure_result::ProcedureResult, +> { let res = ycsb_scan( param.session_id(), - ::mudu_type::datum::value_to_typed::(¶m.param_list()[0], "String")?, - ::mudu_type::datum::value_to_typed::(¶m.param_list()[1], "String")?, - ) - .await; - let tuple = res; - Ok(::mudu_contract::procedure::procedure_result::ProcedureResult::from(tuple, &return_desc)?) + + + ::mududb::types::datum::value_to_typed::< + String, + _, + >(¶m.param_list()[0], "String")?, + + + + ::mududb::types::datum::value_to_typed::< + String, + _, + >(¶m.param_list()[1], "String")?, + + + ).await; + match res { + Ok(tuple) => { + let return_list = { + + vec![ + + ::mududb::types::datum::value_from_typed(&tuple, "Vec")? + + ] + + }; + Ok(::mududb::contract::procedure::procedure_result::ProcedureResult::new(return_list)) + } + Err(e) => Err(e), + } } -pub fn mudu_argv_desc_ycsb_scan() --> &'static ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc { - static ARGV_DESC: std::sync::OnceLock< - ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc, - > = std::sync::OnceLock::new(); - ARGV_DESC.get_or_init(|| { - <(String, String) as ::mudu_contract::tuple::tuple_datum::TupleDatum>::tuple_desc_static(&{ - let _vec: Vec = - <[_]>::into_vec(std::boxed::Box::new(["start_user_key", "end_user_key"])) - .iter() - .map(|s| s.to_string()) - .collect(); - _vec - }) - }) +pub fn mudu_argv_desc_ycsb_scan() -> &'static ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc { + static ARGV_DESC: std::sync::OnceLock<::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc> = + std::sync::OnceLock::new(); + ARGV_DESC.get_or_init(|| + { + ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc::new(vec![ + + ::mududb::contract::tuple::datum_desc::DatumDesc::new( + "start_user_key".to_string(), + + ::dat_type().clone() + + ), + + ::mududb::contract::tuple::datum_desc::DatumDesc::new( + "end_user_key".to_string(), + + ::dat_type().clone() + + ), + + ]) + } + ) } -pub fn mudu_result_desc_ycsb_scan() --> &'static ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc { - static RESULT_DESC: std::sync::OnceLock< - ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc, - > = std::sync::OnceLock::new(); - RESULT_DESC.get_or_init(|| { - <(Vec,) as ::mudu_contract::tuple::tuple_datum::TupleDatum>::tuple_desc_static(&[]) - }) +pub fn mudu_result_desc_ycsb_scan() -> &'static ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc { + static RESULT_DESC: std::sync::OnceLock<::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc> = + std::sync::OnceLock::new(); + RESULT_DESC.get_or_init(|| + { + ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc::new(vec![ + + ::mududb::contract::tuple::datum_desc::DatumDesc::new( + "0".to_string(), + + as ::mududb::types::datum::Datum>::dat_type().clone() + + ), + + ]) + } + ) } -pub fn mudu_proc_desc_ycsb_scan() -> &'static ::mudu_contract::procedure::proc_desc::ProcDesc { - static _PROC_DESC: std::sync::OnceLock<::mudu_contract::procedure::proc_desc::ProcDesc> = - std::sync::OnceLock::new(); - _PROC_DESC.get_or_init(|| { - ::mudu_contract::procedure::proc_desc::ProcDesc::new( - "ycsb".to_string(), - "ycsb_scan".to_string(), - mudu_argv_desc_ycsb_scan().clone(), - mudu_result_desc_ycsb_scan().clone(), - false, - ) - }) +pub fn mudu_proc_desc_ycsb_scan() -> &'static ::mududb::contract::procedure::proc_desc::ProcDesc { + static _PROC_DESC: std::sync::OnceLock< + ::mududb::contract::procedure::proc_desc::ProcDesc, + > = std::sync::OnceLock::new(); + _PROC_DESC + .get_or_init(|| { + ::mududb::contract::procedure::proc_desc::ProcDesc::new( + "ycsb".to_string(), + "ycsb_scan".to_string(), + mudu_argv_desc_ycsb_scan().clone(), + mudu_result_desc_ycsb_scan().clone(), + false + ) + }) } mod mod_ycsb_scan { @@ -410,73 +463,239 @@ mod mod_ycsb_scan { struct GuestYcsbScan {} impl Guest for GuestYcsbScan { - async fn mp2_ycsb_scan(param: Vec) -> Vec { + async fn mp2_ycsb_scan(param:Vec) -> Vec { super::mp2_ycsb_scan(param).await } } export!(GuestYcsbScan); } -async fn mp2_ycsb_insert(param: Vec) -> Vec { - ::mudu_binding::procedure::procedure_invoke::invoke_procedure_async( +async fn mp2_ycsb_read_modify_write(param:Vec) -> Vec { + ::mududb::binding::procedure::procedure_invoke::invoke_procedure_async( param, - mudu_inner_p2_ycsb_insert, - ) - .await + mudu_inner_p2_ycsb_read_modify_write, + ).await } -pub async fn mudu_inner_p2_ycsb_insert( - param: ::mudu_contract::procedure::procedure_param::ProcedureParam, -) -> ::mudu::common::result::RS<::mudu_contract::procedure::procedure_result::ProcedureResult> { - let return_desc = mudu_result_desc_ycsb_insert().clone(); - let res = ycsb_insert( +pub async fn mudu_inner_p2_ycsb_read_modify_write( + param: ::mududb::contract::procedure::procedure_param::ProcedureParam, +) -> ::mududb::common::result::RS< + ::mududb::contract::procedure::procedure_result::ProcedureResult, +> { + let res = ycsb_read_modify_write( param.session_id(), - ::mudu_type::datum::value_to_typed::(¶m.param_list()[0], "String")?, - ::mudu_type::datum::value_to_typed::(¶m.param_list()[1], "String")?, + + + ::mududb::types::datum::value_to_typed::< + String, + _, + >(¶m.param_list()[0], "String")?, + + + + ::mududb::types::datum::value_to_typed::< + String, + _, + >(¶m.param_list()[1], "String")?, + + + ).await; + match res { + Ok(tuple) => { + let return_list = { + + vec![ + + ::mududb::types::datum::value_from_typed(&tuple, "String")? + + ] + + }; + Ok(::mududb::contract::procedure::procedure_result::ProcedureResult::new(return_list)) + } + Err(e) => Err(e), + } +} + +pub fn mudu_argv_desc_ycsb_read_modify_write() -> &'static ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc { + static ARGV_DESC: std::sync::OnceLock<::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc> = + std::sync::OnceLock::new(); + ARGV_DESC.get_or_init(|| + { + ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc::new(vec![ + + ::mududb::contract::tuple::datum_desc::DatumDesc::new( + "user_key".to_string(), + + ::dat_type().clone() + + ), + + ::mududb::contract::tuple::datum_desc::DatumDesc::new( + "append_value".to_string(), + + ::dat_type().clone() + + ), + + ]) + } ) - .await; - let tuple = res; - Ok(::mudu_contract::procedure::procedure_result::ProcedureResult::from(tuple, &return_desc)?) } -pub fn mudu_argv_desc_ycsb_insert() --> &'static ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc { - static ARGV_DESC: std::sync::OnceLock< - ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc, +pub fn mudu_result_desc_ycsb_read_modify_write() -> &'static ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc { + static RESULT_DESC: std::sync::OnceLock<::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc> = + std::sync::OnceLock::new(); + RESULT_DESC.get_or_init(|| + { + ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc::new(vec![ + + ::mududb::contract::tuple::datum_desc::DatumDesc::new( + "0".to_string(), + + ::dat_type().clone() + + ), + + ]) + } + ) +} + +pub fn mudu_proc_desc_ycsb_read_modify_write() -> &'static ::mududb::contract::procedure::proc_desc::ProcDesc { + static _PROC_DESC: std::sync::OnceLock< + ::mududb::contract::procedure::proc_desc::ProcDesc, > = std::sync::OnceLock::new(); - ARGV_DESC.get_or_init(|| { - <(String, String) as ::mudu_contract::tuple::tuple_datum::TupleDatum>::tuple_desc_static(&{ - let _vec: Vec = <[_]>::into_vec(std::boxed::Box::new(["user_key", "value"])) - .iter() - .map(|s| s.to_string()) - .collect(); - _vec + _PROC_DESC + .get_or_init(|| { + ::mududb::contract::procedure::proc_desc::ProcDesc::new( + "ycsb".to_string(), + "ycsb_read_modify_write".to_string(), + mudu_argv_desc_ycsb_read_modify_write().clone(), + mudu_result_desc_ycsb_read_modify_write().clone(), + false + ) }) - }) } -pub fn mudu_result_desc_ycsb_insert() --> &'static ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc { - static RESULT_DESC: std::sync::OnceLock< - ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc, - > = std::sync::OnceLock::new(); - RESULT_DESC.get_or_init(|| { - <() as ::mudu_contract::tuple::tuple_datum::TupleDatum>::tuple_desc_static(&[]) - }) +mod mod_ycsb_read_modify_write { + wit_bindgen::generate!({ + inline: + r##"package mudu:mp2-ycsb-read-modify-write; + world mudu-app-mp2-ycsb-read-modify-write { + export mp2-ycsb-read-modify-write: func(param:list) -> list; + } + "##, + async: true + }); + + #[allow(non_camel_case_types)] + #[allow(unused)] + struct GuestYcsbReadModifyWrite {} + + impl Guest for GuestYcsbReadModifyWrite { + async fn mp2_ycsb_read_modify_write(param:Vec) -> Vec { + super::mp2_ycsb_read_modify_write(param).await + } + } + + export!(GuestYcsbReadModifyWrite); +} +async fn mp2_ycsb_insert(param:Vec) -> Vec { + ::mududb::binding::procedure::procedure_invoke::invoke_procedure_async( + param, + mudu_inner_p2_ycsb_insert, + ).await } -pub fn mudu_proc_desc_ycsb_insert() -> &'static ::mudu_contract::procedure::proc_desc::ProcDesc { - static _PROC_DESC: std::sync::OnceLock<::mudu_contract::procedure::proc_desc::ProcDesc> = +pub async fn mudu_inner_p2_ycsb_insert( + param: ::mududb::contract::procedure::procedure_param::ProcedureParam, +) -> ::mududb::common::result::RS< + ::mududb::contract::procedure::procedure_result::ProcedureResult, +> { + let res = ycsb_insert( + param.session_id(), + + + ::mududb::types::datum::value_to_typed::< + String, + _, + >(¶m.param_list()[0], "String")?, + + + + ::mududb::types::datum::value_to_typed::< + String, + _, + >(¶m.param_list()[1], "String")?, + + + ).await; + match res { + Ok(tuple) => { + let return_list = { + + vec![] + + }; + Ok(::mududb::contract::procedure::procedure_result::ProcedureResult::new(return_list)) + } + Err(e) => Err(e), + } +} + +pub fn mudu_argv_desc_ycsb_insert() -> &'static ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc { + static ARGV_DESC: std::sync::OnceLock<::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc> = + std::sync::OnceLock::new(); + ARGV_DESC.get_or_init(|| + { + ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc::new(vec![ + + ::mududb::contract::tuple::datum_desc::DatumDesc::new( + "user_key".to_string(), + + ::dat_type().clone() + + ), + + ::mududb::contract::tuple::datum_desc::DatumDesc::new( + "value".to_string(), + + ::dat_type().clone() + + ), + + ]) + } + ) +} + +pub fn mudu_result_desc_ycsb_insert() -> &'static ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc { + static RESULT_DESC: std::sync::OnceLock<::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc> = std::sync::OnceLock::new(); - _PROC_DESC.get_or_init(|| { - ::mudu_contract::procedure::proc_desc::ProcDesc::new( - "ycsb".to_string(), - "ycsb_insert".to_string(), - mudu_argv_desc_ycsb_insert().clone(), - mudu_result_desc_ycsb_insert().clone(), - false, - ) - }) + RESULT_DESC.get_or_init(|| + { + ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc::new(vec![ + + ]) + } + ) +} + +pub fn mudu_proc_desc_ycsb_insert() -> &'static ::mududb::contract::procedure::proc_desc::ProcDesc { + static _PROC_DESC: std::sync::OnceLock< + ::mududb::contract::procedure::proc_desc::ProcDesc, + > = std::sync::OnceLock::new(); + _PROC_DESC + .get_or_init(|| { + ::mududb::contract::procedure::proc_desc::ProcDesc::new( + "ycsb".to_string(), + "ycsb_insert".to_string(), + mudu_argv_desc_ycsb_insert().clone(), + mudu_result_desc_ycsb_insert().clone(), + false + ) + }) } mod mod_ycsb_insert { @@ -495,10 +714,10 @@ mod mod_ycsb_insert { struct GuestYcsbInsert {} impl Guest for GuestYcsbInsert { - async fn mp2_ycsb_insert(param: Vec) -> Vec { + async fn mp2_ycsb_insert(param:Vec) -> Vec { super::mp2_ycsb_insert(param).await } } export!(GuestYcsbInsert); -} +} \ No newline at end of file diff --git a/example/ycsb/src/generated/procedure_common.rs b/example/ycsb/src/generated/procedure_common.rs new file mode 100644 index 0000000..f56ff85 --- /dev/null +++ b/example/ycsb/src/generated/procedure_common.rs @@ -0,0 +1,17 @@ +use mududb::common::result::RS; +use mududb::error::ec::EC; +use mududb::m_error; + +pub fn kv_data_key(user_key: &str) -> String { + format!("user/{user_key}") +} + +pub fn decode_utf8(label: &str, bytes: Vec) -> RS { + String::from_utf8(bytes).map_err(|e| { + m_error!( + EC::DecodeErr, + format!("invalid utf8 in ycsb {label}"), + e.to_string() + ) + }) +} \ No newline at end of file diff --git a/example/ycsb/src/rust/mod.rs b/example/ycsb/src/rust/mod.rs index a71b14a..9568eb6 100644 --- a/example/ycsb/src/rust/mod.rs +++ b/example/ycsb/src/rust/mod.rs @@ -1,3 +1,2 @@ pub mod procedure; -pub mod procedure_async; mod procedure_common; diff --git a/example/ycsb/src/rust/procedure.rs b/example/ycsb/src/rust/procedure.rs index e58c757..e2b39af 100644 --- a/example/ycsb/src/rust/procedure.rs +++ b/example/ycsb/src/rust/procedure.rs @@ -1,9 +1,9 @@ use crate::rust::procedure_common::{decode_utf8, kv_data_key}; -use mudu::common::result::RS; -use mudu::common::xid::XID; -use mudu::error::ec::EC; -use mudu::m_error; -use sys_interface::sync_api::{mudu_get, mudu_put, mudu_range}; +use mududb::common::result::RS; +use mududb::common::xid::XID; +use mududb::error::ec::EC; +use mududb::m_error; +use mududb::sys_interface::sync_api::{mudu_get, mudu_put, mudu_range}; fn read_value(session_id: XID, user_key: &str) -> RS { let key = kv_data_key(user_key); @@ -63,7 +63,7 @@ mod tests { use crate::test_lock; use std::path::PathBuf; use std::time::{SystemTime, UNIX_EPOCH}; - use sys_interface::sync_api::{mudu_close, mudu_open}; + use mududb::sys_interface::sync_api::{mudu_close, mudu_open}; fn temp_db_path(name: &str) -> PathBuf { let suffix = SystemTime::now() diff --git a/example/ycsb/src/rust/procedure_async.rs b/example/ycsb/src/rust/procedure_async.rs deleted file mode 100644 index 21eb1c5..0000000 --- a/example/ycsb/src/rust/procedure_async.rs +++ /dev/null @@ -1,133 +0,0 @@ -use crate::rust::procedure_common::{decode_utf8, kv_data_key}; -use mudu::common::result::RS; -use mudu::common::xid::XID; -use mudu::error::ec::EC; -use mudu::m_error; -#[cfg(feature = "benchmark-runner")] -use mudu_utils::task_trace; -use sys_interface::async_api::{mudu_get, mudu_put, mudu_range}; - -#[cfg(not(feature = "benchmark-runner"))] -macro_rules! task_trace { - () => { - () - }; -} - -async fn read_value(session_id: XID, user_key: &str) -> RS { - let _ = task_trace!(); - let key = kv_data_key(user_key); - let value = mudu_get(session_id, key.as_bytes()) - .await? - .ok_or_else(|| m_error!(EC::NoneErr, format!("ycsb key not found: {user_key}")))?; - decode_utf8("value", value) -} - -pub async fn ycsb_insert(xid: XID, user_key: String, value: String) -> RS<()> { - let _ = task_trace!(); - let key = kv_data_key(&user_key); - mudu_put(xid, key.as_bytes(), value.as_bytes()).await -} - -pub async fn ycsb_read(xid: XID, user_key: String) -> RS { - let _ = task_trace!(); - read_value(xid, &user_key).await -} - -pub async fn ycsb_update(xid: XID, user_key: String, value: String) -> RS<()> { - let _ = task_trace!(); - let key = kv_data_key(&user_key); - let _ = mudu_get(xid, key.as_bytes()) - .await? - .ok_or_else(|| m_error!(EC::NoneErr, format!("ycsb key not found: {user_key}")))?; - mudu_put(xid, key.as_bytes(), value.as_bytes()).await -} - -pub async fn ycsb_scan(xid: XID, start_user_key: String, end_user_key: String) -> RS> { - let _ = task_trace!(); - let start_key = kv_data_key(&start_user_key); - let end_key = kv_data_key(&end_user_key); - let pairs = mudu_range(xid, start_key.as_bytes(), end_key.as_bytes()).await?; - let mut rows = Vec::with_capacity(pairs.len()); - for (key, value) in pairs { - let decoded_key = decode_utf8("scan key", key)?; - let decoded_value = decode_utf8("scan value", value)?; - rows.push(format!("{decoded_key}={decoded_value}")); - } - Ok(rows) -} - -pub async fn ycsb_read_modify_write( - xid: XID, - user_key: String, - append_value: String, -) -> RS { - let _ = task_trace!(); - let key = kv_data_key(&user_key); - let mut current = match mudu_get(xid, key.as_bytes()).await? { - Some(value) => decode_utf8("value", value)?, - None => String::new(), - }; - current.push_str(&append_value); - mudu_put(xid, key.as_bytes(), current.as_bytes()).await?; - Ok(current) -} - -#[cfg(test)] -mod tests { - use super::{ycsb_insert, ycsb_read, ycsb_read_modify_write, ycsb_scan, ycsb_update}; - use crate::test_lock; - use std::path::PathBuf; - use std::time::{SystemTime, UNIX_EPOCH}; - use sys_interface::async_api::{mudu_close, mudu_open}; - - fn temp_db_path(name: &str) -> PathBuf { - let suffix = SystemTime::now() - .duration_since(UNIX_EPOCH) - .expect("system time before unix epoch") - .as_nanos(); - std::env::temp_dir().join(format!("ycsb_async_{name}_{suffix}.db")) - } - - #[test] - fn ycsb_async_procedures_roundtrip_against_standalone_adapter() { - let _guard = test_lock().lock().unwrap_or_else(|err| err.into_inner()); - let runtime = tokio::runtime::Runtime::new().unwrap(); - runtime.block_on(async { - let db_path = temp_db_path("async"); - mudu_adapter::config::reset_db_path_override_for_test(); - mudu_adapter::syscall::set_db_path(&db_path); - - let xid = mudu_open().await.unwrap(); - ycsb_insert(xid, "u1".to_string(), "v1".to_string()) - .await - .unwrap(); - ycsb_insert(xid, "u2".to_string(), "v2".to_string()) - .await - .unwrap(); - - assert_eq!(ycsb_read(xid, "u1".to_string()).await.unwrap(), "v1"); - - ycsb_update(xid, "u1".to_string(), "v3".to_string()) - .await - .unwrap(); - assert_eq!(ycsb_read(xid, "u1".to_string()).await.unwrap(), "v3"); - - assert_eq!( - ycsb_scan(xid, "u1".to_string(), "uz".to_string()) - .await - .unwrap(), - vec!["user/u1=v3".to_string(), "user/u2=v2".to_string()] - ); - - assert_eq!( - ycsb_read_modify_write(xid, "u1".to_string(), "-x".to_string()) - .await - .unwrap(), - "v3-x" - ); - - mudu_close(xid).await.unwrap(); - }); - } -} diff --git a/example/ycsb/src/rust/procedure_common.rs b/example/ycsb/src/rust/procedure_common.rs index d5834eb..2b9c73a 100644 --- a/example/ycsb/src/rust/procedure_common.rs +++ b/example/ycsb/src/rust/procedure_common.rs @@ -1,6 +1,6 @@ -use mudu::common::result::RS; -use mudu::error::ec::EC; -use mudu::m_error; +use mududb::common::result::RS; +use mududb::error::ec::EC; +use mududb::m_error; pub fn kv_data_key(user_key: &str) -> String { format!("user/{user_key}") diff --git a/mudu_gen/templates/rust/entity.rs.jinja b/mudu_gen/templates/rust/entity.rs.jinja index 2cad2b3..c22cf4d 100644 --- a/mudu_gen/templates/rust/entity.rs.jinja +++ b/mudu_gen/templates/rust/entity.rs.jinja @@ -1,20 +1,20 @@ pub mod object { use lazy_static::lazy_static; -use mudu::common::result::RS; -use mudu_type::dat_binary::DatBinary; -use mudu_type::dat_textual::DatTextual; -use mudu_type::dat_type::DatType; -use mudu_type::dat_type_id::DatTypeID; -use mudu_type::dat_value::DatValue; -use mudu_type::datum::{Datum, DatumDyn}; -use mudu_contract::database::attr_field_access; -use mudu_contract::database::attr_value::AttrValue; -use mudu_contract::database::entity::Entity; -use mudu_contract::database::entity_utils; -use mudu_contract::tuple::datum_desc::DatumDesc; -use mudu_contract::tuple::tuple_field_desc::TupleFieldDesc; -use mudu_contract::tuple::tuple_datum::TupleDatumMarker; -use mudu_contract::database::sql_params::SQLParamMarker; +use mududb::common::result::RS; +use mududb::contract::database::attr_field_access; +use mududb::contract::database::attr_value::AttrValue; +use mududb::contract::database::entity::Entity; +use mududb::contract::database::entity_utils; +use mududb::contract::database::sql_params::SQLParamMarker; +use mududb::contract::tuple::datum_desc::DatumDesc; +use mududb::contract::tuple::tuple_field_desc::TupleFieldDesc; +use mududb::contract::tuple::tuple_datum::TupleDatumMarker; +use mududb::types::dat_binary::DatBinary; +use mududb::types::dat_textual::DatTextual; +use mududb::types::dat_type::DatType; +use mududb::types::dat_type_id::DatTypeID; +use mududb::types::dat_value::DatValue; +use mududb::types::datum::{Datum, DatumDyn}; // constant definition const {{ table.entity_name_const }}:&str = "{{ table.entity_name }}"; @@ -233,4 +233,4 @@ impl AttrValue<{{ field.data_type }}> for Attr{{ field.field_name_pascal_case }} } {% endfor %} -} \ No newline at end of file +} diff --git a/mudu_kernel/src/server/linux/perf_test.rs b/mudu_kernel/src/server/linux/perf_test.rs index d58d30a..17e62b4 100644 --- a/mudu_kernel/src/server/linux/perf_test.rs +++ b/mudu_kernel/src/server/linux/perf_test.rs @@ -227,6 +227,21 @@ fn candidate_port_ranges(ephemeral: &RangeInclusive) -> Vec bool { + let msg = err.to_string(); + msg.contains("io_uring_queue_init_params error") + || msg.contains("io_uring backend exited before becoming ready") +} + +fn maybe_skip_in_act() -> bool { + if !mudu_sys::io_uring_available() { + eprintln!("skip io_uring perf test: io_uring unavailable"); + true + } else { + false + } +} + async fn wait_for_clients_ready( clients: usize, ready_clients: &AtomicU64, @@ -268,26 +283,6 @@ fn perf_client_setup_timeout(clients: usize) -> Duration { Duration::from_secs(secs) } -async fn wait_until_server_ready_async(port: u16) { - let deadline = mudu_sys::time::instant_now() + Duration::from_secs(10); - while mudu_sys::time::instant_now() < deadline { - match TokioTcpStream::connect(("127.0.0.1", port)).await { - Ok(stream) => { - let _ = stream.set_nodelay(true); - let _ = stream - .into_std() - .and_then(|s| s.shutdown(std::net::Shutdown::Both)); - return; - } - Err(_) => {} - } - mudu_sys::task::sleep(Duration::from_millis(25)) - .await - .expect("linux sleep wrapper should not fail"); - } - panic!("io_uring backend did not become ready on port {}", port); -} - struct TestServerHandle { join_handle: thread::JoinHandle>, exit_rx: Receiver>, @@ -411,6 +406,9 @@ fn avg_us(samples: &[u64]) -> Option { #[tokio::test(flavor = "multi_thread", worker_threads = 2)] async fn iouring_backend_perf_put_get() -> RS<()> { + if maybe_skip_in_act() { + return Ok(()); + } let _guard = lock_network_perf_test(); log_setup("info"); let notifier = NotifyWait::new(); @@ -433,22 +431,15 @@ async fn iouring_backend_perf_put_get() -> RS<()> { )); std::fs::create_dir_all(&data_dir).unwrap(); - let (stop_notifier, server_stop) = notifier.notify_wait(); - let server_cfg = IoUringTcpServerConfig::new( - worker_count, - "127.0.0.1".to_string(), - port, - data_dir.to_string_lossy().into_owned(), - data_dir.to_string_lossy().into_owned(), - RoutingMode::ConnectionId, - None, - ) - .unwrap() - .with_prebound_listener(listener); - let server_thread = - thread::spawn(move || IoUringTcpBackend::sync_serve_with_stop(server_cfg, server_stop)); - - wait_until_server_ready_async(port).await; + let (stop_notifier, server_thread) = + spawn_iouring_server(listener, worker_count, &data_dir, 64 * 1024 * 1024, None); + if let Err(err) = wait_until_server_ready_or_exit_async(port, &server_thread).await { + if should_skip_iouring_perf(&err) { + eprintln!("skip io_uring perf test: {}", err); + return Ok(()); + } + return Err(err); + } let start_clients = Arc::new(AtomicBool::new(false)); let start_notify = Arc::new(Notify::new()); @@ -611,6 +602,9 @@ async fn iouring_backend_perf_put_get() -> RS<()> { #[tokio::test(flavor = "multi_thread", worker_threads = 2)] async fn iouring_backend_recovery_replays_worker_logs() -> RS<()> { + if maybe_skip_in_act() { + return Ok(()); + } let _guard = lock_network_perf_test(); let Some(listener) = reserve_listener() else { return Ok(()); @@ -632,7 +626,13 @@ async fn iouring_backend_recovery_replays_worker_logs() -> RS<()> { 64 * 1024 * 1024, Some(registry.clone()), ); - wait_until_server_ready_or_exit_async(port, &server_thread).await?; + if let Err(err) = wait_until_server_ready_or_exit_async(port, &server_thread).await { + if should_skip_iouring_perf(&err) { + eprintln!("skip io_uring recovery test: {}", err); + return Ok(()); + } + return Err(err); + } { let mut client = AsyncPerfClient::connect(port).await?; @@ -666,7 +666,13 @@ async fn iouring_backend_recovery_replays_worker_logs() -> RS<()> { 64 * 1024 * 1024, Some(registry.clone()), ); - wait_until_server_ready_or_exit_async(restart_port, &server_thread).await?; + if let Err(err) = wait_until_server_ready_or_exit_async(restart_port, &server_thread).await { + if should_skip_iouring_perf(&err) { + eprintln!("skip io_uring recovery restart test: {}", err); + return Ok(()); + } + return Err(err); + } { let mut client = AsyncPerfClient::connect(restart_port).await?; @@ -691,6 +697,9 @@ async fn iouring_backend_recovery_replays_worker_logs() -> RS<()> { #[tokio::test(flavor = "multi_thread", worker_threads = 2)] async fn iouring_backend_recovery_replays_across_multiple_chunks() -> RS<()> { + if maybe_skip_in_act() { + return Ok(()); + } let _guard = lock_network_perf_test(); let Some(listener) = reserve_listener() else { return Ok(()); @@ -712,7 +721,13 @@ async fn iouring_backend_recovery_replays_across_multiple_chunks() -> RS<()> { let (stop_notifier, server_thread) = spawn_iouring_server(listener, worker_count, &data_dir, log_chunk_size, None); - wait_until_server_ready_or_exit_async(port, &server_thread).await?; + if let Err(err) = wait_until_server_ready_or_exit_async(port, &server_thread).await { + if should_skip_iouring_perf(&err) { + eprintln!("skip io_uring multichunk recovery test: {}", err); + return Ok(()); + } + return Err(err); + } { let mut client = AsyncPerfClient::connect(port).await?; for (key, value) in &entries { @@ -745,7 +760,13 @@ async fn iouring_backend_recovery_replays_across_multiple_chunks() -> RS<()> { log_chunk_size, None, ); - wait_until_server_ready_or_exit_async(restart_port, &server_thread).await?; + if let Err(err) = wait_until_server_ready_or_exit_async(restart_port, &server_thread).await { + if should_skip_iouring_perf(&err) { + eprintln!("skip io_uring multichunk recovery restart test: {}", err); + return Ok(()); + } + return Err(err); + } { let mut client = AsyncPerfClient::connect(restart_port).await?; for (key, value) in &entries { @@ -760,6 +781,9 @@ async fn iouring_backend_recovery_replays_across_multiple_chunks() -> RS<()> { #[tokio::test(flavor = "multi_thread", worker_threads = 2)] async fn iouring_backend_open_session_routes_connection_to_requested_partition() -> RS<()> { + if maybe_skip_in_act() { + return Ok(()); + } let _guard = lock_network_perf_test(); let Some(listener) = reserve_listener() else { return Ok(()); @@ -788,7 +812,13 @@ async fn iouring_backend_open_session_routes_connection_to_requested_partition() 64 * 1024 * 1024, Some(registry.clone()), ); - wait_until_server_ready_or_exit_async(port, &server_thread).await?; + if let Err(err) = wait_until_server_ready_or_exit_async(port, &server_thread).await { + if should_skip_iouring_perf(&err) { + eprintln!("skip io_uring route test: {}", err); + return Ok(()); + } + return Err(err); + } { let mut client = AsyncPerfClient::connect(port).await?; @@ -837,6 +867,9 @@ async fn iouring_backend_open_session_routes_connection_to_requested_partition() #[tokio::test(flavor = "multi_thread", worker_threads = 2)] async fn iouring_backend_open_session_rebind_keeps_same_session_id() -> RS<()> { + if maybe_skip_in_act() { + return Ok(()); + } let _guard = lock_network_perf_test(); let Some(listener) = reserve_listener() else { return Ok(()); @@ -865,7 +898,13 @@ async fn iouring_backend_open_session_rebind_keeps_same_session_id() -> RS<()> { 64 * 1024 * 1024, Some(registry.clone()), ); - wait_until_server_ready_or_exit_async(port, &server_thread).await?; + if let Err(err) = wait_until_server_ready_or_exit_async(port, &server_thread).await { + if should_skip_iouring_perf(&err) { + eprintln!("skip io_uring rebind test: {}", err); + return Ok(()); + } + return Err(err); + } { let mut client = AsyncPerfClient::connect(port).await?; diff --git a/mudu_macro/Cargo.toml b/mudu_macro/Cargo.toml deleted file mode 100644 index 216013c..0000000 --- a/mudu_macro/Cargo.toml +++ /dev/null @@ -1,16 +0,0 @@ -[package] -name = "mudu_macro" -version = "0.1.0" -edition = "2024" - -[dependencies] -quote = "1.0.41" -syn = { version = "2.0.106", features = ["full"] } -mudu = { workspace = true } -proc-macro2 = { version = "1.0.103" } -mudu_type = {workspace = true} -mudu_contract = {workspace = true} -mudu_binding = {workspace = true} -wit-bindgen = { workspace = true } -[lib] -proc-macro = true \ No newline at end of file diff --git a/mudu_macro/expand.md b/mudu_macro/expand.md deleted file mode 100644 index 1a3189f..0000000 --- a/mudu_macro/expand.md +++ /dev/null @@ -1,4 +0,0 @@ -```bash -cargo +nightly install cargo-expand -cargo expand -``` \ No newline at end of file diff --git a/mudu_macro/src/lib.rs b/mudu_macro/src/lib.rs deleted file mode 100644 index 6adf9eb..0000000 --- a/mudu_macro/src/lib.rs +++ /dev/null @@ -1,360 +0,0 @@ -use mudu::common::result::RS; -use mudu::error::ec::EC; -use mudu::m_error; -use proc_macro::TokenStream; -use quote::{ToTokens, quote}; -use syn::{GenericArgument, ItemFn, PathArguments, ReturnType, Type, parse_macro_input}; - -const RESULT_TYPE_NAME: &str = "RS"; -#[proc_macro_attribute] -pub fn mudu_proc(_args: TokenStream, input: TokenStream) -> TokenStream { - let input_fn = parse_macro_input!(input as ItemFn); - - // function name - let fn_name = &input_fn.sig.ident; - let fn_name_str = fn_name.to_string(); - let fn_proc_p2_str = format!( - "{}{}", - mudu_contract::procedure::proc::MUDU_PROC_P2_PREFIX, - fn_name - ); - - let fn_wrapper_p2_ident = syn::Ident::new( - &format!( - "{}{}", - mudu_contract::procedure::proc::MUDU_PROC_P2_PREFIX, - fn_name - ), - fn_name.span(), - ); - - let exported_mod = syn::Ident::new( - &format!( - "mod_{}{}", - mudu_contract::procedure::proc::MUDU_PROC_P2_PREFIX, - fn_name - ), - fn_name.span(), - ); - let component_ident = syn::Ident::new( - &format!( - "Component{}", - ::mudu::utils::case_convert::to_pascal_case(&fn_name_str) - ), - fn_name.span(), - ); - - let fn_inner_ident = syn::Ident::new( - &format!( - "{}{}", - mudu_contract::procedure::proc::MUDU_PROC_INNER_PREFIX, - fn_name - ), - fn_name.span(), - ); - - let fn_inner_ident_p2 = syn::Ident::new( - &format!( - "{}{}", - mudu_contract::procedure::proc::MUDU_PROC_INNER_PREFIX_P2, - fn_name - ), - fn_name.span(), - ); - - let fn_argv_desc = syn::Ident::new( - &format!( - "{}{}", - mudu_contract::procedure::proc::MUDU_PROC_ARGV_DESC_PREFIX, - fn_name - ), - fn_name.span(), - ); - let fn_result_desc = syn::Ident::new( - &format!( - "{}{}", - mudu_contract::procedure::proc::MUDU_PROC_RESULT_DESC_PREFIX, - fn_name - ), - fn_name.span(), - ); - let fn_proc_desc = syn::Ident::new( - &format!( - "{}{}", - mudu_contract::procedure::proc::MUDU_PROC_PROC_DESC_PREFIX, - fn_name - ), - fn_name.span(), - ); - - let mut types = Vec::new(); - let mut arg_names = Vec::new(); - let mut ty_string = Vec::new(); - let mut idents = Vec::new(); - for (i, input_arg) in input_fn.sig.inputs.iter().enumerate() { - if let syn::FnArg::Typed(pat_type) = input_arg { - if i == 0 { - // skip first argument xid:XID - continue; - } - - if let syn::Pat::Ident(pat_ident) = &*pat_type.pat { - idents.push(&pat_ident.ident); - let arg_name = pat_ident.ident.to_string(); - arg_names.push(arg_name); - ty_string.push(pat_type.ty.to_token_stream().to_string()); - types.push(&pat_type.ty); - } - } - } - - let code_arg_names = quote! { - { - let _vec: Vec = vec![ - #(#arg_names),* - ].iter().map(|s| s.to_string()).collect(); - _vec - } - }; - - // argument conversion - let mut param_conversions: Vec<_> = Vec::new(); - let mut param_conversions_p2: Vec<_> = Vec::new(); - for (i, ty) in types.iter().enumerate() { - let type_str = &ty_string[i]; - let _ident = idents[i]; - - param_conversions.push(quote! { - ::mudu_type::datum::binary_to_typed::<#ty, _>(¶m.param_vec()[#i], #type_str)? - }); - - param_conversions_p2.push(quote! { - ::mudu_type::datum::value_to_typed::<#ty, _>(¶m.param_list()[#i], #type_str)? - }) - } - - let (_ret_type, inner_type) = handle_return_type(&input_fn).unwrap(); - - let return_desc_construction = build_return_desc(&inner_type); - - let invoke_handling = { - quote! { - let return_desc = #return_desc_construction; - let res = #fn_name(param.session_id(), #(#param_conversions_p2),*); - let tuple = res; - Ok(::mudu_contract::procedure::procedure_result::ProcedureResult::from(tuple, &return_desc)?) - } - }; - - let exported = ::mudu::utils::case_convert::to_kebab_case(&fn_proc_p2_str); - let wit_inline = format!( - r##" -package mudu:{}; - -world mudu-app-{} {{ - export {}: func(param:list) -> list; -}} -"##, - exported, exported, exported - ); - - let output = quote! { - - #input_fn - mod #exported_mod{ - wit_bindgen::generate!({ - inline: #wit_inline, - }); - - #[allow(non_camel_case_types)] - #[allow(unused)] - struct #component_ident; - - impl Guest for #component_ident { - fn #fn_wrapper_p2_ident(param:Vec) -> Vec { - super::#fn_wrapper_p2_ident(param) - } - } - - export!(#component_ident); - } - - fn #fn_wrapper_p2_ident(param:Vec) -> Vec { - ::mudu_binding::procedure::procedure_invoke::invoke_procedure( - param, - #fn_inner_ident_p2 - ) - } - - pub fn #fn_inner_ident( - param: &::mudu_contract::procedure::procedure_param::ProcedureParam, - ) -> ::mudu::common::result::RS<::mudu_contract::procedure::procedure_result::ProcedureResult> { - // generate tuple desc - let desc = <(#(#types),*) as ::mudu_contract::tuple::tuple_datum::TupleDatum>::tuple_desc_static(&#code_arg_names); - - #invoke_handling - } - - pub fn #fn_inner_ident_p2( - param: ::mudu_contract::procedure::procedure_param::ProcedureParam, - ) -> ::mudu::common::result::RS<::mudu_contract::procedure::procedure_result::ProcedureResult> { - #fn_inner_ident(¶m) - } - - pub fn #fn_argv_desc() -> &'static ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc { - static ARGV_DESC: std::sync::OnceLock<::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc> = - std::sync::OnceLock::new(); - ARGV_DESC.get_or_init(|| - { - <(#(#types),*) as ::mudu_contract::tuple::tuple_datum::TupleDatum>::tuple_desc_static(&#code_arg_names) - } - ) - } - - pub fn #fn_result_desc() -> &'static ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc { - static RESULT_DESC: std::sync::OnceLock<::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc> = - std::sync::OnceLock::new(); - RESULT_DESC.get_or_init(|| - { - #return_desc_construction - } - ) - } - - pub fn #fn_proc_desc() -> &'static ::mudu_contract::procedure::proc_desc::ProcDesc { - static PROC_DESC: std::sync::OnceLock< - ::mudu_contract::procedure::proc_desc::ProcDesc, - > = std::sync::OnceLock::new(); - PROC_DESC - .get_or_init(|| { - ::mudu_contract::procedure::proc_desc::ProcDesc::new( - std::env!("CARGO_PKG_NAME").to_string(), - #fn_name_str.to_string(), - #fn_argv_desc().clone(), - #fn_result_desc().clone(), - false - ) - }) - } - - }; - - output.into() -} - -fn build_return_desc(inner_type: &Type) -> proc_macro2::TokenStream { - if is_vec_type(inner_type) { - // Vec - if let Type::Path(type_path) = inner_type { - if let Some(segment) = type_path.path.segments.last() { - if let PathArguments::AngleBracketed(args) = &segment.arguments { - if let Some(GenericArgument::Type(element_type)) = args.args.first() { - // for Vec,use T - return if is_tuple_type(element_type) { - // Vec<(T1, T2, ...)> - quote! { - <#element_type as ::mudu_contract::tuple::tuple_datum::TupleDatum>::tuple_desc_static(&[]) - } - } else { - // Vec - wrap with Vec<(T,)> - quote! { - <(#element_type,) as ::mudu_contract::tuple::tuple_datum::TupleDatum>::tuple_desc_static(&[]) - } - }; - } - } - } - } - } else if is_tuple_type(inner_type) { - // a tuple (T1, T2, ...) - return quote! { - <#inner_type as ::mudu_contract::tuple::tuple_datum::TupleDatum>::tuple_desc_static(&[]) - }; - } else { - // basic type T - use tuple (T,) - return quote! { - <(#inner_type,) as ::mudu_contract::tuple::tuple_datum::TupleDatum>::tuple_desc_static(&[]) - }; - } - - // default - quote! { - use ; - <() as ::mudu_contract::tuple::tuple_datum::TupleDatum>::tuple_desc_static(&[]) - } -} -// check if return a vec type -fn is_vec_type(ty: &Type) -> bool { - if let Type::Path(type_path) = ty { - if let Some(segment) = type_path.path.segments.last() { - if segment.ident == "Vec" { - return true; - } - } - } - false -} - -// check if return a tuple type -fn is_tuple_type(ty: &Type) -> bool { - if let Type::Tuple(_) = ty { - return true; - } - false -} - -// return (result type, inner type), eg. (Result, T) -fn handle_return_type(item_fn: &ItemFn) -> RS<(Type, Type)> { - let return_type = &item_fn.sig.output; - let box_type = match return_type { - ReturnType::Default => { - panic!("A Mudu Procedure cannot return \"()\"") - } - ReturnType::Type(_, ty) => ty, - }; - let ty_path = if let Type::Path(type_path) = &(**box_type) { - if let Some(segment) = type_path.path.segments.last() { - if segment.ident == RESULT_TYPE_NAME { - type_path - } else { - return Err(m_error!( - EC::ParseErr, - format!("Expected Result type, found {}", segment.ident) - )); - } - } else { - return Err(m_error!(EC::ParseErr, "Expected Result type")); - } - } else { - return Err(m_error!(EC::ParseErr, "Expected Result type")); - }; - - // test generics parameters, it must be RS, - let generics = if let PathArguments::AngleBracketed(args) = - &ty_path.path.segments.last().unwrap().arguments - { - &args.args - } else { - return Err(m_error!( - EC::ParseErr, - "Result type must have generic parameters" - )); - }; - if generics.len() != 1 { - return Err(m_error!( - EC::ParseErr, - format!( - "Result must have exactly 2 generic parameters, found {}", - generics.len() - ) - )); - } - - // retrieve T and E type in Result - let t_type = match &generics[0] { - GenericArgument::Type(ty) => ty, - _ => return Err(m_error!(EC::ParseErr, "Expected type parameter for T")), - }; - - Ok((*box_type.clone(), t_type.clone())) -} diff --git a/mudu_macro/wit/procedure.wit b/mudu_macro/wit/procedure.wit deleted file mode 100644 index 2cc3f1c..0000000 --- a/mudu_macro/wit/procedure.wit +++ /dev/null @@ -1,5 +0,0 @@ -package mudu_macro:procedure; - -world procedure { - export proc-func: func(param: list) -> result, vec>; -} \ No newline at end of file diff --git a/mudu_macro_test/Cargo.toml b/mudu_macro_test/Cargo.toml deleted file mode 100644 index e62d2a2..0000000 --- a/mudu_macro_test/Cargo.toml +++ /dev/null @@ -1,12 +0,0 @@ -[package] -name = "mudu_macro_test" -version = "0.1.0" -edition = "2024" - -[dependencies] -mudu_macro = { workspace = true } -mudu = { workspace = true } -mudu_contract = { workspace = true } -mudu_type = { workspace = true } -mudu_binding = {workspace = true} -wit-bindgen = { workspace = true } \ No newline at end of file diff --git a/mudu_macro_test/src/lib.rs b/mudu_macro_test/src/lib.rs deleted file mode 100644 index 8b13789..0000000 --- a/mudu_macro_test/src/lib.rs +++ /dev/null @@ -1 +0,0 @@ - diff --git a/mudu_macro_test/tests/mm_test.rs b/mudu_macro_test/tests/mm_test.rs deleted file mode 100644 index 8013c46..0000000 --- a/mudu_macro_test/tests/mm_test.rs +++ /dev/null @@ -1,61 +0,0 @@ -#[cfg(test)] -mod tests { - use mudu::common::result::RS; - use mudu::common::xid::XID; - use mudu_contract::procedure::procedure_param::ProcedureParam; - use mudu_contract::tuple::tuple_datum::TupleDatum; - use mudu_macro::mudu_proc; - - #[mudu_proc] - pub fn example(xid: XID, a: i32, b: i64, c: String) -> RS<(i64, String)> { - Ok(( - a as i64 + b + 1, - format!("c={}, {} function invoked", c, xid), - )) - } - - #[mudu_proc] - pub fn test_proc2(xid: XID, a: i32) -> RS { - Ok(format!("a {}, {} function invoked", a, xid)) - } - - #[mudu_proc] - pub fn example_vec(xid: XID, a: i32, b: Vec) -> RS<(Vec, String)> { - Ok(( - vec![a as i64, (a + 1) as i64], - format!("a {}, b:{:?}, {} function invoked", a, b, xid), - )) - } - - #[test] - fn test_mudu_macro2() { - let param = ProcedureParam::from_tuple( - 1, - (1i32, 3i64, "string".to_string()), - &<(i32, i64, String)>::tuple_desc_static(&[ - "p1".to_string(), - "p2".to_string(), - "p3".to_string(), - ]), - ) - .unwrap(); - let result = mudu_inner_example(¶m); - println!("result {:?}", result) - } - - #[test] - fn test_mudu_macro_macro_mp2() { - let proc_desc = mudu_proc_desc_example(); - let argv = ProcedureParam::from_datum_vec( - 0, - &[&32i32, &64i64, &"s".to_string()], - proc_desc.param_desc(), - ) - .unwrap(); - let param = mudu_binding::procedure::procedure_invoke::serialize_param(argv).unwrap(); - let result_binary = mp2_example(param); - let result = mudu_binding::procedure::procedure_invoke::deserialize_result(&result_binary); - assert!(result.is_ok()); - println!("Test passed!, result {:?}", result); - } -} diff --git a/mudu_runtime/src/backend/linux/server_ur/test_mpk.rs b/mudu_runtime/src/backend/linux/server_ur/test_mpk.rs index 868ea34..31a5ce2 100644 --- a/mudu_runtime/src/backend/linux/server_ur/test_mpk.rs +++ b/mudu_runtime/src/backend/linux/server_ur/test_mpk.rs @@ -12,6 +12,7 @@ use mudu_contract::tuple::tuple_datum::TupleDatum; use mudu_kernel::server::async_func_runtime::AsyncFuncInvokerPtr; use mudu_kernel::server::routing::RoutingMode as KernelRoutingMode; use mudu_kernel::server::server::{IoUringTcpBackend, IoUringTcpServerConfig}; +use mudu_utils::log::log_setup; use mudu_utils::notifier::notify_wait; use std::env::temp_dir; use std::net::TcpListener; @@ -19,6 +20,7 @@ use std::path::{Path, PathBuf}; use std::process::Command; use std::thread; use std::time::Duration; +use tracing::info; fn reserve_port() -> Option { match TcpListener::bind("127.0.0.1:0") { @@ -181,6 +183,13 @@ fn invoke_and_decode( #[test] #[ignore = "requires Linux io_uring, cargo make, wasm32-wasip2 target, and example/key-value package build"] fn kv_mpk_can_be_used_by_iouring_backend() -> RS<()> { + log_setup("info"); + if !mudu_sys::io_uring_available() { + info!("skip key-value io_uring test: io_uring unavailable"); + return Ok(()); + } + info!("enable key-value io_uring test: io_uring available"); + let package_path = ensure_kv_package_built()?; let mpk_dir = temp_dir_with_prefix("mududb_kv_mpk"); let data_dir = temp_dir_with_prefix("mududb_kv_data"); diff --git a/mudu_runtime/src/backend/sql_async_client_test.rs b/mudu_runtime/src/backend/sql_async_client_test.rs index 14c1f91..b515bce 100644 --- a/mudu_runtime/src/backend/sql_async_client_test.rs +++ b/mudu_runtime/src/backend/sql_async_client_test.rs @@ -17,6 +17,7 @@ mod tests { use std::time::{Duration, Instant}; use tokio::sync::Mutex as AsyncMutex; use tokio::time::{sleep, timeout}; + use tracing::info; lazy_static! { static ref SQL_ASYNC_BACKEND_TEST_LOCK: AsyncMutex<()> = AsyncMutex::new(()); @@ -55,6 +56,31 @@ mod tests { }) } + fn should_skip_iouring_test(err: &mudu::error::err::MError) -> bool { + let msg = err.to_string(); + msg.contains("connect io_uring tcp server error") + || msg.contains("io_uring_queue_init_params error") + || msg.contains("io_uring backend exited before becoming ready") + } + + fn should_skip_iouring_env() -> bool { + #[cfg(target_os = "linux")] + { + match mudu_sys::io_uring_available() { + true => false, + false => { + info!("skip io_uring async client test: io_uring unavailable"); + true + } + } + } + #[cfg(not(target_os = "linux"))] + { + eprintln!("skip io_uring async client test: non-linux target"); + true + } + } + async fn wait_for_client(addr: &str, timeout: Duration) -> RS { let deadline = Instant::now() + timeout; loop { @@ -126,6 +152,9 @@ mod tests { JoinHandle>, )>, > { + if should_skip_iouring_env() { + return None; + } let Some(cfg) = test_cfg() else { return None; }; @@ -137,6 +166,10 @@ mod tests { Err(err) => { stop_notifier.notify_all(); let _ = server.join(); + if should_skip_iouring_test(&err) { + eprintln!("skip io_uring async client test: {}", err); + return None; + } return Some(Err(err)); } }; @@ -151,6 +184,9 @@ mod tests { #[tokio::test(flavor = "multi_thread", worker_threads = 2)] async fn async_client_roundtrip_sql_crud_over_iouring_backend() -> RS<()> { + if should_skip_iouring_env() { + return Ok(()); + } let _guard = SQL_ASYNC_BACKEND_TEST_LOCK.lock().await; let Some(cfg) = test_cfg() else { return Ok(()); @@ -164,10 +200,8 @@ mod tests { Err(err) => { stop_notifier.notify_all(); let _ = server.join(); - if err - .to_string() - .contains("connect io_uring tcp server error") - { + if should_skip_iouring_test(&err) { + eprintln!("skip io_uring async client test: {}", err); return Ok(()); } return Err(err); @@ -232,6 +266,9 @@ mod tests { #[tokio::test(flavor = "multi_thread", worker_threads = 2)] async fn async_client_batch_executes_multiple_sql_commands() -> RS<()> { + if should_skip_iouring_env() { + return Ok(()); + } let _guard = SQL_ASYNC_BACKEND_TEST_LOCK.lock().await; let Some(cfg) = test_cfg() else { return Ok(()); @@ -245,10 +282,8 @@ mod tests { Err(err) => { stop_notifier.notify_all(); let _ = server.join(); - if err - .to_string() - .contains("connect io_uring tcp server error") - { + if should_skip_iouring_test(&err) { + eprintln!("skip io_uring async client test: {}", err); return Ok(()); } return Err(err); diff --git a/mudu_sys/src/lib.rs b/mudu_sys/src/lib.rs index 3529880..7626563 100644 --- a/mudu_sys/src/lib.rs +++ b/mudu_sys/src/lib.rs @@ -20,3 +20,14 @@ pub mod random { pub mod time { pub use crate::api::time::{instant_now, system_time_now, utc_now}; } + +pub fn io_uring_available() -> bool { + #[cfg(target_os = "linux")] + { + crate::uring::IoUring::new(8).is_ok() + } + #[cfg(not(target_os = "linux"))] + { + false + } +} diff --git a/mudu_transpiler/src/rust/test_rs/proc1.rs b/mudu_transpiler/src/rust/test_rs/proc1.rs index 16d1a8d..f3e90c7 100644 --- a/mudu_transpiler/src/rust/test_rs/proc1.rs +++ b/mudu_transpiler/src/rust/test_rs/proc1.rs @@ -2,7 +2,6 @@ use crate::wasm::proc2::object::Wallets; use mudu::common::result::RS; use mudu::common::xid::XID; use mudu_contract::{sql_params, sql_stmt}; -use mudu_macro::mudu_proc; use mudu_type::datum::{Datum, DatumDyn}; use sys_interface::sync_api::{ mudu_close, mudu_command, mudu_get, mudu_open, mudu_put, mudu_query, mudu_range, diff --git a/mudu_transpiler/templates/rust/mudu_proc.rs.jinja b/mudu_transpiler/templates/rust/mudu_proc.rs.jinja index 316aee4..85038cc 100644 --- a/mudu_transpiler/templates/rust/mudu_proc.rs.jinja +++ b/mudu_transpiler/templates/rust/mudu_proc.rs.jinja @@ -1,24 +1,23 @@ {{procedure.opt_async }} fn {{ procedure.fn_exported_name }}(param:Vec) -> Vec { - ::mudu_binding::procedure::procedure_invoke::invoke_procedure{{procedure.opt_underline_async}}( + ::mududb::binding::procedure::procedure_invoke::invoke_procedure{{procedure.opt_underline_async}}( param, {{ procedure.fn_inner_name }}, ){{procedure.opt_dot_await }} } pub {{procedure.opt_async }} fn {{ procedure.fn_inner_name }}( - param: ::mudu_contract::procedure::procedure_param::ProcedureParam, -) -> ::mudu::common::result::RS< - ::mudu_contract::procedure::procedure_result::ProcedureResult, + param: ::mududb::contract::procedure::procedure_param::ProcedureParam, +) -> ::mududb::common::result::RS< + ::mududb::contract::procedure::procedure_result::ProcedureResult, > { - let return_desc = {{ procedure.fn_result_desc }}().clone(); let res = {{ procedure.fn_name }}( param.session_id(), {% for arg_info in procedure.argument_list %} {% if arg_info.is_binary %} param.param_list()[{{ arg_info.arg_index }}].expect_binary().clone(), {% else %} - ::mudu_type::datum::value_to_typed::< + ::mududb::types::datum::value_to_typed::< {{ arg_info.arg_type }}, _, >(¶m.param_list()[{{ arg_info.arg_index }}], "{{ arg_info.arg_type }}")?, @@ -33,9 +32,9 @@ pub {{procedure.opt_async }} fn {{ procedure.fn_inner_name }}( {% elif procedure.return_len == 1 %} vec![ {% if procedure.return_tuple[0].is_binary %} - ::mudu_type::dat_value::DatValue::from_binary(tuple) + ::mududb::types::dat_value::DatValue::from_binary(tuple) {% else %} - ::mudu_type::datum::value_from_typed(&tuple, "{{ procedure.return_tuple[0].ret_type }}")? + ::mududb::types::datum::value_from_typed(&tuple, "{{ procedure.return_tuple[0].ret_type }}")? {% endif %} ] {% else %} @@ -47,33 +46,33 @@ pub {{procedure.opt_async }} fn {{ procedure.fn_inner_name }}( vec![ {% for ret_info in procedure.return_tuple %} {% if ret_info.is_binary %} - ::mudu_type::dat_value::DatValue::from_binary(mudu_ret_{{ loop.index0 }}) + ::mududb::types::dat_value::DatValue::from_binary(mudu_ret_{{ loop.index0 }}) {% else %} - ::mudu_type::datum::value_from_typed(&mudu_ret_{{ loop.index0 }}, "{{ ret_info.ret_type }}")? + ::mududb::types::datum::value_from_typed(&mudu_ret_{{ loop.index0 }}, "{{ ret_info.ret_type }}")? {% endif %}, {% endfor %} ] {% endif %} }; - Ok(::mudu_contract::procedure::procedure_result::ProcedureResult::new(return_list)) + Ok(::mududb::contract::procedure::procedure_result::ProcedureResult::new(return_list)) } Err(e) => Err(e), } } -pub fn {{ procedure.fn_argv_desc }}() -> &'static ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc { - static ARGV_DESC: std::sync::OnceLock<::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc> = +pub fn {{ procedure.fn_argv_desc }}() -> &'static ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc { + static ARGV_DESC: std::sync::OnceLock<::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc> = std::sync::OnceLock::new(); ARGV_DESC.get_or_init(|| { - ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc::new(vec![ + ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc::new(vec![ {% for arg_info in procedure.argument_list %} - ::mudu_contract::tuple::datum_desc::DatumDesc::new( + ::mududb::contract::tuple::datum_desc::DatumDesc::new( "{{ arg_info.arg_name }}".to_string(), {% if arg_info.is_binary %} - ::mudu_type::dat_type::DatType::new_no_param(::mudu_type::dat_type_id::DatTypeID::Binary) + ::mududb::types::dat_type::DatType::new_no_param(::mududb::types::dat_type_id::DatTypeID::Binary) {% else %} - <{{ arg_info.arg_type }} as ::mudu_type::datum::Datum>::dat_type().clone() + <{{ arg_info.arg_type }} as ::mududb::types::datum::Datum>::dat_type().clone() {% endif %} ), {% endfor %} @@ -82,19 +81,19 @@ pub fn {{ procedure.fn_argv_desc }}() -> &'static ::mudu_contract::tuple::tuple ) } -pub fn {{ procedure.fn_result_desc }}() -> &'static ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc { - static RESULT_DESC: std::sync::OnceLock<::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc> = +pub fn {{ procedure.fn_result_desc }}() -> &'static ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc { + static RESULT_DESC: std::sync::OnceLock<::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc> = std::sync::OnceLock::new(); RESULT_DESC.get_or_init(|| { - ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc::new(vec![ + ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc::new(vec![ {% for ret_info in procedure.return_tuple %} - ::mudu_contract::tuple::datum_desc::DatumDesc::new( + ::mududb::contract::tuple::datum_desc::DatumDesc::new( "{{ loop.index0 }}".to_string(), {% if ret_info.is_binary %} - ::mudu_type::dat_type::DatType::new_no_param(::mudu_type::dat_type_id::DatTypeID::Binary) + ::mududb::types::dat_type::DatType::new_no_param(::mududb::types::dat_type_id::DatTypeID::Binary) {% else %} - <{{ ret_info.ret_type }} as ::mudu_type::datum::Datum>::dat_type().clone() + <{{ ret_info.ret_type }} as ::mududb::types::datum::Datum>::dat_type().clone() {% endif %} ), {% endfor %} @@ -103,13 +102,13 @@ pub fn {{ procedure.fn_result_desc }}() -> &'static ::mudu_contract::tuple::tupl ) } -pub fn {{ procedure.fn_proc_desc }}() -> &'static ::mudu_contract::procedure::proc_desc::ProcDesc { +pub fn {{ procedure.fn_proc_desc }}() -> &'static ::mududb::contract::procedure::proc_desc::ProcDesc { static _PROC_DESC: std::sync::OnceLock< - ::mudu_contract::procedure::proc_desc::ProcDesc, + ::mududb::contract::procedure::proc_desc::ProcDesc, > = std::sync::OnceLock::new(); _PROC_DESC .get_or_init(|| { - ::mudu_contract::procedure::proc_desc::ProcDesc::new( + ::mududb::contract::procedure::proc_desc::ProcDesc::new( "{{ procedure.package_name }}".to_string(), "{{ procedure.fn_name }}".to_string(), {{ procedure.fn_argv_desc }}().clone(), diff --git a/mudu_wasm/Cargo.toml b/mudu_wasm/Cargo.toml index 176f6b3..42ba5aa 100644 --- a/mudu_wasm/Cargo.toml +++ b/mudu_wasm/Cargo.toml @@ -5,18 +5,12 @@ edition = "2024" [features] default = ["transpile"] -macro = ["sys_interface/component-model"] -transpile = ["sys_interface/component-model", "sys_interface/async"] +transpile = ["mududb/component-model", "mududb/async"] [lib] crate-type = ["cdylib"] [dependencies] -mudu = { workspace = true } -mudu_type = { workspace = true } -mudu_contract = { workspace = true } -mudu_binding = { workspace = true } +mududb = { workspace = true } wit-bindgen = { workspace = true } -mudu_macro = { workspace = true } -sys_interface = { workspace = true } lazy_static = { workspace = true } diff --git a/mudu_wasm/package/package.desc.json b/mudu_wasm/package/package.desc.json index e19bb2d..9fab223 100644 --- a/mudu_wasm/package/package.desc.json +++ b/mudu_wasm/package/package.desc.json @@ -58,7 +58,7 @@ }, { "module_name": "mod_0", - "proc_name": "proc2_mtp", + "proc_name": "proc_sys_call_mtp", "param_desc": { "fields": [ { @@ -113,7 +113,7 @@ }, { "module_name": "mod_0", - "proc_name": "proc_sys_call_mtp", + "proc_name": "proc2_mtp", "param_desc": { "fields": [ { diff --git a/mudu_wasm/src/generated/mod.rs b/mudu_wasm/src/generated/mod.rs index 1975da6..8ce57f0 100644 --- a/mudu_wasm/src/generated/mod.rs +++ b/mudu_wasm/src/generated/mod.rs @@ -1,2 +1,2 @@ pub mod proc; -pub mod proc2; +pub mod proc2; \ No newline at end of file diff --git a/mudu_wasm/src/generated/proc.rs b/mudu_wasm/src/generated/proc.rs index 8af1de5..237bf4c 100644 --- a/mudu_wasm/src/generated/proc.rs +++ b/mudu_wasm/src/generated/proc.rs @@ -1,5 +1,5 @@ -use mudu::common::result::RS; -use mudu::common::xid::XID; +use mududb::common::result::RS; +use mududb::common::xid::XID; /**mudu-proc**/ pub fn proc_mtp(xid: XID, a: i32, b: i64, c: String) -> RS<(i32, String)> { @@ -8,64 +8,146 @@ pub fn proc_mtp(xid: XID, a: i32, b: i64, c: String) -> RS<(i32, String)> { format!("xid:{}, a={}, b={}, c={}", xid, a, b, c), )) } -fn mp2_proc_mtp(param: Vec) -> Vec { - ::mudu_binding::procedure::procedure_invoke::invoke_procedure(param, mudu_inner_p2_proc_mtp) + fn mp2_proc_mtp(param:Vec) -> Vec { + ::mududb::binding::procedure::procedure_invoke::invoke_procedure( + param, + mudu_inner_p2_proc_mtp, + ) } -pub fn mudu_inner_p2_proc_mtp( - param: ::mudu_contract::procedure::procedure_param::ProcedureParam, -) -> ::mudu::common::result::RS<::mudu_contract::procedure::procedure_result::ProcedureResult> { - let return_desc = mudu_result_desc_proc_mtp().clone(); +pub fn mudu_inner_p2_proc_mtp( + param: ::mududb::contract::procedure::procedure_param::ProcedureParam, +) -> ::mududb::common::result::RS< + ::mududb::contract::procedure::procedure_result::ProcedureResult, +> { let res = proc_mtp( param.session_id(), - ::mudu_type::datum::value_to_typed::(¶m.param_list()[0], "i32")?, - ::mudu_type::datum::value_to_typed::(¶m.param_list()[1], "i64")?, - ::mudu_type::datum::value_to_typed::(¶m.param_list()[2], "String")?, + + + ::mududb::types::datum::value_to_typed::< + i32, + _, + >(¶m.param_list()[0], "i32")?, + + + + ::mududb::types::datum::value_to_typed::< + i64, + _, + >(¶m.param_list()[1], "i64")?, + + + + ::mududb::types::datum::value_to_typed::< + String, + _, + >(¶m.param_list()[2], "String")?, + + ); - let tuple = res; - Ok(::mudu_contract::procedure::procedure_result::ProcedureResult::from(tuple, &return_desc)?) + match res { + Ok(tuple) => { + let return_list = { + + let ( + + mudu_ret_0, + + mudu_ret_1, + + ) = tuple; + vec![ + + + ::mududb::types::datum::value_from_typed(&mudu_ret_0, "i32")? + , + + + ::mududb::types::datum::value_from_typed(&mudu_ret_1, "String")? + , + + ] + + }; + Ok(::mududb::contract::procedure::procedure_result::ProcedureResult::new(return_list)) + } + Err(e) => Err(e), + } } -pub fn mudu_argv_desc_proc_mtp() -> &'static ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc -{ - static ARGV_DESC: std::sync::OnceLock< - ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc, - > = std::sync::OnceLock::new(); - ARGV_DESC.get_or_init(|| { - <(i32, i64, String) as ::mudu_contract::tuple::tuple_datum::TupleDatum>::tuple_desc_static( - &{ - let _vec: Vec = <[_]>::into_vec(std::boxed::Box::new(["a", "b", "c"])) - .iter() - .map(|s| s.to_string()) - .collect(); - _vec - }, - ) - }) +pub fn mudu_argv_desc_proc_mtp() -> &'static ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc { + static ARGV_DESC: std::sync::OnceLock<::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc> = + std::sync::OnceLock::new(); + ARGV_DESC.get_or_init(|| + { + ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc::new(vec![ + + ::mududb::contract::tuple::datum_desc::DatumDesc::new( + "a".to_string(), + + ::dat_type().clone() + + ), + + ::mududb::contract::tuple::datum_desc::DatumDesc::new( + "b".to_string(), + + ::dat_type().clone() + + ), + + ::mududb::contract::tuple::datum_desc::DatumDesc::new( + "c".to_string(), + + ::dat_type().clone() + + ), + + ]) + } + ) } -pub fn mudu_result_desc_proc_mtp() --> &'static ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc { - static RESULT_DESC: std::sync::OnceLock< - ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc, - > = std::sync::OnceLock::new(); - RESULT_DESC.get_or_init(|| { - <(i32, String) as ::mudu_contract::tuple::tuple_datum::TupleDatum>::tuple_desc_static(&[]) - }) +pub fn mudu_result_desc_proc_mtp() -> &'static ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc { + static RESULT_DESC: std::sync::OnceLock<::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc> = + std::sync::OnceLock::new(); + RESULT_DESC.get_or_init(|| + { + ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc::new(vec![ + + ::mududb::contract::tuple::datum_desc::DatumDesc::new( + "0".to_string(), + + ::dat_type().clone() + + ), + + ::mududb::contract::tuple::datum_desc::DatumDesc::new( + "1".to_string(), + + ::dat_type().clone() + + ), + + ]) + } + ) } -pub fn mudu_proc_desc_proc_mtp() -> &'static ::mudu_contract::procedure::proc_desc::ProcDesc { - static _PROC_DESC: std::sync::OnceLock<::mudu_contract::procedure::proc_desc::ProcDesc> = - std::sync::OnceLock::new(); - _PROC_DESC.get_or_init(|| { - ::mudu_contract::procedure::proc_desc::ProcDesc::new( - "mod_0".to_string(), - "proc_mtp".to_string(), - mudu_argv_desc_proc_mtp().clone(), - mudu_result_desc_proc_mtp().clone(), - false, - ) - }) +pub fn mudu_proc_desc_proc_mtp() -> &'static ::mududb::contract::procedure::proc_desc::ProcDesc { + static _PROC_DESC: std::sync::OnceLock< + ::mududb::contract::procedure::proc_desc::ProcDesc, + > = std::sync::OnceLock::new(); + _PROC_DESC + .get_or_init(|| { + ::mududb::contract::procedure::proc_desc::ProcDesc::new( + "mod_0".to_string(), + "proc_mtp".to_string(), + mudu_argv_desc_proc_mtp().clone(), + mudu_result_desc_proc_mtp().clone(), + false + ) + }) } mod mod_proc_mtp { @@ -76,7 +158,7 @@ mod mod_proc_mtp { export mp2-proc-mtp: func(param:list) -> list; } "##, - + }); #[allow(non_camel_case_types)] @@ -84,10 +166,10 @@ mod mod_proc_mtp { struct GuestProcMtp {} impl Guest for GuestProcMtp { - fn mp2_proc_mtp(param: Vec) -> Vec { + fn mp2_proc_mtp(param:Vec) -> Vec { super::mp2_proc_mtp(param) } } export!(GuestProcMtp); -} +} \ No newline at end of file diff --git a/mudu_wasm/src/generated/proc2.rs b/mudu_wasm/src/generated/proc2.rs index d1a0a79..4715d4a 100644 --- a/mudu_wasm/src/generated/proc2.rs +++ b/mudu_wasm/src/generated/proc2.rs @@ -1,9 +1,9 @@ -use mudu::common::result::RS; -use mudu::common::xid::XID; -use mudu_contract::{sql_params, sql_stmt}; -use mudu_type::datum::{Datum, DatumDyn}; +use mududb::common::result::RS; +use mududb::common::xid::XID; +use mududb::contract::{sql_params, sql_stmt}; +use mududb::types::datum::{Datum, DatumDyn}; use object::Wallets; -use sys_interface::async_api::{mudu_command, mudu_query}; +use mududb::sys_interface::async_api::{mudu_command, mudu_query}; /**mudu-proc**/ pub async fn proc_sys_call_mtp(xid: XID, a: i32, b: i64, c: String) -> RS<(i32, String)> { @@ -18,8 +18,7 @@ CREATE TABLE wallets );"# .to_string(), &vec![], - ) - .await?; + ).await?; for i in 1..=2 { let _affected_rows = mudu_command( @@ -37,16 +36,14 @@ INSERT INTO wallets )"# .to_string(), &(i, 100i32, 10000i32), - ) - .await?; + ).await?; } let wallet_rs = mudu_query::( xid, sql_stmt!(&"SELECT user_id, balance, updated_at FROM wallets;"), sql_params!(&()), - ) - .await?; + ).await?; let mut result = String::new(); while let Some(row) = wallet_rs.next_record()? { @@ -72,21 +69,21 @@ pub fn proc2_mtp(xid: XID, a: i32, b: i64, c: String) -> RS<(i32, String)> { #[allow(unused)] pub mod object { use lazy_static::lazy_static; - use mudu::common::result::RS; - use mudu_contract::database::attr_field_access; - use mudu_contract::database::attr_value::AttrValue; - use mudu_contract::database::entity::Entity; - use mudu_contract::database::entity_utils; - use mudu_contract::database::sql_params::SQLParamMarker; - use mudu_contract::tuple::datum_desc::DatumDesc; - use mudu_contract::tuple::tuple_datum::TupleDatumMarker; - use mudu_contract::tuple::tuple_field_desc::TupleFieldDesc; - use mudu_type::dat_binary::DatBinary; - use mudu_type::dat_textual::DatTextual; - use mudu_type::dat_type::DatType; - use mudu_type::dat_type_id::DatTypeID; - use mudu_type::dat_value::DatValue; - use mudu_type::datum::{Datum, DatumDyn}; + use mududb::common::result::RS; + use mududb::contract::database::attr_field_access; + use mududb::contract::database::attr_value::AttrValue; + use mududb::contract::database::entity::Entity; + use mududb::contract::database::entity_utils; + use mududb::contract::database::sql_params::SQLParamMarker; + use mududb::contract::tuple::datum_desc::DatumDesc; + use mududb::contract::tuple::tuple_datum::TupleDatumMarker; + use mududb::contract::tuple::tuple_field_desc::TupleFieldDesc; + use mududb::types::dat_binary::DatBinary; + use mududb::types::dat_textual::DatTextual; + use mududb::types::dat_type::DatType; + use mududb::types::dat_type_id::DatTypeID; + use mududb::types::dat_value::DatValue; + use mududb::types::datum::{Datum, DatumDyn}; const TABLE_WALLETS: &str = "wallets"; const COLUMN_USER_ID: &str = "user_id"; @@ -333,175 +330,333 @@ pub mod object { } } } // end mod object -fn mp2_proc2_mtp(param: Vec) -> Vec { - ::mudu_binding::procedure::procedure_invoke::invoke_procedure(param, mudu_inner_p2_proc2_mtp) +async fn mp2_proc_sys_call_mtp(param:Vec) -> Vec { + ::mududb::binding::procedure::procedure_invoke::invoke_procedure_async( + param, + mudu_inner_p2_proc_sys_call_mtp, + ).await } -pub fn mudu_inner_p2_proc2_mtp( - param: ::mudu_contract::procedure::procedure_param::ProcedureParam, -) -> ::mudu::common::result::RS<::mudu_contract::procedure::procedure_result::ProcedureResult> { - let return_desc = mudu_result_desc_proc2_mtp().clone(); - let res = proc2_mtp( +pub async fn mudu_inner_p2_proc_sys_call_mtp( + param: ::mududb::contract::procedure::procedure_param::ProcedureParam, +) -> ::mududb::common::result::RS< + ::mududb::contract::procedure::procedure_result::ProcedureResult, +> { + let res = proc_sys_call_mtp( param.session_id(), - ::mudu_type::datum::value_to_typed::(¶m.param_list()[0], "i32")?, - ::mudu_type::datum::value_to_typed::(¶m.param_list()[1], "i64")?, - ::mudu_type::datum::value_to_typed::(¶m.param_list()[2], "String")?, - ); - let tuple = res; - Ok(::mudu_contract::procedure::procedure_result::ProcedureResult::from(tuple, &return_desc)?) + + + ::mududb::types::datum::value_to_typed::< + i32, + _, + >(¶m.param_list()[0], "i32")?, + + + + ::mududb::types::datum::value_to_typed::< + i64, + _, + >(¶m.param_list()[1], "i64")?, + + + + ::mududb::types::datum::value_to_typed::< + String, + _, + >(¶m.param_list()[2], "String")?, + + + ).await; + match res { + Ok(tuple) => { + let return_list = { + + let ( + + mudu_ret_0, + + mudu_ret_1, + + ) = tuple; + vec![ + + + ::mududb::types::datum::value_from_typed(&mudu_ret_0, "i32")? + , + + + ::mududb::types::datum::value_from_typed(&mudu_ret_1, "String")? + , + + ] + + }; + Ok(::mududb::contract::procedure::procedure_result::ProcedureResult::new(return_list)) + } + Err(e) => Err(e), + } } -pub fn mudu_argv_desc_proc2_mtp() --> &'static ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc { - static ARGV_DESC: std::sync::OnceLock< - ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc, - > = std::sync::OnceLock::new(); - ARGV_DESC.get_or_init(|| { - <(i32, i64, String) as ::mudu_contract::tuple::tuple_datum::TupleDatum>::tuple_desc_static( - &{ - let _vec: Vec = <[_]>::into_vec(std::boxed::Box::new(["a", "b", "c"])) - .iter() - .map(|s| s.to_string()) - .collect(); - _vec - }, - ) - }) +pub fn mudu_argv_desc_proc_sys_call_mtp() -> &'static ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc { + static ARGV_DESC: std::sync::OnceLock<::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc> = + std::sync::OnceLock::new(); + ARGV_DESC.get_or_init(|| + { + ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc::new(vec![ + + ::mududb::contract::tuple::datum_desc::DatumDesc::new( + "a".to_string(), + + ::dat_type().clone() + + ), + + ::mududb::contract::tuple::datum_desc::DatumDesc::new( + "b".to_string(), + + ::dat_type().clone() + + ), + + ::mududb::contract::tuple::datum_desc::DatumDesc::new( + "c".to_string(), + + ::dat_type().clone() + + ), + + ]) + } + ) } -pub fn mudu_result_desc_proc2_mtp() --> &'static ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc { - static RESULT_DESC: std::sync::OnceLock< - ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc, - > = std::sync::OnceLock::new(); - RESULT_DESC.get_or_init(|| { - <(i32, String) as ::mudu_contract::tuple::tuple_datum::TupleDatum>::tuple_desc_static(&[]) - }) +pub fn mudu_result_desc_proc_sys_call_mtp() -> &'static ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc { + static RESULT_DESC: std::sync::OnceLock<::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc> = + std::sync::OnceLock::new(); + RESULT_DESC.get_or_init(|| + { + ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc::new(vec![ + + ::mududb::contract::tuple::datum_desc::DatumDesc::new( + "0".to_string(), + + ::dat_type().clone() + + ), + + ::mududb::contract::tuple::datum_desc::DatumDesc::new( + "1".to_string(), + + ::dat_type().clone() + + ), + + ]) + } + ) } -pub fn mudu_proc_desc_proc2_mtp() -> &'static ::mudu_contract::procedure::proc_desc::ProcDesc { - static _PROC_DESC: std::sync::OnceLock<::mudu_contract::procedure::proc_desc::ProcDesc> = - std::sync::OnceLock::new(); - _PROC_DESC.get_or_init(|| { - ::mudu_contract::procedure::proc_desc::ProcDesc::new( - "mod_0".to_string(), - "proc2_mtp".to_string(), - mudu_argv_desc_proc2_mtp().clone(), - mudu_result_desc_proc2_mtp().clone(), - false, - ) - }) +pub fn mudu_proc_desc_proc_sys_call_mtp() -> &'static ::mududb::contract::procedure::proc_desc::ProcDesc { + static _PROC_DESC: std::sync::OnceLock< + ::mududb::contract::procedure::proc_desc::ProcDesc, + > = std::sync::OnceLock::new(); + _PROC_DESC + .get_or_init(|| { + ::mududb::contract::procedure::proc_desc::ProcDesc::new( + "mod_0".to_string(), + "proc_sys_call_mtp".to_string(), + mudu_argv_desc_proc_sys_call_mtp().clone(), + mudu_result_desc_proc_sys_call_mtp().clone(), + false + ) + }) } -mod mod_proc2_mtp { +mod mod_proc_sys_call_mtp { wit_bindgen::generate!({ inline: - r##"package mudu:mp2-proc2-mtp; - world mudu-app-mp2-proc2-mtp { - export mp2-proc2-mtp: func(param:list) -> list; + r##"package mudu:mp2-proc-sys-call-mtp; + world mudu-app-mp2-proc-sys-call-mtp { + export mp2-proc-sys-call-mtp: func(param:list) -> list; } "##, - + async: true }); #[allow(non_camel_case_types)] #[allow(unused)] - struct GuestProc2Mtp {} + struct GuestProcSysCallMtp {} - impl Guest for GuestProc2Mtp { - fn mp2_proc2_mtp(param: Vec) -> Vec { - super::mp2_proc2_mtp(param) + impl Guest for GuestProcSysCallMtp { + async fn mp2_proc_sys_call_mtp(param:Vec) -> Vec { + super::mp2_proc_sys_call_mtp(param).await } } - export!(GuestProc2Mtp); + export!(GuestProcSysCallMtp); } -async fn mp2_proc_sys_call_mtp(param: Vec) -> Vec { - ::mudu_binding::procedure::procedure_invoke::invoke_procedure_async( + fn mp2_proc2_mtp(param:Vec) -> Vec { + ::mududb::binding::procedure::procedure_invoke::invoke_procedure( param, - mudu_inner_p2_proc_sys_call_mtp, + mudu_inner_p2_proc2_mtp, ) - .await } -pub async fn mudu_inner_p2_proc_sys_call_mtp( - param: ::mudu_contract::procedure::procedure_param::ProcedureParam, -) -> ::mudu::common::result::RS<::mudu_contract::procedure::procedure_result::ProcedureResult> { - let return_desc = mudu_result_desc_proc_sys_call_mtp().clone(); - let res = proc_sys_call_mtp( +pub fn mudu_inner_p2_proc2_mtp( + param: ::mududb::contract::procedure::procedure_param::ProcedureParam, +) -> ::mududb::common::result::RS< + ::mududb::contract::procedure::procedure_result::ProcedureResult, +> { + let res = proc2_mtp( param.session_id(), - ::mudu_type::datum::value_to_typed::(¶m.param_list()[0], "i32")?, - ::mudu_type::datum::value_to_typed::(¶m.param_list()[1], "i64")?, - ::mudu_type::datum::value_to_typed::(¶m.param_list()[2], "String")?, - ) - .await; - let tuple = res; - Ok(::mudu_contract::procedure::procedure_result::ProcedureResult::from(tuple, &return_desc)?) + + + ::mududb::types::datum::value_to_typed::< + i32, + _, + >(¶m.param_list()[0], "i32")?, + + + + ::mududb::types::datum::value_to_typed::< + i64, + _, + >(¶m.param_list()[1], "i64")?, + + + + ::mududb::types::datum::value_to_typed::< + String, + _, + >(¶m.param_list()[2], "String")?, + + + ); + match res { + Ok(tuple) => { + let return_list = { + + let ( + + mudu_ret_0, + + mudu_ret_1, + + ) = tuple; + vec![ + + + ::mududb::types::datum::value_from_typed(&mudu_ret_0, "i32")? + , + + + ::mududb::types::datum::value_from_typed(&mudu_ret_1, "String")? + , + + ] + + }; + Ok(::mududb::contract::procedure::procedure_result::ProcedureResult::new(return_list)) + } + Err(e) => Err(e), + } } -pub fn mudu_argv_desc_proc_sys_call_mtp() --> &'static ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc { - static ARGV_DESC: std::sync::OnceLock< - ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc, - > = std::sync::OnceLock::new(); - ARGV_DESC.get_or_init(|| { - <(i32, i64, String) as ::mudu_contract::tuple::tuple_datum::TupleDatum>::tuple_desc_static( - &{ - let _vec: Vec = <[_]>::into_vec(std::boxed::Box::new(["a", "b", "c"])) - .iter() - .map(|s| s.to_string()) - .collect(); - _vec - }, - ) - }) +pub fn mudu_argv_desc_proc2_mtp() -> &'static ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc { + static ARGV_DESC: std::sync::OnceLock<::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc> = + std::sync::OnceLock::new(); + ARGV_DESC.get_or_init(|| + { + ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc::new(vec![ + + ::mududb::contract::tuple::datum_desc::DatumDesc::new( + "a".to_string(), + + ::dat_type().clone() + + ), + + ::mududb::contract::tuple::datum_desc::DatumDesc::new( + "b".to_string(), + + ::dat_type().clone() + + ), + + ::mududb::contract::tuple::datum_desc::DatumDesc::new( + "c".to_string(), + + ::dat_type().clone() + + ), + + ]) + } + ) } -pub fn mudu_result_desc_proc_sys_call_mtp() --> &'static ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc { - static RESULT_DESC: std::sync::OnceLock< - ::mudu_contract::tuple::tuple_field_desc::TupleFieldDesc, - > = std::sync::OnceLock::new(); - RESULT_DESC.get_or_init(|| { - <(i32, String) as ::mudu_contract::tuple::tuple_datum::TupleDatum>::tuple_desc_static(&[]) - }) +pub fn mudu_result_desc_proc2_mtp() -> &'static ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc { + static RESULT_DESC: std::sync::OnceLock<::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc> = + std::sync::OnceLock::new(); + RESULT_DESC.get_or_init(|| + { + ::mududb::contract::tuple::tuple_field_desc::TupleFieldDesc::new(vec![ + + ::mududb::contract::tuple::datum_desc::DatumDesc::new( + "0".to_string(), + + ::dat_type().clone() + + ), + + ::mududb::contract::tuple::datum_desc::DatumDesc::new( + "1".to_string(), + + ::dat_type().clone() + + ), + + ]) + } + ) } -pub fn mudu_proc_desc_proc_sys_call_mtp() -> &'static ::mudu_contract::procedure::proc_desc::ProcDesc -{ - static _PROC_DESC: std::sync::OnceLock<::mudu_contract::procedure::proc_desc::ProcDesc> = - std::sync::OnceLock::new(); - _PROC_DESC.get_or_init(|| { - ::mudu_contract::procedure::proc_desc::ProcDesc::new( - "mod_0".to_string(), - "proc_sys_call_mtp".to_string(), - mudu_argv_desc_proc_sys_call_mtp().clone(), - mudu_result_desc_proc_sys_call_mtp().clone(), - false, - ) - }) +pub fn mudu_proc_desc_proc2_mtp() -> &'static ::mududb::contract::procedure::proc_desc::ProcDesc { + static _PROC_DESC: std::sync::OnceLock< + ::mududb::contract::procedure::proc_desc::ProcDesc, + > = std::sync::OnceLock::new(); + _PROC_DESC + .get_or_init(|| { + ::mududb::contract::procedure::proc_desc::ProcDesc::new( + "mod_0".to_string(), + "proc2_mtp".to_string(), + mudu_argv_desc_proc2_mtp().clone(), + mudu_result_desc_proc2_mtp().clone(), + false + ) + }) } -mod mod_proc_sys_call_mtp { +mod mod_proc2_mtp { wit_bindgen::generate!({ inline: - r##"package mudu:mp2-proc-sys-call-mtp; - world mudu-app-mp2-proc-sys-call-mtp { - export mp2-proc-sys-call-mtp: func(param:list) -> list; + r##"package mudu:mp2-proc2-mtp; + world mudu-app-mp2-proc2-mtp { + export mp2-proc2-mtp: func(param:list) -> list; } "##, - async: true + }); #[allow(non_camel_case_types)] #[allow(unused)] - struct GuestProcSysCallMtp {} + struct GuestProc2Mtp {} - impl Guest for GuestProcSysCallMtp { - async fn mp2_proc_sys_call_mtp(param: Vec) -> Vec { - super::mp2_proc_sys_call_mtp(param).await + impl Guest for GuestProc2Mtp { + fn mp2_proc2_mtp(param:Vec) -> Vec { + super::mp2_proc2_mtp(param) } } - export!(GuestProcSysCallMtp); -} + export!(GuestProc2Mtp); +} \ No newline at end of file diff --git a/mudu_wasm/src/lib.rs b/mudu_wasm/src/lib.rs index 162a950..49f70e7 100644 --- a/mudu_wasm/src/lib.rs +++ b/mudu_wasm/src/lib.rs @@ -1,6 +1,3 @@ -#[cfg(all(target_arch = "wasm32", feature = "macro"))] -pub mod wasm; - #[cfg(all(target_arch = "wasm32", feature = "transpile"))] pub mod generated; #[cfg(target_arch = "x86_64")] diff --git a/mudu_wasm/src/wasm/mod.rs b/mudu_wasm/src/wasm/mod.rs deleted file mode 100644 index bf6cc13..0000000 --- a/mudu_wasm/src/wasm/mod.rs +++ /dev/null @@ -1,3 +0,0 @@ -mod proc; -mod proc2; -mod test; diff --git a/mudu_wasm/src/wasm/proc.rs b/mudu_wasm/src/wasm/proc.rs deleted file mode 100644 index a819cca..0000000 --- a/mudu_wasm/src/wasm/proc.rs +++ /dev/null @@ -1,11 +0,0 @@ -use mudu::common::result::RS; -use mudu::common::xid::XID; -use mudu_macro::mudu_proc; - -#[mudu_proc] -pub fn proc(xid: XID, a: i32, b: i64, c: String) -> RS<(i32, String)> { - Ok(( - (a + b as i32), - format!("xid:{}, a={}, b={}, c={}", xid, a, b, c), - )) -} diff --git a/mudu_wasm/src/wasm/proc2.rs b/mudu_wasm/src/wasm/proc2.rs deleted file mode 100644 index 3548900..0000000 --- a/mudu_wasm/src/wasm/proc2.rs +++ /dev/null @@ -1,333 +0,0 @@ -use crate::wasm::proc2::object::Wallets; -use mudu::common::result::RS; -use mudu::common::xid::XID; -use mudu_contract::{sql_params, sql_stmt}; -use mudu_macro::mudu_proc; -use mudu_type::datum::{Datum, DatumDyn}; -use sys_interface::sync_api::{mudu_command, mudu_query}; - -#[mudu_proc] -pub fn proc_sys_call(xid: XID, a: i32, b: i64, c: String) -> RS<(i32, String)> { - let _affected_rows = mudu_command( - xid, - &r#" -CREATE TABLE wallets -( - user_id INT PRIMARY KEY, - balance INT, - updated_at INT -);"# - .to_string(), - &vec![], - )?; - - for i in 1..=2 { - let _affected_rows = mudu_command( - xid, - &r#" -INSERT INTO wallets -( - user_id, - balance, - updated_at -) VALUES ( - ?, - ?, - ? -)"# - .to_string(), - &(i, 100i32, 10000i32), - )?; - } - - let wallet_rs = mudu_query::( - xid, - sql_stmt!(&"SELECT user_id, balance, updated_at FROM wallets;"), - sql_params!(&()), - )?; - - let mut result = String::new(); - while let Some(row) = wallet_rs.next_record()? { - let value = row.to_value(Wallets::dat_type())?; - let s = value.to_textual(Wallets::dat_type())?; - result.push_str(&s); - result.push('\n'); - } - Ok(( - (a + b as i32), - format!("xid:{}, a={}, b={}, c={}, result {}", xid, a, b, c, result), - )) -} - -#[mudu_proc] -pub fn proc2(xid: XID, a: i32, b: i64, c: String) -> RS<(i32, String)> { - Ok(( - (a + b as i32), - format!("xid:{}, a={}, b={}, c={}", xid, a, b, c), - )) -} - -#[allow(unused)] -pub mod object { - use lazy_static::lazy_static; - use mudu::common::result::RS; - use mudu_contract::database::attr_field_access; - use mudu_contract::database::attr_value::AttrValue; - use mudu_contract::database::entity::Entity; - use mudu_contract::database::entity_utils; - use mudu_contract::database::sql_params::SQLParamMarker; - use mudu_contract::tuple::datum_desc::DatumDesc; - use mudu_contract::tuple::tuple_datum::TupleDatumMarker; - use mudu_contract::tuple::tuple_field_desc::TupleFieldDesc; - use mudu_type::dat_binary::DatBinary; - use mudu_type::dat_textual::DatTextual; - use mudu_type::dat_type::DatType; - use mudu_type::dat_type_id::DatTypeID; - use mudu_type::dat_value::DatValue; - use mudu_type::datum::{Datum, DatumDyn}; - - const TABLE_WALLETS: &str = "wallets"; - const COLUMN_USER_ID: &str = "user_id"; - const COLUMN_BALANCE: &str = "balance"; - const COLUMN_UPDATED_AT: &str = "updated_at"; - #[allow(unused)] - #[derive(Debug, Clone)] - pub struct Wallets { - user_id: Option, - balance: Option, - updated_at: Option, - } - - impl TupleDatumMarker for Wallets {} - - impl SQLParamMarker for Wallets {} - #[allow(unused)] - impl Wallets { - pub fn new(user_id: Option, balance: Option, updated_at: Option) -> Self { - let s = Self { - user_id, - balance, - updated_at, - }; - s - } - - pub fn set_user_id(&mut self, user_id: i32) { - self.user_id = Some(user_id); - } - - pub fn get_user_id(&self) -> &Option { - &self.user_id - } - - pub fn set_balance(&mut self, balance: i32) { - self.balance = Some(balance); - } - - pub fn get_balance(&self) -> &Option { - &self.balance - } - - pub fn set_updated_at(&mut self, updated_at: i32) { - self.updated_at = Some(updated_at); - } - - pub fn get_updated_at(&self) -> &Option { - &self.updated_at - } - } - - impl Datum for Wallets { - fn dat_type() -> &'static DatType { - lazy_static! { - static ref DAT_TYPE: DatType = entity_utils::entity_dat_type::(); - } - &DAT_TYPE - } - - fn from_binary(binary: &[u8]) -> RS { - entity_utils::entity_from_binary(binary) - } - - fn from_value(value: &DatValue) -> RS { - entity_utils::entity_from_value(value) - } - - fn from_textual(textual: &str) -> RS { - entity_utils::entity_from_textual(textual) - } - } - - impl DatumDyn for Wallets { - fn dat_type_id(&self) -> RS { - entity_utils::entity_dat_type_id() - } - - fn to_binary(&self, dat_type: &DatType) -> RS { - entity_utils::entity_to_binary(self, dat_type) - } - - fn to_textual(&self, dat_type: &DatType) -> RS { - entity_utils::entity_to_textual(self, dat_type) - } - - fn to_value(&self, dat_type: &DatType) -> RS { - entity_utils::entity_to_value(self, dat_type) - } - - fn clone_boxed(&self) -> Box { - entity_utils::entity_clone_boxed(self) - } - } - - impl Entity for Wallets { - fn new_empty() -> Self { - let s = Self { - user_id: None, - balance: None, - updated_at: None, - }; - s - } - fn tuple_desc() -> &'static TupleFieldDesc { - lazy_static! { - static ref TUPLE_DESC: TupleFieldDesc = TupleFieldDesc::new(vec![ - AttrUserId::datum_desc().clone(), - AttrBalance::datum_desc().clone(), - AttrUpdatedAt::datum_desc().clone(), - ]); - } - &TUPLE_DESC - } - - fn object_name() -> &'static str { - TABLE_WALLETS - } - - fn get_field_binary(&self, column: &str) -> RS>> { - match column { - COLUMN_USER_ID => attr_field_access::attr_get_binary::<_>(&self.user_id), - COLUMN_BALANCE => attr_field_access::attr_get_binary::<_>(&self.balance), - COLUMN_UPDATED_AT => attr_field_access::attr_get_binary::<_>(&self.updated_at), - _ => { - panic!("unknown name"); - } - } - } - - fn set_field_binary>(&mut self, column: &str, binary: B) -> RS<()> { - match column { - COLUMN_USER_ID => { - attr_field_access::attr_set_binary::<_, _>(&mut self.user_id, binary.as_ref())?; - } - COLUMN_BALANCE => { - attr_field_access::attr_set_binary::<_, _>(&mut self.balance, binary.as_ref())?; - } - COLUMN_UPDATED_AT => { - attr_field_access::attr_set_binary::<_, _>( - &mut self.updated_at, - binary.as_ref(), - )?; - } - _ => { - panic!("unknown name"); - } - } - Ok(()) - } - fn get_field_value(&self, column: &str) -> RS> { - match column { - COLUMN_USER_ID => attr_field_access::attr_get_value::<_>(&self.user_id), - COLUMN_BALANCE => attr_field_access::attr_get_value::<_>(&self.balance), - COLUMN_UPDATED_AT => attr_field_access::attr_get_value::<_>(&self.updated_at), - _ => { - panic!("unknown name"); - } - } - } - - fn set_field_value>(&mut self, column: &str, value: B) -> RS<()> { - match column { - COLUMN_USER_ID => { - attr_field_access::attr_set_value::<_, _>(&mut self.user_id, value)?; - } - COLUMN_BALANCE => { - attr_field_access::attr_set_value::<_, _>(&mut self.balance, value)?; - } - COLUMN_UPDATED_AT => { - attr_field_access::attr_set_value::<_, _>(&mut self.updated_at, value)?; - } - _ => { - panic!("unknown name"); - } - } - Ok(()) - } - } - - pub struct AttrUserId {} - - impl AttrValue for AttrUserId { - fn dat_type() -> &'static DatType { - static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); - ONCE_LOCK.get_or_init(|| Self::attr_dat_type()) - } - - fn datum_desc() -> &'static DatumDesc { - static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); - ONCE_LOCK.get_or_init(|| Self::attr_datum_desc()) - } - - fn object_name() -> &'static str { - TABLE_WALLETS - } - - fn attr_name() -> &'static str { - COLUMN_USER_ID - } - } - - pub struct AttrBalance {} - - impl AttrValue for AttrBalance { - fn dat_type() -> &'static DatType { - static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); - ONCE_LOCK.get_or_init(|| Self::attr_dat_type()) - } - - fn datum_desc() -> &'static DatumDesc { - static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); - ONCE_LOCK.get_or_init(|| Self::attr_datum_desc()) - } - - fn object_name() -> &'static str { - TABLE_WALLETS - } - - fn attr_name() -> &'static str { - COLUMN_BALANCE - } - } - - pub struct AttrUpdatedAt {} - - impl AttrValue for AttrUpdatedAt { - fn dat_type() -> &'static DatType { - static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); - ONCE_LOCK.get_or_init(|| Self::attr_dat_type()) - } - - fn datum_desc() -> &'static DatumDesc { - static ONCE_LOCK: std::sync::OnceLock = std::sync::OnceLock::new(); - ONCE_LOCK.get_or_init(|| Self::attr_datum_desc()) - } - - fn object_name() -> &'static str { - TABLE_WALLETS - } - - fn attr_name() -> &'static str { - COLUMN_UPDATED_AT - } - } -} // end mod object diff --git a/mudu_wasm/src/wasm/test.rs b/mudu_wasm/src/wasm/test.rs deleted file mode 100644 index 7c92d91..0000000 --- a/mudu_wasm/src/wasm/test.rs +++ /dev/null @@ -1,32 +0,0 @@ -#[cfg(test)] -mod tests { - use crate::wasm::{proc, proc2}; - use mudu::common::result::RS; - use mudu::this_file; - use mudu::utils::json::write_json; - use mudu_contract::procedure::mod_proc_desc::ModProcDesc; - use std::path::PathBuf; - - #[test] - fn test_gen_proc_desc() { - _test_gen_proc_desc().unwrap(); - } - - fn _test_gen_proc_desc() -> RS<()> { - let mut app_proc_desc = ModProcDesc::new_empty(); - for proc_desc in vec![ - proc::mudu_proc_desc_proc(), - proc2::mudu_proc_desc_proc_sys_call(), - proc2::mudu_proc_desc_proc2(), - ] { - app_proc_desc.add(proc_desc.clone()); - } - let mut path_buf = PathBuf::from(this_file!()); - path_buf.pop(); - path_buf.pop(); - path_buf.pop(); - let path_buf = path_buf.join("package").join("package.desc.json"); - write_json(&app_proc_desc, &path_buf).unwrap(); - Ok(()) - } -} diff --git a/mudu_wasm/src/wasm_mtp/proc.rs b/mudu_wasm/src/wasm_mtp/proc.rs index dafd863..23e18aa 100644 --- a/mudu_wasm/src/wasm_mtp/proc.rs +++ b/mudu_wasm/src/wasm_mtp/proc.rs @@ -1,5 +1,5 @@ -use mudu::common::result::RS; -use mudu::common::xid::XID; +use mududb::common::result::RS; +use mududb::common::xid::XID; /**mudu-proc**/ pub fn proc_mtp(xid: XID, a: i32, b: i64, c: String) -> RS<(i32, String)> { diff --git a/mudu_wasm/src/wasm_mtp/proc2.rs b/mudu_wasm/src/wasm_mtp/proc2.rs index 3891166..2bcb954 100644 --- a/mudu_wasm/src/wasm_mtp/proc2.rs +++ b/mudu_wasm/src/wasm_mtp/proc2.rs @@ -1,9 +1,9 @@ -use mudu::common::result::RS; -use mudu::common::xid::XID; -use mudu_contract::{sql_params, sql_stmt}; -use mudu_type::datum::{Datum, DatumDyn}; +use mududb::common::result::RS; +use mududb::common::xid::XID; +use mududb::contract::{sql_params, sql_stmt}; +use mududb::types::datum::{Datum, DatumDyn}; use object::Wallets; -use sys_interface::sync_api::{mudu_command, mudu_query}; +use mududb::sys_interface::sync_api::{mudu_command, mudu_query}; /**mudu-proc**/ pub fn proc_sys_call_mtp(xid: XID, a: i32, b: i64, c: String) -> RS<(i32, String)> { @@ -69,21 +69,21 @@ pub fn proc2_mtp(xid: XID, a: i32, b: i64, c: String) -> RS<(i32, String)> { #[allow(unused)] pub mod object { use lazy_static::lazy_static; - use mudu::common::result::RS; - use mudu_contract::database::attr_field_access; - use mudu_contract::database::attr_value::AttrValue; - use mudu_contract::database::entity::Entity; - use mudu_contract::database::entity_utils; - use mudu_contract::database::sql_params::SQLParamMarker; - use mudu_contract::tuple::datum_desc::DatumDesc; - use mudu_contract::tuple::tuple_datum::TupleDatumMarker; - use mudu_contract::tuple::tuple_field_desc::TupleFieldDesc; - use mudu_type::dat_binary::DatBinary; - use mudu_type::dat_textual::DatTextual; - use mudu_type::dat_type::DatType; - use mudu_type::dat_type_id::DatTypeID; - use mudu_type::dat_value::DatValue; - use mudu_type::datum::{Datum, DatumDyn}; + use mududb::common::result::RS; + use mududb::contract::database::attr_field_access; + use mududb::contract::database::attr_value::AttrValue; + use mududb::contract::database::entity::Entity; + use mududb::contract::database::entity_utils; + use mududb::contract::database::sql_params::SQLParamMarker; + use mududb::contract::tuple::datum_desc::DatumDesc; + use mududb::contract::tuple::tuple_datum::TupleDatumMarker; + use mududb::contract::tuple::tuple_field_desc::TupleFieldDesc; + use mududb::types::dat_binary::DatBinary; + use mududb::types::dat_textual::DatTextual; + use mududb::types::dat_type::DatType; + use mududb::types::dat_type_id::DatTypeID; + use mududb::types::dat_value::DatValue; + use mududb::types::datum::{Datum, DatumDyn}; const TABLE_WALLETS: &str = "wallets"; const COLUMN_USER_ID: &str = "user_id"; diff --git a/mududb/Cargo.toml b/mududb/Cargo.toml new file mode 100644 index 0000000..383893f --- /dev/null +++ b/mududb/Cargo.toml @@ -0,0 +1,31 @@ +[package] +name = "mududb" +version = "0.1.0" +edition = "2024" + +[dependencies] +mudu = { workspace = true, optional = true } +mudu_type = { workspace = true, optional = true } +mudu_contract = { workspace = true, optional = true } +mudu_binding = { workspace = true, optional = true } +mudu_sys = { workspace = true, optional = true } +sys_interface = { path = "../sys_interface", optional = true, default-features = false } + +[features] +default = ["app"] +app = [ + "dep:mudu", + "dep:mudu_type", + "dep:mudu_contract", + "dep:mudu_binding", + "dep:mudu_sys", + "component-model", +] +interface = ["dep:sys_interface"] +component-model = ["interface", "sys_interface/component-model"] +wasip2 = ["interface", "sys_interface/wasip2"] +async = ["interface", "sys_interface/async"] +# Enables local standalone syscall execution via the in-process adapter. +# Use this for local tests/debug runs without an external host/runtime. +standalone-adapter = ["interface", "sys_interface/standalone-adapter"] +uniffi-bindings = ["interface", "sys_interface/uniffi-bindings"] diff --git a/mududb/src/lib.rs b/mududb/src/lib.rs new file mode 100644 index 0000000..46b8369 --- /dev/null +++ b/mududb/src/lib.rs @@ -0,0 +1,49 @@ +//! App-facing facade for MuduDB. +//! This crate intentionally exports only interfaces used by Mudu apps. +//! +//! # Feature Guide +//! +//! - [`app` (default)](#feature-app) +//! - [`interface`](#feature-interface) +//! - [`component-model`](#feature-component-model) +//! - [`wasip2`](#feature-wasip2) +//! - [`async`](#feature-async) +//! - [`standalone-adapter`](#feature-standalone-adapter) +//! - [`uniffi-bindings`](#feature-uniffi-bindings) +//! +//! ## Feature `app` +//! Enables app-facing exports (`common`, `types`, `contract`, `binding`, `sys`) +//! and enables `component-model`. +//! +//! ## Feature `interface` +//! Enables [`sys_interface`] re-export as [`crate::sys_interface`]. +//! +//! ## Feature `component-model` +//! Forwards to `sys_interface/component-model`. +//! +//! ## Feature `wasip2` +//! Forwards to `sys_interface/wasip2`. +//! +//! ## Feature `async` +//! Forwards to `sys_interface/async`. +//! +//! ## Feature `standalone-adapter` +//! Forwards to `sys_interface/standalone-adapter`. +//! Enables local standalone syscall execution through the in-process adapter, +//! useful for native integration tests and local debugging without an external runtime host. +//! +//! ## Feature `uniffi-bindings` +//! Forwards to `sys_interface/uniffi-bindings`. + +pub use mudu_binding as binding; +pub use mudu::common; +pub use mudu::error; +pub use mudu; +pub use mudu::m_error; +pub use mudu_contract as contract; +pub use mudu_sys as sys; +pub use mudu_type as types; +pub use mudu_contract::{sql_params, sql_stmt}; + +#[cfg(feature = "interface")] +pub use sys_interface; diff --git a/mudup/Cargo.toml b/mudup/Cargo.toml new file mode 100644 index 0000000..5465fa2 --- /dev/null +++ b/mudup/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "mudup" +version = "0.1.0" +edition = "2024" + +[[bin]] +name = "mudup" +path = "src/main.rs" + +[dependencies] +anyhow = { workspace = true } +clap = { workspace = true, features = ["derive"] } +reqwest = { workspace = true } +serde = { workspace = true } +sha2 = { workspace = true } +tokio = { workspace = true } +toml = { workspace = true } diff --git a/mudup/src/archive.rs b/mudup/src/archive.rs new file mode 100644 index 0000000..b83a20d --- /dev/null +++ b/mudup/src/archive.rs @@ -0,0 +1,189 @@ +use anyhow::{Context, Result, anyhow, bail}; +use std::collections::BTreeSet; +use std::ffi::OsStr; +use std::fs; +use std::path::{Component, Path, PathBuf}; +use std::process::Command; + +use crate::config::{Config, TOOL_BINARIES}; +use crate::util::{clean_dir, run_command}; + +#[derive(Debug)] +struct ArtifactManifest { + version: String, + bin_dir: PathBuf, + lib_list: PathBuf, + files: BTreeSet, +} + +pub(crate) fn extract_toolchain( + cfg: &Config, + archive_path: &Path, + version: &str, +) -> Result { + validate_archive_paths(archive_path, version)?; + + let tmp_dir = cfg.root.join("tmp").join(version); + let install_dir = cfg.root.join("toolchains").join(version); + clean_dir(&tmp_dir)?; + if install_dir.exists() { + bail!("toolchain {version} is already installed"); + } + fs::create_dir_all(&tmp_dir)?; + + run_command( + Command::new("tar") + .arg("-xzf") + .arg(archive_path) + .arg("-C") + .arg(&tmp_dir), + ) + .with_context(|| format!("extract {}", archive_path.display()))?; + + let extracted = tmp_dir.join(version); + if !extracted.is_dir() { + bail!("archive did not contain expected top-level directory {version}"); + } + fs::rename(&extracted, &install_dir)?; + clean_dir(&tmp_dir)?; + Ok(install_dir) +} + +fn validate_archive_paths(archive_path: &Path, version: &str) -> Result<()> { + let output = Command::new("tar") + .arg("-tzf") + .arg(archive_path) + .output() + .with_context(|| format!("list archive {}", archive_path.display()))?; + if !output.status.success() { + bail!("tar failed to list {}", archive_path.display()); + } + + let listing = String::from_utf8(output.stdout)?; + for entry in listing.lines() { + validate_relative_archive_path(entry, version)?; + } + Ok(()) +} + +fn validate_relative_archive_path(entry: &str, version: &str) -> Result<()> { + let path = Path::new(entry); + let mut components = path.components(); + match components.next() { + Some(Component::Normal(first)) if first == OsStr::new(version) => {} + _ => bail!("archive entry escapes expected root: {entry}"), + } + + for component in components { + match component { + Component::Normal(_) => {} + _ => bail!("unsafe archive entry: {entry}"), + } + } + Ok(()) +} + +pub(crate) fn validate_toolchain(install_dir: &Path) -> Result<()> { + let manifest_path = install_dir.join("manifest.txt"); + let manifest = parse_artifact_manifest(&manifest_path)?; + let dir_version = install_dir + .file_name() + .and_then(OsStr::to_str) + .ok_or_else(|| anyhow!("invalid toolchain directory {}", install_dir.display()))?; + if manifest.version != dir_version { + bail!( + "manifest version {} does not match toolchain directory {}", + manifest.version, + dir_version + ); + } + + for bin in TOOL_BINARIES { + let path = install_dir.join(&manifest.bin_dir).join(bin); + if !path.is_file() { + bail!("required binary missing: {}", path.display()); + } + } + + let lib_list = install_dir.join(&manifest.lib_list); + if !lib_list.is_file() { + bail!("library list missing: {}", lib_list.display()); + } + + for file in &manifest.files { + let path = install_dir.join(file); + if !path.exists() { + bail!("manifest file missing: {}", path.display()); + } + } + + Ok(()) +} + +fn parse_artifact_manifest(path: &Path) -> Result { + let text = fs::read_to_string(path) + .with_context(|| format!("read artifact manifest {}", path.display()))?; + let mut version = None; + let mut bin_dir = None; + let mut lib_list = None; + let mut files = BTreeSet::new(); + let mut in_files = false; + + for line in text.lines() { + let line = line.trim(); + if line.is_empty() { + continue; + } + if line == "[files]" { + in_files = true; + continue; + } + if in_files { + files.insert(PathBuf::from(line)); + continue; + } + if let Some((key, value)) = line.split_once('=') { + let value = value.trim(); + match key.trim() { + "version" => version = Some(value.to_string()), + "bin_dir" => bin_dir = Some(PathBuf::from(value)), + "lib_list" => lib_list = Some(PathBuf::from(value)), + _ => {} + } + } + } + + Ok(ArtifactManifest { + version: version.ok_or_else(|| anyhow!("manifest missing version"))?, + bin_dir: bin_dir.unwrap_or_else(|| PathBuf::from("bin")), + lib_list: lib_list.unwrap_or_else(|| PathBuf::from("lib/lib-list.txt")), + files, + }) +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn rejects_archive_path_escape() { + assert!(validate_relative_archive_path("v1/bin/mudud", "v1").is_ok()); + assert!(validate_relative_archive_path("/v1/bin/mudud", "v1").is_err()); + assert!(validate_relative_archive_path("v1/../bin/mudud", "v1").is_err()); + assert!(validate_relative_archive_path("other/bin/mudud", "v1").is_err()); + } + + #[test] + fn parses_artifact_manifest() { + let path = std::env::temp_dir().join(format!("mudup-manifest-{}.txt", std::process::id())); + fs::write( + &path, + "version=v1\nbin_dir=bin\nlib_list=lib/lib-list.txt\n\n[files]\nbin/mudud\n", + ) + .unwrap(); + let manifest = parse_artifact_manifest(&path).unwrap(); + let _ = fs::remove_file(path); + assert_eq!(manifest.version, "v1"); + assert!(manifest.files.contains(Path::new("bin/mudud"))); + } +} diff --git a/mudup/src/checksum.rs b/mudup/src/checksum.rs new file mode 100644 index 0000000..7df74ea --- /dev/null +++ b/mudup/src/checksum.rs @@ -0,0 +1,33 @@ +use anyhow::{Result, bail}; +use sha2::{Digest, Sha256}; +use std::fs; +use std::io::Read; +use std::path::Path; + +pub(crate) fn verify_sha256(path: &Path, expected: &str) -> Result<()> { + let mut file = fs::File::open(path)?; + let mut hasher = Sha256::new(); + let mut buffer = [0_u8; 64 * 1024]; + + loop { + let read = file.read(&mut buffer)?; + if read == 0 { + break; + } + hasher.update(&buffer[..read]); + } + + let actual = format!("{:x}", hasher.finalize()); + let expected = expected.trim().to_ascii_lowercase(); + if actual != expected { + let _ = fs::remove_file(path); + bail!( + "checksum mismatch for {}: expected {}, got {}", + path.display(), + expected, + actual + ); + } + + Ok(()) +} diff --git a/mudup/src/cli.rs b/mudup/src/cli.rs new file mode 100644 index 0000000..4feec27 --- /dev/null +++ b/mudup/src/cli.rs @@ -0,0 +1,52 @@ +use clap::{Args, Parser, Subcommand}; +use std::path::PathBuf; + +use crate::config::{DEFAULT_BASE_URL, DEFAULT_CHANNEL}; + +#[derive(Parser, Debug)] +#[command(name = "mudup")] +#[command(version)] +#[command(about = "MuduDB toolchain installer and version manager")] +pub(crate) struct Cli { + #[arg(long, global = true, help = "Override the mudup root directory.")] + pub(crate) root: Option, + #[arg( + long, + global = true, + default_value = DEFAULT_BASE_URL, + help = "Base URL for release artifacts." + )] + pub(crate) base_url: String, + #[arg( + long, + global = true, + default_value = DEFAULT_CHANNEL, + help = "Release channel used by update and install stable." + )] + pub(crate) channel: String, + #[command(subcommand)] + pub(crate) command: Commands, +} + +#[derive(Subcommand, Debug)] +pub(crate) enum Commands { + /// Install a version such as v20260514.1144, or install the channel with stable. + Install(InstallArgs), + /// Install the latest version from the configured channel. + Update, + /// List installed toolchains. + List, + /// Remove an installed version. + Uninstall(UninstallArgs), +} + +#[derive(Args, Debug)] +pub(crate) struct InstallArgs { + #[arg(help = "Version to install, or stable to use the configured channel.")] + pub(crate) version: String, +} + +#[derive(Args, Debug)] +pub(crate) struct UninstallArgs { + pub(crate) version: String, +} diff --git a/mudup/src/config.rs b/mudup/src/config.rs new file mode 100644 index 0000000..cb5bc59 --- /dev/null +++ b/mudup/src/config.rs @@ -0,0 +1,41 @@ +use anyhow::{Result, anyhow}; +use std::path::PathBuf; + +pub(crate) const DEFAULT_BASE_URL: &str = "https://mududb.dist.scupt.io/"; +pub(crate) const DEFAULT_CHANNEL: &str = "stable"; +pub(crate) const TOOL_BINARIES: &[&str] = &["mudud", "mcli", "mpk", "mgen", "mtp"]; + +#[derive(Debug)] +pub(crate) struct Config { + pub(crate) root: PathBuf, + pub(crate) base_url: String, + pub(crate) channel: String, +} + +impl Config { + pub(crate) fn new(root: Option, base_url: String, channel: String) -> Result { + Ok(Self { + root: resolve_root(root)?, + base_url: base_url.trim_end_matches('/').to_string(), + channel, + }) + } +} + +fn resolve_root(root: Option) -> Result { + if let Some(root) = root { + return Ok(root); + } + if let Ok(root) = std::env::var("MUDUP_HOME") { + return Ok(PathBuf::from(root)); + } + let home = std::env::var_os("HOME").ok_or_else(|| anyhow!("HOME is not set"))?; + Ok(PathBuf::from(home).join(".mudup")) +} + +pub(crate) fn host_triple() -> Result { + match (std::env::consts::ARCH, std::env::consts::OS) { + ("x86_64", "linux") => Ok("x86_64-unknown-linux-gnu".to_string()), + (arch, os) => anyhow::bail!("unsupported host {arch}-{os}"), + } +} diff --git a/mudup/src/libs.rs b/mudup/src/libs.rs new file mode 100644 index 0000000..f28b93a --- /dev/null +++ b/mudup/src/libs.rs @@ -0,0 +1,94 @@ +use anyhow::{Context, Result, anyhow, bail}; +use std::fs; +use std::path::{Path, PathBuf}; +use std::process::Command; + +use crate::config::Config; +use crate::util::{clean_dir, run_command}; + +pub(crate) fn check_system_libraries( + cfg: &Config, + archive_path: &Path, + version: &str, +) -> Result<()> { + let tmp_dir = cfg.root.join("tmp").join(format!("{version}.lib-check")); + clean_dir(&tmp_dir)?; + fs::create_dir_all(&tmp_dir)?; + + run_command( + Command::new("tar") + .arg("-xzf") + .arg(archive_path) + .arg("-C") + .arg(&tmp_dir) + .arg(format!("{version}/lib/lib-list.txt")), + ) + .with_context(|| format!("extract lib-list.txt from {}", archive_path.display()))?; + + let lib_list = tmp_dir.join(version).join("lib").join("lib-list.txt"); + let missing = missing_libraries(&lib_list)?; + clean_dir(&tmp_dir)?; + + if !missing.is_empty() { + bail!( + "missing required dynamic libraries: {}. Install the matching OS packages before activation", + missing.join(", ") + ); + } + + Ok(()) +} + +fn missing_libraries(lib_list: &Path) -> Result> { + if !lib_list.exists() { + return Ok(Vec::new()); + } + + let text = fs::read_to_string(lib_list)?; + let mut missing = Vec::new(); + for line in text.lines() { + let line = line.trim(); + if line.is_empty() || line.starts_with('#') { + continue; + } + let name = line + .split_whitespace() + .next() + .ok_or_else(|| anyhow!("invalid lib-list line: {line}"))?; + if is_os_runtime_library(name) { + continue; + } + if !system_library_exists(name) { + missing.push(name.to_string()); + } + } + Ok(missing) +} + +fn is_os_runtime_library(name: &str) -> bool { + name.starts_with("libc.so") + || name.starts_with("libm.so") + || name.starts_with("ld-linux") + || name.starts_with("ld-musl") +} + +fn system_library_exists(name: &str) -> bool { + let paths = [ + PathBuf::from("/lib"), + PathBuf::from("/lib64"), + PathBuf::from("/usr/lib"), + PathBuf::from("/usr/lib64"), + PathBuf::from("/lib/x86_64-linux-gnu"), + PathBuf::from("/usr/lib/x86_64-linux-gnu"), + ]; + if paths.iter().any(|dir| dir.join(name).exists()) { + return true; + } + + Command::new("ldconfig") + .arg("-p") + .output() + .ok() + .and_then(|output| String::from_utf8(output.stdout).ok()) + .is_some_and(|stdout| stdout.contains(name)) +} diff --git a/mudup/src/main.rs b/mudup/src/main.rs new file mode 100644 index 0000000..2c2b894 --- /dev/null +++ b/mudup/src/main.rs @@ -0,0 +1,76 @@ +mod archive; +mod checksum; +mod cli; +mod config; +mod libs; +mod remote; +mod toolchain; +mod util; + +use anyhow::Result; +use clap::Parser; + +use crate::archive::{extract_toolchain, validate_toolchain}; +use crate::checksum::verify_sha256; +use crate::cli::{Cli, Commands}; +use crate::config::{Config, host_triple}; +use crate::libs::check_system_libraries; +use crate::remote::{ + ReleaseArtifact, artifact_version, download_artifact, fetch_channel_manifest, fetch_sha256, + select_channel_artifact, +}; +use crate::toolchain::{ + activate_toolchain, ensure_layout, list_toolchains, print_path_hint, refresh_proxies, uninstall, +}; + +#[tokio::main(flavor = "current_thread")] +async fn main() { + if let Err(err) = run().await { + eprintln!("error: {err:#}"); + std::process::exit(1); + } +} + +async fn run() -> Result<()> { + let cli = Cli::parse(); + let cfg = Config::new(cli.root, cli.base_url, cli.channel)?; + + match cli.command { + Commands::Install(args) => install(&cfg, &args.version).await, + Commands::Update => install(&cfg, "stable").await, + Commands::List => list_toolchains(&cfg), + Commands::Uninstall(args) => uninstall(&cfg, &args.version), + } +} + +async fn install(cfg: &Config, requested: &str) -> Result<()> { + ensure_layout(&cfg.root)?; + + let host = host_triple()?; + let artifact = if requested == "stable" { + let channel = fetch_channel_manifest(cfg).await?; + select_channel_artifact(&channel, &host)? + } else { + let url = format!( + "{}/{}/mududb-{}-{}.tar.gz", + cfg.base_url, requested, requested, host + ); + let sha256_url = format!("{url}.sha256"); + let sha256 = fetch_sha256(&sha256_url).await?; + ReleaseArtifact { host, url, sha256 } + }; + + let version = artifact_version(&artifact.url).unwrap_or_else(|| requested.to_string()); + let archive_path = download_artifact(cfg, &artifact, &version).await?; + verify_sha256(&archive_path, &artifact.sha256)?; + check_system_libraries(cfg, &archive_path, &version)?; + + let install_dir = extract_toolchain(cfg, &archive_path, &version)?; + validate_toolchain(&install_dir)?; + activate_toolchain(cfg, &version)?; + refresh_proxies(cfg)?; + + println!("installed {version} for {}", artifact.host); + print_path_hint(cfg); + Ok(()) +} diff --git a/mudup/src/remote.rs b/mudup/src/remote.rs new file mode 100644 index 0000000..b78ac71 --- /dev/null +++ b/mudup/src/remote.rs @@ -0,0 +1,101 @@ +use anyhow::{Context, Result, anyhow}; +use serde::Deserialize; +use std::fs; +use std::path::PathBuf; + +use crate::config::Config; + +#[derive(Debug, Deserialize)] +pub(crate) struct ChannelManifest { + latest: String, + releases: Vec, +} + +#[derive(Debug, Deserialize)] +struct Release { + version: String, + artifacts: Vec, +} + +#[derive(Clone, Debug, Deserialize)] +pub(crate) struct ReleaseArtifact { + pub(crate) host: String, + pub(crate) url: String, + pub(crate) sha256: String, +} + +pub(crate) async fn fetch_channel_manifest(cfg: &Config) -> Result { + let url = format!("{}/{}.toml", cfg.base_url, cfg.channel); + let text = reqwest::get(&url) + .await + .with_context(|| format!("download channel manifest {url}"))? + .error_for_status() + .with_context(|| format!("channel manifest request failed: {url}"))? + .text() + .await?; + toml::from_str(&text).with_context(|| format!("parse channel manifest {url}")) +} + +pub(crate) async fn fetch_sha256(url: &str) -> Result { + let text = reqwest::get(url) + .await + .with_context(|| format!("download checksum {url}"))? + .error_for_status() + .with_context(|| format!("checksum request failed: {url}"))? + .text() + .await?; + text.split_whitespace() + .next() + .map(str::to_string) + .ok_or_else(|| anyhow!("empty checksum response from {url}")) +} + +pub(crate) fn select_channel_artifact( + channel: &ChannelManifest, + host: &str, +) -> Result { + let latest = channel + .releases + .iter() + .find(|release| release.version == channel.latest) + .ok_or_else(|| anyhow!("latest release {} not found in channel", channel.latest))?; + + latest + .artifacts + .iter() + .find(|artifact| artifact.host == host) + .cloned() + .ok_or_else(|| anyhow!("no artifact for host {host} in release {}", latest.version)) +} + +pub(crate) async fn download_artifact( + cfg: &Config, + artifact: &ReleaseArtifact, + version: &str, +) -> Result { + let filename = artifact + .url + .rsplit('/') + .next() + .filter(|name| !name.is_empty()) + .ok_or_else(|| anyhow!("artifact URL has no filename: {}", artifact.url))?; + let archive_path = cfg.root.join("downloads").join(filename); + + let bytes = reqwest::get(&artifact.url) + .await + .with_context(|| format!("download artifact {}", artifact.url))? + .error_for_status() + .with_context(|| format!("artifact request failed: {}", artifact.url))? + .bytes() + .await?; + fs::write(&archive_path, bytes)?; + println!("downloaded {version} to {}", archive_path.display()); + Ok(archive_path) +} + +pub(crate) fn artifact_version(url: &str) -> Option { + url.rsplit('/') + .nth(1) + .filter(|version| version.starts_with('v')) + .map(str::to_string) +} diff --git a/mudup/src/toolchain.rs b/mudup/src/toolchain.rs new file mode 100644 index 0000000..db99ac5 --- /dev/null +++ b/mudup/src/toolchain.rs @@ -0,0 +1,117 @@ +use anyhow::{Result, anyhow, bail}; +use std::ffi::OsStr; +use std::fs; +use std::path::Path; + +use crate::config::{Config, TOOL_BINARIES}; +use crate::util::{clean_dir, create_symlink, remove_path}; + +pub(crate) fn ensure_layout(root: &Path) -> Result<()> { + fs::create_dir_all(root.join("downloads"))?; + fs::create_dir_all(root.join("tmp"))?; + fs::create_dir_all(root.join("bin"))?; + fs::create_dir_all(root.join("toolchains"))?; + + let settings = root.join("settings.toml"); + if !settings.exists() { + fs::write( + settings, + format!("manifest_version = 1\nroot = \"{}\"\n", root.display()), + )?; + } + + Ok(()) +} + +pub(crate) fn activate_toolchain(cfg: &Config, version: &str) -> Result<()> { + let toolchain = cfg.root.join("toolchains").join(version); + if !toolchain.is_dir() { + bail!("toolchain does not exist: {}", toolchain.display()); + } + + let current = cfg.root.join("toolchains").join("current"); + let next = cfg.root.join("toolchains").join(".current-next"); + remove_path(&next)?; + create_symlink(Path::new(version), &next)?; + remove_path(¤t)?; + fs::rename(&next, ¤t)?; + Ok(()) +} + +pub(crate) fn refresh_proxies(cfg: &Config) -> Result<()> { + let bin_dir = cfg.root.join("bin"); + fs::create_dir_all(&bin_dir)?; + for bin in TOOL_BINARIES { + let proxy = bin_dir.join(bin); + remove_path(&proxy)?; + let target = Path::new("..") + .join("toolchains") + .join("current") + .join("bin") + .join(bin); + create_symlink(&target, &proxy)?; + } + Ok(()) +} + +pub(crate) fn list_toolchains(cfg: &Config) -> Result<()> { + let toolchains_dir = cfg.root.join("toolchains"); + if !toolchains_dir.exists() { + println!("no toolchains installed"); + return Ok(()); + } + + let current = current_version(cfg).ok(); + for entry in fs::read_dir(toolchains_dir)? { + let entry = entry?; + let name = entry.file_name().to_string_lossy().to_string(); + if name == "current" || name.starts_with('.') { + continue; + } + if entry.path().is_dir() { + if current.as_deref() == Some(name.as_str()) { + println!("{name} (current)"); + } else { + println!("{name}"); + } + } + } + Ok(()) +} + +pub(crate) fn uninstall(cfg: &Config, version: &str) -> Result<()> { + let current = current_version(cfg).ok(); + if current.as_deref() == Some(version) { + bail!("cannot uninstall current toolchain {version}; install another version first"); + } + + let dir = cfg.root.join("toolchains").join(version); + if !dir.exists() { + bail!("toolchain {version} is not installed"); + } + clean_dir(&dir)?; + println!("uninstalled {version}"); + Ok(()) +} + +fn current_version(cfg: &Config) -> Result { + let path = fs::read_link(cfg.root.join("toolchains").join("current"))?; + path.file_name() + .and_then(OsStr::to_str) + .map(str::to_string) + .ok_or_else(|| anyhow!("current toolchain link is invalid")) +} + +pub(crate) fn print_path_hint(cfg: &Config) { + let bin_dir = cfg.root.join("bin"); + if std::env::var_os("PATH") + .and_then(|path| { + std::env::split_paths(&path) + .any(|item| item == bin_dir) + .then_some(()) + }) + .is_none() + { + println!("add {} to PATH", bin_dir.display()); + } +} diff --git a/mudup/src/util.rs b/mudup/src/util.rs new file mode 100644 index 0000000..6f9b2b5 --- /dev/null +++ b/mudup/src/util.rs @@ -0,0 +1,50 @@ +use anyhow::{Result, bail}; +use std::fs; +use std::io; +use std::path::Path; +use std::process::Command; + +pub(crate) fn clean_dir(path: &Path) -> Result<()> { + if path.exists() { + fs::remove_dir_all(path)?; + } + Ok(()) +} + +pub(crate) fn remove_path(path: &Path) -> Result<()> { + match fs::symlink_metadata(path) { + Ok(metadata) if metadata.is_dir() && !metadata.file_type().is_symlink() => { + fs::remove_dir_all(path)?; + } + Ok(_) => { + fs::remove_file(path)?; + } + Err(err) if err.kind() == io::ErrorKind::NotFound => {} + Err(err) => return Err(err.into()), + } + Ok(()) +} + +pub(crate) fn run_command(command: &mut Command) -> Result<()> { + let status = command.status()?; + if !status.success() { + bail!("command failed with status {status}"); + } + Ok(()) +} + +#[cfg(unix)] +pub(crate) fn create_symlink(target: &Path, link: &Path) -> Result<()> { + std::os::unix::fs::symlink(target, link)?; + Ok(()) +} + +#[cfg(windows)] +pub(crate) fn create_symlink(target: &Path, link: &Path) -> Result<()> { + if target.is_dir() { + std::os::windows::fs::symlink_dir(target, link)?; + } else { + std::os::windows::fs::symlink_file(target, link)?; + } + Ok(()) +} diff --git a/script/build-cfg/package-list.json b/script/build-cfg/package-list.json new file mode 100644 index 0000000..6fd75ad --- /dev/null +++ b/script/build-cfg/package-list.json @@ -0,0 +1,11 @@ +{ + "packages": [ + "mudu_wasm", + "example/game-backend", + "example/key-value", + "example/tpcc", + "example/vote", + "example/wallet", + "example/ycsb" + ] +} diff --git a/script/build/build.py b/script/build/build.py index 0c668c7..8bc0292 100644 --- a/script/build/build.py +++ b/script/build/build.py @@ -1,5 +1,6 @@ #!/usr/bin/env python3 import argparse +import json import os import platform import shutil @@ -32,6 +33,12 @@ def __init__(self): def init_colors(self): """Initialize color support for Windows""" + self.RED = Color.RED + self.GREEN = Color.GREEN + self.YELLOW = Color.YELLOW + self.BLUE = Color.BLUE + self.NC = Color.NC + if self.system == "windows": try: import colorama @@ -297,6 +304,8 @@ def parse_args() -> argparse.Namespace: build.py --build # Build project (with release) build.py --build --mode debug --features X # Debug build with X feature build.py --clean --test # Clean cache and run tests +build.py --package # Build packages from script/build-cfg/package-list.json +build.py --package --package-list cfg.json # Build packages from a custom package list """ ) @@ -365,6 +374,11 @@ def parse_args() -> argparse.Namespace: action="store_true", help="Create example .mpk package" ) + parser.add_argument( + "--package-list", + default="script/build-cfg/package-list.json", + help="JSON file listing .mpk package project directories" + ) return parser.parse_args() @@ -386,6 +400,7 @@ def __init__(self): self.toggle_setup_rust = self.args.setup_rust self.toggle_build_project = self.args.build self.toggle_build_package = self.args.package + self.package_list_path = self.args.package_list self.toggle_install_tools = self.args.install_tools self.verbose = self.args.verbose self.build_features = "" @@ -642,22 +657,74 @@ def build_package(self): return True work_dir = os.getcwd() + package_projects = self.load_package_projects(work_dir) + if package_projects is None: + return False - for path in [ - "mudu_wasm", - "example/vote", - "example/wallet" - ]: - os.chdir(path) - cmd = "cargo make package".format(path) + for path in package_projects: + project_dir = os.path.join(work_dir, path) + if not os.path.isdir(project_dir): + self.logger.error(f"{path}, package project directory does not exist") + return False + + os.chdir(project_dir) + makefile = "Makefile.toml" + if not os.path.exists(makefile) and os.path.exists("makefile.toml"): + makefile = "makefile.toml" + if not os.path.exists(makefile): + self.logger.error(f"{path}, cargo-make file not found") + os.chdir(work_dir) + return False + cmd = f"cargo make --makefile {makefile} package" if not self.run_command(cmd, capture_output=True): self.logger.error("{}, build package failed".format(path)) + os.chdir(work_dir) return False os.chdir(work_dir) self.show_artifact() return True + def load_package_projects(self, work_dir: str) -> Optional[List[str]]: + """Load package project directories from JSON config.""" + package_list_path = self.package_list_path + if not os.path.isabs(package_list_path): + package_list_path = os.path.join(work_dir, package_list_path) + + if not os.path.exists(package_list_path): + self.logger.error(f"Package list file not found: {package_list_path}") + return None + + try: + with open(package_list_path, "r", encoding="utf-8") as f: + package_list = json.load(f) + except json.JSONDecodeError as e: + self.logger.error(f"Invalid package list JSON: {package_list_path}: {e}") + return None + except OSError as e: + self.logger.error(f"Failed to read package list: {package_list_path}: {e}") + return None + + if isinstance(package_list, dict): + package_list = package_list.get("packages") + + if not isinstance(package_list, list): + self.logger.error("Package list must be a JSON array or an object with a 'packages' array") + return None + + projects = [] + for item in package_list: + if not isinstance(item, str) or not item.strip(): + self.logger.error("Package project entries must be non-empty strings") + return None + projects.append(item.strip()) + + if not projects: + self.logger.error("Package list is empty") + return None + + return projects + def show_configuration(self): """Display build configuration""" self.logger.info(f"Platform: {self.platform_manager.platform.value}") diff --git a/script/build/inspect_iouring_env.sh b/script/build/inspect_iouring_env.sh new file mode 100644 index 0000000..a7c56b1 --- /dev/null +++ b/script/build/inspect_iouring_env.sh @@ -0,0 +1,39 @@ +#!/usr/bin/env bash +set -euo pipefail + +echo "== io_uring environment ==" +echo "date: $(date -Is)" +echo "user: $(id)" +echo "uname: $(uname -a)" + +echo +echo "== kernel toggles ==" +if [[ -r /proc/sys/kernel/io_uring_disabled ]]; then + echo -n "kernel.io_uring_disabled=" + cat /proc/sys/kernel/io_uring_disabled +else + echo "kernel.io_uring_disabled=" +fi + +echo +echo "== process status ==" +grep -E '^(Seccomp|CapEff|NoNewPrivs):' /proc/self/status || true + +echo +echo "== cgroup ==" +cat /proc/self/cgroup || true + +echo +echo "== container hints ==" +if [[ -f /.dockerenv ]]; then + echo "/.dockerenv=present" +else + echo "/.dockerenv=absent" +fi + +if command -v docker >/dev/null 2>&1; then + echo + echo "== docker socket ==" + ls -l /var/run/docker.sock 2>/dev/null || true +fi + diff --git a/sys_interface/standalone_adapter.md b/sys_interface/standalone_adapter.md index a024e7f..f10d6c0 100644 --- a/sys_interface/standalone_adapter.md +++ b/sys_interface/standalone_adapter.md @@ -17,6 +17,7 @@ Use `sync_api` for synchronous native code, or add `async` and use `async_api` f sys_interface = { path = "../sys_interface", features = ["standalone-adapter"] } ``` + For async native code: ```toml @@ -24,6 +25,7 @@ For async native code: sys_interface = { path = "../sys_interface", features = ["standalone-adapter", "async"] } ``` + After that, native builds can directly call the standalone adapter through: - `sys_interface::sync_api::*` for synchronous code diff --git a/test_utils/Cargo.toml b/test_utils/Cargo.toml index 0bb84e1..00bdc7d 100644 --- a/test_utils/Cargo.toml +++ b/test_utils/Cargo.toml @@ -4,4 +4,4 @@ version = "0.1.0" edition = "2024" [dependencies] -arbitrary = { workspace = true } \ No newline at end of file +arbitrary = { workspace = true } diff --git a/testing/tests/linux/test_tpcc_concurrent_procedure.rs b/testing/tests/linux/test_tpcc_concurrent_procedure.rs index ed56ff5..e04264c 100644 --- a/testing/tests/linux/test_tpcc_concurrent_procedure.rs +++ b/testing/tests/linux/test_tpcc_concurrent_procedure.rs @@ -26,18 +26,17 @@ use mudu_utils::debug::debug_serve; fn tpcc_procedure_concurrent_terminals_metrics() -> RS<()> { let log_level = std::env::var("TPCC_TEST_LOG_LEVEL").unwrap_or_else(|_| "info".to_string()); log_setup(&log_level); + if !mudu_sys::io_uring_available() { + info!("skip tpcc concurrent test: io_uring unavailable"); + return Ok(()); + } + info!("enable tpcc concurrent test: io_uring available"); let _ = thread::spawn(move || { debug_serve(Default::default(), 1801); }); info!(log_level = %log_level, "starting tpcc concurrent procedure test"); - let Some(ctx) = TestContext::new(ServerMode::IOUring)? else { - eprintln!("skip tpcc concurrent test: local TCP/HTTP bind is not permitted"); - return Ok(()); - }; - let _server = ctx.start_server()?; - let cfg = TpccBenchCfg::from_env(); info!( terminals = cfg.terminals, @@ -61,6 +60,12 @@ fn tpcc_procedure_concurrent_terminals_metrics() -> RS<()> { }; debug!(mpk_path = %mpk_path.display(), "resolved tpcc mpk path"); + let Some(ctx) = TestContext::new(ServerMode::IOUring)? else { + eprintln!("skip tpcc concurrent test: local TCP/HTTP bind is not permitted"); + return Ok(()); + }; + let _server = ctx.start_server()?; + let runtime = tokio::runtime::Builder::new_current_thread() .enable_all() .build() diff --git a/testing/tests/linux/wallet_mpk.rs b/testing/tests/linux/wallet_mpk.rs index 7cea60f..bc55e42 100644 --- a/testing/tests/linux/wallet_mpk.rs +++ b/testing/tests/linux/wallet_mpk.rs @@ -11,12 +11,14 @@ use mudu_contract::tuple::tuple_datum::TupleDatum; use mudu_runtime::backend::backend::Backend; use mudu_runtime::backend::mududb_cfg::{MuduDBCfg, RoutingMode, ServerMode}; use mudu_runtime::service::runtime_opt::ComponentTarget; +use mudu_utils::log::log_setup; use mudu_utils::notifier::{Notifier, notify_wait}; use serde_json::{Value, json}; use std::fs; use std::path::{Path, PathBuf}; use std::thread::{self, JoinHandle}; use testing::{reserve_port, wait_until_port_ready}; +use tracing::info; #[test] fn wallet_mpk_http_end_to_end() -> RS<()> { @@ -118,6 +120,13 @@ fn wallet_mpk_http_end_to_end() -> RS<()> { #[test] fn wallet_mpk_via_mudu_cli_library() -> RS<()> { + log_setup("info"); + if !mudu_sys::io_uring_available() { + info!("skip wallet mudu_cli io_uring test: io_uring unavailable"); + return Ok(()); + } + info!("enable wallet mudu_cli io_uring test: io_uring available"); + let Some(ctx) = TestContext::new(ServerMode::IOUring)? else { eprintln!("skip wallet mudu_cli io_uring test: local TCP/HTTP bind is not permitted"); return Ok(()); diff --git a/testing/tests/test_copy_roundtrip.rs b/testing/tests/test_copy_roundtrip.rs index 6521257..61bd076 100644 --- a/testing/tests/test_copy_roundtrip.rs +++ b/testing/tests/test_copy_roundtrip.rs @@ -17,6 +17,11 @@ use tracing::{debug, info}; #[test] fn copy_from_to_roundtrip_iouring() -> RS<()> { log_setup("debug"); + if !mudu_sys::io_uring_available() { + info!("skip copy roundtrip iouring test: io_uring unavailable"); + return Ok(()); + } + info!("enable copy roundtrip iouring test: io_uring available"); let Some(ctx) = TestContext::new(ServerMode::IOUring)? else { eprintln!("skip copy roundtrip test: local TCP/HTTP bind is not permitted"); return Ok(()); @@ -170,7 +175,15 @@ fn run_shell_script_outputs(ctx: &TestContext, app: &str, input: &str) -> RS RS<()> { + log_setup("info"); + if !mudu_sys::io_uring_available() { + info!("skip interactive mcli io_uring test: io_uring unavailable"); + return Ok(()); + } + info!("enable interactive mcli io_uring test: io_uring available"); let Some(ctx) = TestContext::new(ServerMode::IOUring)? else { eprintln!("skip interactive mcli io_uring test: local TCP/HTTP bind is not permitted"); return Ok(()); @@ -31,6 +39,12 @@ fn interactive_mcli_shell_io_uring() -> RS<()> { #[test] fn interactive_mcli_shell_io_uring_tui() -> RS<()> { + log_setup("info"); + if !mudu_sys::io_uring_available() { + info!("skip interactive mcli io_uring tui test: io_uring unavailable"); + return Ok(()); + } + info!("enable interactive mcli io_uring tui test: io_uring available"); let Some(ctx) = TestContext::new(ServerMode::IOUring)? else { eprintln!("skip interactive mcli io_uring tui test: local TCP/HTTP bind is not permitted"); return Ok(()); diff --git a/testing/tests/test_restart.rs b/testing/tests/test_restart.rs index 4adf6cb..a3cc43a 100644 --- a/testing/tests/test_restart.rs +++ b/testing/tests/test_restart.rs @@ -12,10 +12,16 @@ use std::net::{TcpListener, TcpStream}; use std::path::PathBuf; use std::thread::{self, JoinHandle}; use std::time::Duration; +use tracing::info; #[test] fn test_mudud_restart_persistence_iouring() -> RS<()> { log_setup("info"); + if !mudu_sys::io_uring_available() { + info!("skip restart persistence iouring test: io_uring unavailable"); + return Ok(()); + } + info!("enable restart persistence iouring test: io_uring available"); let Some(ctx) = TestContext::new(ServerMode::IOUring)? else { eprintln!("skip test: local TCP/HTTP bind is not permitted"); return Ok(());