やってみる

アウトプットすべく己を導くためのブログ。その試行錯誤すらたれ流す。

Rust自習(人称辞典 2)

 ランダムで1件取得する。

成果物

Cargo.toml

[dependencies]
diesel = { version = "1.4.2", features = ["sqlite", "chrono"] }
dotenv = "0.14.1"
chrono = { version = "0.4", features = ["serde"] }
serde = { version = "1.0.97", features = ["derive"] }
serde_json = "1.0.40"
json5 = "0.2.5"
rand = "0"

 初回ビルドでダウンロード&コンパイルjson5chronoは今のところ使ってないしその予定もないが一応。

cargo build

schema.rs

 前回までで以下のように自動生成されている。

table! {
    FirstPersons (id) {
        id -> Nullable<Integer>,
        value -> Text,
        ruby -> Nullable<Text>,
        comment -> Nullable<Text>,
    }
}

 idNullableを外して以下のように修正する。

table! {
    FirstPersons (id) {
        id -> Integer,
        value -> Text,
        ruby -> Nullable<Text>,
        comment -> Nullable<Text>,
    }
}

 これを元にmodels.rsファイルを作成する。

models.rs

#[derive(Queryable)]
pub struct FirstPersons {
    pub id: i32,
    pub value: String,
    pub ruby: Option<String>,
    pub comment: Option<String>,
}

lib.rs

#[macro_use]
extern crate diesel;
extern crate dotenv;

pub mod models;
pub mod schema;

use diesel::prelude::*;
use dotenv::dotenv;
use std::env;

pub fn establish_connection() -> SqliteConnection {
    dotenv().ok();
    let database_url = env::var("DATABASE_URL").expect("DATABASE_URL must be set");
    SqliteConnection::establish(&database_url)
        .unwrap_or_else(|_| panic!("Error connecting to {}", database_url))
}

main.rs

extern crate diesel;
extern crate personal_pronoun;

use self::diesel::prelude::*;
use self::personal_pronoun::models::*;
use self::personal_pronoun::*;
use rand::{distributions::{Distribution, Standard},Rng};

fn main() {
    use personal_pronoun::schema::FirstPersons::dsl::*;
    let connection = establish_connection();

    let count: i64 = personal_pronoun::schema::FirstPersons::dsl::FirstPersons.count().get_result(&connection).unwrap();
    println!("count: {}", count);
    let mut rng = rand::thread_rng();
    let rnd_id = rng.gen_range(0, count-1);
    println!("rnd_id: {}", rnd_id);

    let results = personal_pronoun::schema::FirstPersons::dsl::FirstPersons
        .filter(id.eq(rnd_id as i32))
        .load::<self::personal_pronoun::models::FirstPersons>(&connection)
        .expect("Error loading table.");

    for first in results {
        println!("{}", first.value);
    }
}

 FirstPersonsという名前がschema.rsmodels.rsで重複していたのでフルネーム指定した。

cargo run
count: 123
rnd_id: 35
あてくし

 LIKE句でカンマを含む値にマッチさせたい。SQL文なら以下のような。

sqlite> select * from FirstPersons where (',' || comment || ',') LIKE '%,私的表現,%';
  • *私的表現*
  • *,私的表現*
  • *私的表現,*
  • *,私的表現,*
    let results = personal_pronoun::schema::FirstPersons::dsl::FirstPersons
        .filter(id.eq(rnd_id as i32)
            .and(comment.eq("私的表現").or(like("私的表現,%")).or(like("%,私的表現")).or(like("%,私的表現,%")))
        )

対象環境

$ uname -a
Linux raspberrypi 4.19.42-v7+ #1219 SMP Tue May 14 21:20:58 BST 2019 armv7l GNU/Linux

前回まで