Schema
In NimbusDB, a schema defines the structure of your data, including the types of data you can store and the rules for how that data is organized. A well-designed schema helps ensure data integrity and makes it easier to query and manage your data.
Schemaless Models
Section titled “Schemaless Models”You can create a model without defining a schema, which allows you to store any type of data without restrictions. However, this approach may lead to data inconsistency and makes it harder to manage your data effectively.
// `schema` is an optional parameter when creating a model, placed after the `name` parameter// If you don't provide a schema, the model will be created with an empty schema,// which means you can store any data in the model without any restrictionsvar model_no_schema = new NimbusDBModel("global", "items");Defining a Schema
Section titled “Defining a Schema”A schema is defined as an object where each key represents a column name and the value defines the rules for that column. The rules can be as simple as specifying a data type or as complex as defining constraints, validators, and default values.
// Here's an example of a simple schema definition for an 'items' modelvar simple_schema = { id: NIMBUSDB_DATA_TYPE.INTEGER, name: NIMBUSDB_DATA_TYPE.STRING, price: NIMBUSDB_DATA_TYPE.NUMBER};var model_with_schema = new NimbusDBModel("global", "items", simple_schema);
// You can define schema with union data types using arraysvar union_schema = { id: NIMBUSDB_DATA_TYPE.INTEGER, name: NIMBUSDB_DATA_TYPE.STRING, price: [NIMBUSDB_DATA_TYPE.NUMBER, NIMBUSDB_DATA_TYPE.STRING] // price can be a number or a string};var model_with_union_schema = new NimbusDBModel("global", "items", union_schema);
// Alternatively, you can define the schema using the object formatvar object_schema = { id: { type: NIMBUSDB_DATA_TYPE.INTEGER, const: NIMBUSDB_CONSTRAINT.PRIMARY_KEY // `id` column is the primary key of the model }, name: NIMBUSDB_DATA_TYPE.STRING, price: { type: [NIMBUSDB_DATA_TYPE.NUMBER, NIMBUSDB_DATA_TYPE.STRING] }};var model_with_object_schema = new NimbusDBModel("global", "items", object_schema);You can choose to use the simple one (directly using data types or arrays of data types) or the advanced one (using the object format to specify constraints, validators, and default values) based on your needs.
Data Types
Section titled “Data Types”NimbusDB supports a variety of data types that you can use in your schema definitions, including primitive types like NUMBER, STRING, and BOOLEAN, as well as complex types like STRUCT, METHOD, and various asset types.
You can also define union data types using arrays, allowing a column to accept multiple types of data.
Constraints
Section titled “Constraints”Constraints are rules that you can apply to your columns to enforce data integrity. For example, you can use the PRIMARY_KEY constraint to designate a column as the primary key of the model, or the UNIQUE constraint to ensure that all values in a column are unique.
Here’s an example of how to use constraints in your schema definition:
var schema_with_constraints = { id: { type: NIMBUSDB_DATA_TYPE.INTEGER, const: NIMBUSDB_CONSTRAINT.PRIMARY_KEY // `id` column is the primary key of the model }, name: { type: NIMBUSDB_DATA_TYPE.STRING, const: NIMBUSDB_CONSTRAINT.UNIQUE // name must be unique across the model }, price: { type: [NIMBUSDB_DATA_TYPE.NUMBER, NIMBUSDB_DATA_TYPE.STRING] }, is_locked: { type: NIMBUSDB_DATA_TYPE.BOOLEAN, const: NIMBUSDB_CONSTRAINT.OPTIONAL // is_locked is an optional column }, sprite: { type: NIMBUSDB_DATA_TYPE.ASSET_SPRITE, const: [NIMBUSDB_CONSTRAINT.OPTIONAL, NIMBUSDB_CONSTRAINT.UNIQUE] // sprite is an optional column and its value must be unique if provided }};Validators and Default Values
Section titled “Validators and Default Values”Validators are methods that you can define in your schema to validate the data before it’s set to a column. If the validator fails (returns false):
- If a
default_valueis provided, the column will be set to the default value instead of the new value, or call the method to get the default value if it’s a method. - Otherwise, the operation will be aborted and the data will not be inserted/updated in the model.
Here’s an example of how to use validators and default values in your schema definition:
var object_schema = { id: { type: NIMBUSDB_DATA_TYPE.INTEGER, const: NIMBUSDB_CONSTRAINT.PRIMARY_KEY }, name: { type: NIMBUSDB_DATA_TYPE.STRING, validator: function(data, value) { return string_length(value) > 0; // name must be a non-empty string } }, price: { type: [NIMBUSDB_DATA_TYPE.NUMBER, NIMBUSDB_DATA_TYPE.STRING], validator: function(data, value) { return is_numeric(value) ? (value >= 0) : (is_string(value) && real(value) >= 0); // price must be non-negative }, default_value: 0 // default price is 0 if the validator fails // you can also use a method to get the default value, for example: // default_value: function(data, value) { // return 0; // default price is 0 if the validator fails // } }, is_locked: { type: NIMBUSDB_DATA_TYPE.BOOLEAN, const: NIMBUSDB_CONSTRAINT.OPTIONAL, default_value: false // default is_locked is false if `is_locked` is not provided }};var model_with_object_schema = new NimbusDBModel("global", "items", object_schema);References
Section titled “References”NimbusDBModel
Section titled “NimbusDBModel”Model for NimbusDB that manages schema-backed data, relations, queries, and lifecycle operations.
class NimbusDBModel { constructor( _root: Instance | "global", _name: string, _schema?: NimbusDBSchema, _data?: Struct | Struct[], _option?: NimbusDBModelOptions );
cache: { [key: number | string]: NimbusDBData; }; custom_id: int; data: NimbusDBData[]; debug: boolean | 2 | 3; id: int; name: string; ref: { // exposed data [key: string]: NimbusDBData; }; primary_key?: string; temp?: Struct; // temporary user data
static __id: int; __root: Instance | "global"; __data_id: int; __in_transaction: boolean; __locked: boolean; __column_names?: string[]; __relations: NimbusDBRelation[]; __schema?: NimbusDBSchema; __sys_temp?: Struct; // temporary system data
// ...public and internal methods}Constructor
Section titled “Constructor”class NimbusDBModel { constructor( _root: Instance | "global", _name: string, _schema?: NimbusDBSchema, _data?: Struct | Struct[], _option?: NimbusDBModelOptions )}- Type:
Instance|"global" - The root/place where the model is located. If the model is located in the global scope (e.g. global variable), you can use
"global"as the value. Otherwise, you can provide an instance/object id of the root object where the model is located.
- Type:
string - The name of the model.
_schema
Section titled “_schema”- Type:
NimbusDBSchema - Default:
undefined - The schema (column rules) of the model. If not provided, the model will be created with an empty schema.
- Type:
Struct|Struct[] - Default:
undefined - The initial data to be inserted into the model. If not provided, the model doesn’t have any data initially.
_option
Section titled “_option”- Type:
NimbusDBModelOptions - Default:
undefined - The options for the model. See the NimbusDBModelOptions type for the available options.
NimbusDBSchema
Section titled “NimbusDBSchema”The schema is a type that defines the columns and their rules for a model. It is an object where the keys are the column names and the values are the column rules.
type NimbusDBSchema = { [column_name: string]: NimbusDBColumnRules;};NimbusDBColumnRules
Section titled “NimbusDBColumnRules”The column rules are used to define the type, constraints, and validation rules for a column in a model. It can be a single data type, an array of data types, or an object with additional options.
type NimbusDBColumnRules = | NIMBUSDB_DATA_TYPE | NIMBUSDB_DATA_TYPE[] | { type: NIMBUSDB_DATA_TYPE | NIMBUSDB_DATA_TYPE[]; const?: NIMBUSDB_CONSTRAINT | NIMBUSDB_CONSTRAINT[]; // `const` is used to specify constraints for the column validator?: ( // a function that validates the value before it's set to the column data: Struct, // new data (after calling the method if it's a method) value: any, // new value temp: Struct, model: NimbusDBModel ) => boolean; default_value?: any | (( // a default value or a function that returns a default value when the validator fails or when the value is not provided data: Struct, // original data value: any, // original value temp: Struct, model: NimbusDBModel ) => any); };NimbusDBModelOptions
Section titled “NimbusDBModelOptions”The model options are used to configure the behavior of a model, such as column order, custom ID, debugging, and more.
type NimbusDBModelOptions = Partial<{ column_order: string[]; // order of columns (default = undefined, use columns in the `column_names` property) custom_id: int; // set custom ID (default = 0) debug: boolean | 2 | 3; // enable debugging, true/1 = ~warning, 2 = ~success, 3 = ~info (default = false) init_cache: boolean; // initialize cache for initial data (default = false) in_tx: boolean; // [INTERNAL] whether the model is in a transaction (default = false) force_insert: boolean; // force insertion of initial data (default = false) start_id: int; // start ID for auto-increment (default = 1) temp: Struct; // set temporary data (default = undefined)}>;NIMBUSDB_DATA_TYPE
Section titled “NIMBUSDB_DATA_TYPE”The data types are used to define the type of data that can be stored in a column in a model. They can be used directly as the value of the type property in the column rules, or as an array of data types to allow a column to accept multiple types of data.
enum NIMBUSDB_DATA_TYPE { ANY, NUMBER, INTEGER, STRING, BOOLEAN, STRUCT, METHOD, INSTANCE, ASSET_OBJECT, ASSET_SPRITE, ASSET_SOUND, ASSET_ROOM, ASSET_TILES, ASSET_PATH, ASSET_FONT, ASSET_SHADER, ARRAY_ANY, ARRAY_NUMBER, ARRAY_INTEGER, ARRAY_STRING, ARRAY_BOOLEAN, ARRAY_STRUCT, ARRAY_METHOD, ARRAY_INSTANCE, ARRAY_ASSET_OBJECT, ARRAY_ASSET_SPRITE, ARRAY_ASSET_SOUND, ARRAY_ASSET_ROOM, ARRAY_ASSET_TILES, ARRAY_ASSET_PATH, ARRAY_ASSET_FONT, ARRAY_ASSET_SHADER}NIMBUSDB_CONSTRAINT
Section titled “NIMBUSDB_CONSTRAINT”The constraints are used to define the rules for a column in a model, such as whether it is optional, unique, or primary key.
enum NIMBUSDB_CONSTRAINT { NONE, OPTIONAL, UNIQUE, PRIMARY_KEY // NOT_NULL = set automatically when the column is defined with data type(s) // CHECK = `validator` in the column rules // DEFAULT = `default_value` in the column rules // AUTO_INCREMENT = set automatically on a column with PRIMARY_KEY constraint // FOREIGN_KEY = set automatically through `.define_relation()` method}