From cf4d48ebb9ee65b713bf2d4a61074ee5089c9ba0 Mon Sep 17 00:00:00 2001 From: Alexey Velikiy Date: Fri, 29 Oct 2021 20:42:17 +0300 Subject: [PATCH] mergin on server --- server/src/api/segments.rs | 3 ++- server/src/services/data_service.rs | 36 +++++++++++++++++++++-------- 2 files changed, 28 insertions(+), 11 deletions(-) diff --git a/server/src/api/segments.rs b/server/src/api/segments.rs index 2572c6f..f4fe6dd 100644 --- a/server/src/api/segments.rs +++ b/server/src/api/segments.rs @@ -41,6 +41,7 @@ pub mod filters { mod handlers { use hastic::services::data_service; + use hastic::services::data_service::Segment; use super::models::{CreateResponse, Db, ListOptions}; use crate::api::BadQuery; @@ -58,7 +59,7 @@ mod handlers { db: Db, ) -> Result { match db.write().insert_segment(&segment) { - Ok(id) => Ok(API::json(&CreateResponse { id })), + Ok(segment) => Ok(API::json(&segment)), Err(e) => { println!("{:?}", e); Err(warp::reject::custom(BadQuery)) diff --git a/server/src/services/data_service.rs b/server/src/services/data_service.rs index 607789e..e667ab1 100644 --- a/server/src/services/data_service.rs +++ b/server/src/services/data_service.rs @@ -1,4 +1,4 @@ -use rusqlite::{params, Connection}; +use rusqlite::{Connection, ToSql, params}; use serde::{Deserialize, Serialize}; @@ -42,21 +42,30 @@ impl DataService { } // returns id of created segment - pub fn insert_segment(&self, segment: &Segment) -> anyhow::Result { + pub fn insert_segment(&self, segment: &Segment) -> anyhow::Result { let id: SegmentId = repeat_with(fastrand::alphanumeric) .take(ID_LENGTH) .collect(); - { - // merging - // TODO extract intersected ids + + // merging + // 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::::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( "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> { @@ -98,7 +107,14 @@ impl DataService { Ok(res) } - pub fn delete_segments(&self, ids: &Vec) { - let v = Rc::new(ids); + pub fn delete_segments(&self, ids: &Vec) -> anyhow::Result { + // 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::>().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) } } +