Skip to content

Commit f77bef9

Browse files
ObjectBox.iogitbook-bot
authored andcommitted
GitBook: [#103] New image
1 parent d42d661 commit f77bef9

File tree

6 files changed

+51
-54
lines changed

6 files changed

+51
-54
lines changed
31.6 KB
Loading

custom-types.md

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,9 @@ float32, float64
2121

2222
## Defining a converter
2323

24-
To add support for a custom type, you can map properties to one of the built-in types using a `converter` annotation.
24+
To add support for a custom type, you can map properties to one of the built-in types using a `converter` annotation. 
2525

26-
For example, you could define a color in your entity using a custom `Color` struct and map it to an `int32`. Or you can map the `time.Time` to an `int64`, though losing some precision - less than a millisecond, i. e. a thousandth of a second\):
26+
For example, you could define a color in your entity using a custom `Color` struct and map it to an `int32`. Or you can map the `time.Time` to an `int64`, though losing some precision - less than a millisecond, i. e. a thousandth of a second):
2727

2828
```go
2929
type Task struct {
@@ -33,7 +33,7 @@ type Task struct {
3333
}
3434
```
3535

36-
In the entity definition above, we instruct ObjectBox to store the `DateCreated` field as a `int64` while converting it to/from `time.Time` when using in the program. ObjectBox will generate a binding code that will call the following two functions \(both start with the prefix `timeInt64` specified above\):
36+
In the entity definition above, we instruct ObjectBox to store the `DateCreated` field as a `int64` while converting it to/from `time.Time` when using in the program. ObjectBox will generate a binding code that will call the following two functions (both start with the prefix `timeInt64` specified above):
3737

3838
```go
3939
// from DB value to runtime value
@@ -64,10 +64,10 @@ func timeInt64ToDatabaseValue(goValue time.Time) (int64, error) {
6464
```
6565

6666
{% hint style="info" %}
67-
Actually this converter for `time.Time` is already part of the `objectbox` package and used automatically when you mark a `time.Time` property with ```objectbox:"date"`.``
67+
Actually this converter for `time.Time` is already part of the `objectbox` package and used automatically when you mark a `time.Time` property with `` `objectbox:"date"`. `` 
6868
{% endhint %}
6969

70-
## Queries on custom types <a id="queries"></a>
70+
## Queries on custom types <a href="#queries" id="queries"></a>
7171

7272
When you use a converter, the actual value stored in the database is the result of the `...ToDatabaseValue()` call, e.g. `int64` in the previous example. Therefore, when you want to compare the stored data in a query condition, make sure you use the converted value as well:
7373

