Browse Source

mergin on server

pull/25/head
Alexey Velikiy 3 years ago
parent
commit
cf4d48ebb9
  1. 3
      server/src/api/segments.rs
  2. 36
      server/src/services/data_service.rs

3
server/src/api/segments.rs

@ -41,6 +41,7 @@ pub mod filters {
mod handlers { mod handlers {
use hastic::services::data_service; use hastic::services::data_service;
use hastic::services::data_service::Segment;
use super::models::{CreateResponse, Db, ListOptions}; use super::models::{CreateResponse, Db, ListOptions};
use crate::api::BadQuery; use crate::api::BadQuery;
@ -58,7 +59,7 @@ mod handlers {
db: Db, db: Db,
) -> Result<impl warp::Reply, warp::Rejection> { ) -> Result<impl warp::Reply, warp::Rejection> {
match db.write().insert_segment(&segment) { match db.write().insert_segment(&segment) {
Ok(id) => Ok(API::json(&CreateResponse { id })), Ok(segment) => Ok(API::json(&segment)),
Err(e) => { Err(e) => {
println!("{:?}", e); println!("{:?}", e);
Err(warp::reject::custom(BadQuery)) Err(warp::reject::custom(BadQuery))

36
server/src/services/data_service.rs

@ -1,4 +1,4 @@
use rusqlite::{params, Connection}; use rusqlite::{Connection, ToSql, params};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
@ -42,21 +42,30 @@ impl DataService {
} }
// returns id of created segment // returns id of created segment
pub fn insert_segment(&self, segment: &Segment) -> anyhow::Result<SegmentId> { pub fn insert_segment(&self, segment: &Segment) -> anyhow::Result<Segment> {
let id: SegmentId = repeat_with(fastrand::alphanumeric) let id: SegmentId = repeat_with(fastrand::alphanumeric)
.take(ID_LENGTH) .take(ID_LENGTH)
.collect(); .collect();
{
// merging // merging
// TODO extract intersected ids // TODO extract intersected ids
// TODO: merge with other segments
let sgms = self.get_segments_intersected(segment.from, segment.to)?;
let mut min = segment.from;
let mut max = segment.to;
let mut ids_to_delete = Vec::<SegmentId>::new();
for s in sgms {
min = min.min(s.from);
max = max.max(s.to);
ids_to_delete.push(s.id.unwrap());
} }
self.delete_segments(&ids_to_delete)?;
// TODO: merge with other segments
self.connection.lock().unwrap().execute( self.connection.lock().unwrap().execute(
"INSERT INTO segment (id, start, end) VALUES (?1, ?2, ?3)", "INSERT INTO segment (id, start, end) VALUES (?1, ?2, ?3)",
params![id, segment.from, segment.to], params![id, min, max],
)?; )?;
Ok(id) Ok(Segment { id: Some(id), from: min, to: max })
} }
pub fn get_segments_inside(&self, from: u64, to: u64) -> anyhow::Result<Vec<Segment>> { pub fn get_segments_inside(&self, from: u64, to: u64) -> anyhow::Result<Vec<Segment>> {
@ -98,7 +107,14 @@ impl DataService {
Ok(res) Ok(res)
} }
pub fn delete_segments(&self, ids: &Vec<SegmentId>) { pub fn delete_segments(&self, ids: &Vec<SegmentId>) -> anyhow::Result<usize> {
let v = Rc::new(ids); // TODO: here could be sql injection if you substitute id with string :)
let conn = self.connection.lock().unwrap();
let ids_comma = ids.iter().map(|id| "\"".to_string() + id + "\"").collect::<Vec<String>>().join(",");
let query_str = format!("DELETE FROM segment WHERE id in ({})", ids_comma);
let mut stmt = conn.prepare(&query_str)?;
let res = stmt.execute([])?;
Ok(res)
} }
} }

Loading…
Cancel
Save