Files
mrdeploy/src/conf/mod.rs

140 lines
4.3 KiB
Rust

use rusqlite::{Connection, Result};
use fallible_iterator::FallibleIterator;
pub mod storage;
const PATH: &str = "mdeploy.db";
pub struct ConfServer{
ip: String,
port: String,
ip_top_limit: u8,
ip_base_limit: u8,
}
pub struct Instance {
id: i64,
pub docker_id: String,
pub ip: String,
pub domain: String,
pub image: i64,
}
pub struct InstanceStorage {
con: Connection,
}
impl InstanceStorage {
pub fn new() -> Result<Self> {
let con = Connection::open(PATH)?;
let ret = Self {
con : con,
};
ret.create_table()?;
Ok(ret)
}
fn create_table(&self) -> Result<()> {
self.con.execute_batch(
"BEGIN;
CREATE TABLE IF NOT EXISTS images(
id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT UNIQUE);
CREATE TABLE IF NOT EXISTS l_instances(
id INTEGER PRIMARY KEY AUTOINCREMENT,
docker_id TEXT,
ip TEXT,
domain TEXT,
image INTEGER,
FOREIGN KEY(image) REFERENCES images(id));
COMMIT;"
)
}
fn insert_image(&self, image: String) -> Result<()>{
let mut stmt = self.con.prepare("INSERT INTO images(name) values(?1)")?;
stmt.execute([image])?;
Ok(())
}
fn load_instances(&mut self) -> Result<Vec<Instance>> {
let mut stmt = self.con.prepare("select id, docker_id, ip, domain, image from l_instances")?;
let mut rows = stmt.query([])?;
rows.map(|r| Ok(Instance{
id: r.get::<_, i64>(0)?,
docker_id: r.get::<_, String>(1)?,
ip: r.get::<_, String>(2)?,
domain: r.get::<_, String>(3)?,
image: r.get::<_, i64>(4)?,
})).collect()
}
fn load_images(&mut self) -> Result<Vec<(String, i64)>> {
let mut stmt = self.con.prepare("select id, name from images")?;
let mut rows = stmt.query([])?;
rows.map(|row| Ok((row.get::<_, String>(1)?, row.get::<_, i64>(0)?))).collect()
}
fn get_image_id(&self, image: String) -> Result<Option<i64>> {
let mut stmt = self.con.prepare("select id from images where name = ?1")?;
let mut rows = stmt.query([image])?;
Ok(match rows.next()? {
Some(i) => Some(i.get::<_, i64>(0)?),
None => None,
})
}
pub fn get_image_name(&self, id: i64) -> Result<String> {
let mut stmt = self.con.prepare("select name from images where id = ?1")?;
let mut rows = stmt.query([id])?;
Ok(rows.next()?.unwrap().get::<_, String>(0)?)
}
fn get_instance_id(&self, domain: String) -> Result<Option<i64>> {
let mut stmt = self.con.prepare("select id from l_instances where domain = ?1")?;
let mut rows = stmt.query([domain])?;
Ok(match rows.next()? {
Some(i) => Some(i.get::<_, i64>(0)?),
None => None,
})
}
pub fn new_instance(&mut self, docker_id: String, ip: String, domain: String, image: i64) -> Result<Instance>{
//let image_id = self.create_or_get_image_id(image.clone(), 0)?;
let mut stmt = self.con.prepare("INSERT INTO l_instances(docker_id, ip, domain, image) values(?1, ?2, ?3, ?4)")?;
stmt.execute([docker_id.clone(),
ip.clone(),
domain.clone(),
image.to_string()])?;
Ok(Instance {
id: image,
docker_id: docker_id,
ip: ip,
domain: domain,
image: image,
})
}
pub fn image_to_id(&self, image: String) -> Result<i64> {
self.create_or_get_image_id(image, 0)
}
fn create_or_get_image_id(&self, image: String, mut depth: i64) -> Result<i64> {
if depth > 1 {
return Err(rusqlite::Error::QueryReturnedNoRows);
}
depth+=1;
match self.get_image_id(image.clone()) {
Ok(Some(id)) => Ok(id),
Ok(None) => {
self.insert_image(image.clone())?;
self.create_or_get_image_id(image, depth)
}
Err(_e) => {
self.insert_image(image.clone())?;
self.create_or_get_image_id(image, depth)
}
}
}
}