use crate::proto;
pub const SUCCESS: &str = "00000";
pub const OMITTED_RESULT: &str = "00001";
pub const WARNING: &str = "01000";
pub const WARNING_STRING_TRUNCATION: &str = "01004";
pub const WARNING_GRAPH_NOT_FOUND: &str = "01G03";
pub const WARNING_GRAPH_TYPE_NOT_FOUND: &str = "01G04";
pub const WARNING_NULL_ELIMINATED: &str = "01G11";
pub const NO_DATA: &str = "02000";
pub const INFORMATIONAL: &str = "03000";
pub const CONNECTION_EXCEPTION: &str = "08000";
pub const TRANSACTION_RESOLUTION_UNKNOWN: &str = "08007";
pub const DATA_EXCEPTION: &str = "22000";
pub const STRING_TRUNCATION: &str = "22001";
pub const NUMERIC_OUT_OF_RANGE: &str = "22003";
pub const NULL_NOT_ALLOWED: &str = "22004";
pub const INVALID_DATETIME_FORMAT: &str = "22007";
pub const DATETIME_OVERFLOW: &str = "22008";
pub const SUBSTRING_ERROR: &str = "22011";
pub const DIVISION_BY_ZERO: &str = "22012";
pub const INTERVAL_FIELD_OVERFLOW: &str = "22015";
pub const INVALID_CHARACTER_VALUE_FOR_CAST: &str = "22018";
pub const INVALID_VALUE_TYPE: &str = "22G03";
pub const NOT_COMPARABLE: &str = "22G04";
pub const NEGATIVE_LIMIT: &str = "22G05";
pub const INVALID_ELEMENT_ID: &str = "22G06";
pub const DUPLICATE_NODE_IN_PATH: &str = "22G07";
pub const DUPLICATE_EDGE_IN_PATH: &str = "22G08";
pub const LIST_DATA_RIGHT_TRUNCATION: &str = "22G09";
pub const INCOMPATIBLE_LIST_ELEMENT_TYPES: &str = "22G0A";
pub const INVALID_PROPERTY_REFERENCE: &str = "22G0B";
pub const PROPERTY_NOT_FOUND: &str = "22G0C";
pub const INVALID_LABEL_VALUE: &str = "22G0D";
pub const INVALID_ELEMENT_TYPE: &str = "22G0E";
pub const INCOMPATIBLE_RECORD_FIELD_TYPES: &str = "22G0F";
pub const RECORD_MISMATCH: &str = "22G0U";
pub const MALFORMED_PATH: &str = "22G0Z";
pub const INVALID_TRANSACTION_STATE: &str = "25000";
pub const ACTIVE_TRANSACTION: &str = "25G01";
pub const NO_ACTIVE_TRANSACTION: &str = "25G02";
pub const READ_ONLY_TRANSACTION: &str = "25G03";
pub const TRANSACTION_FAILED_STATE: &str = "25G04";
pub const INVALID_TRANSACTION_TERMINATION: &str = "2D000";
pub const TRANSACTION_ROLLBACK: &str = "40000";
pub const COMPLETION_UNKNOWN: &str = "40003";
pub const SYNTAX_OR_ACCESS_ERROR: &str = "42000";
pub const INVALID_SYNTAX: &str = "42001";
pub const INVALID_REFERENCE: &str = "42002";
pub const DUPLICATE_DEFINITION: &str = "42004";
pub const AMBIGUOUS_REFERENCE: &str = "42005";
pub const UNSUPPORTED_FEATURE: &str = "42006";
pub const DUPLICATE_LABEL: &str = "42007";
pub const INVALID_ARGUMENT_COUNT: &str = "42008";
pub const INCOMPATIBLE_TYPES: &str = "42009";
pub const INVALID_PATTERN: &str = "42010";
pub const INVALID_AGGREGATION_OPERAND: &str = "42011";
pub const INVALID_ORDERING: &str = "42012";
pub const MISSING_MANDATORY_PROPERTY: &str = "42013";
pub const INVALID_GRAPH_MODIFICATION: &str = "42014";
pub const PROCEDURE_NOT_FOUND: &str = "42015";
pub const DEPENDENT_OBJECTS_EXIST: &str = "G1000";
pub const GRAPH_DEPENDS_ON_SCHEMA: &str = "G1001";
pub const GRAPH_TYPE_DEPENDS_ON_SCHEMA: &str = "G1002";
pub const GRAPH_DEPENDS_ON_GRAPH_TYPE: &str = "G1003";
pub const GRAPH_TYPE_VIOLATION: &str = "G2000";
#[must_use]
pub fn success() -> proto::GqlStatus {
proto::GqlStatus {
code: SUCCESS.to_owned(),
message: "successful completion".to_owned(),
diagnostic: None,
cause: None,
}
}
#[must_use]
pub fn omitted() -> proto::GqlStatus {
proto::GqlStatus {
code: OMITTED_RESULT.to_owned(),
message: "successful completion - omitted result".to_owned(),
diagnostic: None,
cause: None,
}
}
#[must_use]
pub fn no_data() -> proto::GqlStatus {
proto::GqlStatus {
code: NO_DATA.to_owned(),
message: "no data".to_owned(),
diagnostic: None,
cause: None,
}
}
#[must_use]
pub fn error(code: &str, message: impl Into<String>) -> proto::GqlStatus {
proto::GqlStatus {
code: code.to_owned(),
message: message.into(),
diagnostic: None,
cause: None,
}
}
#[must_use]
pub fn warning(code: &str, message: impl Into<String>) -> proto::GqlStatus {
proto::GqlStatus {
code: code.to_owned(),
message: message.into(),
diagnostic: None,
cause: None,
}
}
#[must_use]
pub fn informational(code: &str, message: impl Into<String>) -> proto::GqlStatus {
proto::GqlStatus {
code: code.to_owned(),
message: message.into(),
diagnostic: None,
cause: None,
}
}
#[must_use]
pub fn error_with_diagnostic(
code: &str,
message: impl Into<String>,
operation: impl Into<String>,
operation_code: i32,
) -> proto::GqlStatus {
proto::GqlStatus {
code: code.to_owned(),
message: message.into(),
diagnostic: Some(proto::DiagnosticRecord {
operation: operation.into(),
operation_code,
current_schema: None,
invalid_reference: None,
}),
cause: None,
}
}
#[must_use]
pub fn class(code: &str) -> &str {
if code.len() >= 2 { &code[..2] } else { code }
}
#[must_use]
pub fn is_success(code: &str) -> bool {
class(code) == "00"
}
#[must_use]
pub fn is_warning(code: &str) -> bool {
class(code) == "01"
}
#[must_use]
pub fn is_no_data(code: &str) -> bool {
class(code) == "02"
}
#[must_use]
pub fn is_informational(code: &str) -> bool {
class(code) == "03"
}
#[must_use]
pub fn is_exception(code: &str) -> bool {
let c = class(code);
if c.len() < 2 {
return false;
}
let first = c.as_bytes()[0];
if first.is_ascii_alphabetic() {
return true;
}
c >= "08"
}
pub const OP_SESSION_SET_SCHEMA: i32 = 1;
pub const OP_SESSION_SET_GRAPH: i32 = 2;
pub const OP_SESSION_SET_TIME_ZONE: i32 = 3;
pub const OP_SESSION_SET_PARAMETER: i32 = 4;
pub const OP_SESSION_RESET: i32 = 5;
pub const OP_SESSION_CLOSE: i32 = 6;
pub const OP_START_TRANSACTION: i32 = 100;
pub const OP_COMMIT: i32 = 101;
pub const OP_ROLLBACK: i32 = 102;
pub const OP_CREATE_SCHEMA: i32 = 200;
pub const OP_DROP_SCHEMA: i32 = 201;
pub const OP_CREATE_GRAPH: i32 = 300;
pub const OP_DROP_GRAPH: i32 = 301;
pub const OP_CREATE_GRAPH_TYPE: i32 = 400;
pub const OP_DROP_GRAPH_TYPE: i32 = 401;
pub const OP_INSERT_STATEMENT: i32 = 500;
pub const OP_SET_STATEMENT: i32 = 501;
pub const OP_REMOVE_STATEMENT: i32 = 502;
pub const OP_DELETE_STATEMENT: i32 = 503;
pub const OP_MATCH_STATEMENT: i32 = 600;
pub const OP_OPTIONAL_MATCH: i32 = 601;
pub const OP_FILTER_STATEMENT: i32 = 602;
pub const OP_LET_STATEMENT: i32 = 603;
pub const OP_FOR_STATEMENT: i32 = 604;
pub const OP_ORDER_BY: i32 = 605;
pub const OP_RETURN_STATEMENT: i32 = 700;
pub const OP_CALL_PROCEDURE: i32 = 800;
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn success_status() {
let s = success();
assert_eq!(s.code, "00000");
assert!(is_success(&s.code));
assert!(!is_exception(&s.code));
}
#[test]
fn omitted_status() {
let s = omitted();
assert_eq!(s.code, "00001");
assert!(is_success(&s.code));
}
#[test]
fn no_data_status() {
let s = no_data();
assert_eq!(s.code, "02000");
assert!(is_no_data(&s.code));
assert!(!is_success(&s.code));
assert!(!is_exception(&s.code));
}
#[test]
fn error_status() {
let s = error(INVALID_SYNTAX, "unexpected token");
assert_eq!(s.code, "42001");
assert!(is_exception(&s.code));
assert!(!is_success(&s.code));
}
#[test]
fn error_with_diagnostic_status() {
let s = error_with_diagnostic(
NUMERIC_OUT_OF_RANGE,
"value 999 exceeds INT8 range",
"MATCH STATEMENT",
600,
);
assert_eq!(s.code, "22003");
assert!(is_exception(&s.code));
let d = s.diagnostic.unwrap();
assert_eq!(d.operation, "MATCH STATEMENT");
assert_eq!(d.operation_code, 600);
}
#[test]
fn warning_classification() {
assert!(is_warning(WARNING));
assert!(!is_exception(WARNING));
assert!(!is_success(WARNING));
}
#[test]
fn graph_type_violation_is_exception() {
assert!(is_exception(GRAPH_TYPE_VIOLATION));
}
#[test]
fn class_extraction() {
assert_eq!(class("00000"), "00");
assert_eq!(class("42001"), "42");
assert_eq!(class("G2000"), "G2");
}
#[test]
fn warning_constructor() {
let s = warning(WARNING_GRAPH_NOT_FOUND, "graph 'test' does not exist");
assert_eq!(s.code, "01G03");
assert!(is_warning(&s.code));
assert!(!is_exception(&s.code));
}
#[test]
fn informational_constructor() {
let s = informational(INFORMATIONAL, "operation completed with information");
assert_eq!(s.code, "03000");
assert!(is_informational(&s.code));
assert!(!is_exception(&s.code));
}
#[test]
fn connection_exception_is_exception() {
assert!(is_exception(CONNECTION_EXCEPTION));
assert!(is_exception(TRANSACTION_RESOLUTION_UNKNOWN));
}
#[test]
fn dependent_objects_is_exception() {
assert!(is_exception(DEPENDENT_OBJECTS_EXIST));
assert!(is_exception(GRAPH_DEPENDS_ON_SCHEMA));
}
}