sentence endpoint is paginated now

This commit is contained in:
Brandon Thomas committed 2020-06-04 22:34:59 -04:00
1 parent e0d10496c3
commit 9568b8333b
7 files changed
+137 -13

No files matched your search

+75
View File
@@ -1547,11 +1547,26 @@
"@types/react": "*"
}
},
"@types/react-tag-autocomplete": {
"version": "5.12.0",
"resolved": "https://registry.npmjs.org/@types/react-tag-autocomplete/-/react-tag-autocomplete-5.12.0.tgz",
"integrity": "sha512-QvPBUrXnkU5e3EaHiXQcI0oRsV1JwvL2vvgXtY5x7SkW19O3FRGFdcPg4+SA545+pcIsijf1O2wQ/sCCTeEe9w==",
"dev": true,
"requires": {
"@types/react": "*"
}
},
"@types/stack-utils": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-1.0.1.tgz",
"integrity": "sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw=="
},
"@types/tabulator-tables": {
"version": "4.6.7",
"resolved": "https://registry.npmjs.org/@types/tabulator-tables/-/tabulator-tables-4.6.7.tgz",
"integrity": "sha512-mmPuILf3jdiutn1qbqSAZRVOUPUemsjeTClHC8iwEdi6wjIptz/t5e2xYO+EVlia7XvWAiD00Y+y1iF2cKkxbw==",
"dev": true
},
"@types/testing-library__dom": {
"version": "6.11.1",
"resolved": "https://registry.npmjs.org/@types/testing-library__dom/-/testing-library__dom-6.11.1.tgz",
@@ -4829,6 +4844,12 @@
"es6-symbol": "^3.1.1"
}
},
"es6-promise": {
"version": "4.2.8",
"resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz",
"integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==",
"dev": true
},
"es6-symbol": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz",
@@ -6366,6 +6387,12 @@
"resolved": "https://registry.npmjs.org/hsla-regex/-/hsla-regex-1.0.0.tgz",
"integrity": "sha1-wc56MWjIxmFAM6S194d/OyJfnDg="
},
"html-attributes": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/html-attributes/-/html-attributes-1.1.0.tgz",
"integrity": "sha1-ggJ6T6x6YHDqbBjMOIauoY1t6gk=",
"dev": true
},
"html-comment-regex": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/html-comment-regex/-/html-comment-regex-1.1.2.tgz",
@@ -8320,6 +8347,12 @@
"resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz",
"integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0="
},
"lodash.isplainobject": {
"version": "4.0.6",
"resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz",
"integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=",
"dev": true
},
"lodash.memoize": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz",
@@ -9520,6 +9553,17 @@
"resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
"integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns="
},
"pick-react-known-prop": {
"version": "0.1.5",
"resolved": "https://registry.npmjs.org/pick-react-known-prop/-/pick-react-known-prop-0.1.5.tgz",
"integrity": "sha512-SnDf64AVdvqoAFpHeZUKT9kdn40Ellj84CPALRxYWqNJ6r6f44eAAT+Jtkb0Suhiw7yg5BdOFAQ25OJnjG+afw==",
"dev": true,
"requires": {
"html-attributes": "^1.1.0",
"lodash.isplainobject": "^4.0.6",
"svg-attributes": "^1.0.0"
}
},
"pify": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
@@ -11092,6 +11136,26 @@
"workbox-webpack-plugin": "4.3.1"
}
},
"react-tabulator": {
"version": "0.12.7",
"resolved": "https://registry.npmjs.org/react-tabulator/-/react-tabulator-0.12.7.tgz",
"integrity": "sha512-PQVdB20yMhtq7tt+tkToZKWEdqNPT3EshGl7E3TX222KKhvLk6hz8saJGvzAgCePYGyKkhpRh2dsbl6KQSj2eA==",
"dev": true,
"requires": {
"@types/react-tag-autocomplete": "^5.6.0",
"dotenv": "^8.2.0",
"es6-promise": "^4.2.8",
"pick-react-known-prop": "^0.1.5",
"react-tag-autocomplete": "^5.7.1",
"tabulator-tables": "^4.6.2"
}
},
"react-tag-autocomplete": {
"version": "5.13.1",
"resolved": "https://registry.npmjs.org/react-tag-autocomplete/-/react-tag-autocomplete-5.13.1.tgz",
"integrity": "sha512-ECcQnizAxw8VnEDUfCKuA2ZDQ0Fyxds3kVtE4NVAhJvBYOMMgkRNAM3UwyEXAQ0h7nnCwmIA+czJiwso07Mrqw==",
"dev": true
},
"read-pkg": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz",
@@ -12545,6 +12609,12 @@
"has-flag": "^3.0.0"
}
},
"svg-attributes": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/svg-attributes/-/svg-attributes-1.0.0.tgz",
"integrity": "sha1-tcWWjzYke32+OFMgfyqcaK2Aa/w=",
"dev": true
},
"svg-parser": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/svg-parser/-/svg-parser-2.0.2.tgz",
@@ -12608,6 +12678,11 @@
}
}
},
"tabulator-tables": {
"version": "4.6.3",
"resolved": "https://registry.npmjs.org/tabulator-tables/-/tabulator-tables-4.6.3.tgz",
"integrity": "sha512-e/SeG1jU5ryg0OlBpKo89ZmKTYdgfRYLRT366Vu17jIrTFxtyaAhgg95N7L0vzvnvQHuSATUY3UynHzYh2iDYw=="
},
"tapable": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz",
+4 -1
View File
@@ -13,6 +13,8 @@
"react": "^16.12.0",
"react-dom": "^16.12.0",
"react-scripts": "3.3.0",
"react-tabulator": "^0.12.7",
"tabulator-tables": "^4.6.3",
"typescript": "^3.7.4"
},
"scripts": {
@@ -42,6 +44,7 @@
"devDependencies": {
"@types/howler": "^2.1.2",
"@types/react": "^16.9.17",
"@types/react-dom": "^16.9.4"
"@types/react-dom": "^16.9.4",
"@types/tabulator-tables": "^4.6.7"
}
}
+1
View File
@@ -28,6 +28,7 @@ class ApiConfig {
case "localhost":
switch (url.port) {
case "8080":
case "7000":
console.log('environment', 'localhost_js');
environment = Environment.LOCALHOST_JS;
break;
+7 -2
View File
@@ -2,13 +2,18 @@ import React from 'react';
import './App.css';
import { MainComponent } from './components/MainComponent';
import ApiConfig from './ApiConfig';
import { SentencesComponent } from './components/sentences/SentencesComponent';
const App: React.FC = () => {
let apiConfig = new ApiConfig();
//
//<h1>Neural TTS</h1>
//<MainComponent apiConfig={apiConfig} />
//
return (
<div className="App">
<h1>Neural TTS</h1>
<MainComponent apiConfig={apiConfig} />
<br />
<SentencesComponent />
</div>
);
}
+14 -2
View File
@@ -4,6 +4,7 @@ use crate::database::connector::{DatabaseConnector, MysqlPooledConnection};
use crate::schema::sentences;
//use crate::schema::sentences::dsl::*;
use diesel::prelude::*;
use diesel::expression::dsl::count_star;
#[derive(Queryable, Serialize, Debug)]
pub struct Sentence {
@@ -35,11 +36,22 @@ impl NewSentence {
impl Sentence {
pub fn load(db_connector: &DatabaseConnector, limit: i64) -> AnyhowResult<Vec<Sentence>> {
/// Get a count of all sentence records.
pub fn count(db_connector: &DatabaseConnector) -> AnyhowResult<i64> {
let pooled_connection : MysqlPooledConnection = db_connector.get_pooled_connection()?;
let count : i64 = sentences::dsl::sentences
.select(count_star())
.first(&*pooled_connection)?;
Ok(count)
}
/// Load sentence records
pub fn load(db_connector: &DatabaseConnector, limit: i64, offset: i64) -> AnyhowResult<Vec<Sentence>> {
let pooled_connection : MysqlPooledConnection = db_connector.get_pooled_connection()?;
let results = sentences::dsl::sentences
.limit(limit)
.order(sentences::dsl::id.desc())
.offset(offset)
.order(sentences::dsl::id.asc())
.load::<Sentence>(&pooled_connection)?;
Ok(results)
}
+35 -8
View File
@@ -1,7 +1,4 @@
use actix_web::web::{
Data,
Json,
};
use actix_web::web::{Data, Json, Query};
use actix_web::http::StatusCode;
use actix_web::{HttpRequest, get, HttpResponse, Either};
@@ -9,20 +6,46 @@ use std::sync::Arc;
use crate::AppState;
use crate::database::model::Sentence;
/// Request with pagination from Tabulator.js
#[derive(Deserialize, Debug)]
pub struct SentencesRequest {
page: Option<i64>,
per_page: Option<i64>,
}
/// Paginated responses in the format expected by Tabulator.js
#[derive(Serialize, Debug)]
pub struct SentencesResult {
sentences: Vec<Sentence>,
record_count: i64, // Added for my own purposes
last_page: i64,
data: Vec<Sentence>,
}
#[get("/sentences")]
pub async fn get_sentences(
_request: HttpRequest,
query: Query<SentencesRequest>,
app_state: Data<Arc<AppState>>
) -> Either<Json<SentencesResult>, std::io::Result<HttpResponse>>{
debug!("SentencesRequest: {:?}", query);
let app_state = app_state.into_inner();
let limit = 1000;
let sentences = match Sentence::load(&app_state.database_connector, limit) {
let sentence_count = Sentence::count(&app_state.database_connector)
.ok()
.unwrap_or(0);
debug!("Total Sentence Records: {:?}", sentence_count);
let page = query.page.unwrap_or(1);
let limit = query.per_page.unwrap_or(100);
let offset = limit * (page - 1);
debug!("Sentence Query Limit: {}, Offset: {}", limit, offset);
let sentences = match Sentence::load(&app_state.database_connector, limit, offset) {
Err(e) => {
error!("Couldn't query database for sentences: {:?}", e);
return Either::B(Ok(HttpResponse::build(StatusCode::INTERNAL_SERVER_ERROR)
@@ -32,7 +55,11 @@ pub async fn get_sentences(
Ok(results) => results,
};
let last_page = sentence_count / limit;
Either::A(Json(SentencesResult {
sentences: sentences,
data: sentences,
last_page,
record_count: sentence_count,
}))
}
+1
View File
@@ -205,6 +205,7 @@ async fn run_server(app_state: AppState, server_args: ServerArgs) -> std::io::Re
.allowed_methods(vec!["GET", "POST", "OPTIONS"])
.allowed_headers(vec![
http::header::ACCEPT,
http::header::ACCESS_CONTROL_ALLOW_ORIGIN, // Tabulator Ajax
http::header::CONTENT_TYPE,
http::header::HeaderName::from_static("x-requested-with") // Tabulator Ajax sends
])