1 /// C API interface to the memgraph mgclient library. 2 /// 3 /// Provides `mg_session`, a data type representing a connection to Bolt 4 /// server, along with functions for connecting to Bolt database and 5 /// executing queries against it, and `mg_value`, a data type representing a 6 /// value in Bolt protocol along with supporting types and manipulation 7 /// functions for them. 8 /// 9 /// `mg_session` is an opaque data type representing a connection to Bolt 10 /// server. Commands can be submitted for execution using `mg_session_run` 11 /// and results can be obtained using `mg_session_pull`. A `mg_session` 12 /// can execute at most one command at a time, and all results should be 13 /// consumed before trying to execute the next query. 14 /// 15 /// The usual flow for execution of a single query would be the following: 16 /// 17 /// 1. Submit the command for execution using `mg_session_run`. 18 /// 19 /// 2. Call `mg_session_pull` until it returns 0 to consume result rows and 20 /// access result values using `mg_result_row`. 21 /// 22 /// 3. If necessary, access command execution summary using `mg_result_summary`. 23 /// 24 /// If any of the functions returns an error exit code, more detailed error 25 /// message can be obtained by calling `mg_session_error`. 26 /// 27 /// `mg_value` is an opaque data type representing an arbitrary value of any 28 /// of the types specified by the Bolt protocol. It can encapsulate any of its 29 /// supporting types: `mg_string`, `mg_list`, `mg_map`, `mg_node`, 30 /// `mg_relationship`, `mg_unbound_relationship` and `mg_path`. 31 /// Provided along with them are basic manipulation functions for those data 32 /// types. The API for most of data types is quite rudimentary, and as such is 33 /// not usable for complex operations on strings, maps, lists, etc. It is only 34 /// supposed to be used to construct data to be sent to the Bolt server, and 35 /// read data obtained from the Bolt server. 36 /// 37 /// Each object has a corresponding `mg_*_destroy` function that should be 38 /// invoked on the object at the end of its lifetime to free the resources 39 /// allocated for its storage. Each object has an owner, that is responsible for 40 /// its destruction. Object can be owned by the API client or by another 41 /// object. When being destroyed, an object will also destroy all other 42 /// objects it owns. Therefore, API client is only responsible for 43 /// destroying the object it directly owns. For example, if the API client 44 /// constructed a `mg_list` value and inserted some other `mg_value` 45 /// objects into it, they must only invoke `mg_list_destroy` on the list and 46 /// all of its members will be properly destroyed, because the list owns all of 47 /// its elements. Invoking `mg_*_destroy` on objects that are not owned by the 48 /// caller will usually result in memory corruption, double freeing, nuclear 49 /// apocalypse and similar unwanted behaviors. Therefore, object ownership 50 /// should be tracked carefully. 51 /// 52 /// Invoking certain functions on objects might cause ownership changes. 53 /// Obviously, you shouldn't pass objects you don't own to functions that steal 54 /// ownership. 55 /// 56 /// Function signatures are of big help in ownership tracking. Now follow two 57 /// simple rules, all functions that do not conform to those rules (if any) will 58 /// explicitly specify that in their documentation. 59 /// 60 /// 1. Return values 61 /// 62 /// Functions that return a non-const pointer to an object give 63 /// ownership of the returned object to the caller. Examples are: 64 /// - creation functions (e.g. `mg_list_make_empty`). 65 /// - copy functions (e.g. `mg_value_copy`). 66 /// - `mg_connect` has a `mg_session **` output parameter because the 67 /// API client becomes the owner of the `mg_session` object 68 /// 69 /// Functions that return a const pointer to a object provide 70 /// read-only access to the returned object that is valid only while the 71 /// owning object is alive. Examples are: 72 /// - access functions on `mg_value` (e.g. `mg_value_list`). 73 /// - member access functions on containers (e.g. `mg_map_key_at`, 74 /// `mg_list_at`, `mg_map_at`). 75 /// - field access functions on graph types (e.g. `mg_node_properties`). 76 /// - `mg_session_pull` has a `const mg_result **` output parameter, 77 /// because the `mg_session` object keeps ownership of the returned 78 /// result and destroys it on next pull 79 /// 80 /// 2. Function arguments 81 /// 82 /// Functions that take a non-const pointer to a object either modify 83 /// it or change its ownership (it is usually obvious what happens). 84 /// Examples are: 85 /// - member insert functions on containers transfer the ownership of 86 /// inserted values to the container. They also take a non-const pointer 87 /// to the container because they modify it. Ownership of the container 88 /// is not changed (e.g. `mg_map_insert` takes ownership of the 89 /// passed key and value). 90 /// - `mg_session_run` takes a non-const pointer to the session because 91 /// it modifies it internal state, but there is no ownership change 92 /// 93 /// An obvious exception here are `mg_*_destroy` functions which do not 94 /// change ownership of the object. 95 /// 96 /// Functions that take a const pointer to a object do not change the 97 /// owner of the passed object nor they modify it. Examples are: 98 /// - member access functions on containers take const pointer to the 99 /// container (e.g. `mg_list_at`, `mg_map_at`, ...). 100 /// - member access functions on graph types take const pointer to the 101 /// container (e.g. `mg_path_node_at`, `mg_node_label_count`, 102 /// ...). 103 /// - copy functions. 104 module memgraph.mgclient; 105 106 /// Initializes the client (the whole process). 107 /// Module constructor used to initialise memgraph via a call to mg_init(). 108 static this() { 109 const rc = mg_init(); 110 assert(rc == mg_error.MG_SUCCESS); 111 } 112 113 /// Finalizes the client (the whole process). 114 /// Module destructor used to finalise memgraph via a call to mg_finalize(). 115 static ~this() { 116 mg_finalize(); 117 } 118 119 extern (C) { 120 /// Client software version. 121 /// Return: Client version in the major.minor.patch format. 122 const (char) *mg_client_version(); 123 124 /// Initializes the client (the whole process). 125 /// Should be called at the beginning of each process using the client. 126 /// Return: Zero if initialization was successful. 127 mg_error mg_init(); 128 129 /// Finalizes the client (the whole process). 130 /// Should be called at the end of each process using the client. 131 void mg_finalize(); 132 133 /// An enum listing all the types as specified by Bolt protocol. 134 enum mg_value_type { 135 MG_VALUE_TYPE_NULL, 136 MG_VALUE_TYPE_BOOL, 137 MG_VALUE_TYPE_INTEGER, 138 MG_VALUE_TYPE_FLOAT, 139 MG_VALUE_TYPE_STRING, 140 MG_VALUE_TYPE_LIST, 141 MG_VALUE_TYPE_MAP, 142 MG_VALUE_TYPE_NODE, 143 MG_VALUE_TYPE_RELATIONSHIP, 144 MG_VALUE_TYPE_UNBOUND_RELATIONSHIP, 145 MG_VALUE_TYPE_PATH, 146 MG_VALUE_TYPE_DATE, 147 MG_VALUE_TYPE_TIME, 148 MG_VALUE_TYPE_LOCAL_TIME, 149 MG_VALUE_TYPE_DATE_TIME, 150 MG_VALUE_TYPE_DATE_TIME_ZONE_ID, 151 MG_VALUE_TYPE_LOCAL_DATE_TIME, 152 MG_VALUE_TYPE_DURATION, 153 MG_VALUE_TYPE_POINT_2D, 154 MG_VALUE_TYPE_POINT_3D, 155 MG_VALUE_TYPE_UNKNOWN 156 } 157 158 /// A Bolt value, encapsulating all other values. 159 version(unittest) { 160 struct mg_value { 161 mg_value_type type; 162 union { 163 int bool_v; 164 long integer_v; 165 double float_v; 166 mg_string *string_v; 167 mg_list *list_v; 168 mg_map *map_v; 169 mg_node *node_v; 170 mg_relationship *relationship_v; 171 mg_unbound_relationship *unbound_relationship_v; 172 mg_path *path_v; 173 mg_date *date_v; 174 mg_time *time_v; 175 mg_local_time *local_time_v; 176 mg_date_time *date_time_v; 177 mg_date_time_zone_id *date_time_zone_id_v; 178 mg_local_date_time *local_date_time_v; 179 mg_duration *duration_v; 180 mg_point_2d *point_2d_v; 181 mg_point_3d *point_3d_v; 182 } 183 } 184 } else { 185 struct mg_value; 186 } 187 188 /// An UTF-8 encoded string. 189 /// 190 /// Note that the length of the string is the byte count of the UTF-8 encoded 191 /// data. It is guaranteed that the bytes of the string are stored contiguously, 192 /// and they can be accessed through a pointer to first element returned by 193 /// `mg_string_data`. 194 /// 195 /// Note that the library doesn't perform any checks whatsoever to see if the 196 /// provided data is a valid UTF-8 encoded string when constructing instances of 197 /// `mg_string`. 198 /// 199 /// Maximum possible string length allowed by Bolt protocol is `uint.max`. 200 version(unittest) { 201 struct mg_string { 202 uint size; 203 char *data; 204 } 205 } else { 206 struct mg_string; 207 } 208 209 /// An ordered sequence of values. 210 /// 211 /// List may contain a mixture of different types as its elements. A list owns 212 /// all values stored in it. 213 /// 214 /// Maximum possible list length allowed by Bolt is `uint.max`. 215 version(unittest) { 216 struct mg_list { 217 uint size; 218 uint capacity; 219 mg_value **elements; 220 } 221 } else { 222 struct mg_list; 223 } 224 225 /// Sized sequence of pairs of keys and values. 226 /// 227 /// Map may contain a mixture of different types as values. A map owns all keys 228 /// and values stored in it. 229 /// 230 /// Maximum possible map size allowed by Bolt protocol is `uint.max`. 231 version(unittest) { 232 struct mg_map { 233 uint size; 234 uint capacity; 235 mg_string **keys; 236 mg_value **values; 237 } 238 } else { 239 struct mg_map; 240 } 241 242 /// Represents a node from a labeled property graph. 243 /// 244 /// Consists of a unique identifier (withing the scope of its origin graph), a 245 /// list of labels and a map of properties. A node owns its labels and 246 /// properties. 247 /// 248 /// Maximum possible number of labels allowed by Bolt protocol is `uint.max`. 249 version(unittest) { 250 struct mg_node { 251 long id; 252 uint label_count; 253 mg_string **labels; 254 mg_map *properties; 255 } 256 } else { 257 struct mg_node; 258 } 259 260 /// Represents a relationship from a labeled property graph. 261 /// 262 /// Consists of a unique identifier (within the scope of its origin graph), 263 /// identifiers for the start and end nodes of that relationship, a type and a 264 /// map of properties. A relationship owns its type string and property map. 265 version(unittest) { 266 struct mg_relationship { 267 long id; 268 long start_id; 269 long end_id; 270 mg_string *type; 271 mg_map *properties; 272 } 273 } else { 274 struct mg_relationship; 275 } 276 277 /// Represents a relationship from a labeled property graph. 278 /// 279 /// Like `mg_relationship`, but without identifiers for start and end nodes. 280 /// Mainly used as a supporting type for `mg_path`. An unbound relationship 281 /// owns its type string and property map. 282 version(unittest) { 283 struct mg_unbound_relationship { 284 long id; 285 mg_string *type; 286 mg_map *properties; 287 } 288 } else { 289 struct mg_unbound_relationship; 290 } 291 292 /// Represents a sequence of alternating nodes and relationships 293 /// corresponding to a walk in a labeled property graph. 294 /// 295 /// A path of length L consists of L + 1 nodes indexed from 0 to L, and L 296 /// unbound relationships, indexed from 0 to L - 1. Each relationship has a 297 /// direction. A relationship is said to be reversed if it was traversed in the 298 /// direction opposite of the direction of the underlying relationship in the 299 /// data graph. 300 version(unittest) { 301 struct mg_path { 302 uint node_count; 303 uint relationship_count; 304 uint sequence_length; 305 mg_node **nodes; 306 mg_unbound_relationship **relationships; 307 long *sequence; 308 } 309 } else { 310 struct mg_path; 311 } 312 313 /// Represents a date. 314 /// 315 /// Date is defined with number of days since the Unix epoch. 316 version(unittest) { 317 struct mg_date { 318 long days; 319 } 320 } else { 321 struct mg_date; 322 } 323 324 /// Represents time with its time zone. 325 /// 326 /// Time is defined with nanoseconds since midnight. 327 /// Timezone is defined with seconds from UTC. 328 version(unittest) { 329 struct mg_time { 330 long nanoseconds; 331 long tz_offset_seconds; 332 } 333 } else { 334 struct mg_time; 335 } 336 337 /// Represents local time. 338 /// 339 /// Time is defined with nanoseconds since midnight. 340 version(unittest) { 341 struct mg_local_time { 342 long nanoseconds; 343 } 344 } else { 345 struct mg_local_time; 346 } 347 348 /// Represents date and time with its time zone. 349 /// 350 /// Date is defined with seconds since the adjusted Unix epoch. 351 /// Time is defined with nanoseconds since midnight. 352 /// Time zone is defined with minutes from UTC. 353 version(unittest) { 354 struct mg_date_time { 355 long seconds; 356 long nanoseconds; 357 long tz_offset_minutes; 358 } 359 } else { 360 struct mg_date_time; 361 } 362 363 /// Represents date and time with its time zone. 364 /// 365 /// Date is defined with seconds since the adjusted Unix epoch. 366 /// Time is defined with nanoseconds since midnight. 367 /// Timezone is defined with an identifier for a specific time zone. 368 version(unittest) { 369 struct mg_date_time_zone_id { 370 long seconds; 371 long nanoseconds; 372 long tz_id; 373 } 374 } else { 375 struct mg_date_time_zone_id; 376 } 377 378 /// Represents date and time without its time zone. 379 /// 380 /// Date is defined with seconds since the Unix epoch. 381 /// Time is defined with nanoseconds since midnight. 382 version(unittest) { 383 struct mg_local_date_time { 384 long seconds; 385 long nanoseconds; 386 } 387 } else { 388 struct mg_local_date_time; 389 } 390 391 /// Represents a temporal amount which captures the difference in time 392 /// between two instants. 393 /// 394 /// Duration is defined with months, days, seconds, and nanoseconds. 395 /// Note: Duration can be negative. 396 version(unittest) { 397 struct mg_duration { 398 long months; 399 long days; 400 long seconds; 401 long nanoseconds; 402 } 403 } else { 404 struct mg_duration; 405 } 406 407 /// Represents a single location in 2-dimensional space. 408 /// 409 /// Contains SRID along with its x and y coordinates. 410 version(unittest) { 411 struct mg_point_2d { 412 long srid; 413 double x; 414 double y; 415 } 416 } else { 417 struct mg_point_2d; 418 } 419 420 /// Represents a single location in 3-dimensional space. 421 /// 422 /// Contains SRID along with its x, y and z coordinates. 423 version(unittest) { 424 struct mg_point_3d { 425 long srid; 426 double x; 427 double y; 428 double z; 429 } 430 } else { 431 struct mg_point_3d; 432 } 433 434 /// Constructs a nil `mg_value`. 435 /// 436 /// Return: Pointer to the newly constructed value or NULL if error occurred. 437 @safe @nogc mg_value *mg_value_make_null() pure nothrow; 438 439 /// Constructs a boolean `mg_value`. 440 /// 441 /// Params: val = If the parameter is zero, constructed value will be false. 442 /// Otherwise, it will be true. 443 /// Return: Pointer to the newly constructed value or NULL if error occurred. 444 @safe @nogc mg_value *mg_value_make_bool(int val) pure nothrow; 445 446 /// Constructs an integer `mg_value` with the given underlying value. 447 /// 448 /// Return: Pointer to the newly constructed value or NULL if error occurred. 449 @safe @nogc mg_value *mg_value_make_integer(long val) pure nothrow; 450 451 /// Constructs a float `mg_value` with the given underlying value. 452 /// 453 /// Return: Pointer to the newly constructed value or NULL if error occurred. 454 @safe @nogc mg_value *mg_value_make_float(double val) pure nothrow; 455 456 /// Constructs a string `mg_value` given a null-terminated string. 457 /// 458 /// A new `mg_string` instance will be created from the null-terminated 459 /// string as the underlying value. 460 /// 461 /// Params: str = A null-terminated UTF-8 string. 462 /// 463 /// Return: Pointer to the newly constructed value or NULL if error occurred. 464 @safe @nogc mg_value *mg_value_make_string(const char *str) pure nothrow; 465 466 /// Construct a string `mg_value` given the underlying `mg_string`. 467 /// 468 /// Return: Pointer to the newly constructed value or NULL if error occurred. 469 @safe @nogc mg_value *mg_value_make_string2(mg_string *str) pure nothrow; 470 471 /// Constructs a list `mg_value` given the underlying `mg_list`. 472 /// 473 /// Return: Pointer to the newly constructed value or NULL if error occurred. 474 @safe @nogc mg_value *mg_value_make_list(mg_list *list) pure nothrow; 475 476 /// Constructs a map `mg_value` given the underlying `mg_map`. 477 /// 478 /// Return: Pointer to the newly constructed value or NULL if error occurred. 479 @safe @nogc mg_value *mg_value_make_map(mg_map *map) pure nothrow; 480 481 /// Constructs a node `mg_value` given the underlying `mg_node`. 482 /// 483 /// Return: Pointer to the newly constructed value or NULL if error occurred. 484 @safe @nogc mg_value *mg_value_make_node(mg_node *node) pure nothrow; 485 486 /// Constructs a relationship `mg_value` given the underlying 487 /// `mg_relationship`. 488 /// 489 /// Return: Pointer to the newly constructed value or NULL if error occurred. 490 @safe @nogc mg_value *mg_value_make_relationship(mg_relationship *rel) pure nothrow; 491 492 /// Constructs an unbound relationship `mg_value` given the underlying 493 /// `mg_unbound_relationship`. 494 /// 495 /// Return: Pointer to the newly constructed value or NULL if error occurred. 496 @safe @nogc mg_value *mg_value_make_unbound_relationship(mg_unbound_relationship *rel) pure nothrow; 497 498 /// Constructs a path `mg_value` given the underlying `mg_path`. 499 /// 500 /// Return: Pointer to the newly constructed value or NULL if error occurred. 501 @safe @nogc mg_value *mg_value_make_path(mg_path *path) pure nothrow; 502 503 /// Constructs a date `mg_value` given the underlying `mg_date`. 504 /// 505 /// Return: Pointer to the newly constructed value or NULL if error occurred. 506 @safe @nogc mg_value *mg_value_make_date(mg_date *date) pure nothrow; 507 508 /// Constructs a time `mg_value` given the underlying `mg_time`. 509 /// 510 /// Return: Pointer to the newly constructed value or NULL if error occurred. 511 @safe @nogc mg_value *mg_value_make_time(mg_time *time) pure nothrow; 512 513 /// Constructs a local time `mg_value` given the underlying `mg_local_time`. 514 /// 515 /// Return: Pointer to the newly constructed value or NULL if error occurred. 516 @safe @nogc mg_value *mg_value_make_local_time(mg_local_time *local_time) pure nothrow; 517 518 /// Constructs a date and time `mg_value` given the underlying `mg_date_time`. 519 /// 520 /// Return: Pointer to the newly constructed value or NULL if error occurred. 521 @safe @nogc mg_value *mg_value_make_date_time(mg_date_time *date_time) pure nothrow; 522 523 /// Constructs a date and time `mg_value` given the underlying `mg_date_time_zone_id`. 524 /// 525 /// Return: Pointer to the newly constructed value or NULL if error occurred. 526 @safe @nogc mg_value *mg_value_make_date_time_zone_id(mg_date_time_zone_id *date_time_zone_id) pure nothrow; 527 528 /// Constructs a local date and time `mg_value` given the underlying `mg_local_date_time`. 529 /// 530 /// Return: Pointer to the newly constructed value or NULL if error occurred. 531 @safe @nogc mg_value *mg_value_make_local_date_time(mg_local_date_time *local_date_time) pure nothrow; 532 533 /// Constructs a duration `mg_value` given the underlying `mg_duration`. 534 /// 535 /// Return: Pointer to the newly constructed value or NULL if error occurred. 536 @safe @nogc mg_value *mg_value_make_duration(mg_duration *duration) pure nothrow; 537 538 /// Constructs a 2D point `mg_value` given the underlying `mg_point_2d`. 539 /// 540 /// Return: Pointer to the newly constructed value or NULL if error occurred. 541 @safe @nogc mg_value *mg_value_make_point_2d(mg_point_2d *point_2d) pure nothrow; 542 543 /// Constructs a 3D point `mg_value` given the underlying `mg_point_3d`. 544 /// 545 /// Return: Pointer to the newly constructed value or NULL if error occurred. 546 @safe @nogc mg_value *mg_value_make_point_3d(mg_point_3d *point_3d) pure nothrow; 547 548 /// Returns the type of the given `mg_value`. 549 mg_value_type mg_value_get_type(const mg_value *val); 550 551 /// Returns non-zero value if value contains true, zero otherwise. 552 /// 553 /// Type check should be made first. Accessing the wrong value results in 554 /// undefined behavior. 555 /// TODO: check if this is really ok, as the original return type was int !!! 556 bool mg_value_bool(const mg_value *val); 557 558 /// Returns the underlying integer value. 559 /// 560 /// Type check should be made first. Accessing the wrong value results in 561 /// undefined behavior. 562 long mg_value_integer(const mg_value *val); 563 564 /// Returns the underlying float value. 565 /// 566 /// Type check should be made first. Accessing the wrong value results in 567 /// undefined behavior. 568 double mg_value_float(const mg_value *val); 569 570 /// Returns the underlying `mg_string` value. 571 /// 572 /// Type check should be made first. Accessing the wrong value results in 573 /// undefined behavior. 574 const (mg_string) *mg_value_string(const mg_value *val); 575 576 /// Returns the underlying `mg_list` value. 577 /// 578 /// Type check should be made first. Accessing the wrong value results in 579 /// undefined behavior. 580 const (mg_list) *mg_value_list(const mg_value *val); 581 582 /// Returns the underlying `mg_map` value. 583 /// 584 /// Type check should be made first. Accessing the wrong value results in 585 /// undefined behavior. 586 const (mg_map) *mg_value_map(const mg_value *val); 587 588 /// Returns the underlying `mg_node` value. 589 /// 590 /// Type check should be made first. Accessing the wrong value results in 591 /// undefined behavior. 592 const (mg_node) *mg_value_node(const mg_value *val); 593 594 /// Returns the underlying `mg_relationship` value. 595 /// 596 /// Type check should be made first. Accessing the wrong value results in 597 /// undefined behavior. 598 const (mg_relationship) *mg_value_relationship(const mg_value *val); 599 600 /// Returns the underlying `mg_unbound_relationship` value. 601 /// 602 /// Type check should be made first. Accessing the wrong value results in 603 /// undefined behavior. 604 const (mg_unbound_relationship) *mg_value_unbound_relationship(const mg_value *val); 605 606 /// Returns the underlying `mg_path` value. 607 /// 608 /// Type check should be made first. Accessing the wrong value results in 609 /// undefined behavior. 610 const (mg_path) *mg_value_path(const mg_value *val); 611 612 /// Returns the underlying `mg_date` value. 613 /// 614 /// Type check should be made first. Accessing the wrong value results in 615 /// undefined behavior. 616 const (mg_date) *mg_value_date(const mg_value *val); 617 618 /// Returns the underlying `mg_time` value. 619 /// 620 /// Type check should be made first. Accessing the wrong value results in 621 /// undefined behavior. 622 const (mg_time) *mg_value_time(const mg_value *val); 623 624 /// Returns the underlying `mg_local_time` value. 625 /// 626 /// Type check should be made first. Accessing the wrong value results in 627 /// undefined behavior. 628 const (mg_local_time) *mg_value_local_time(const mg_value *val); 629 630 /// Returns the underlying `mg_date_time` value. 631 /// 632 /// Type check should be made first. Accessing the wrong value results in 633 /// undefined behavior. 634 const (mg_date_time) *mg_value_date_time(const mg_value *val); 635 636 /// Returns the underlying `mg_date_time_zone_id` value. 637 /// 638 /// Type check should be made first. Accessing the wrong value results in 639 /// undefined behavior. 640 const (mg_date_time_zone_id) *mg_value_date_time_zone_id(const mg_value *val); 641 642 /// Returns the underlying `mg_local_date_time` value. 643 /// 644 /// Type check should be made first. Accessing the wrong value results in 645 /// undefined behavior. 646 const (mg_local_date_time) *mg_value_local_date_time(const mg_value *val); 647 648 /// Returns the underlying `mg_duration` value. 649 /// 650 /// Type check should be made first. Accessing the wrong value results in 651 /// undefined behavior. 652 const (mg_duration) *mg_value_duration(const mg_value *val); 653 654 /// Returns the underlying `mg_point_2d` value. 655 /// 656 /// Type check should be made first. Accessing the wrong value results in 657 /// undefined behavior. 658 const (mg_point_2d) *mg_value_point_2d(const mg_value *val); 659 660 /// Returns the underlying `mg_point_3d` value. 661 /// 662 /// Type check should be made first. Accessing the wrong value results in 663 /// undefined behavior. 664 const (mg_point_3d) *mg_value_point_3d(const mg_value *val); 665 666 /// Creates a copy of the given value. 667 /// 668 /// Return: Pointer to the copy or NULL if error occurred. 669 @safe @nogc mg_value *mg_value_copy(const mg_value *val) pure nothrow; 670 671 /// Destroys the given value. 672 @safe @nogc void mg_value_destroy(mg_value *val) pure nothrow; 673 674 /// Constructs a string given a null-terminated string. 675 /// 676 /// A new buffer of appropriate length will be allocated and the given string 677 /// will be copied there. 678 /// 679 /// Params: str = A null-terminated UTF-8 string. 680 /// 681 /// Return: A pointer to the newly constructed `mg_string` object or NULL 682 /// if an error occurred. 683 @safe @nogc mg_string *mg_string_make(const char *str) pure nothrow; 684 685 /// Constructs a string given its length (in bytes) and contents. 686 /// 687 /// A new buffer of will be allocated and the given data will be copied there. 688 /// 689 /// Params: len = Number of bytes in the data buffer. 690 /// data = The string contents. 691 /// 692 /// Return: A pointer to the newly constructed `mg_string` object or NULL 693 /// if an error occurred. 694 @safe @nogc mg_string *mg_string_make2(uint len, const char *data) pure nothrow; 695 696 /// Returns a pointer to the beginning of data buffer of string `str`. 697 const (char) *mg_string_data(const mg_string *str); 698 699 /// Returns the length (in bytes) of string `str`. 700 uint mg_string_size(const mg_string *str); 701 702 /// Creates a copy of the given string. 703 /// 704 /// Return: A pointer to the copy or NULL if an error occurred. 705 @safe @nogc mg_string *mg_string_copy(const mg_string *str) pure nothrow; 706 707 /// Destroys the given string. 708 @safe @nogc void mg_string_destroy(mg_string *str) pure nothrow; 709 710 /// Constructs a list that can hold at most `capacity` elements. 711 /// 712 /// Elements should be constructed and then inserted using `mg_list_append`. 713 /// 714 /// Params: capacity = The maximum number of elements that the newly constructed 715 /// list can hold. 716 /// 717 /// Return: A pointer to the newly constructed empty list or NULL if an error 718 /// occurred. 719 @safe @nogc mg_list *mg_list_make_empty(uint capacity) pure nothrow; 720 721 /// Appends an element at the end of the list `list`. 722 /// 723 /// Insertion will fail if the list capacity is already exhausted. If the 724 /// insertion fails, the map doesn't take ownership of `value`. 725 /// 726 /// Params: list = The list instance to be modified. 727 /// value = The value to be appended. 728 /// 729 /// Return: The function returns non-zero value if insertion failed, zero 730 /// otherwise. 731 mg_error mg_list_append(mg_list *list, mg_value *value); 732 733 /// Returns the number of elements in list `list`. 734 uint mg_list_size(const mg_list *list); 735 736 /// Retrieves the element at position `pos` in list `list`. 737 /// 738 /// Return: A pointer to required list element. If `pos` is outside of list 739 /// bounds, NULL is returned. 740 const (mg_value) *mg_list_at(const mg_list *list, uint pos); 741 742 /// Creates a copy of the given list. 743 /// 744 /// Return: A pointer to the copy or NULL if an error occurred. 745 @safe @nogc mg_list *mg_list_copy(const mg_list *list) pure nothrow; 746 747 /// Destroys the given list. 748 @safe @nogc void mg_list_destroy(mg_list *list) pure nothrow; 749 750 /// Constructs an empty map that can hold at most `capacity` key-value pairs. 751 /// 752 /// Key-value pairs should be constructed and then inserted using 753 /// `mg_map_insert`, `mg_map_insert_unsafe` and similar. 754 /// 755 /// Params: capacity = The maximum number of key-value pairs that the newly 756 /// constructed list can hold. 757 /// 758 /// Return: A pointer to the newly constructed empty map or NULL if an error 759 /// occurred. 760 @safe @nogc mg_map *mg_map_make_empty(uint capacity) pure nothrow; 761 762 /// Inserts the given key-value pair into the map. 763 /// 764 /// A check is performed to see if the given key is unique in the map which 765 /// means that a number of key comparisons equal to the current number of 766 /// elements in the map is made. 767 /// 768 /// If key length is greater that `uint.max`, or the key already exists in 769 /// map, or the map's capacity is exhausted, the insertion will fail. If 770 /// insertion fails, the map doesn't take ownership of `value`. 771 /// 772 /// If the insertion is successful, a new `mg_string` is constructed for 773 /// the storage of the key and the map takes ownership of `value`. 774 /// 775 /// Params: map = The map instance to be modifed. 776 /// key_str = A null-terminated string to be used as key. 777 /// value = Value to be inserted. 778 /// 779 /// Return: The function returns non-zero value if insertion failed, zero 780 /// otherwise. 781 mg_error mg_map_insert(mg_map *map, const char *key_str, mg_value *value); 782 783 /// Inserts the given key-value pair into the map. 784 /// 785 /// A check is performed to see if the given key is unique in the map which 786 /// means that a number of key comparisons equal to the current number of 787 /// elements in the map is made. 788 /// 789 /// If the key already exists in map, or the map's capacity is exhausted, the 790 /// insertion will fail. If insertion fails, the map doesn't take ownership of 791 /// `key` and `value`. 792 /// 793 /// If the insertion is successful, map takes ownership of `key` and `value`. 794 /// 795 /// Params: map = The map instance to be modifed. 796 /// key = A `mg_string` to be used as key. 797 /// value = Value to be inserted. 798 /// 799 /// Return: The function returns non-zero value if insertion failed, zero 800 /// otherwise. 801 int mg_map_insert2(mg_map *map, mg_string *key, mg_value *value); 802 803 /// Inserts the given key-value pair into the map. 804 /// 805 /// No check is performed for key uniqueness. Note that map containing duplicate 806 /// keys is considered invalid in Bolt protocol. 807 /// 808 /// If key length is greated than `uint.max` or or the map's capacity is 809 /// exhausted, the insertion will fail. If insertion fails, the map doesn't take 810 /// ownership of `value`. 811 /// 812 /// If the insertion is successful, a new `mg_string` is constructed for the 813 /// storage of the key and the map takes ownership of `value`. 814 /// 815 /// Params: map = The map instance to be modifed. 816 /// key_str = A null-terminated string to be used as key. 817 /// value = Value to be inserted. 818 /// 819 /// Return: The function returns non-zero value if insertion failed, zero 820 /// otherwise. 821 @safe @nogc int mg_map_insert_unsafe(mg_map *map, const char *key_str, mg_value *value); 822 823 /// Inserts the given key-value pair into the map. 824 /// 825 /// No check is performed for key uniqueness. Note that map containing duplicate 826 /// keys is considered invalid in Bolt protocol. 827 /// 828 /// If the map's capacity is exhausted, the insertion will fail. If insertion 829 /// fails, the map doesn't take ownership of `key` and `value`. 830 /// 831 /// If the insertion is successful, map takes ownership of `key` and `value`. 832 /// 833 /// Params: map = The map instance to be modifed. 834 /// key = A `mg_string` to be used as key. 835 /// value = Value to be inserted. 836 /// 837 /// Return: The function returns non-zero value if insertion failed, zero 838 /// otherwise. 839 @safe @nogc int mg_map_insert_unsafe2(mg_map *map, mg_string *key, mg_value *value); 840 841 /// Looks up a map value with the given key. 842 /// 843 /// Params: map = The map instance to be queried. 844 /// key_str = A null-terminated string representing the key to be looked-up 845 /// in the map. 846 /// 847 /// Return: If the key is found in the map, the pointer to the corresponding 848 /// `mg_value` is returned. Otherwise, NULL is returned. 849 const (mg_value) *mg_map_at(const mg_map *map, const char *key_str); 850 851 /// Looks up a map value with the given key. 852 /// 853 /// Params: map = The map instance to be queried. 854 /// key_size = The length of the string representing the key to be 855 /// looked-up in the map. 856 /// key_data = Bytes constituting the key string. 857 /// 858 /// Return: If the key is found in the map, the pointer to the corresponding 859 /// `mg_value` is returned. Otherwise, NULL is returned. 860 const (mg_value) *mg_map_at2(const mg_map *map, uint key_size, const char *key_data); 861 862 /// Returns the number of key-value pairs in map `map`. 863 uint mg_map_size(const mg_map *map); 864 865 /// Retrieves the key at position `pos` in map `map`. 866 /// 867 /// Return: A pointer to required key. If `pos` is outside of map bounds, 868 /// NULL is returned. 869 const (mg_string) *mg_map_key_at(const mg_map *, uint pos); 870 871 /// Retrieves the value at position `pos` in map `map`. 872 /// 873 /// Return: A pointer to required value. If `pos` is outside of map bounds, 874 /// NULL is returned. 875 const (mg_value) *mg_map_value_at(const mg_map *, uint pos); 876 877 /// Creates a copy of the given map. 878 /// 879 /// Return: A pointer to the copy or NULL if an error occurred. 880 @safe @nogc mg_map *mg_map_copy(const mg_map *map) pure nothrow; 881 882 /// Destroys the given map. 883 @safe @nogc void mg_map_destroy(mg_map *map) pure nothrow; 884 885 /// Returns the ID of node `node`. 886 long mg_node_id(const mg_node *node); 887 888 /// Returns the number of labels of node `node`. 889 uint mg_node_label_count(const mg_node *node); 890 891 /// Returns the label at position `pos` in node `node`'s label list. 892 /// 893 /// Return: A pointer to the required label. If `pos` is outside of label list 894 /// bounds, NULL is returned. 895 const (mg_string) *mg_node_label_at(const mg_node *node, uint pos); 896 897 /// Returns property map of node `node`. 898 const (mg_map) *mg_node_properties(const mg_node *node); 899 900 /// Creates a copy of the given node. 901 /// 902 /// Return: A pointer to the copy or NULL if an error occurred. 903 @safe @nogc mg_node *mg_node_copy(const mg_node *node) pure nothrow; 904 905 /// Destroys the given node. 906 @safe @nogc void mg_node_destroy(mg_node *node) pure nothrow; 907 908 /// Returns the ID of the relationship `rel`. 909 long mg_relationship_id(const mg_relationship *rel); 910 911 /// Returns the ID of the start node of relationship `rel`. 912 long mg_relationship_start_id(const mg_relationship *rel); 913 914 /// Returns the ID of the end node of relationship `rel`. 915 long mg_relationship_end_id(const mg_relationship *rel); 916 917 /// Returns the type of the relationship `rel`. 918 const (mg_string) *mg_relationship_type(const mg_relationship *rel); 919 920 /// Returns the property map of the relationship `rel`. 921 const (mg_map) *mg_relationship_properties(const mg_relationship *rel); 922 923 /// Creates a copy of the given relationship. 924 /// 925 /// Return: A pointer to the copy or NULL if an error occurred. 926 @safe @nogc mg_relationship *mg_relationship_copy(const mg_relationship *rel) pure nothrow; 927 928 /// Destroys the given relationship. 929 @safe @nogc void mg_relationship_destroy(mg_relationship *rel) pure nothrow; 930 931 /// Returns the ID of the unbound relationship `rel`. 932 long mg_unbound_relationship_id(const mg_unbound_relationship *rel); 933 934 /// Returns the type of the unbound relationship `rel`. 935 const (mg_string) *mg_unbound_relationship_type(const mg_unbound_relationship *rel); 936 937 /// Returns the property map of the unbound relationship `rel`. 938 const (mg_map) *mg_unbound_relationship_properties(const mg_unbound_relationship *rel); 939 940 /// Creates a copy of the given unbound relationship. 941 /// 942 /// Return: A pointer to the copy or NULL if an error occurred. 943 @safe @nogc mg_unbound_relationship *mg_unbound_relationship_copy(const mg_unbound_relationship *rel) pure nothrow; 944 945 /// Destroys the given unbound relationship. 946 @safe @nogc void mg_unbound_relationship_destroy(mg_unbound_relationship *rel) pure nothrow; 947 948 /// Returns the length (the number of edges) of path `path`. 949 uint mg_path_length(const mg_path *path); 950 951 /// Returns the node at position `pos` in the traversal of path `path`. 952 /// 953 /// Nodes are indexed from 0 to path length. 954 /// 955 /// Return: A pointer to the required node. If `pos` is out of path bounds, 956 /// NULL is returned. 957 const (mg_node) *mg_path_node_at(const mg_path *path, uint pos); 958 959 /// Returns the relationship at position `pos` in traversal of path `path`. 960 /// 961 /// Relationships are indexed from 0 to path length - 1. 962 /// 963 /// Return: A pointer to the required relationship. If `pos` is outside of 964 /// path bounds, NULL is returned. 965 const (mg_unbound_relationship) *mg_path_relationship_at(const mg_path *path, uint pos); 966 967 /// Checks if the relationship at position `pos` in traversal of path `path` 968 /// is reversed. 969 /// 970 /// Relationships are indexed from 0 to path length - 1. 971 /// 972 /// Return: Returns 0 if relationships is traversed in the same direction as the 973 /// underlying relationship in the data graph, and 1 if it is traversed 974 /// in the opposite direction. If `pos` is outside of path bounds, -1 975 /// is returned. 976 int mg_path_relationship_reversed_at(const mg_path *path, uint pos); 977 978 /// Creates a copy of the given path. 979 /// 980 /// Return: A pointer to the copy or NULL if an error occurred. 981 @safe @nogc mg_path *mg_path_copy(const mg_path *path) pure nothrow; 982 983 /// Destroys the given path. 984 @safe @nogc void mg_path_destroy(mg_path *path) pure nothrow; 985 986 /// Returns days since the Unix epoch. 987 long mg_date_days(const mg_date *date); 988 989 /// Creates a copy of the given date. 990 /// 991 /// Return: A pointer to the copy or NULL if an error occured. 992 @safe @nogc mg_date *mg_date_copy(const mg_date *date) pure nothrow; 993 994 /// Destroys the given date. 995 @safe @nogc void mg_date_destroy(mg_date *date) pure nothrow; 996 997 /// Returns nanoseconds since midnight. 998 long mg_time_nanoseconds(const mg_time *time); 999 1000 /// Returns time zone offset in seconds from UTC. 1001 long mg_time_tz_offset_seconds(const mg_time *time); 1002 1003 /// Creates a copy of the given time. 1004 /// 1005 /// Return: A pointer to the copy or NULL if an error occured. 1006 @safe @nogc mg_time *mg_time_copy(const mg_time *time) pure nothrow; 1007 1008 /// Destroys the given time. 1009 @safe @nogc void mg_time_destroy(mg_time *time) pure nothrow; 1010 1011 /// Returns nanoseconds since midnight. 1012 long mg_local_time_nanoseconds(const mg_local_time *local_time); 1013 1014 /// Creates a copy of the given local time. 1015 /// 1016 /// Return: A pointer to the copy or NULL if an error occured. 1017 @safe @nogc mg_local_time *mg_local_time_copy(const mg_local_time *local_time) pure nothrow; 1018 1019 /// Destroys the given local time. 1020 @safe @nogc void mg_local_time_destroy(mg_local_time *local_time) pure nothrow; 1021 1022 /// Returns seconds since Unix epoch. 1023 long mg_date_time_seconds(const mg_date_time *date_time); 1024 1025 /// Returns nanoseconds since midnight. 1026 long mg_date_time_nanoseconds(const mg_date_time *date_time); 1027 1028 /// Returns time zone offset in minutes from UTC. 1029 long mg_date_time_tz_offset_minutes(const mg_date_time *date_time); 1030 1031 /// Creates a copy of the given date and time. 1032 /// 1033 /// Return: A pointer to the copy or NULL if an error occured. 1034 @safe @nogc mg_date_time *mg_date_time_copy(const mg_date_time *date_time) pure nothrow; 1035 1036 /// Destroys the given date and time. 1037 @safe @nogc void mg_date_time_destroy(mg_date_time *date_time) pure nothrow; 1038 1039 /// Returns seconds since Unix epoch. 1040 long mg_date_time_zone_id_seconds(const mg_date_time_zone_id *date_time_zone_id); 1041 1042 /// Returns nanoseconds since midnight. 1043 long mg_date_time_zone_id_nanoseconds(const mg_date_time_zone_id *date_time_zone_id); 1044 1045 /// Returns time zone represented by the identifier. 1046 long mg_date_time_zone_id_tz_id(const mg_date_time_zone_id *date_time_zone_id); 1047 1048 /// Creates a copy of the given date and time. 1049 /// 1050 /// Return: A pointer to the copy or NULL if an error occured. 1051 @safe @nogc mg_date_time_zone_id *mg_date_time_zone_id_copy(const mg_date_time_zone_id *date_time_zone_id) pure nothrow; 1052 1053 /// Destroys the given date and time. 1054 @safe @nogc void mg_date_time_zone_id_destroy(mg_date_time_zone_id *date_time_zone_id) pure nothrow; 1055 1056 /// Returns seconds since Unix epoch. 1057 long mg_local_date_time_seconds(const mg_local_date_time *local_date_time); 1058 1059 /// Returns nanoseconds since midnight. 1060 long mg_local_date_time_nanoseconds(const mg_local_date_time *local_date_time); 1061 1062 /// Creates a copy of the given local date and time. 1063 /// 1064 /// Return: A pointer to the copy or NULL if an error occured. 1065 @safe @nogc mg_local_date_time *mg_local_date_time_copy(const mg_local_date_time *local_date_time) pure nothrow; 1066 1067 /// Destroy the given local date and time. 1068 @safe @nogc void mg_local_date_time_destroy(mg_local_date_time *local_date_time) pure nothrow; 1069 1070 /// Returns the months part of the temporal amount. 1071 long mg_duration_months(const mg_duration *duration); 1072 1073 /// Returns the days part of the temporal amount. 1074 long mg_duration_days(const mg_duration *duration); 1075 1076 /// Returns the seconds part of the temporal amount. 1077 long mg_duration_seconds(const mg_duration *duration); 1078 1079 /// Returns the nanoseconds part of the temporal amount. 1080 long mg_duration_nanoseconds(const mg_duration *duration); 1081 1082 /// Creates a copy of the given duration. 1083 /// 1084 /// Return: A pointer to the copy or NULL if an error occured. 1085 @safe @nogc mg_duration *mg_duration_copy(const mg_duration *duration) pure nothrow; 1086 1087 /// Destroy the given duration. 1088 @safe @nogc void mg_duration_destroy(mg_duration *duration) pure nothrow; 1089 1090 /// Returns SRID of the 2D point. 1091 long mg_point_2d_srid(const mg_point_2d *point_2d); 1092 1093 /// Returns the x coordinate of the 2D point. 1094 double mg_point_2d_x(const mg_point_2d *point_2d); 1095 1096 /// Returns the y coordinate of the 2D point. 1097 double mg_point_2d_y(const mg_point_2d *point_2d); 1098 1099 /// Creates a copy of the given 2D point. 1100 /// 1101 /// Return: A pointer to the copy or NULL if an error occured. 1102 @safe @nogc mg_point_2d *mg_point_2d_copy(const mg_point_2d *point_2d) pure nothrow; 1103 1104 /// Destroys the given 2D point. 1105 @safe @nogc void mg_point_2d_destroy(mg_point_2d *point_2d) pure nothrow; 1106 1107 /// Returns SRID of the 3D point. 1108 long mg_point_3d_srid(const mg_point_3d *point_3d); 1109 1110 /// Returns the x coordinate of the 3D point. 1111 double mg_point_3d_x(const mg_point_3d *point_3d); 1112 1113 /// Returns the y coordinate of the 3D point. 1114 double mg_point_3d_y(const mg_point_3d *point_3d); 1115 1116 /// Returns the z coordinate of the 3D point. 1117 double mg_point_3d_z(const mg_point_3d *point_3d); 1118 1119 /// Creates a copy of the given 3D point. 1120 /// 1121 /// Return: A pointer to the copy or NULL if an error occured. 1122 @safe @nogc mg_point_3d *mg_point_3d_copy(const mg_point_3d *point_3d) pure nothrow; 1123 1124 /// Destroys the given 3D point. 1125 @safe @nogc void mg_point_3d_destroy(mg_point_3d *point_3d) pure nothrow; 1126 1127 /// Return codes for `mg_session_status`. 1128 enum mg_session_code { 1129 /// Marks a `mg_session` ready to execute a new query using `mg_session_run`. 1130 MG_SESSION_READY = 0, 1131 /// Marks a `mg_session` which is currently executing a query. Results can be 1132 /// pulled using `mg_session_pull`. 1133 MG_SESSION_EXECUTING = 1, 1134 /// Marks a bad `mg_session` which cannot be used to execute queries and can 1135 /// only be destroyed. 1136 MG_SESSION_BAD = 2, 1137 /// Marks a `mg_session` which is currently fetching result of a query. 1138 /// Results can be fetched using `mg_session_fetch`. 1139 MG_SESSION_FETCHING = 3 1140 } 1141 1142 /// Return codes used by mgclient functions. 1143 enum mg_error { 1144 /// Success code. 1145 MG_SUCCESS = 0, 1146 /// Failed to send data to server. 1147 MG_ERROR_SEND_FAILED = -1, 1148 /// Failed to receive data from server. 1149 MG_ERROR_RECV_FAILED = -2, 1150 /// Out of memory. 1151 MG_ERROR_OOM = -3, 1152 /// Trying to insert more values in a full container. 1153 MG_ERROR_CONTAINER_FULL = -4, 1154 /// Invalid value type was given as a function argument. 1155 MG_ERROR_INVALID_VALUE = -5, 1156 /// Failed to decode data returned from server. 1157 MG_ERROR_DECODING_FAILED = -6, 1158 /// Trying to insert a duplicate key in map. 1159 MG_ERROR_DUPLICATE_KEY = -7, 1160 /// An error occurred while trying to connect to server. 1161 MG_ERROR_NETWORK_FAILURE = -8, 1162 /// Invalid parameter supplied to `mg_connect`. 1163 MG_ERROR_BAD_PARAMETER = -9, 1164 /// Server violated the Bolt protocol by sending an invalid message type or 1165 /// invalid value. 1166 MG_ERROR_PROTOCOL_VIOLATION = -10, 1167 /// Server sent a FAILURE message containing ClientError code. 1168 MG_ERROR_CLIENT_ERROR = -11, 1169 /// Server sent a FAILURE message containing TransientError code. 1170 MG_ERROR_TRANSIENT_ERROR = -12, 1171 /// Server sent a FAILURE message containing DatabaseError code. 1172 MG_ERROR_DATABASE_ERROR = -13, 1173 /// Got an unknown error message from server. 1174 MG_ERROR_UNKNOWN_ERROR = -14, 1175 /// Invalid usage of the library. 1176 MG_ERROR_BAD_CALL = -15, 1177 /// Maximum container size allowed by Bolt exceeded. 1178 MG_ERROR_SIZE_EXCEEDED = -16, 1179 /// An error occurred during SSL connection negotiation. 1180 MG_ERROR_SSL_ERROR = -17, 1181 /// User provided trust callback returned a non-zeron value after SSL connection 1182 /// negotiation. 1183 MG_ERROR_TRUST_CALLBACK = -18, 1184 /// Unable to initialize the socket (both create and connect). 1185 MG_ERROR_SOCKET = -100, 1186 /// Function unimplemented. 1187 MG_ERROR_UNIMPLEMENTED = -1000 1188 } 1189 1190 /// Determines whether a secure SSL TCP/IP connection will be negotiated with 1191 /// the server. 1192 enum mg_sslmode { 1193 /// Only try a non-SSL connection. 1194 MG_SSLMODE_DISABLE, 1195 /// Only try a SSL connection. 1196 MG_SSLMODE_REQUIRE, 1197 } 1198 1199 /// An object encapsulating a Bolt session. 1200 struct mg_session; 1201 1202 /// An object containing parameters for `mg_connect`. 1203 /// 1204 /// Currently recognized parameters are: 1205 /// - host 1206 /// 1207 /// DNS resolvable name of host to connect to. Exactly one of host and 1208 /// address parameters must be specified. 1209 /// 1210 /// - address 1211 /// 1212 /// Numeric IP address of host to connect to. This should be in the 1213 /// standard IPv4 address format. You can also use IPv6 if your machine 1214 /// supports it. Exactly one of host and address parameters must be 1215 /// specified. 1216 /// 1217 /// - port 1218 /// 1219 /// Port number to connect to at the server host. 1220 /// 1221 /// - username 1222 /// 1223 /// Username to connect as. 1224 /// 1225 /// - password 1226 /// 1227 /// Password to be used if the server demands password authentication. 1228 /// 1229 /// - user_agent 1230 /// 1231 /// Alternate name and version of the client to send to server. Default is 1232 /// "MemgraphBolt/0.1". 1233 /// 1234 /// - sslmode 1235 /// 1236 /// This option determines whether a secure connection will be negotiated 1237 /// with the server. There are 2 possible values: 1238 /// 1239 /// - `MG_SSLMODE_DISABLE` 1240 /// 1241 /// Only try a non-SSL connection (default). 1242 /// 1243 /// - `MG_SSLMODE_REQUIRE` 1244 /// 1245 /// Only try an SSL connection. 1246 /// 1247 /// - sslcert 1248 /// 1249 /// This parameter specifies the file name of the client SSL certificate. 1250 /// It is ignored in case an SSL connection is not made. 1251 /// 1252 /// - sslkey 1253 /// 1254 /// This parameter specifies the location of the secret key used for the 1255 /// client certificate. This parameter is ignored in case an SSL connection 1256 /// is not made. 1257 /// 1258 /// - trust_callback 1259 /// 1260 /// A pointer to a function of prototype: 1261 /// int trust_callback(const char *hostname, const char *ip_address, 1262 /// const char *key_type, const char *fingerprint, 1263 /// void *trust_data); 1264 /// 1265 /// After performing the SSL handshake, `mg_connect` will call this 1266 /// function providing the hostname, IP address, public key type and 1267 /// fingerprint and user provided data. If the function returns a non-zero 1268 /// value, SSL connection will be immediately terminated. This can be used 1269 /// to implement TOFU (trust on first use) mechanism. 1270 /// It might happen that hostname can not be determined, in that case the 1271 /// trust callback will be called with hostname="undefined". 1272 /// 1273 /// - trust_data 1274 /// 1275 /// Additional data that will be provided to trust_callback function. 1276 struct mg_session_params; 1277 1278 /// Prototype of the callback function for verifying an SSL connection by user. 1279 alias mg_trust_callback_type = int function(const char *, const char *, const char *, const char *, void *); 1280 1281 /// Creates a new `mg_session_params` object. 1282 @safe @nogc mg_session_params *mg_session_params_make() pure nothrow; 1283 1284 /// Destroys a `mg_session_params` object. 1285 @safe @nogc void mg_session_params_destroy(mg_session_params *) pure nothrow; 1286 1287 /// Getters and setters for `mg_session_params` values. 1288 void mg_session_params_set_address(mg_session_params *, const char *address); 1289 void mg_session_params_set_host(mg_session_params *, const char *host); 1290 void mg_session_params_set_port(mg_session_params *, ushort port); 1291 void mg_session_params_set_username(mg_session_params *, const char *username); 1292 void mg_session_params_set_password(mg_session_params *, const char *password); 1293 void mg_session_params_set_user_agent(mg_session_params *, const char *user_agent); 1294 void mg_session_params_set_sslmode(mg_session_params *, mg_sslmode sslmode); 1295 void mg_session_params_set_sslcert(mg_session_params *, const char *sslcert); 1296 void mg_session_params_set_sslkey(mg_session_params *, const char *sslkey); 1297 void mg_session_params_set_trust_callback(mg_session_params *, mg_trust_callback_type trust_callback); 1298 void mg_session_params_set_trust_data(mg_session_params *, void *trust_data); 1299 const (char) *mg_session_params_get_address(const mg_session_params *); 1300 const (char) *mg_session_params_get_host(const mg_session_params *); 1301 ushort mg_session_params_get_port(const mg_session_params *); 1302 const (char) *mg_session_params_get_username(const mg_session_params *); 1303 const (char) *mg_session_params_get_password(const mg_session_params *); 1304 const (char) *mg_session_params_get_user_agent(const mg_session_params *); 1305 mg_sslmode mg_session_params_get_sslmode(const mg_session_params *); 1306 const (char) *mg_session_params_get_sslcert(const mg_session_params *); 1307 const (char) *mg_session_params_get_sslkey(const mg_session_params *); 1308 mg_trust_callback_type mg_session_params_get_trust_callback(const mg_session_params *params); 1309 void *mg_session_params_get_trust_data(const mg_session_params *); 1310 1311 /// Makes a new connection to the database server. 1312 /// 1313 /// This function opens a new database connection using the parameters specified 1314 /// in provided `params` argument. 1315 /// 1316 /// Params: params = New Bolt connection parameters. See documentation for 1317 /// `mg_session_params`. 1318 /// session = A pointer to a newly created `mg_session` is written 1319 /// here, unless there wasn't enough memory to allocate a 1320 /// `mg_session` object. In that case, it is set to NULL. 1321 /// 1322 /// Return: Returns 0 if connected successfuly, otherwise returns a non-zero 1323 /// error code. A more detailed error message can be obtained by using 1324 /// `mg_session_error` on `session`, unless it is set to NULL. 1325 int mg_connect(const mg_session_params *params, mg_session **session); 1326 1327 /// Returns the status of `mg_session`. 1328 /// 1329 /// Return: One of the session codes in `mg_session_code`. 1330 mg_session_code mg_session_status(const mg_session *session); 1331 1332 /// Obtains the error message stored in `mg_session` (if any). 1333 const (char) *mg_session_error(mg_session *session); 1334 1335 /// Destroys a `mg_session` and releases all of its resources. 1336 @safe @nogc void mg_session_destroy(mg_session *session) pure nothrow; 1337 1338 /// An object encapsulating a single result row or query execution summary. Its 1339 /// lifetime is limited by lifetime of parent `mg_session`. Also, invoking 1340 /// `mg_session_pull` ends the lifetime of previously returned `mg_result`. 1341 struct mg_result; 1342 1343 /// Submits a query to the server for execution. 1344 /// 1345 /// All records from the previous query must be pulled before executing the 1346 /// next query. 1347 /// 1348 /// Params: session = A `mg_session` to be used for query execution. 1349 /// query = Query string. 1350 /// params = A `mg_map` containing query parameters. NULL 1351 /// can be supplied instead of an empty parameter 1352 /// map. 1353 /// columns = Names of the columns output by the query 1354 /// execution will be stored in here. This is the 1355 /// same as the value 1356 /// obtained by `mg_result_columns` on a pulled 1357 /// `mg_result`. NULL can be supplied if we're 1358 /// not interested in the columns names. 1359 /// extra_run_information = A `mg_map` containing extra information for 1360 /// running the statement. 1361 /// It can contain the following information: 1362 /// - bookmarks - list of strings containing some 1363 /// kind of bookmark identification 1364 /// - tx_timeout - integer that specifies a 1365 /// transaction timeout in ms. 1366 /// - tx_metadata - dictionary taht can contain 1367 /// some metadata information, mainly used for 1368 /// logging. 1369 /// - mode - specifies what kind of server is the 1370 /// run targeting. For write access use "w" and 1371 /// for read access use "r". Defaults to write 1372 /// access. 1373 /// - db - specifies the database name for 1374 /// multi-database to select where the transaction 1375 /// takes place. If no `db` is sent or empty 1376 /// string it implies that it is the default 1377 /// database. 1378 /// qid = QID for the statement will be stored in here 1379 /// if an Explicit transaction was started. 1380 /// Return: Returns 0 if query was submitted for execution successfuly. 1381 /// Otherwise, a non-zero error code is returned. 1382 int mg_session_run(mg_session *session, const char *query, const mg_map *params, const mg_map *extra_run_information, const mg_list **columns, long *qid); 1383 1384 /// Starts an Explicit transaction on the server. 1385 /// 1386 /// Every run will be part of that transaction until its explicitly ended. 1387 /// 1388 /// Params: session = A `mg_session` on which the transaction should be started. 1389 /// extra_run_information = A `mg_map` containing extra information that will be used 1390 /// for every statement that is ran as part of the transaction. 1391 /// It can contain the following information: 1392 /// - bookmarks - list of strings containing some 1393 /// kind of bookmark identification 1394 /// - tx_timeout - integer that specifies a 1395 /// transaction timeout in ms. 1396 /// - tx_metadata - dictionary taht can contain 1397 /// some metadata information, mainly used for 1398 /// logging. 1399 /// - mode - specifies what kind of server is the 1400 /// run targeting. For write access use "w" and 1401 /// for read access use "r". Defaults to write 1402 /// access. 1403 /// - db - specifies the database name for 1404 /// multi-database to select where the transaction 1405 /// takes place. If no `db` is sent or empty 1406 /// string it implies that it is the default 1407 /// database. 1408 /// Return: Returns 0 if the transaction was started successfully. 1409 /// Otherwise, a non-zero error code is returned. 1410 int mg_session_begin_transaction(mg_session *session, const mg_map *extra_run_information); 1411 1412 /// Commits current Explicit transaction. 1413 /// 1414 /// Params: session = A `mg_session` on which the transaction should be committed. 1415 /// result = Contains the information about the committed transaction 1416 /// if it was successful. 1417 /// Return: Returns 0 if the transaction was ended successfully. 1418 /// Otherwise, a non-zero error code is returned. 1419 int mg_session_commit_transaction(mg_session *session, mg_result **result); 1420 1421 /// Rollbacks current Explicit transaction. 1422 /// 1423 /// Params: session = A `mg_session` on which the transaction should be rolled back. 1424 /// result = Contains the information about the rolled back transaction 1425 /// if it was successful. 1426 /// Return: Returns 0 if the transaction was ended successfully. 1427 /// Otherwise, a non-zero error code is returned. 1428 int mg_session_rollback_transaction(mg_session *session, mg_result **result); 1429 1430 /// Tries to fetch the next query result from `mg_session`. 1431 /// 1432 /// The owner of the returned result is `mg_session` `session`, and the 1433 /// result is destroyed on next call to `mg_session_fetch`. 1434 /// 1435 /// Return: On success, 0 or 1 is returned. Exit code 1 means that a new result 1436 /// row was obtained and stored in `result` and its contents may be 1437 /// accessed using `mg_result_row`. Exit code 0 means that there are 1438 /// no more result rows and that the query execution summary was stored 1439 /// in `result`. Its contents may be accessed using `mg_result_summary`. 1440 /// On failure, a non-zero exit code is returned. 1441 int mg_session_fetch(mg_session *session, mg_result **result); 1442 1443 /// Tries to pull results of a statement. 1444 /// 1445 /// Params: session = A `mg_session` from which the results should be pulled. 1446 /// pull_information = A `mg_map` that contains extra information for pulling the results. 1447 /// It can contain the following information: 1448 /// - n - how many records to fetch. `n=-1` will fetch 1449 /// all records. 1450 /// - qid - query identification, specifies the result 1451 /// from which statement the results should be pulled. 1452 /// `qid=-1` denotes the last executed statement. This 1453 /// is only for Explicit transactions. 1454 /// Return: Returns 0 if the result was pulled successfuly. 1455 /// Otherwise, a non-zero error code is returned. 1456 int mg_session_pull(mg_session *session, const mg_map *pull_information); 1457 1458 /// Returns names of columns output by the current query execution. 1459 const (mg_list) *mg_result_columns(const mg_result *result); 1460 1461 /// Returns column values of current result row. 1462 const (mg_list) *mg_result_row(const mg_result *result); 1463 1464 /// Returns query execution summary. 1465 const (mg_map) *mg_result_summary(const mg_result *result); 1466 } 1467 1468 version(unittest) { 1469 // Extern C definitions for allocation of memgraph internal types. 1470 extern (C) { 1471 // Need at least an empty definition for extern struct. 1472 struct mg_allocator {} 1473 extern shared mg_allocator mg_system_allocator; 1474 1475 @safe @nogc mg_string *mg_string_alloc(uint size, mg_allocator *allocator); 1476 @safe @nogc mg_list *mg_list_alloc(uint size, mg_allocator *allocator); 1477 @safe @nogc mg_map *mg_map_alloc(uint size, mg_allocator *allocator); 1478 @safe @nogc mg_node *mg_node_alloc(uint label_count, mg_allocator *allocator); 1479 @safe @nogc mg_path *mg_path_alloc(uint node_count, uint relationship_count, uint sequence_length, mg_allocator *allocator); 1480 1481 @safe @nogc mg_date *mg_date_alloc(shared mg_allocator *alloc) pure nothrow; 1482 @safe @nogc mg_time *mg_time_alloc(shared mg_allocator *alloc) pure nothrow; 1483 @safe @nogc mg_local_time *mg_local_time_alloc(shared mg_allocator *alloc) pure nothrow; 1484 @safe @nogc mg_date_time *mg_date_time_alloc(shared mg_allocator *alloc) pure nothrow; 1485 @safe @nogc mg_date_time_zone_id *mg_date_time_zone_id_alloc(shared mg_allocator *alloc) pure nothrow; 1486 @safe @nogc mg_local_date_time *mg_local_date_time_alloc(shared mg_allocator *alloc) pure nothrow; 1487 @safe @nogc mg_duration *mg_duration_alloc(shared mg_allocator *alloc) pure nothrow; 1488 1489 @safe @nogc mg_point_2d *mg_point_2d_alloc(shared mg_allocator *allocator) pure nothrow; 1490 @safe @nogc mg_point_3d *mg_point_3d_alloc(shared mg_allocator *allocator) pure nothrow; 1491 } 1492 } 1493 1494 unittest { 1495 import testutils : startContainer; 1496 startContainer(); 1497 } 1498 1499 /// Test connection to memgraph on 127.0.0.1, port 7688. 1500 unittest { 1501 import std..string : toStringz, fromStringz; 1502 import std.conv : to; 1503 1504 assert(mg_init() == 0); 1505 1506 auto params = mg_session_params_make(); 1507 assert(params != null); 1508 1509 mg_session_params_set_host(params, toStringz("127.0.0.1")); 1510 mg_session_params_set_port(params, to!ushort(7688)); 1511 mg_session_params_set_sslmode(params, mg_sslmode.MG_SSLMODE_DISABLE); 1512 1513 mg_session *session = null; 1514 int status = mg_connect(params, &session); 1515 mg_session_params_destroy(params); 1516 1517 assert(status == 0, fromStringz(mg_session_error(session))); 1518 1519 mg_session_destroy(session); 1520 mg_finalize(); 1521 }