You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: custom-types.md
+6-7Lines changed: 6 additions & 7 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -21,9 +21,9 @@ float32, float64
21
21
22
22
## Defining a converter
23
23
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. 
25
25
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):
27
27
28
28
```go
29
29
typeTaskstruct {
@@ -33,7 +33,7 @@ type Task struct {
33
33
}
34
34
```
35
35
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):
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"`.`` 
68
68
{% endhint %}
69
69
70
-
## Queries on custom types <aid="queries"></a>
70
+
## Queries on custom types <ahref="#queries"id="queries"></a>
71
71
72
72
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:
73
73
@@ -88,9 +88,8 @@ tasks, _ := box.Query(
88
88
89
89
## Things to look out for
90
90
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.
92
92
93
93
Your converter implementation must be **thread safe** as it can be called from multiple go routines in parallel. Try to avoid using global variables.
94
94
95
95
`Query` is unaware of custom types. You have to **use the primitive DB type for queries**.
Copy file name to clipboardExpand all lines: getting-started.md
+12-12Lines changed: 12 additions & 12 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -9,7 +9,7 @@ description: >-
9
9
10
10
## Creating an Entity
11
11
12
-
Using ObjectBox in your project is fairly straight-forward.
12
+
Using ObjectBox in your project is fairly straight-forward. 
13
13
14
14
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.
15
15
@@ -29,13 +29,13 @@ type Task struct {
29
29
{% endcode %}
30
30
31
31
{% 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. 
33
33
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"\`.\
35
35
For more information see [Entity Annotations](entity-annotations.md).
36
36
{% endhint %}
37
37
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` 
39
39
40
40
```bash
41
41
cd my-project-dir
@@ -44,8 +44,8 @@ go generate ./...
44
44
45
45
The generated bindings code has two main competencies:
46
46
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`
49
49
50
50
{% hint style="warning" %}
51
51
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.
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. 
75
75
76
76
{% code title="main.go" %}
77
77
```go
@@ -97,13 +97,13 @@ func main() {
97
97
98
98
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:
99
99
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. 
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. 
102
103
***Remove:** Deletes a previously persisted object from its box. Use `RemoveAll` to delete all objects and empty the box.
103
104
***Count:** The number of objects stored in this box.
104
105
105
106
## Task-list example application
106
107
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:\
Copy file name to clipboardExpand all lines: install.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -99,7 +99,7 @@ As a workaround, you can install an ARMv6 version of the native library (instead
99
99
100
100
## Windows
101
101
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.
Copy file name to clipboardExpand all lines: relations.md
+13-14Lines changed: 13 additions & 14 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -9,15 +9,15 @@ description: >-
9
9
10
10
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.
11
11
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**. 
13
13
14
14
{% 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. 
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.
23
23
@@ -64,7 +64,7 @@ box.Put(&model.Order{
64
64
```
65
65
{% endcode %}
66
66
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).
68
68
69
69
We can also **read**, **update** or **remove** the relationship to a customer:
70
70
@@ -89,18 +89,18 @@ Note that removing the relation does not remove the customer from the database,
89
89
90
90
## To-Many Relations
91
91
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. \
93
93
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.
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.
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()`.
106
106
@@ -145,7 +145,7 @@ box.Put(student2)
145
145
```
146
146
{% endcode %}
147
147
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). 
149
149
150
150
To **get** the teachers of a student we just access the list:
151
151
@@ -159,11 +159,11 @@ for _, teacher := range student1.Teachers {
159
159
```
160
160
{% endcode %}
161
161
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.
163
163
164
164
### Lazy loading
165
165
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: 
167
167
168
168
{% code title="model.go" %}
169
169
```go
@@ -208,7 +208,7 @@ for _, teacher := range student1.Teachers {
208
208
209
209
#### Updating a lazy-loaded slice
210
210
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).
0 commit comments