# Models

## Concepts

* Entity
  * A representation of a table in a programatic way
* Entity registry
  * Mandarine keeps a list of all the entities that your application contains. This list is called *Entity Registry* as it works as a registry for Mandarine's engine to interact with your entities.

## Database interaction

* Your tables (entities) as well as the columns of those tables are created automatically in the database if they **do not** exist. This process happens at *mandarine compile time.*
  * If one of your entities is already in the database, but you have added a new column, Mandarine will resolve the new column and will add it to your table in your database.

## Declaring an entity

An entity is declared by using the decorator `@Table` . This decorator will add your virtual object database to the entity registry to then be used across your application.

The table decorator targets a **class.**

**Syntax:**

```typescript
@Table({ name?: string, schema: string})
```

* `name`
  * Optional
  * If name is not defined, the name of the target class will be considered the table's name
* `schema`
  * Required
  * Schema where your table will be located

### Declaring a column

In order to declare a column for your entity, you will need to use the decorator `@Column` .&#x20;

The `@Column` decorator targets a class field/property.

**Syntax:**

```typescript
@Column({ 
            name?: string, // Default = property's key
            type?: Types // See more below
            unique?: boolean, // Default = false
            nullable?: boolean, // Default = true
            length?: number, // Default = 255
            precision?: number, // Default = 8
            scale?: number // Default 2
       })
```

* `name`: Name of the column
* `type`: The reference of a SQL type given by a mandarine internal enum [(See enum here)](https://doc.deno.land/https/raw.githubusercontent.com/mandarineorg/mandarinets/master/orm-core/sql/types.ts). **Note** that if your current dialect does not recognize the indicated value, then the value will be set to character varying
  * If the type of the variable is: numeric, string, boolean. Mandarine will automatically read & detect its type
* `unique`: Specifies whether the column will have an unique constraint
* `nullable`: Specifies whether the column can be null
* `length`: Specifies the length of the column (used in certain cases, such as when the column's type is character varying/varchar)
* `precision`: Specifies the precision of a numeric character (used in certain cases, such as when the type is decimal)
* `scale`: Specifies the scale of the numeric character (used in certain cases, such as when the type is decimal)

### Declaring a primary key

The declaration of a primary key depends on two decorators, the decorator `@Id` and the decorator `@GeneratedValue`. Both decorators target a class field **previously decorated** with the decorator `@Column`

* `@Id` will specify that a column is a primary key
* `@GeneratedValue` will specify the type of strategy to be used for the declared primary key

**Syntax:**

```typescript
@Id()
```

```typescript
@GeneratedValue({strategy: "SEQUENCE" | "MANUAL", manualHandler?: Function})
```

* Declares what strategy the table's primary key will use.
* If `strategy` is *SEQUENCE*, then the column is assumed to be serial (*auto-increment*)
* If `strategy` is *MANUAL*, then when an insert is invoked *through Mandarine's ORM*, the value will be generated by invoking `manualHandler`.

## Creating a model

Now that we have seen the concepts involved in Models, we can create one.

```typescript
@Table({ schema: "public" })
class Users {

    @Id()
    @GeneratedValue({strategy: "SEQUENCE"})
    @Column()
    public id: number;

    @Column()
    public firstname: string;

    @Column()
    public lastname: string;

    @Column()
    public country: string;

}
```

In the example above we are declaring an entity that will have *Users* as name, it has 4 columns: *id*, *firstname*, *lastname*, *country*. The column *id* has been annotated with *ID*, and *GeneratedValue*, meaning *id* will be a primary key and its strategy is SEQUENCE/Auto-increment.\
**Note** that if your model has a constructor, **ALL** its parameters must be optional.
