Skip to content

Commit

Permalink
[Doc] update model doc to accurate latest.
Browse files Browse the repository at this point in the history
  • Loading branch information
agrosner committed Oct 21, 2018
1 parent 256b823 commit 83bce91
Showing 1 changed file with 31 additions and 73 deletions.
104 changes: 31 additions & 73 deletions usage2/usage/models.md
Original file line number Diff line number Diff line change
@@ -1,61 +1,39 @@
# Models

In DBFlow we dont have any restrictions on what your table class is. We do, however if you use Java, we recommend you subclass `BaseModel` on your highest-order base-class, which provides a default implementation for you.

When using regular models:

```java
FlowManager.getModelAdapter(MyTable.class).save(myTableObject);
```

When using `BaseModel`, it is much cleaner:

```java
myTableObject.save();
```

if you use Kotlin, you can add the [kotlin extensions](https://github.com/agrosner/DBFlow/tree/fb3739caa4c894d50fd0d7873c70a33416c145e6/KotlinSupport.md) to your project use them as extension methods:
In DBFlow we dont have any restrictions on what your table class is. We do, however if you use Java, we recommend you subclass `BaseModel` on your highest-order base-class, which provides a default implementation for you. Otherwise utilize a kotlin extension method on `Any`.

```kotlin
myTableObject.save()
```

## Columns

By default, DBFlow lazily looks for columns. This means that they all must contain either `@PrimaryKey`, `@Column`, or `@ForeignKey` to be used in tables.
By default, DBFlow inclusdes all properties as columns. For other kinds of fields, they must contain either `@PrimaryKey` or `@ForeignKey` to be used in tables. However this still requires you to specify at least one `@PrimaryKey` field. You can then explicitly ignore fields via the `@ColumnIgnore` annotation if necessary. You can turn off all fields and make it explicit using `@Table(allFields = false)`

If you wish to make it simpler and include all fields in a class, set `@Table(allFields = true)`. However this still requires you to specify at least one `@PrimaryKey` field. You can then explicitly ignore fields via the `@ColumnIgnore` annotation.
In Kotlin, Column properties must be public and `var` for now. In future versions, we hope to support Kotlin constructors without default arguments. For now, all must be `var` and provide a default constructor. We respect nullability of the properties and won't assign `null` to them if they're not nullable.

Columns can be `public`, package-private, or `private`. `private` fields **must** come with `public` java-bean-style getters and setters.
In Java, Columns can be `public`, package-private, or `private`. `private` fields **must** come with `public` java-bean-style getters and setters. Package private used in other packages generate a `_Helper` class which exposes a method to call these fields in an accessible way. This has some overhead, so consider making them with `public` get/set or public.

Here is an example of a "nice" `private` field:

```java
@Table(database = AppDatabase.class)
public class Dog {

@PrimaryKey
private String name;

public void setName(String name) {
this.name = name;
}

public String getName() {
return name;
}

}
```
Here is an example of a "nice" `Table`:

```kotlin
@Table(database = AppDatabase.class)
public class Dog(@Primary var name: String? = null)
public class Dog(@PrimaryKey var id: Int = 0, var name: String? = null)
```

Columns have a wide-range of supported types in the `Model` classes: **Supported Types**: 1. all java primitives including `char`,`byte`, `short`, and `boolean`. 2. All java boxed primitive classes 3. String, Date, java.sql.Date, Calendar, Blob, Boolean 4. Custom data types via a [TypeConverter](typeconverters.md) 5. `Model` as fields, but only as `@PrimaryKey` and/or `@ForeignKey` 6. `@ColumnMap` objects that flatten an object into the current table. Just like a `@ForeignKey`, but without requiring a separate table. \(4.1.0+\). Avoid nesting more than one object, as the column count could get out of control.
Columns have a wide-range of supported types in the `Model` classes: **Supported Types**:

1. all primitives including `Char`,`Byte`, `Short`, and `Boolean`.
2. All Kotlin nullable primitives (java boxed).
3. String, Date, java.sql.Date, Calendar, Blob, Boolean
4. Custom data types via a [TypeConverter](typeconverters.md)
5. `Model` as fields, but only as `@PrimaryKey` and/or `@ForeignKey`
6. `@ColumnMap` objects that flatten an object into the current table. Just like a `@ForeignKey`, but without requiring a separate table. \(4.1.0+\). Avoid nesting more than one object, as the column count could get out of control.

**Unsupported Types**: 1. `List<T>` : List columns are not supported and not generally proper for a relational database. However, you can get away with a non-generic `List` column via a `TypeConverter`. But again, avoid this if you can. 2. Anything that is generically typed \(even with an associated `TypeConverter`\). If you need to include the field, subclass the generic object and provide a `TypeConverter`.
**Unsupported Types**:

1. `List<T>` : List columns are not supported and not generally proper for a relational database. However, you can get away with a non-generic `List` column via a `TypeConverter`. But again, avoid this if you can.
2. Anything that is generically typed \(even with an associated `TypeConverter`\). If you need to include the field, subclass the generic object and provide a `TypeConverter`.

## Inherited Columns

Expand All @@ -71,27 +49,15 @@ Since we don't require extension on `BaseModel` directly, tables can extend non-
public class InheritorModel extends InheritedModel implements Model {
```

Generally, this should be avoided and if you control the source, just place your model objects / db objects in same module as a `db` module.

## Primary Keys

DBFlow supports multiple primary keys, right out of the box. Simply create a table with multiple `@PrimaryKey`:

```java
@Table(database = AppDatabase.class)
public class Dog extends BaseModel {

@PrimaryKey
String name;

@PrimaryKey
String breed;

}
```

```kotlin
@Table(database = AppDatabase::class)
class Dog(@PrimaryKey var name: String? = null,
@PrimaryKey var breed: String? = null)
class Dog(@PrimaryKey var name: String = "", @PrimaryKey var breed: String = "")
```

If we want an auto-incrementing key, you specify `@PrimaryKey(autoincrement = true)`, but only one of these kind can exist in a table and you cannot mix with regular primary keys.
Expand All @@ -112,30 +78,23 @@ UNIQUE('name', 'number') ON CONFLICT FAIL, UNIQUE('name', 'address') ON CONFLICT

We declare the annotations as such:

```java
@Table(database = AppDatabase.class,
```kotlin
@Table(database = AppDatabase::class,
uniqueColumnGroups = {@UniqueGroup(groupNumber = 1, uniqueConflict = ConflictAction.FAIL),
@UniqueGroup(groupNumber = 2, uniqueConflict = ConflictAction.ROLLBACK))
public class UniqueModel {

@PrimaryKey
@Unique(unique = false, uniqueGroups = {1,2})
String name;

@Column
@Unique(unique = false, uniqueGroups = 1)
String number;

@Column
@Unique(unique = false, uniqueGroups = 2)
String address;

}
class UniqueModel(
@PrimaryKey @Unique(unique = false, uniqueGroups = {1,2})
var name: String = "",
@Column @Unique(unique = false, uniqueGroups = 1)
var number: String = "",
@Column @Unique(unique = false, uniqueGroups = 2)
var address: String = "")
```

The `groupNumber` within each defined `uniqueColumnGroups` with an associated `@Unique` column. We need to specify `unique=false` for any column used in a group so we expect the column to be part of a group. If true as well, the column will _also_ alone be unique.

## Default Values
**Not to be confused with Kotlin default values** This only applies when fields are marked as `nullable`. When fields are non null in kotlin, we utilize the default constructor value when it is set, so when the column data is `null` from a `Cursor`, we do not override the initial assignment.

DBFlow supports default values in a slighty different way that SQLite does. Since we do not know exactly the intention of missing data when saving a `Model`, since we group all fields, `defaultValue` specifies a value that we replace when saving to the database when the value of the field is `null`.

Expand All @@ -156,4 +115,3 @@ Boolean aBoolean;
```

DBFlow inserts it's literal value into the `ModelAdapter` for the table so any `String` must be escaped.

0 comments on commit 83bce91

Please sign in to comment.