@@ -88,9 +88,8 @@ tasks, _ := box.Query(
8888

8989
## Things to look out for
9090

91-
You must **not interact with the database** \(such as using `Box` or `ObjectBox`\) inside the converter. The converter methods are called within a transaction, so for example getting or putting entities to a box will fail.
91+
You must **not interact with the database** (such as using `Box` or `ObjectBox`) inside the converter. The converter methods are called within a transaction, so for example getting or putting entities to a box will fail.
9292

9393
Your converter implementation must be **thread safe** as it can be called from multiple go routines in parallel. Try to avoid using global variables.
9494

9595
`Query` is unaware of custom types. You have to **use the primitive DB type for queries**.
96-

getting-started.md

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ description: >-
99

1010
## Creating an Entity
1111

12-
Using ObjectBox in your project is fairly straight-forward.
12+
Using ObjectBox in your project is fairly straight-forward.&#x20;
1313

1414
First of all, let's define an Entity which is just a `struct`. It could be located basically anywhere but to keep our project structure clean, let's have it in a `internal/model/task.go` i. e. `model` package.
1515

@@ -29,13 +29,13 @@ type Task struct {
2929
{% endcode %}
3030

3131
{% hint style="info" %}
32-
Note that `Id uint64` is recognized by ObjectBox to contain an ID field which gives us a direct access to the stored Tasks objects by their ID.
32+
Note that `Id uint64` is recognized by ObjectBox to contain an ID field which gives us a direct access to the stored Tasks objects by their ID.&#x20;
3333

34-
Alternatively if your ID field is named differently, you can annotate it with \`objectbox:"id"\`.
34+
Alternatively if your ID field is named differently, you can annotate it with \`objectbox:"id"\`.\
3535
For more information see [Entity Annotations](entity-annotations.md).
3636
{% endhint %}
3737

38-
Having the entity file, we can run bindings generator to get the necessary `task.obx.go`
38+
Having the entity file, we can run bindings generator to get the necessary `task.obx.go`&#x20;
3939

4040
```bash
4141
cd my-project-dir
@@ -44,8 +44,8 @@ go generate ./...
4444

4545
The generated bindings code has two main competencies:
4646

47-
* provide Entity model \(schema\) to the ObjectBox
48-
* convert between internal object representation \(FlatBuffers\) and our struct `Task`
47+
* provide Entity model (schema) to the ObjectBox
48+
* convert between internal object representation (FlatBuffers) and our struct `Task`
4949

5050
{% hint style="warning" %}
5151
Additionally to the `task.obx.go` there's an `objectbox-model.json` which holds information about the model and `objectbox-model.go` which defines a model initialization function. All these files should be committed in source control along with the rest of your code.
@@ -69,9 +69,9 @@ func initObjectBox() *objectbox.ObjectBox {
6969

7070
## Working with Object Boxes
7171

72-
Bet you wondered where our name comes from :\)
72+
Bet you wondered where our name comes from :)
7373

74-
From ObjectBox you vend Box instances to manage your entities. While you can have multiple Box instances of the same type \(for the same Entity\) "open" at once, it's usually preferable to just use one instance and pass it around your code.
74+
From ObjectBox you vend Box instances to manage your entities. While you can have multiple Box instances of the same type (for the same Entity) "open" at once, it's usually preferable to just use one instance and pass it around your code.&#x20;
7575

7676
{% code title="main.go" %}
7777
```go
@@ -97,13 +97,13 @@ func main() {
9797

9898
Wherever you have access to a Box, you can use it to persist objects and fetch objects from disk. **Boxes are thread safe.** Here are some of the basic operations:
9999

100-
* **Put:** Persist an object, which may overwrite an existing object with the same ID. In other words, use `Put`to insert or update objects. When put succeeds, an ID will be assigned to the entity.
101-
* **Get:** When you have an object's ID, you can get to the object very efficiently using `Get`. It will return `nil` & error in case an error occurred and `nil` without any error if the object doesn't exist. To get all objects of a type, use `GetAll`which returns a slice.
100+
* **Put:** Persist an object, which may overwrite an existing object with the same ID. In other words, use `Put`to insert or update objects. When put succeeds, an ID will be assigned to the entity.&#x20;
101+
* **Get:** When you have an object's ID, you can get to the object very efficiently using `Get`. It will return `nil` & error in case an error occurred and `nil` without any error if the object doesn't exist.\
102+
To get all objects of a type, use `GetAll`which returns a slice.&#x20;
102103
* **Remove:** Deletes a previously persisted object from its box. Use `RemoveAll` to delete all objects and empty the box.
103104
* **Count:** The number of objects stored in this box.
104105

105106
## Task-list example application
106107

107-
To see it all put together, have a look at the Task-List application example in our git repository:
108+
To see it all put together, have a look at the Task-List application example in our git repository:\
108109
[https://github.com/objectbox/objectbox-go/tree/main/examples](https://github.com/objectbox/objectbox-go/tree/main/examples)
109-

install.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ As a workaround, you can install an ARMv6 version of the native library (instead
9999

100100
## Windows
101101

102-
The main prerequisite to using ObjectBox in Go is the ObjectBox binary DLL which actually implements the database functionality. We are using CGO which requires you to have MinGW `gcc` in PATH, e. g. [http://tdm-gcc.tdragon.net/](http://tdm-gcc.tdragon.net) - in case you don't have MinGW installed yet, please do so first.
102+
The main prerequisite to using ObjectBox in Go is the ObjectBox binary DLL which actually implements the database functionality. We are using CGO which requires you to have MinGW `gcc` in PATH, e. g. [http://tdm-gcc.tdragon.net/](http://tdm-gcc.tdragon.net/) - in case you don't have MinGW installed yet, please do so first.
103103

104104
### **Quick installation**
105105

relations.md

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,15 @@ description: >-
99

1010
Objects may reference other objects, for example using a simple reference or a list of objects. In database terms, we call those references **relations**. The object defining the relation we call the **source** object, the referenced object we call **target** object. So the relation has a direction.
1111

12-
If there is one target object, we call the relation **to-one.** And if there can be multiple target objects, we call it **to-many**.
12+
If there is one target object, we call the relation **to-one.** And if there can be multiple target objects, we call it **to-many**.&#x20;
1313

1414
{% hint style="info" %}
15-
Relations are initialized eagerly by default - i.e. the targets are loaded & as soon as the source object is read from the database. Lazy/manual loading of to-many relations is possible, using an annotation.
15+
Relations are initialized eagerly by default - i.e. the targets are loaded & as soon as the source object is read from the database. Lazy/manual loading of to-many relations is possible, using an annotation.&#x20;
1616
{% endhint %}
1717

1818
## To-One Relations
1919

20-
![To-One Relations](.gitbook/assets/image.png)
20+
<figure><img src=".gitbook/assets/to-one-relations-2.png" alt="To-One-relations"><figcaption><p>To-One Relations</p></figcaption></figure>
2121

2222
You define a to-one relation using \`link\` annotation on a field that is a pointer or value type of another entity. Consider the following example - the Order entity has a to-one relation to the Customer entity.
2323

@@ -64,7 +64,7 @@ box.Put(&model.Order{
6464
```
6565
{% endcode %}
6666

67-
After the `box.Put` has been executed on the first order, the `customer.Id` would be `1` because we're using pointers \(`Customer *Customer` field\) so Put could update the variable when it has inserted the Customer. Note that this wouldn't be possible if we were using copies \(`Customer Customer` field\) and in that case you should insert the customer manually into it's box first \(or use an existing customer selected from the database\).
67+
After the `box.Put` has been executed on the first order, the `customer.Id` would be `1` because we're using pointers (`Customer *Customer` field) so Put could update the variable when it has inserted the Customer. Note that this wouldn't be possible if we were using copies (`Customer Customer` field) and in that case you should insert the customer manually into it's box first (or use an existing customer selected from the database).
6868

6969
We can also **read**, **update** or **remove** the relationship to a customer:
7070

@@ -89,18 +89,18 @@ Note that removing the relation does not remove the customer from the database,
8989

9090
## To-Many Relations
9191

92-
There is a slight difference if you require a one-to-many \(1:N\) or many-to-many \(N:M\) relation.
92+
There is a slight difference if you require a one-to-many (1:N) or many-to-many (N:M) relation. \
9393
A 1:N relation is like the example above where a customer can have multiple orders, but an order is only associated with a single customer. An example for an N:M relation are students and teachers: students can have classes by several teachers but a teacher can also instruct several students.
9494

95-
### One-to-Many \(1:N\)
95+
### One-to-Many (1:N)
9696

97-
![One-to-Many \(1:N\)](http://objectbox.io/wordpress/wp-content/uploads/2017/02/One-To-Many-2.png)
97+
![One-to-Many (1:N)](http://objectbox.io/wordpress/wp-content/uploads/2017/02/One-To-Many-2.png)
9898

9999
Currently, one-to-many relations are defined implicitly as an opposite relation to a [to-one relation ](relations.md#to-one-relations)as defined above. This is useful for queries, e.g. to select all customers with an order placed within the last seven days.
100100

101-
### Many-to-Many \(N:M\)
101+
### Many-to-Many (N:M)
102102

103-
![Many-to-Many \(N:M\)](http://objectbox.io/wordpress/wp-content/uploads/2017/02/Many-To-Many-2.png)
103+
![Many-to-Many (N:M)](http://objectbox.io/wordpress/wp-content/uploads/2017/02/Many-To-Many-2.png)
104104

105105
To define a to-many relation, you can use a slice of entities - no need to specify the `link` annotation this time because ObjectBox wouldn't know how to store a slice of structs by itself anyway so it assumes it must be a many-to-may relation. They're stored when you put the source entity and loaded when you read it from the database, unless you specify a `lazy` annotation in which case, they're loaded manually, using `Box::GetRelated()`.
106106

@@ -145,7 +145,7 @@ box.Put(student2)
145145
```
146146
{% endcode %}
147147

148-
Similar to the to-one relations, related entities are inserted automatically if they are new. If the teacher entities do not yet exist in the database, the to-many will also put them. If they already exist, the to-many will only create the relation \(but not put them\).
148+
Similar to the to-one relations, related entities are inserted automatically if they are new. If the teacher entities do not yet exist in the database, the to-many will also put them. If they already exist, the to-many will only create the relation (but not put them).&#x20;
149149

150150
To **get** the teachers of a student we just access the list:
151151

@@ -159,11 +159,11 @@ for _, teacher := range student1.Teachers {
159159
```
160160
{% endcode %}
161161

162-
**Remove** and **update** work similar to insert - you just change the `student.Teachers` slice to reflect the new state \(i.e. remove element, add elements, etc\) and `box.Put(student)`. Note that if you want to change actual teacher data \(e.g. change teachers name\), you need to update the teacher entity itself, not just change it in one of the student.Teachers slice.
162+
**Remove** and **update** work similar to insert - you just change the `student.Teachers` slice to reflect the new state (i.e. remove element, add elements, etc) and `box.Put(student)`. Note that if you want to change actual teacher data (e.g. change teachers name), you need to update the teacher entity itself, not just change it in one of the student.Teachers slice.
163163

164164
### Lazy loading
165165

166-
In case the slices might contain many objects and you don't need to access the slice of the related objects each time you work with the source object, you may consider enabling the so called lazy-loading. You do that by specifying the \`lazy\` annotation on the field. Consider the updated model of the previous example:
166+
In case the slices might contain many objects and you don't need to access the slice of the related objects each time you work with the source object, you may consider enabling the so called lazy-loading. You do that by specifying the \`lazy\` annotation on the field. Consider the updated model of the previous example:&#x20;
167167

168168
{% code title="model.go" %}
169169
```go
@@ -208,7 +208,7 @@ for _, teacher := range student1.Teachers {
208208

209209
#### Updating a lazy-loaded slice
210210

211-
To update the list of `Teachers`, we can either overwrite the slice with completely new data \(new slice\), or if we want to keep the original data and update it, e.g. change a few items, we need to load them first the same way as when [reading \(above\)](relations.md#reading-a-lazy-loaded-slice).
211+
To update the list of `Teachers`, we can either overwrite the slice with completely new data (new slice), or if we want to keep the original data and update it, e.g. change a few items, we need to load them first the same way as when [reading (above)](relations.md#reading-a-lazy-loaded-slice).
212212

213213
{% code title="main.go" %}
214214
```go
@@ -226,4 +226,3 @@ student1.Teachers = append(student1.Teachers, &model.Teacher{Name: "Peter Clever
226226
box.Put(student1)
227227
```
228228
{% endcode %}
229-

0 commit comments

Comments
 (0)