Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(query-engine-wasm): reduce size of postgres Query Engine after regression #5018

Merged
merged 12 commits into from
Oct 15, 2024
Merged
4 changes: 4 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ tokio = { version = "1", features = [
"time",
] }
chrono = { version = "0.4.38", features = ["serde"] }
derive_more = "0.99.17"
user-facing-errors = { path = "./libs/user-facing-errors" }
uuid = { version = "1", features = ["serde", "v4", "v7", "js"] }
indoc = "2.0.1"
Expand Down
3 changes: 3 additions & 0 deletions libs/crosstarget-utils/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
derive_more.workspace = true
enumflags2.workspace = true
futures = "0.3"

[target.'cfg(target_arch = "wasm32")'.dependencies]
Expand All @@ -17,3 +19,4 @@ pin-project = "1"

[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
tokio.workspace = true
regex.workspace = true
23 changes: 0 additions & 23 deletions libs/crosstarget-utils/src/common.rs

This file was deleted.

3 changes: 3 additions & 0 deletions libs/crosstarget-utils/src/common/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
pub mod regex;
pub mod spawn;
pub mod timeout;
37 changes: 37 additions & 0 deletions libs/crosstarget-utils/src/common/regex.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
use derive_more::Display;

#[derive(Debug, Display)]
#[display(fmt = "Regular expression error: {message}")]
pub struct RegExpError {
pub message: String,
}

impl std::error::Error for RegExpError {}

/// Flag modifiers for regular expressions.
#[enumflags2::bitflags]
#[derive(Copy, Clone, Debug, PartialEq)]
#[repr(u8)]
pub enum RegExpFlags {
IgnoreCase = 0b0001,
Multiline = 0b0010,
}

impl RegExpFlags {
pub fn as_str(&self) -> &'static str {
match self {
Self::IgnoreCase => "i",
Self::Multiline => "m",
}
}
}

pub trait RegExpCompat {
/// Searches for the first match of this regex in the haystack given, and if found,
/// returns not only the overall match but also the matches of each capture group in the regex.
/// If no match is found, then None is returned.
fn captures(&self, message: &str) -> Option<Vec<String>>;

/// Tests if the regex matches the input string.
fn test(&self, message: &str) -> bool;
}
8 changes: 8 additions & 0 deletions libs/crosstarget-utils/src/common/spawn.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
use derive_more::Display;

#[derive(Debug, Display)]
#[display(fmt = "Failed to spawn a future")]

pub struct SpawnError;

impl std::error::Error for SpawnError {}
7 changes: 7 additions & 0 deletions libs/crosstarget-utils/src/common/timeout.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
use derive_more::Display;

#[derive(Debug, Display)]
#[display(fmt = "Operation timed out")]
pub struct TimeoutError;

impl std::error::Error for TimeoutError {}
3 changes: 2 additions & 1 deletion libs/crosstarget-utils/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,5 @@ mod native;
#[cfg(not(target_arch = "wasm32"))]
pub use crate::native::*;

pub use common::SpawnError;
pub use crate::common::regex::RegExpCompat;
pub use crate::common::spawn::SpawnError;
1 change: 1 addition & 0 deletions libs/crosstarget-utils/src/native/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
pub mod regex;
pub mod spawn;
pub mod task;
pub mod time;
41 changes: 41 additions & 0 deletions libs/crosstarget-utils/src/native/regex.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
use enumflags2::BitFlags;
use regex::{Regex as NativeRegex, RegexBuilder};

use crate::common::regex::{RegExpCompat, RegExpError, RegExpFlags};

pub struct RegExp {
inner: NativeRegex,
}

impl RegExp {
jkomyno marked this conversation as resolved.
Show resolved Hide resolved
pub fn new(pattern: &str, flags: BitFlags<RegExpFlags>) -> Result<Self, RegExpError> {
let mut builder = RegexBuilder::new(pattern);

if flags.contains(RegExpFlags::Multiline) {
builder.multi_line(true);
}

if flags.contains(RegExpFlags::IgnoreCase) {
builder.case_insensitive(true);
}

let inner = builder.build().map_err(|e| RegExpError { message: e.to_string() })?;

Ok(Self { inner })
}
}

impl RegExpCompat for RegExp {
fn captures(&self, message: &str) -> Option<Vec<String>> {
self.inner.captures(message).map(|captures| {
captures
.iter()
.flat_map(|capture| capture.map(|cap| cap.as_str().to_owned()))
.collect()
})
}

fn test(&self, message: &str) -> bool {
self.inner.is_match(message)
}
}
2 changes: 1 addition & 1 deletion libs/crosstarget-utils/src/native/spawn.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use futures::TryFutureExt;
use std::future::Future;

