Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions quaint/src/ast/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ mod json_unquote;
mod lower;
mod maximum;
mod minimum;
mod now;
mod row_number;
mod row_to_json;
mod search;
Expand All @@ -32,6 +33,7 @@ pub use json_unquote::*;
pub use lower::*;
pub use maximum::*;
pub use minimum::*;
pub use now::*;
pub use row_number::*;
pub use row_to_json::*;
pub use search::*;
Expand Down Expand Up @@ -90,6 +92,7 @@ pub(crate) enum FunctionType<'a> {
UuidToBin,
UuidToBinSwapped,
Uuid,
Now,
}

impl<'a> Aliasable<'a> for Function<'a> {
Expand Down
26 changes: 26 additions & 0 deletions quaint/src/ast/function/now.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
use super::{Function, FunctionType};
use crate::ast::Expression;

/// Generates the SQL function NOW() returning the current timestamp in MySQL/PostgreSQL.
/// ```rust
/// # use quaint::{ast::*, visitor::{Visitor, Mysql, Postgres}};
/// # fn main() -> Result<(), quaint::error::Error> {
///
/// let query = Select::default().value(now());
///

Check failure on line 10 in quaint/src/ast/function/now.rs

View workflow job for this annotation

GitHub Actions / tests (--features=all-native)

cannot find function `now` in this scope
/// let (sql, _) = Mysql::build(query)?;
/// assert_eq!("SELECT NOW()", sql);
///
/// let (sql, _) = Postgres::build(query)?;
/// assert_eq!("SELECT NOW()", sql);
/// # Ok(())
/// # }
/// ```
pub fn native_now() -> Expression<'static> {
let func = Function {
typ_: FunctionType::Now,
alias: None,
};

func.into()
}
1 change: 1 addition & 0 deletions quaint/src/visitor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1205,6 +1205,7 @@ pub trait Visitor<'a> {
self.write("uuid_to_bin(uuid(), 1)")?;
}
FunctionType::Uuid => self.write("uuid()")?,
FunctionType::Now => self.write("NOW()")?,
FunctionType::Concat(concat) => {
self.visit_concat(concat)?;
}
Expand Down
2 changes: 2 additions & 0 deletions query-compiler/query-compiler/src/expression.rs
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,7 @@ pub enum FieldOperation {
Subtract(PrismaValue),
Multiply(PrismaValue),
Divide(PrismaValue),
Now,
}

impl TryFrom<ScalarWriteOperation> for FieldOperation {
Expand All @@ -258,6 +259,7 @@ impl TryFrom<ScalarWriteOperation> for FieldOperation {
ScalarWriteOperation::Subtract(val) => Ok(Self::Subtract(val)),
ScalarWriteOperation::Multiply(val) => Ok(Self::Multiply(val)),
ScalarWriteOperation::Divide(val) => Ok(Self::Divide(val)),
ScalarWriteOperation::Now => Ok(Self::Now),
ScalarWriteOperation::Field(_) | ScalarWriteOperation::Unset(_) => Err(UnsupportedScalarWriteOperation(op)),
}
}
Expand Down
1 change: 1 addition & 0 deletions query-compiler/query-compiler/src/expression/format.rs
Original file line number Diff line number Diff line change
Expand Up @@ -453,6 +453,7 @@ where
self.keyword("mul").append(self.space()).append(self.value(val))
}
FieldOperation::Divide(val) => self.keyword("div").append(self.space()).append(self.value(val)),
FieldOperation::Now => self.keyword("now"),
},
)
})))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,13 @@
doc! { "$multiply": [dollar_field_path, (field, rhs).into_bson()?] },
)),
ScalarWriteOperation::Divide(rhs) => Some(UpdateOperation::generic(
field_path,

Check warning on line 44 in query-engine/connectors/mongodb-query-connector/src/root_queries/update/into_operation.rs

View workflow job for this annotation

GitHub Actions / run lints and formatting checks

Diff in /home/runner/work/prisma-engines/prisma-engines/query-engine/connectors/mongodb-query-connector/src/root_queries/update/into_operation.rs
doc! { "$divide": [dollar_field_path, (field, rhs).into_bson()?] },
)),
ScalarWriteOperation::Now => Some(UpdateOperation::generic(
field_path,
doc! { "$currentDate": true },
)),
ScalarWriteOperation::Unset(true) => Some(UpdateOperation::unset(field_path)),
ScalarWriteOperation::Unset(false) => None,
ScalarWriteOperation::Field(_) => unimplemented!(),
Expand Down
4 changes: 4 additions & 0 deletions query-engine/query-builders/sql-query-builder/src/write.rs
Original file line number Diff line number Diff line change
Expand Up @@ -188,9 +188,13 @@

ScalarWriteOperation::Divide(rhs) => {
let e: Expression<'_> = Column::from((table.clone(), name.clone())).into();
e / field.value(rhs, ctx).into()

Check warning on line 191 in query-engine/query-builders/sql-query-builder/src/write.rs

View workflow job for this annotation

GitHub Actions / run lints and formatting checks

Diff in /home/runner/work/prisma-engines/prisma-engines/query-engine/query-builders/sql-query-builder/src/write.rs
}

ScalarWriteOperation::Now => {
native_now()
},

ScalarWriteOperation::Unset(_) => unreachable!("Unset is not supported on SQL connectors"),
};

Expand Down
4 changes: 4 additions & 0 deletions query-engine/query-structure/src/write_args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,9 @@ pub enum ScalarWriteOperation {

/// Divide field by value.
Divide(PrismaValue),

/// Set field to the current date-time
Now,
}

