* Moving away from auto_increment

! Initial id size will stay as u64 but u128 are easily the next major change
This change shouldn't break clients written in high level languages since most already use 128's under the hood anyway
- This commit also removes the auto_increment flag from basically everything that uses RNG id's
This commit is contained in:
shockrah 2021-03-24 01:14:37 -07:00
parent d02084a22c
commit a1f86fdf6e
8 changed files with 32 additions and 35 deletions

View File

@ -11,3 +11,4 @@ mysql_async = "0.23.1"
serde = { version = "1.0.117", features = [ "derive" ] }
tokio = { version = "1", features = ["fs", "io-util"] }
rand = "0.8.3"

3
json-api/db/Makefile Normal file
View File

@ -0,0 +1,3 @@
default:
cargo build --release

View File

@ -5,7 +5,7 @@ use mysql_async::error::Error as SqlError;
use crate::{VarChar, UBigInt, Integer};
use crate::{sql_err, no_conn, Response};
use rand::RngCore;
pub const VOICE_CHANNEL: Integer = 1;
pub const TEXT_CHANNEL: Integer = 2;
@ -58,19 +58,15 @@ impl crate::Channel {
// bounds are literally [1, 2]
if kind == TEXT_CHANNEL || kind == VOICE_CHANNEL {
let conn = p.get_conn().await?;
let q = "INSERT INTO channels (name, description, kind) VALUES (:n, :d, :k)";
let conn = conn.drop_exec(q, params!{
let q = "INSERT INTO channels (id, name, description, kind) VALUES (:i, :n, :d, :k)";
let id = rand::rngs::OsRng.next_u64(); // generate id's randomly for channels
conn.drop_exec(q, params!{
"i" => id,
"n" => name,
"d" => description,
"k" => kind
}).await?;
let q = "SELECT id FROM channels WHERE name = :name";
let (_, id): (_, Option<UBigInt>) =
conn.first_exec(q, params!{"name" => name}).await?;
// probably safe but honestly could fail if the net goes down right here
let id = id.unwrap();
Ok(Response::Row(Self {
id,
name: name.to_string(),

View File

@ -7,7 +7,7 @@ use crate::{Response, no_conn, sql_err};
use crate::{UBigInt, Integer, VarChar};
use crate::{PublicMember, Member};
use rand::RngCore;
pub const STATUS_ONLINE: Integer = 0;
@ -95,34 +95,25 @@ impl Member {
//! @returns : on_failure => Err(SomeBS)
let conn = p.get_conn().await?;
let conn = conn.drop_exec(
let id: u64 = rand::rngs::OsRng.next_u64();
conn.drop_exec(
"INSERT INTO members(secret, name, status, permissions)
VALUES(:secret, :name, :status, :permissions)",
VALUES(:id, :secret, :name, :status, :permissions)",
mysql_async::params!{
"id" => id,
"secret" => secret.clone(),
"name" => name.clone(),
"status" => STATUS_ONLINE,
"permissions" => perms
}).await?;
let (_, opt_id): (Conn, Option<UBigInt>) = conn.first_exec(
"SELECT id FROM members WHERE secret = :secret",
params!{
"secret" => secret.clone()
}).await?;
if let Some(id) = opt_id {
return Ok(Response::Row(Self {
id,
secret: secret.into(),
name: name.into(),
status: STATUS_ONLINE,
permissions: perms
}))
}
return Ok(Response::Empty);
return Ok(Response::Row(Self {
id,
secret: secret.into(),
name: name.into(),
status: STATUS_ONLINE,
permissions: perms
}))
}
pub async fn update_perms(p: &Pool, uid: UBigInt, permissions: UBigInt) -> Result<UBigInt, SqlError> {

View File

@ -15,6 +15,8 @@ use crate::{Response, sql_err};
use crate::{UBigInt, BigInt, VarChar};
use crate::{Message, UserMessage};
use rand::RngCore;
const MAX_MESSAGES: u64 = 1000;
@ -46,9 +48,10 @@ impl Message {
let conn = p.get_conn().await?;
let q = "INSERT INTO messages
(time, content, content_type, author_id, channel_id)
VALUES (:time, :content, :ctype, :author, :channel)";
(id, time, content, content_type, author_id, channel_id)
VALUES (id, :time, :content, :ctype, :author, :channel)";
let id: u64 = rand::rngs::OsRng.next_u64();
let now: i64 = SystemTime::now()
.duration_since(UNIX_EPOCH)
.expect("System time `NOW` failed")
@ -60,6 +63,7 @@ impl Message {
Ok(Response::RestrictedInput("Large text not allowed".into()))
} else {
let res = conn.prep_exec(q, params!{
"id" => id,
"time" => now,
"content" => content,
"ctype" => content_type,
@ -84,6 +88,7 @@ impl Message {
let content_ref = format!("{cid}-{time}.{ext}", cid=cid, time=now, ext=extension);
let res = conn.prep_exec(q, params!{
"id" => id,
"time" => now,
"content" => &content_ref, // store a ref to a file instead of the actual payload
"ctype" => content_type,

View File

@ -1,6 +1,6 @@
-- TODO: somehow make the name colum unique
CREATE TABLE IF NOT EXISTS `channels` (
`id` BIGINT UNSIGNED NOT NULL auto_increment,
`id` BIGINT UNSIGNED NOT NULL,
`name` VARCHAR(255) NOT NULL,
`description` VARCHAR(2048),
`kind` INTEGER NOT NULL,

View File

@ -1,7 +1,7 @@
-- TODO: add rate limiter in some form
-- PERMISSIONS start at 0 and full perms => all F's
CREATE TABLE IF NOT EXISTS `members`(
`id` BIGINT UNSIGNED NOT NULL auto_increment,
`id` BIGINT UNSIGNED NOT NULL,
`secret` varchar(256) NOT NULL,
`name` varchar(256) NOT NULL,
`status` integer NOT NULL,

View File

@ -1,7 +1,8 @@
-- Time stamp is _not_ in ms
CREATE TABLE IF NOT EXISTS `messages`(
`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
`id` BIGINT UNSIGNED NOT NULL,
`time` BIGINT NOT NULL,
-- Assuming content-type is `not` text/plain this will be a reference to some auto-named file
`content` VARCHAR(4096) NOT NULL,
`content_type` VARCHAR(10) NOT NULL,
`author_id` BIGINT UNSIGNED NOT NULL,