nene

nene is a command-line tool to generate Rust code for Google Cloud Spanner.
nene uses database schema to generate code by using Information Schema. nene runs SQL queries against tables in INFORMATION_SCHEMA to fetch metadata for a database, and applies the metadata to Go templates to generate code/models to acccess Cloud Spanner.

crates.io CI

Installation

cargo install nene

Usage

```bash export RUSTLOG=info export SPANNERDSN=projects/local-project/instances/test-instance/databases/local-database

if you don't use emulator use GOOGLEAPPLICATIONCREDENTIALS instead of SPANNEREMULATORHOST

export SPANNEREMULATORHOST=localhost:9010 mkdir ./gen nene -o ./gen -j ```

Generated file with default template

Default template generates the files for google-cloud-spanner.

```rust // DON'T EDIT. this code is generated by nene. use googlecloudgoogleapis::spanner::v1::Mutation; use googlecloudgax::grpc::Status; use googlecloudspanner::client::{RunInTxError, TxError}; use googlecloudspanner::key::Key; use googlecloudspanner::mutation::{ delete, insertorupdatestruct, insertstruct, replacestruct, updatestruct, }; use googlecloudspanner::reader::AsyncIterator; use googlecloudspanner::row::{Error as RowError, Row, Struct, TryFromStruct}; use googlecloudspanner::statement::{Kinds, Statement, ToKind, ToStruct, Types}; use googlecloudspanner::transaction::Transaction; use googlecloudspanner::transaction::CallOptions; use googlecloudspanner::value::CommitTimestamp; use std::convert::TryFrom; use crate::domain::model::readbystatement;

pub const TABLENAME: &str = "User"; pub const COLUMNUSERID: &str = "UserId"; pub const COLUMNPREMIUM: &str = "Premium"; pub const COLUMNUPDATEDAT: &str = "UpdatedAt";

[derive(Debug,Clone,Default,Table,serde::Serialize,serde::Deserialize)]

pub struct User { pub userid: String, pub premium: bool, pub updatedat: chrono::DateTime, }

impl User { pub fn insert(&self) -> Mutation { insertstruct(TABLENAME, &self) }

pub fn update(&self) -> Mutation { updatestruct(TABLENAME, &self) }

pub fn replace(&self) -> Mutation { replacestruct(TABLENAME, &self) }

pub fn insertorupdate(&self) -> Mutation { insertorupdatestruct(TABLENAME, &self) }

pub fn delete(&self) -> Mutation { delete(TABLENAME, Key::key(&self.userid)) }

pub async fn findbypk( tx: &mut Transaction, userid: &String, options: Option ) -> Result, RunInTxError> { let mut stmt = Statement::new("SELECT * From User WHERE UserId = @UserId"); stmt.addparam(COLUMNUSERID, userid); let mut rows = Self::readbystatement(tx, stmt, options).await?; if !rows.isempty() { Ok(rows.pop()) } else { Ok(None) } } } ```