#[derive(Debug, PartialEq, Clone)]
Expand Down Expand Up @@ -487,5 +490,6 @@ pub fn apply_expression(val: PrismaValue, scalar_write: ScalarWriteOperation) ->
ScalarWriteOperation::Multiply(rhs) => val * rhs,
ScalarWriteOperation::Divide(rhs) => val / rhs,
ScalarWriteOperation::Unset(_) => unimplemented!(),
ScalarWriteOperation::Now => PrismaValue::generator_now(),
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,34 +16,35 @@
}
}

impl DataInputFieldMapper for UpdateDataInputFieldMapper {

Check warning on line 19 in query-engine/schema/src/build/input_types/fields/data_input_mapper/update.rs

View workflow job for this annotation

GitHub Actions / run lints and formatting checks

Diff in /home/runner/work/prisma-engines/prisma-engines/query-engine/schema/src/build/input_types/fields/data_input_mapper/update.rs
fn map_scalar<'a>(&self, ctx: &'a QuerySchema, sf: ScalarFieldRef) -> InputField<'a> {
let base_update_type = match sf.type_identifier() {
TypeIdentifier::Float => InputType::object(update_operations_object_type(ctx, "Float", sf.clone(), true)),
TypeIdentifier::Float => InputType::object(update_operations_object_type(ctx, "Float", sf.clone(), true, false)),
TypeIdentifier::Decimal => {
InputType::object(update_operations_object_type(ctx, "Decimal", sf.clone(), true))
InputType::object(update_operations_object_type(ctx, "Decimal", sf.clone(), true, false))
}
TypeIdentifier::Int => InputType::object(update_operations_object_type(ctx, "Int", sf.clone(), true)),
TypeIdentifier::BigInt => InputType::object(update_operations_object_type(ctx, "BigInt", sf.clone(), true)),
TypeIdentifier::Int => InputType::object(update_operations_object_type(ctx, "Int", sf.clone(), true, false)),

Check warning on line 26 in query-engine/schema/src/build/input_types/fields/data_input_mapper/update.rs

View workflow job for this annotation

GitHub Actions / run lints and formatting checks

Diff in /home/runner/work/prisma-engines/prisma-engines/query-engine/schema/src/build/input_types/fields/data_input_mapper/update.rs
TypeIdentifier::BigInt => InputType::object(update_operations_object_type(ctx, "BigInt", sf.clone(), true, false)),
TypeIdentifier::String => {
InputType::object(update_operations_object_type(ctx, "String", sf.clone(), false))
InputType::object(update_operations_object_type(ctx, "String", sf.clone(), false, false))
}
TypeIdentifier::Boolean => InputType::object(update_operations_object_type(ctx, "Bool", sf.clone(), false)),
TypeIdentifier::Boolean => InputType::object(update_operations_object_type(ctx, "Bool", sf.clone(), false, false)),

Check warning on line 31 in query-engine/schema/src/build/input_types/fields/data_input_mapper/update.rs

View workflow job for this annotation

GitHub Actions / run lints and formatting checks

Diff in /home/runner/work/prisma-engines/prisma-engines/query-engine/schema/src/build/input_types/fields/data_input_mapper/update.rs
TypeIdentifier::Enum(enum_id) => {
let enum_name = ctx.internal_data_model.walk(enum_id).name();
InputType::object(update_operations_object_type(
ctx,
&format!("Enum{enum_name}"),
sf.clone(),
false,
false,
))
}
TypeIdentifier::Json => map_scalar_input_type_for_field(ctx, &sf),
TypeIdentifier::DateTime => {

Check warning on line 43 in query-engine/schema/src/build/input_types/fields/data_input_mapper/update.rs

View workflow job for this annotation

GitHub Actions / run lints and formatting checks

Diff in /home/runner/work/prisma-engines/prisma-engines/query-engine/schema/src/build/input_types/fields/data_input_mapper/update.rs
InputType::object(update_operations_object_type(ctx, "DateTime", sf.clone(), false))
InputType::object(update_operations_object_type(ctx, "DateTime", sf.clone(), false, true))
}
TypeIdentifier::UUID => InputType::object(update_operations_object_type(ctx, "Uuid", sf.clone(), false)),
TypeIdentifier::Bytes => InputType::object(update_operations_object_type(ctx, "Bytes", sf.clone(), false)),
TypeIdentifier::UUID => InputType::object(update_operations_object_type(ctx, "Uuid", sf.clone(), false, false)),
TypeIdentifier::Bytes => InputType::object(update_operations_object_type(ctx, "Bytes", sf.clone(), false, false)),

TypeIdentifier::Unsupported => unreachable!("No unsupported field should reach that path"),
};
Expand Down Expand Up @@ -160,6 +161,7 @@
prefix: &str,
sf: ScalarField,
with_number_operators: bool,
with_datetime_operators: bool,
) -> InputObjectType<'a> {
let ident = Identifier::new_prisma(IdentifierType::FieldUpdateOperationsInput(
!sf.is_required(),
Expand All @@ -184,6 +186,10 @@
fields.push(simple_input_field(operations::DIVIDE, typ, None).optional());
}

if with_datetime_operators {
fields.push(InputField::new(operations::NOW.into(), vec![], None, false));
}

if ctx.has_capability(ConnectorCapability::UndefinedType) && !sf.is_required() {
fields.push(simple_input_field(operations::UNSET, InputType::boolean(), None).optional());
}
Expand Down
3 changes: 3 additions & 0 deletions query-engine/schema/src/constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,9 @@ pub mod operations {
pub const DECREMENT: &str = "decrement";
pub const MULTIPLY: &str = "multiply";
pub const DIVIDE: &str = "divide";

// date-time
pub const NOW: &str = "now";
}

pub mod filters {
Expand Down
Loading