@apparts/model
v5.2.0
Published
A model for reading and writing to the database. It stores data.
Downloads
89
Readme
#+TITLE: Apparts-Model #+DATE: [2020-08-06 Thu] #+AUTHOR: Philipp Uhl
- Usage
You can either work with one, multiple, or no elements. The respective classes are ~OneModel~, ~ManyModel~, and ~NoneModel~. You can extend these classes by using them:
#+BEGIN_SRC js const { useModel, makeModel } = require("@apparts/model");
const types = {
id: {
/* Types as defined by @apparts/types /
type: "id",
/ Will be shown in output of getPublic*/
public: true,
/* Auto increment this field /
auto: true,
/ This is a key. Combined keys are possible, too, by setting
{ key: true } on multiple fields. /
key: true
}
optionalVal: {
type: "string",
/ This field can be NULL /
optional: true
},
derivedValue: {
type: "string",
public: true,
/ This field will not be persisted. It's value is derived from
other values and will be generated on the fly. When using the
getPublic method, while having derived values, you must first
call generateDerived. /
derived: async (c, model) => {
/ c is the content of the model, model is the whole Model object /
return (await model._dbs._getSomeRelation()).text;
}
},
createdOn: {
type: "time",
/ This field will be set to the functions result, if the field is
NULL. The function recieves the element as parameter. /
default: (c) => c.optionalVal || Date.now()
},
fixedDefault: {
type: "int",
/ This field will be set to the given value, if the field is
NULL. /
default: 7,
/ This field will be named "someNumber" in the output of
getPublic */
mapped: "someNumber",
public: true
},
};
const [Users, _User, NoUser] = useModel(types, "users");
// You can extend the classes like this: class User extends _User { constructor(dbs, content) { super(dbs, content); // do something here } additionalFunc() { return this.content; } }
module.exports = makeModel("User", [Users, User, NoUser]); #+END_SRC
The extended classes can then be used:
#+BEGIN_SRC js // get dbs from "@apparts/db" somehow const peter = await new User(dbs, { optionalVal: "Peter"}).store(); console.log(peter.content); // => { id: 1, optionalVal: "Peter", createdOn: 12345, fixedDefault: 7 } #+END_SRC
** =useModel= and =makeModel=
@apparts/model exports two functions: =useModel= and =makeModel=:
- =useModel : (, ) => <[ManyModel, OneModel, NoneModel]>= :: A function that takes the type definition of the model and the name for the collection (with Postgresql that would be the table name). It returns an array with a =ManyModel=, an =OneModel= and a =NoneModel= for the given type and collection name.
- =makeModel : (, [ManyModel, OneModel, NoneModel]) => { use, , s, No }= ::
A function that is intended to generate what a file exports, that
defines a model. It takes the overloaded classes as input and the
models name. It returns an object with a function that works similar
to =useModel= and the respective Many-, One-, NoneModel but named
according to the =name=-parameter.
- =use : (?dbs) => [s, , No]= :: The =use= function can be either invoked with a [[https://github.com/phuhl/apparts-db][Dbs]] or without. When invoked with a Dbs, the returned Models will have the Dbs set already and have a changed constructor signature: The ManyModel and OneModel take the content as first and only parameter, the NoneModel doesn't take a parameter at all.
** ManyModel
Values:
- ~contents~ :: Array, that contains the values. The values can be edited. To save the changes, call ~update~.
Functions:
- ~constructor(dbs, ?[contents])~ :: Constructor, when used via =use()=.
- ~constructor(?[contents])~ :: Constructor, when used via =use(dbs)=.
- ~async load(filter, ?limit, ?offset, ?order)~ :: Load data, filter grammar is as defined by the =find= function of the =dbs=. For more information, see below at in the section "Filter Grammar".
- ~async loadByIds(ids, ?limit, ?offset)~ :: Load data by IDs. For models with only one key, you can use ~[, , ...]~, for a model with multiple keys, you have to use ~{ : [ , ...], : [, ...], ...}~.
- ~async store()~ :: Saves to the database
- ~async update()~ :: Updates the values, if you updated the contents.
- ~length()~ :: Length of ~contents~
- ~set(field, val)~ :: Set a field on all elements
- ~setF(field, f)~ :: Set a field on all elements through a function, that receives the element and returns the new value
- ~async deleteAll()~ :: Delete all from the loaded collection from the database. If any of the items is referenced by another item, =IsReference= will be thrown.
- ~getPublic()~ :: Get the public representation (marked as public in the types definition by the key ~public (bool)~). If there are derived values in the type, =generateDerived= must be called first!
- =async generateDerived()= :: Generate derived values. The derived values will be saved in =_derived=. This function must be called before =getPublic= is called, if derived values exist in the type.
- =static getTypes()= :: Returns the type of the model
** OneModel
Values:
- ~content~ :: Object, that contains the values. The values can be edited. To save the changes, call ~update~.
Functions:
- ~constructor(dbs, ?content)~ :: Constructor, when used via =use()=.
- ~constructor(?content)~ :: Constructor, when used via =use(dbs)=.
- ~async load(filter)~ :: Load one item. If more than one item was found that satisfies the filter, a =NotUnique= error will be thrown. If no item was found, a =NotFound= error will be thrown. The filter grammar is as defined by the =find= function of the =dbs=. For more information, see below at in the section "Filter Grammar".
- ~async loadById(id)~ :: Load data by ID. For models with only one key, you can use ~~, for a model with multiple keys, you have to use ~{ : , : , ... }~.
- ~async store()~ :: Saves to the database
- ~async update()~ :: Updates the values, if you updated the contents.
- ~set(field, val)~ :: Set a field on all elements
- ~async delete()~ :: Delete this element from the database. If the item is referenced by another item, =IsReference= will be thrown.
- ~getPublic()~ :: Get the public representation (marked as public in the types definition by the key ~public (bool)~). If there are derived values in the type, =generateDerived= must be called first!
- =async generateDerived()= :: Generate derived values. The derived values will be saved in =_derived=. This function must be called before =getPublic= is called, if derived values exist in the type.
- =static getTypes()= :: Returns the type of the model
** NoneModel
Functions:
- ~constructor(dbs)~ :: Constructor
- ~async loadNone(filter)~ :: Throws an ~DoesExist~ error, if something was loaded, does nothing if nothing was loaded. The filter grammar is as defined by the =find= function of the =dbs=. For more information, see below at in the section "Filter Grammar".
- =static getTypes()= :: Returns the type of the model
** Errors
- ~DoesExist~
- ~NotFound~
- ~NotUnique~
- =IsReference=
- =ConstraintFailed=
#+BEGIN_SRC js const { NotUnique, NotFound, DoesExist, IsReference, ConstraintFailed } = require("@apparts/model"); #+END_SRC
** Filter Grammar
The filter syntax is like this:
#+BEGIN_SRC js const filter = { : , ...}; // where is a key from the type and // where matcher is = | { op: , val: } | { op: , val: } | { op: "and", val: } // logical and for all subconditions = lte // less than or equals | lt // less than | gte // greater than or equals | gt // greater than = like // sql like, a string comparison where the "%" character // will be matched against anything. E.g. "bread%crumb" // matches "bread crumb" or "bread eating crumb". = | | | null #+END_SRC