Browse Source

segment ids

pull/25/head
Alexey Velikiy 3 years ago
parent
commit
ff4f998f6d
  1. 21
      client/src/components/Graph.vue
  2. 10
      client/src/components/hastic_pod/index.ts
  3. 5
      client/src/services/segments.ts
  4. 6
      client/src/types/segment.ts
  5. 19
      server/src/api/segments.rs
  6. 23
      server/src/services/data_service.rs

21
client/src/components/Graph.vue

@ -9,10 +9,12 @@ import { getMetrics } from '../services/metrics.service';
import { postSegment } from '../services/segments'; import { postSegment } from '../services/segments';
import { LineTimeSerie } from "@chartwerk/line-pod"; import { LineTimeSerie } from "@chartwerk/line-pod";
import _ from "lodash";
import { SegmentArray } from '@/types/segment_array'; import { SegmentArray } from '@/types/segment_array';
import { Segment, SegmentId } from '@/types/segment';
import _ from "lodash";
// TODO: move to store
async function resolveData(range: TimeRange): Promise<LineTimeSerie[]> { async function resolveData(range: TimeRange): Promise<LineTimeSerie[]> {
// TODO: return segments from the promise too // TODO: return segments from the promise too
const endTime = Math.floor(range.to); const endTime = Math.floor(range.to);
@ -35,6 +37,21 @@ async function resolveData(range: TimeRange): Promise<LineTimeSerie[]> {
} }
} }
// TODO: move to store
async function addSegment(segment: Segment): Promise<SegmentId> {
try {
const id = await postSegment(segment);
return id;
} catch (e) {
this.$notify({
title: "Error during saving segment",
text: e,
type: 'error'
});
console.error(e);
}
}
export default defineComponent({ export default defineComponent({
name: 'Graph', name: 'Graph',
props: {}, props: {},
@ -46,7 +63,7 @@ export default defineComponent({
var pod = new HasticPod( var pod = new HasticPod(
document.getElementById('chart'), document.getElementById('chart'),
resolveData.bind(this), resolveData.bind(this),
postSegment, addSegment.bind(this),
s s
); );
pod.render(); pod.render();

10
client/src/components/hastic_pod/index.ts

@ -107,16 +107,18 @@ export class HasticPod extends LinePod {
} }
} }
protected addLabeling(from: number, to: number) { protected async addLabeling(from: number, to: number) {
// TODO: implement // TODO: implement
// TODO: persistance of the label // TODO: persistance of the label
// const id = this.getNewTempSegmentId(); const id = this.getNewTempSegmentId();
from = Math.floor(from); from = Math.floor(from);
to = Math.ceil(to); to = Math.ceil(to);
const segment = new Segment(undefined, from, to); const segment = new Segment(id, from, to);
const storedId = await this._usc(segment);
segment.id = storedId;
this._segmentSet.addSegment(segment); this._segmentSet.addSegment(segment);
this._usc(segment);
this.renderSegment(segment); this.renderSegment(segment);
} }

5
client/src/services/segments.ts

@ -20,8 +20,7 @@ export async function getSegments(from: number, to: number) {
} }
export async function postSegment(segment: Segment): Promise<SegmentId> { export async function postSegment(segment: Segment): Promise<SegmentId> {
delete segment.id; // because we post a new segment segment.id = undefined; // because we post a new segment. It's a hack
const resp = await axios.post(SEGMENTS_API_URL, segment); const resp = await axios.post(SEGMENTS_API_URL, segment);
console.log(resp); return resp['data']['id'];
return 10 + "";
} }

6
client/src/types/segment.ts

@ -2,9 +2,9 @@ export type SegmentId = string;
export class Segment { export class Segment {
constructor(private _id: SegmentId | undefined, public from: number, public to: number) { constructor(private _id: SegmentId | undefined, public from: number, public to: number) {
// if(this._id === undefined) { if(this._id === undefined) {
// throw new Error('id is undefined'); throw new Error('id is undefined');
// } }
if(isNaN(+from)) { if(isNaN(+from)) {
throw new Error('from can`t be NaN'); throw new Error('from can`t be NaN');
} }

19
server/src/api/segments.rs

@ -42,8 +42,7 @@ pub mod filters {
mod handlers { mod handlers {
use hastic::services::data_service; use hastic::services::data_service;
use super::models::Db; use super::models::{ Db, ListOptions, CreateResponse };
use super::models::ListOptions;
use crate::api::BadQuery; use crate::api::BadQuery;
use crate::api::API; use crate::api::API;
@ -61,16 +60,19 @@ mod handlers {
) -> Result<impl warp::Reply, warp::Rejection> { ) -> Result<impl warp::Reply, warp::Rejection> {
// Just return a JSON array of todos, applying the limit and offset. // Just return a JSON array of todos, applying the limit and offset.
match db.write().insert_segment(&segment) { match db.write().insert_segment(&segment) {
Ok(segments) => Ok(API::json(&segments)), Ok(id) => Ok(API::json(&CreateResponse { id })),
Err(e) => Err(warp::reject::custom(BadQuery)), Err(e) => {
println!("{:?}", e);
Err(warp::reject::custom(BadQuery))
}
} }
} }
} }
mod models { mod models {
use hastic::services::data_service; use hastic::services::data_service::{self, SegmentId};
use parking_lot::RwLock; use parking_lot::RwLock;
use serde::Deserialize; use serde::{Deserialize, Serialize};
use std::sync::Arc; use std::sync::Arc;
pub type Db = Arc<RwLock<data_service::DataService>>; pub type Db = Arc<RwLock<data_service::DataService>>;
@ -81,4 +83,9 @@ mod models {
pub from: u64, pub from: u64,
pub to: u64, pub to: u64,
} }
#[derive(Debug, Serialize )]
pub struct CreateResponse {
pub id: SegmentId,
}
} }

23
server/src/services/data_service.rs

@ -4,9 +4,14 @@ use serde::{Deserialize, Serialize};
use std::sync::{Arc, Mutex}; use std::sync::{Arc, Mutex};
use std::iter::repeat_with;
const ID_LENGTH: usize = 20;
pub type SegmentId = String;
#[derive(Debug, Serialize, Deserialize)] #[derive(Debug, Serialize, Deserialize)]
pub struct Segment { pub struct Segment {
pub id: Option<u64>, pub id: Option<SegmentId>,
pub from: u64, pub from: u64,
pub to: u64, pub to: u64,
} }
@ -23,7 +28,7 @@ impl DataService {
let conn = Connection::open("./data.db")?; let conn = Connection::open("./data.db")?;
conn.execute( conn.execute(
"CREATE TABLE IF NOT EXISTS segment ( "CREATE TABLE IF NOT EXISTS segment (
id INTEGER PRIMARY KEY, id TEXT PRIMARY KEY,
start INTEGER NOT NULL, start INTEGER NOT NULL,
end INTEGER NOT NULL end INTEGER NOT NULL
)", )",
@ -35,19 +40,23 @@ impl DataService {
}) })
} }
pub fn insert_segment(&self, segment: &Segment) -> anyhow::Result<u64> { // returns id of created segment
pub fn insert_segment(&self, segment: &Segment) -> anyhow::Result<SegmentId> {
let id: SegmentId = repeat_with(fastrand::alphanumeric)
.take(ID_LENGTH)
.collect();
// TODO: merge with other segments // TODO: merge with other segments
self.connection.lock().unwrap().execute( self.connection.lock().unwrap().execute(
"INSERT INTO segment (start, end) VALUES (?1, ?2)", "INSERT INTO segment (id, start, end) VALUES (?1, ?2, ?3)",
params![segment.from, segment.to], params![id, segment.from, segment.to],
)?; )?;
Ok(10) Ok(id)
} }
pub fn get_segments(&self, from: u64, to: u64) -> anyhow::Result<Vec<Segment>> { pub fn get_segments(&self, from: u64, to: u64) -> anyhow::Result<Vec<Segment>> {
let conn = self.connection.lock().unwrap(); let conn = self.connection.lock().unwrap();
let mut stmt = let mut stmt =
conn.prepare("SELECT id, start, end FROM person WHERE ?1 < start AND end < ?2")?; conn.prepare("SELECT id, start, end FROM segment WHERE ?1 < start AND end < ?2")?;
let res = stmt let res = stmt
.query_map(params![from, to], |row| { .query_map(params![from, to], |row| {

Loading…
Cancel
Save