notesmachine/server/nm-store/docs/reserved.rs

191 lines
5.6 KiB
Rust

/async fn insert_note<'e, E>(executor: E, id: &str, content: &str, notetype: &str) -> SqlResult<i64>
where
E: 'e + Executor<'e, Database = Sqlite>,
{
lazy_static! {
static ref INSERT_ONE_NOTE_SQL: String = include_str!("sql/insert_one_note.sql");
}
let now = chrono::Utc::now();
Ok(sqlx::query(INSERT_ONE_NOTE_SQL)
.bind(&id)
.bind(&content)
.bind(&notetype)
.bind(&now)
.bind(&now)
.bind(&now)
.execute(executor)
.await?
.last_insert_rowid())
}
#[derive(Clone, FromRow)]
struct JustSlugs {
slug: String
}
// Given an initial string and an existing collection of slugs,
// generate a new slug that does not conflict with the current
// collection.
async fn generate_slug<'e, E>(executor: E, title: &str) -> SqlResult<String>
where
E: 'e + Executor<'e, Database = Sqlite>,
{
lazy_static! {
static ref RE_JUSTNUM: Regex = Regex::new(r"-\d+$").unwrap();
}
lazy_static! {
static ref RE_CAPNUM: Regex = Regex::new(r"-(\d+)$").unwrap();
}
let initial_slug = slugify::slugify(title);
let sample_slug = RE_JUSTNUM.replace_all(slug, "");
let similar_slugs: Vec<JustSlugs> = sqlx::query("SELECT slug FROM pages WHERE slug LIKE '?%';")
.bind(&sample_slug)
.execute(executor)
.await?;
let slug_counters = similar_slugs
.iter()
.map(|slug| RE_CAPNUM.captures(slug.slug))
.filter_map(|cap| cap.get(1).unwrap().parse::<u32>().unwrap())
.collect();
match slug_counters.len() {
0 => Ok(initial_slug),
_ => {
slug_counters.sort_unstable();
return Ok(format!("{}-{}", initial_slug, slug_counters.pop() + 1))
}
}
}
async fn insert_page<'e, E>(executor: E, page: &RawPage) -> SqlResult<i64>
where
E: 'e + Executor<'e, Database = Sqlite>,
{
let insert_one_page_sql = include_str!("sql/insert_one_page.sql");
Ok(sqlx::query(insert_one_page_sql)
.bind(&page.id)
.bind(&page.title)
.bind(&page.note_id)
.bind(&page.creation_date)
.bind(&page.updated_date)
.bind(&page.lastview_date)
.execute(&mut tx)
.await?
.last_insert_rowid())
}
/// Given a title, insert a new page. All dates are today, and the slug is
/// generated as above:
async fn insert_new_page_for_title<'e, E>(executor: E, title: &str) -> SqlResult<Page> {
// /// Fetch page by title
// ///
// /// This is the most common use case, in which a specific title
// /// has been requested of the server via POST. The page always
// /// exists; if it doesn't, it will be automatically generated.
// pub async fn get_page_by_title(&slug, slug: &title) -> NoteResult<(Page, Notes)> {
// let mut tx = self.0.begin().await?;
// let maybe_page = sqlx::query_as(select_one_page_by_title)
// .bind(&title)
// .fetch_one(&tx)
// .await;
// let page = match maybe_page {
// Ok(page) => page,
// Err(sqlx::Error::NotFound) => insert_new_page_for_title(tx, title),
// Err(a) => return Err(a)
// };
// let notes = sqlx::query_as(select_note_collection_for_root)
// .bind(page.note_id)
// .fetch(&tx)
// .await?;
// tx.commit().await?;
// Ok((page, notes))
// }
//
//
//
//
//
//
//
//
//
//
// /// This will erase all the data in the database. Only use this
// /// if you're sure that's what you want.
// pub async fn reset_database(&self) -> NoteResult<()> {
// let initialize_sql = include_str!("sql/initialize_database.sql");
// sqlx::query(initialize_sql).execute(&*self.0).await?;
// Ok(())
// }
//
// async fn create_new_page(&self, title: &str) -> SqlResult<Page, Vec<Notes>> {
// let now = chrono::Utc::now();
// let new_note_id = friendly_id::create();
//
// let mut tx = self.0.begin().await?;
// let new_slug = generate_slug(&mut tx, title);
// let note_id = insert_note(&mut tx, &new_note_id, &"", &"page").await?;
// insert_page(&mut tx, NewPage {
// slug,
// title,
// note_id,
// creation_date: now,
// updated_date: now,
// lastview_date: now
// }).await;
// tx.commit();
// self.fetch_one_page(title)
// }
//
// async fn fetch_one_page(&self, title: &str) ->
//
// pub async fn fetch_page(&self, title: &str) -> SqlResult<(Page, Vec<Notes>)> {
// match self.fetch_one_page(title) {
// Ok((page, notes)) => Ok((page, notes)),
// Err(NotFound) => self.create_new_page(title),
// Err(e) => Err(e)
// }
// }
//
// pub async fn fetch_raw_page(&self, id: &str) -> SqlResult<RawPage> {
// let select_one_page_sql = include_str!("sql/select_one_page.sql");
// sqlx::query_as(select_one_page_sql).bind(&id).fetch_one(&*self.0).await
// }
//
// pub async fn fetch_raw_note(&self, id: &str) -> SqlResult<RawNote> {
// let select_one_note_sql = include_str!("sql/select_one_note.sql");
// sqlx::query_as(select_one_note_sql).bind(&id).fetch_one(&*self.0).await
// }
//
// pub async fn insert_note(&self, id: &str, content: &str, notetype: &str) -> SqlResult<i64> {
// insert_note(&*self.0, id, content, notetype).await
// }
//
// pub async fn update_raw_note(&self, id: &str, content: &str) -> NoteResult<()> {
// let update_one_note_sql = include_str!("sql/update_one_note.sql");
// let now = chrono::Utc::now();
// let rows_updated = sqlx::query(update_one_note_sql)
// .bind(&content)
// .bind(&now)
// .bind(&now)
// .bind(&id)
// .execute(&*self.0).await?
// .rows_affected();
// match rows_updated {
// 1 => Ok(()),
// _ => Err(NoteStoreError::NotFound)
// }
// }
//
// // TODO: We're returning the raw page with the raw note id, note
// // the friendly ID. Is there a disconnect there? It's making me
// // furiously to think.
//