use crate::common::SpawnError;
use crate::common::spawn::SpawnError;

pub fn spawn_if_possible<F>(future: F) -> impl Future<Output = Result<F::Output, SpawnError>>
where
Expand Down
2 changes: 1 addition & 1 deletion libs/crosstarget-utils/src/native/time.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use std::{
time::{Duration, Instant},
};

use crate::common::TimeoutError;
use crate::common::timeout::TimeoutError;

pub struct ElapsedTimeCounter {
instant: Instant,
Expand Down
1 change: 1 addition & 0 deletions libs/crosstarget-utils/src/wasm/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
pub mod regex;
pub mod spawn;
pub mod task;
pub mod time;
38 changes: 38 additions & 0 deletions libs/crosstarget-utils/src/wasm/regex.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
use enumflags2::BitFlags;
use js_sys::RegExp as JSRegExp;

use crate::common::regex::{RegExpCompat, RegExpError, RegExpFlags};

pub struct RegExp {
inner: JSRegExp,
}

impl RegExp {
pub fn new(pattern: &str, flags: BitFlags<RegExpFlags>) -> Result<Self, RegExpError> {
let mut flags: String = flags.into_iter().map(|flag| flag.as_str()).collect();

// Global flag is implied in `regex::Regex`, so we match that behavior for consistency.
flags.push('g');

Ok(Self {
inner: JSRegExp::new(pattern, &flags),
})
}
}

impl RegExpCompat for RegExp {
fn captures(&self, message: &str) -> Option<Vec<String>> {
self.inner.exec(message).map(|matches| {
// We keep the same number of captures as the number of groups in the regex pattern,
// but we guarantee that the captures are always strings.
matches
.iter()
.map(|match_value| match_value.try_into().ok().unwrap_or_default())
.collect()
})
}

fn test(&self, input: &str) -> bool {
self.inner.test(input)
}
}
2 changes: 1 addition & 1 deletion libs/crosstarget-utils/src/wasm/spawn.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use futures::TryFutureExt;
use tokio::sync::oneshot;
use wasm_bindgen_futures::spawn_local;

use crate::common::SpawnError;
use crate::common::spawn::SpawnError;

pub fn spawn_if_possible<F>(future: F) -> impl Future<Output = Result<F::Output, SpawnError>>
where
Expand Down
2 changes: 1 addition & 1 deletion libs/crosstarget-utils/src/wasm/time.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use std::time::Duration;
use wasm_bindgen::prelude::*;
use wasm_bindgen_futures::JsFuture;

use crate::common::TimeoutError;
use crate::common::timeout::TimeoutError;

#[wasm_bindgen]
extern "C" {
Expand Down
1 change: 1 addition & 0 deletions quaint/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ url.workspace = true
hex = "0.4"
itertools.workspace = true
regex.workspace = true
enumflags2.workspace = true

either = { version = "1.6" }
base64 = { version = "0.12.3" }
Expand Down
8 changes: 4 additions & 4 deletions quaint/src/connector/postgres/error.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use regex::Regex;
use crosstarget_utils::{regex::RegExp, RegExpCompat};
use enumflags2::BitFlags;
use std::fmt::{Display, Formatter};

use crate::error::{DatabaseConstraint, Error, ErrorKind, Name};
Expand Down Expand Up @@ -30,9 +31,8 @@ impl Display for PostgresError {
}

fn extract_fk_constraint_name(message: &str) -> Option<String> {
let re = Regex::new(r#"foreign key constraint "([^"]+)""#).unwrap();
re.captures(message)
.and_then(|caps| caps.get(1).map(|m| m.as_str().to_string()))
let re = RegExp::new(r#"foreign key constraint "([^"]+)""#, BitFlags::empty()).unwrap();
re.captures(message).and_then(|caps| caps.get(1).cloned())
}

impl From<PostgresError> for Error {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ uuid.workspace = true
indexmap.workspace = true
query-engine-metrics = { path = "../../metrics" }
cuid = { git = "https://github.com/prisma/cuid-rust", branch = "wasm32-support" }
derive_more = "0.99.17"
derive_more.workspace = true

[dependencies.query-structure]
path = "../../query-structure"
Expand Down
Loading