KeiSeiKit-1.0/_primitives/_rust/kei-content-store/src/campaigns.rs
Parfii-bot a4e667de10 KeiSeiKit-public — clean state
Single-commit clean baseline after security scrub of niche-tells,
project codenames, internal jargon, and contributor-email leaks.

Contents:
- 100 Rust crates (_primitives/_rust/)
- 37 agent manifests (_manifests/) + generated specs (_generated/)
- 67 user-invocable skills (skills/)
- 33 hooks (hooks/)
- Composition blocks (_blocks/)
- Documentation (docs/, README.md)
- TS adapter packages (_ts_packages/)
- Assembler (_assembler/)
- Roles (_roles/)
- Templates (_templates/)
- Forgejo CI (.forgejo/)

Author: Denis Parfionovich <info@greendragon.info>

License: see LICENSE.
2026-05-01 12:09:03 +08:00

44 lines
1.7 KiB
Rust

//! Campaigns + campaign_assets join.
//!
//! `create_campaign` delegates to `kei_entity_store::verbs::create` under
//! `CAMPAIGNS_SCHEMA` — plain INTEGER-PK CRUD, engine-owned since
//! 2026-04-23.
//!
//! `attach_asset` / `campaign_assets` stay bespoke: `campaign_assets`
//! has a composite `(campaign_id, asset_id)` PK with no single-column
//! id, so it cannot be described as an `EntitySchema` (engine requires
//! exactly one PK field). The attach path also uses `INSERT OR IGNORE`
//! for idempotent joins, which the engine's plain-INSERT `create` verb
//! would not preserve.
use crate::schema::CAMPAIGNS_SCHEMA;
use crate::store::Store;
use anyhow::{anyhow, Result};
use kei_entity_store::verbs::create as v_create;
use rusqlite::params;
use serde_json::json;
pub fn create_campaign(store: &Store, name: &str, description: &str) -> Result<i64> {
let input = json!({ "name": name, "description": description });
let v = v_create::run(store.conn(), &CAMPAIGNS_SCHEMA, input)
.map_err(|e| anyhow!("{e}"))?;
v["id"].as_i64().ok_or_else(|| anyhow!("missing id in create response"))
}
pub fn attach_asset(store: &Store, campaign_id: i64, asset_id: i64) -> Result<()> {
store.conn().execute(
"INSERT OR IGNORE INTO campaign_assets (campaign_id, asset_id) VALUES (?1,?2)",
params![campaign_id, asset_id],
)?;
Ok(())
}
pub fn campaign_assets(store: &Store, campaign_id: i64) -> Result<Vec<i64>> {
let mut stmt = store.conn().prepare(
"SELECT asset_id FROM campaign_assets WHERE campaign_id=?1"
)?;
let rows = stmt.query_map(params![campaign_id], |r| r.get::<_, i64>(0))?;
let mut out = Vec::new();
for r in rows { out.push(r?); }
Ok(out)
}