### Go ObjectBox Basic CRUD Operations Example Source: https://golang.objectbox.io/getting-started This Go example demonstrates the fundamental Create, Read, Update, and Delete (CRUD) operations using an ObjectBox Box instance. It initializes ObjectBox, obtains a Box for the Task model, and performs Put (create/update), Get (read), and Remove (delete) operations on a Task entity, showcasing a typical application flow. ```Go func main() { // load objectbox ob := initObjectBox() defer ob.Close() // In a server app, you would just keep ob and close on shutdown box := model.BoxForTask(ob) // Create id, _ := box.Put(&model.Task{ Text: "Buy milk", }) task, _ := box.Get(id) // Read task.Text += " & some bread" box.Put(task) // Update box.Remove(task) // Delete } ``` -------------------------------- ### Initialize ObjectBox Database Instance in Go Source: https://golang.objectbox.io/getting-started This Go function demonstrates how to initialize an ObjectBox database instance. It uses `objectbox.NewBuilder()` and `Model(model.ObjectBoxModel())` to configure ObjectBox with the generated schema, returning the initialized `*objectbox.ObjectBox` object. ```Go import ( "github.com/objectbox/objectbox-go/objectbox" "github.com/objectbox/objectbox-go/examples/tasks/internal/model" ) func initObjectBox() *objectbox.ObjectBox { objectBox, err := objectbox.NewBuilder().Model(model.ObjectBoxModel()).Build() return objectBox } ``` -------------------------------- ### Quick Installation of ObjectBox Go on Linux/macOS Source: https://golang.objectbox.io/install This snippet provides the fastest way to install ObjectBox Go on Linux or macOS using a curl command to execute an installation script. It includes commands for both the standard ObjectBox library and the ObjectBox Sync library, streamlining the setup process. ```bash bash <(curl -s https://raw.githubusercontent.com/objectbox/objectbox-go/main/install.sh) ``` ```bash bash <(curl -s https://raw.githubusercontent.com/objectbox/objectbox-go/main/install.sh) --sync ``` -------------------------------- ### Install ObjectBox Go Dependencies for Legacy Projects Source: https://golang.objectbox.io/install Provides commands to install the ObjectBox Go library and its FlatBuffers dependency using `go get`. This method is applicable for Go projects that do not utilize Go modules. ```Go go get -u github.com/objectbox/objectbox-go/... go get -u github.com/google/flatbuffers/go ``` -------------------------------- ### Manual Installation of ObjectBox C Binary Library on Linux/macOS Source: https://golang.objectbox.io/install This snippet details the manual installation process for the ObjectBox C binary library, which is a prerequisite for ObjectBox Go. It involves creating a temporary directory and executing a download script for a specific version, including an option for ObjectBox Sync. The temporary directory can be removed after installation. ```bash mkdir objectboxlib && cd objectboxlib bash <(curl -s https://raw.githubusercontent.com/objectbox/objectbox-c/main/download.sh) 0.13.0 ``` ```bash bash <(curl -s https://raw.githubusercontent.com/objectbox/objectbox-c/main/download.sh) --sync 0.13.0 ``` -------------------------------- ### Run Go Generate for ObjectBox Bindings Source: https://golang.objectbox.io/getting-started This shell command executes `go generate` within the project directory. It triggers the ObjectBox code generator to create necessary binding files (`task.obx.go`, `objectbox-model.json`, `objectbox-model.go`) that provide the entity model to ObjectBox and handle struct-to-FlatBuffers conversion. ```Bash cd my-project-dir go generate ./... ``` -------------------------------- ### ObjectBox Box Core Operations API Reference Source: https://golang.objectbox.io/getting-started This section provides an API reference for the core methods available on an ObjectBox Box instance. It details the purpose, parameters, and return values for operations such as `Put` (insert/update), `Get` (retrieve by ID), `GetAll` (retrieve all of a type), `Remove` (delete by object), `RemoveAll` (clear box), and `Count` (get object count). ```APIDOC Box: Put(object): description: Persists an object, which may overwrite an existing object with the same ID. Use to insert or update objects. Assigns an ID to the entity on success. parameters: object: The entity to persist. returns: ID of the persisted entity. Get(id): description: Retrieves an object very efficiently using its ID. parameters: id: The ID of the object to retrieve. returns: The object if found, nil & error if an error occurred, or nil without error if the object doesn't exist. GetAll(): description: Retrieves all objects of a specific type from the box. returns: A slice containing all objects of the type. Remove(object): description: Deletes a previously persisted object from its box. parameters: object: The object to remove. RemoveAll(): description: Deletes all objects and empties the box. Count(): description: Returns the number of objects stored in this box. returns: The number of objects. ``` -------------------------------- ### Combining Multiple AND Conditions in ObjectBox Go Query Source: https://golang.objectbox.io/queries This example demonstrates how to combine multiple query conditions implicitly using a logical AND operation. The query will select 'Device' objects where the 'Profile' equals 42 AND the 'Location' starts with "US-". ```Go box.Query(Device_.Profile.Equals(42), Device_.Location.HasPrefix("US-", false)) ``` -------------------------------- ### Import ObjectBox Go Package with Modules Source: https://golang.objectbox.io/install Demonstrates the standard way to import the ObjectBox Go package when your project uses Go modules for dependency management. No additional installation steps are required beyond this import. ```Go import "github.com/objectbox/objectbox-go/objectbox" ``` -------------------------------- ### Install ObjectBox ARMv6 Native Library for Raspberry Pi Workaround Source: https://golang.objectbox.io/install Describes a workaround for SIGBUS/SIGSEGV crashes on Raspberry Pi 3 & 4 by installing the ARMv6 version of the ObjectBox native library. This command uses the `download.sh` script with specific arguments. ```Shell ./download.sh 0.13.0 Linux armv6 ``` -------------------------------- ### Combining Multiple OR Conditions with objectbox.Any() in Go Source: https://golang.objectbox.io/queries This example illustrates how to combine multiple query conditions using the 'objectbox.Any()' function, which performs a logical OR operation. The query will select 'Device' objects where the 'Name' is "Dev1" OR "Dev2". ```Go box.Query(objectbox.Any( Device_.Name.Equals("Dev1", false), Device_.Name.Equals("Dev2", false), )) ``` -------------------------------- ### Define Go Struct as ObjectBox Entity Source: https://golang.objectbox.io/getting-started This Go snippet defines a `Task` struct, which acts as an ObjectBox entity. The `Id` field is automatically recognized as the primary key. It includes the `go:generate` directive to trigger ObjectBox code generation for schema binding. ```Go package model //go:generate go run github.com/objectbox/objectbox-go/cmd/objectbox-gogen // Put this on a new line to enable sync: // `objectbox:"sync"` type Task struct { Id uint64 Text string DateCreated int64 DateFinished int64 } ``` -------------------------------- ### ObjectBox Go Entity with Indexed Property for Query Performance Source: https://golang.objectbox.io/entity-annotations This example illustrates how to create a database index on a specific property using the `objectbox:"index"` tag. Indexing significantly improves query performance for fields that are frequently used in search conditions or filtering operations. It's important to note that indexing is not supported for all data types, such as `byte[]`, `float`, and `double`. ```Go type Task struct { Uid string `objectbox:"index"` } ``` -------------------------------- ### ObjectBox Go: Implement Custom Time Converter Functions Source: https://golang.objectbox.io/custom-types Provides the full implementation for the `timeInt64ToEntityProperty` and `timeInt64ToDatabaseValue` functions. These examples demonstrate how to convert between a `time.Time` object and its `int64` Unix timestamp representation, suitable for storage in ObjectBox. ```Go // converts Unix timestamp in milliseconds (ObjectBox date field format) to time.Time func timeInt64ToEntityProperty(dbValue int64) (goValue time.Time, err error) { err = goValue.UnmarshalText([]byte(dbValue)) if err != nil { err = fmt.Errorf("error unmarshalling time %v: %v", dbValue, err) } return goValue, err } // converts time.Time to Unix timestamp in milliseconds // i. e. internal format expected by ObjectBox on a date field func timeInt64ToDatabaseValue(goValue time.Time) (int64, error) { var ms = int64(goValue.Nanosecond()) / 1000000 return goValue.Unix()*1000 + ms, nil } ``` -------------------------------- ### Define ObjectBox String Index Type in Go Source: https://golang.objectbox.io/entity-annotations ObjectBox allows specifying index types for string properties. By default, it uses a hash-based index for strings to save space. This example demonstrates how to explicitly set a `hash64` index for a string field. ```Go type Task struct { Uid string `objectbox:"index:hash64"` } ``` -------------------------------- ### ObjectBox Go Entity with Custom `id` Field Name Annotation Source: https://golang.objectbox.io/entity-annotations This example demonstrates how to explicitly designate a `uint64` field as the ObjectBox ID using the `objectbox:"id"` tag, even when its name is not `Id`. This flexibility allows developers to adhere to custom naming conventions for their primary key fields while still leveraging ObjectBox's robust ID management system. ```Go type Group struct { GroupID uint64 `objectbox:"id"` } ``` -------------------------------- ### Embed Structs in ObjectBox Entities in Go Source: https://golang.objectbox.io/entity-annotations ObjectBox can embed non-relation structs directly into an entity. By default, fields of the embedded struct are prefixed with the struct's field name (e.g., `Meta_Created`). This example shows a `Metadata` struct embedded within a `Task` entity. ```Go // NOTE this is be placed in a separate field because it's not an entity type Metadata struct { Created int64 Modified int64 } // this is an Entity, with code genereated using objectbox-gogen type Task struct { Id uint64 Meta Metadata Text string } ``` -------------------------------- ### Constructing a Basic ObjectBox Go Query Source: https://golang.objectbox.io/queries This snippet demonstrates the fundamental way to build and execute a query in ObjectBox Go. It initializes a query on a 'box' object using a generated property 'Device_.Location' and applies a 'HasPrefix' condition. Finally, it calls 'Find()' to retrieve matching objects. ```Go query := box.Query(Device_.Location.HasPrefix("US-", false)) devices, err := query.Find() ``` -------------------------------- ### ObjectBox Go: Build Initial Query for Reusable Parameters Source: https://golang.objectbox.io/queries Initializes an ObjectBox query for 'User' objects, specifically for the 'FirstName' property. An empty string is passed as an initial parameter value, as it will be overridden later using 'SetStringParams()'. ```Go var caseSensitive = false var query = box.Query(User_.FirstName.Equals("", caseSensitive)) ``` -------------------------------- ### ObjectBox Go: Apply Limit and Offset for Pagination Source: https://golang.objectbox.io/queries Illustrates how to use 'Offset()' and 'Limit()' methods on an ObjectBox query to retrieve a subset of results, useful for pagination or limiting large result sets. ```Go query := box.Query(User_.FirstName.Equals("Joe", false)) joes, err := query.Offset(10).Limit(5).Find() ``` -------------------------------- ### Perform Basic ObjectBox Go Property Query Source: https://golang.objectbox.io/queries Illustrates how to use a `PropertyQuery` to retrieve specific property values (e.g., emails) instead of full objects. The `FindStrings(nil)` method returns a slice of string values, omitting entries where the property is null. ```Go query := userBox.Query() emails, err := query.Property(User_.Email).FindStrings(nil) ``` -------------------------------- ### ObjectBox Go: Alternative Alias Syntax for Queries Source: https://golang.objectbox.io/queries Shows an alternative, more maintainable syntax for defining and using aliases in ObjectBox queries by assigning alias objects to variables. This avoids repeating string constants. ```Go var minAgeAlias = objectbox.Alias("min age") var maxAgeAlias = objectbox.Alias("max age") var query = box.Query( User_.Age.GreaterThan().As(minAgeAlias), User_.Age.LessThan().As(maxAgeAlias)) // Then use the alias when setting the parameter value query.SetInt64Params(minAgeAlias, 50) query.SetInt64Params(maxAgeAlias, 100) ``` -------------------------------- ### Define To-One Relation Entity Models in Go Source: https://golang.objectbox.io/relations This snippet defines two Go structs, `Order` and `Customer`, demonstrating a To-One relationship where an `Order` has a single `Customer`. The `objectbox:"link"` tag on the `Customer` field in `Order` establishes the relation, allowing ObjectBox to manage the link automatically. ```Go type Order struct { Id uint64 Customer *Customer `objectbox:"link"` Notes string } type Customer struct { Id uint64 Name string } ``` -------------------------------- ### ObjectBox Go: Set Query String Parameters and Find Results Source: https://golang.objectbox.io/queries Sets the 'FirstName' parameter for an existing ObjectBox query to 'Joe' using 'SetStringParams()' and then executes the query to find matching 'User' objects. ```Go query.SetStringParams(User_.FirstName, "Joe") joes, _ := query.Find() ``` -------------------------------- ### Query ObjectBox Go Linked Objects (Person to Address) Source: https://golang.objectbox.io/queries Demonstrates how to query `Person` objects based on conditions applied to their linked `Address` entities. It uses the `Person_.Address.Link()` method to specify conditions on the related `Address` properties, similar to a SQL JOIN. ```Go // get all Person objects named "Elmo" which have an address on "Sesame Street" var query = BoxForPerson(ob).Query( Person_.name.Equals("Elmo", true), Person_.Address.Link(Address_.Street.Equals("Sesame Street", true)), ) var elmosOnSesameStreet = query.Find() ``` -------------------------------- ### ObjectBox Go: Query Result Handling Methods Source: https://golang.objectbox.io/queries Describes various methods available for handling the results of an ObjectBox query, such as retrieving full objects, just IDs, removing matching objects, counting results, and utility functions for debugging. ```APIDOC Find(): returns a slice of the matching objects FindIds(): fetches just the IDs of the matching objects as a slice, which can be more efficient in case you don't need the whole object Remove(): deletes all the matching objects from the database (in a single transaction) Count(): gives you the number of the objects that match the query Limit() and Offset(): let you select just part of the result (e. g. for paging) DescribeParams(): is a utility function which returns a human-readable representation of the query ``` -------------------------------- ### ObjectBox Go: Order Query Results by Multiple Properties Source: https://golang.objectbox.io/queries Shows how to apply multiple ordering parameters to an ObjectBox query, including specifying case sensitivity for string ordering, to achieve complex sorting of results. ```Go query := box.Query( User_.FirstName.Equals("Joe", false), User_.LastName.OrderDesc(false), // caseSensitive bool argument User_.Age.OrderAsc() ) joes, err := query.Find() ``` -------------------------------- ### ObjectBox Go: Query with Aliased Conditions Source: https://golang.objectbox.io/queries Demonstrates how to use aliases for multiple conditions on the same property (e.g., 'Age') within an ObjectBox query. This allows setting parameters for each specific condition independently. ```Go var query = box.Query( User_.Age.GreaterThan().Alias("min age"), User_.Age.LessThan().Alias("max age")) // Then use the alias when setting the parameter value query.SetInt64Params(objectbox.Alias("min age"), 50) query.SetInt64Params(objectbox.Alias("max age"), 100) ``` -------------------------------- ### Manage To-One Relations (Read, Update, Remove) in ObjectBox Go Source: https://golang.objectbox.io/relations This Go snippet illustrates how to perform read, update, and remove operations on To-One relationships in ObjectBox. It shows how to retrieve an `Order` (which eagerly loads its `Customer`), remove the relation by setting the `Customer` field to `nil`, or update it by assigning a different `Customer` object, followed by calling `box.Put`. ```Go var box = model.BoxForOrder(ob) order, _ := box.Get(1) // Read // at this point, order.Customer is already loaded automatically (eager-loading) order.Customer = nil // Remove the relation box.Put(order) // Update // or do an update to a different customer customers, _ := model.BoxForCustomer(ob).GetAll() order.Customer = customers[2] box.Put(order) ``` -------------------------------- ### ObjectBox Go Property Annotations Reference Source: https://golang.objectbox.io/entity-annotations This section provides a comprehensive reference for various ObjectBox annotations and index types that can be applied to Go struct properties, detailing their purpose, behavior, and limitations. ```APIDOC Index Types: Not specified: Uses best index based on property type (uses `hash` for `string`, `value` for others). "value": Uses property values to build index. For `String`, this may require more storage than a hash-based index. "hash": Uses 32-bit hash of property values to build index. Occasional collisions may occur which should not have any performance impact in practice. Usually a better choice than `hash64`, as it requires less storage. "hash64": Uses long hash of property values to build the index. Requires more storage than `hash` and thus should not be the first choice in most cases. Limits of hash-based indexes: Hashes work great for equality checks, but not for "starts with" type conditions. If you frequently use those, you should use value-based indexes instead. Annotations: converter: Defines converter for custom types. See Custom types docs for more information. date: Informs ObjectBox that it should store the given property as a DateType - it expects timestamp since UNIX epoch in milliseconds. If you use a `time.Time` field, it's automatically recognized as a date and the code generator will use the built-in converter and store the field internally as a Unix timestamp. Because ObjectBox stores dates internally as Unix timestamps with millisecond precision, the built-in converter falls-back to that precision when working with `time.Time` struct. If you require greater precision, define your own converter with any built-in supported type that can accommodate your storage format (e.g. `int`, `string`, `[]byte`, etc.). date-nano: Similar to `date` but storing the timestamp as nanoseconds since UNIX epoch. id-companion: To enable Time Series (TS) for an entity type, use the id-companion annotation on a `date` or `date-nano` field. TS enabled types require this special companion property. For more information about how to use ObjectBox TS (Time Series), please refer to the C++ TS APIs for now. lazy: Specifies that the "To-Many" relation on the current field should not be called right away when the object is read but manually, using GetRelated. See Relations docs for more details. link: Declares the struct field that is itself a struct (or a pointer to one) as a relation, instructing ObjectBox to create a link between the Entity where this field is contained and the Entity of the field (type of the struct field). See Relations docs for more details on how relations work and how you can define them. name: Lets you define under what name the property is stored in the database. This allows you to rename the Go field without affecting the property name on the database level. To rename the property in the DB, you should use the uid annotation instead. ``` -------------------------------- ### ObjectBox Go: Notable Query Conditions and Operators Source: https://golang.objectbox.io/queries Lists additional important query conditions and operators available in ObjectBox Go beyond basic equality checks, including 'Between()', 'In()', 'NotIn()', 'HasPrefix()', 'HasSuffix()', and 'Contains()' for advanced filtering. ```APIDOC Between(): to filter for values that are between the given two (inclusive) In() and NotIn(): to filter for values that match any in the given set HasPrefix(), HasSuffix() and Contains(): for extended String filtering ``` -------------------------------- ### ObjectBox Go Generated Property Struct for Device Entity Source: https://golang.objectbox.io/queries This snippet shows the structure of the 'Device_' variable, which is automatically generated by ObjectBox based on the 'Device' entity definition. It provides type-safe accessors (e.g., PropertyUint64, PropertyString) for each field, enabling compile-time checked queries and preventing runtime errors from typos. ```Go var Device_ = struct { Id *objectbox.PropertyUint64 Name *objectbox.PropertyString Location *objectbox.PropertyString Profile *objectbox.PropertyUint32 }{...} ``` -------------------------------- ### Handle Null Values in ObjectBox Go Property Query Source: https://golang.objectbox.io/queries Demonstrates how to specify a replacement value for null fields when performing a property query. Passing a non-nil argument to `FindStrings()` ensures that null database values are replaced with the provided string instead of being omitted from the results. ```Go // includes 'unknown' instead of each null email emails, err := userBox.Query().Property(User_.Email).FindStrings("unknown") ``` -------------------------------- ### Explicitly Combining Multiple AND Conditions with objectbox.All() in Go Source: https://golang.objectbox.io/queries This snippet shows how to explicitly combine multiple query conditions using the 'objectbox.All()' function, which performs a logical AND operation. This approach can improve readability for complex queries by clearly indicating that all provided conditions must be met. ```Go box.Query(objectbox.All( Device_.Profile.Equals(42), Device_.Location.HasPrefix("US-", false), )) ``` -------------------------------- ### Apply Multiple ObjectBox Annotations in Go Source: https://golang.objectbox.io/entity-annotations This snippet demonstrates the application of various ObjectBox annotations on different fields within a single struct. It includes `name` for database field renaming, `date` for date type handling, `uid` for unique identifiers, and `-` to ignore a field. ```Go // `objectbox:"uid:1306759095002958910"` type Task struct { Text string `objectbox:"name:text"` Date uint64 `objectbox:"date"` notes string `objectbox:"-"` DateCreated int64 `objectbox:"date uid:7144924247938981575"` } ``` -------------------------------- ### Defining a Go Entity for ObjectBox Source: https://golang.objectbox.io/queries This Go struct defines the 'Device' entity, which ObjectBox uses to generate corresponding property accessors for type-safe queries. It includes fields for 'Id', 'Name', 'Location', and 'Profile'. ```Go type Device struct { Id uint64 Name string Location string Profile uint32 } ``` -------------------------------- ### ObjectBox Go: Built-in Supported Types Source: https://golang.objectbox.io/custom-types Lists the primitive Go types and their array equivalents that are natively recognized and stored by ObjectBox without requiring custom converters. ```Go int, int8, int16, int32, int64 uint, uint8, uint16, uint32, uint64 bool string, []string byte, []byte rune float32, float64 ``` -------------------------------- ### ObjectBox Go: Order Query Results by Single Property Source: https://golang.objectbox.io/queries Demonstrates how to order query results in ObjectBox Go by a single property, in this case, 'User_.Age' in descending order, after applying a 'FirstName' filter. ```Go query := box.Query(User_.FirstName.Equals("Joe", false), User_.Age.OrderDesc()) joes, err := query.Find() ``` -------------------------------- ### Query ObjectBox Go Linked Objects (Address to Person) Source: https://golang.objectbox.io/queries Shows how to query `Address` objects based on conditions applied to their linked `Person` entities, illustrating the implicit reverse relation. This query uses `Person_.Address.Link()` within an `Address` query context to filter addresses by linked person names. ```Go // get all Address objects on "Sesame Street" linked from a Person named "Elmo" val builder = box.query().equal(Address_.Street, "Sesame Street") var query = BoxForAddress(ob).Query( Address_.Street.Equals("Sesame Street", true), Person_.Address.Link(Person_.Name.Equals("Elmo", true)), ) var addressesSesameStreetWithElmo = query.Find() ``` -------------------------------- ### Add Many-to-Many Related Entities in ObjectBox Go Source: https://golang.objectbox.io/relations Demonstrates how to create and associate `Teacher` entities with `Student` entities in a many-to-many relationship. Related entities can be added by initializing the slice directly or by appending to it, and are persisted using `Box.Put()` on the source entity. ```Go var teacher1 = &model.Teacher{Name: "John Wise"} var teacher2 = &model.Teacher{Name: "Peter Clever"} var student1 = &model.Student{ Name: "Martin Curious", // we can create the slice in place Teachers: []*model.Teacher{teacher1, teacher2}, } // or append to it var student2 = &model.Student{Name: "Earl Eager"} student2.Teachers = append(student2.Teachers, teacher2) // puts students and teachers var box = model.BoxForStudent(ob) box.Put(student1) box.Put(student2) ``` -------------------------------- ### Define ObjectBox Go Entities with Relations Source: https://golang.objectbox.io/queries Defines `Person` and `Address` structs for ObjectBox, demonstrating a one-to-many relationship where a `Person` can be associated with multiple `Address` entities. The `go:generate` directive is included for ObjectBox code generation. ```Go //go:generate go run github.com/objectbox/objectbox-go/cmd/objectbox-gogen type Person struct { Id uint64 Name string Address []*Address } type Address struct { Id uint64 Street string ZIP string } ``` -------------------------------- ### Perform Language-Level Rename with UID Source: https://golang.objectbox.io/schema-changes Shows the final step of renaming an entity or property in Go after applying the correct ObjectBox UID. This ensures that existing data associated with the old name is correctly mapped to the new name. ```Go // `objectbox:"uid:1306759095002958910"` type RenamedEntity struct { Id uint64 } type Task struct { Id uint64 RenamedProperty string `objectbox:"uid:9141374017424160113"` } ``` -------------------------------- ### ObjectBox Go: Custom Type Converter Function Signatures Source: https://golang.objectbox.io/custom-types Shows the required function signatures for a custom type converter in ObjectBox Go. These functions, `timeInt64ToEntityProperty` and `timeInt64ToDatabaseValue`, handle the conversion between the database's `int64` representation and the Go program's `time.Time` type. ```Go // from DB value to runtime value func timeInt64ToEntityProperty(dbValue int64) (time.Time, error) // from runtime value to DB value func timeInt64ToDatabaseValue(goValue time.Time) (int64, error) ``` -------------------------------- ### Retrieve Distinct Values with ObjectBox Go Property Query Source: https://golang.objectbox.io/queries Shows how to use `Distinct()` and `DistinctString()` with a property query to retrieve only unique values. `DistinctString()` provides an option for case sensitivity when comparing string values, allowing for more precise control over distinctness. ```Go pq := userBox.Query().Property(User_.FirstName) // returns ['joe'] because by default, the case of strings is ignored. err := pq.Distinct(true) // args: Distinct(value bool) names := pq.FindStrings(nil) // returns ['Joe', 'joe', 'JOE'] pq.DistinctString(true, true) // args: DistinctString(value, caseSensitive bool) names = pq.FindStrings(nil) ``` -------------------------------- ### Perform Bulk Inserts with ObjectBox Go Write Transaction Source: https://golang.objectbox.io/transactions This Go code snippet illustrates how to use an explicit write transaction (`ob.RunInWriteTx`) to efficiently insert a large number of objects. By wrapping multiple `box.Put()` calls within a single transaction, it minimizes the overhead associated with individual transaction commits, which is beneficial for bulk data operations and ensures atomicity. ```Go ob.RunInWriteTx(func() error { for i := 1000000; i > 0; i-- { box.Put(&iot.Event{}) } return nil // return no error so the transaction is not rolled back }) ``` -------------------------------- ### Define ObjectBox Go Entity with `go:generate` Command Source: https://golang.objectbox.io/entity-annotations This snippet demonstrates the fundamental structure for defining a Go struct as an ObjectBox entity. It includes the `//go:generate` comment, which is crucial for triggering the `objectbox-gogen` tool to process the struct and enable its persistence capabilities. The `Id` field is automatically recognized by ObjectBox as the primary key. ```Go //go:generate go run github.com/objectbox/objectbox-go/cmd/objectbox-gogen type Task struct { Id uint64 Text string DateCreated time.Time DateFinished time.Time } ``` -------------------------------- ### ObjectBox Go Property Query Aggregation Functions Source: https://golang.objectbox.io/queries Documents the aggregate functions available for ObjectBox Go `PropertyQuery`, allowing direct calculation of minimum, maximum, sum, average, and count of values matching the query. These functions operate on non-null values. ```APIDOC PropertyQuery Aggregation Functions: - Min() / MinDouble(): Finds the minimum value for the given property over all objects matching the query. - Max() / MaxFloat64(): Finds the maximum value. - Sum() / SumFloat64(): Calculates the sum of all values. Note: the integer version detects overflows and returns an error in that case. - Average(): Calculates the average (always a float64) of all values. - Count(): Returns the number of results. This is faster than finding and getting the length of the result array. Can be combined with Distinct() to count only the number of distinct values. ``` -------------------------------- ### Apply Generated UID for Entity/Property Renaming Source: https://golang.objectbox.io/schema-changes Demonstrates how to apply the UID obtained from the ObjectBox generation error message to the `objectbox:"uid"` annotation for both entities and properties. This step links the old schema element to its new name, preserving data. ```Go // `objectbox:"uid:1306759095002958910"` type OldEntityName struct { Id uint64 } type Task struct { Id uint64 OldPropertyName string `objectbox:"uid:9141374017424160113"` } ``` -------------------------------- ### ObjectBox Generation Error: Empty Property UID Source: https://golang.objectbox.io/schema-changes Illustrates the command-line output from `go generate ./...` when a property has an empty `objectbox:"uid"` annotation. The output provides both the current UID for renaming and a new UID for resetting the property's data. ```CLI can't merge binding model information: uid annotation value must not be empty on property OldPropertyName, entity Task: [rename] apply the current UID 9141374017424160113 [change/reset] apply a new UID 6050128673802995827 ``` -------------------------------- ### Apply New UID for Property Data Reset Source: https://golang.objectbox.io/schema-changes Demonstrates applying the 'new UID' obtained from the ObjectBox generation error message to a property, along with changing its type. This action effectively resets the property's data in the database, treating it as a new property. ```Go type Task struct { Id uint64 Property int `objectbox:"uid:6050128673802995827"` } ``` -------------------------------- ### ObjectBox Generation Error: Empty Entity UID Source: https://golang.objectbox.io/schema-changes Shows the command-line output from `go generate ./...` when an entity has an empty `objectbox:"uid"` annotation. The error message provides the specific UID required to correctly rename the entity. ```CLI can't merge binding model information: uid annotation value must not be empty (model entity UID = 1306759095002958910) on entity OldEntityName ``` -------------------------------- ### Insert Entities with To-One Relations in ObjectBox Go Source: https://golang.objectbox.io/relations This Go code demonstrates inserting `Order` entities with associated `Customer` entities into ObjectBox. It illustrates how ObjectBox automatically handles the insertion of a new customer (if `customer.Id` is zero) and references an existing one (if `customer.Id` is non-zero). This behavior relies on using pointer fields for the related entity, allowing ObjectBox to update the ID after insertion. ```Go // note that here we're creating a new customer // but we could have also reused an existing one var customer = &model.Customer{Name: "ACME Inc."} var box = model.BoxForOrder(ob) // Insert a new order. ObjectBox also inserts the customer automatically // because it's new (customer.Id == 0 at this point) box.Put(&model.Order{ Notes: "first order, new customer", Customer: customer, }) ... // Add another order. Now the customer.Id is already > 0 // so it's not inserted again, just referenced box.Put(&model.Order{ Text: "second order, existing customer", Customer: customer, }) ``` -------------------------------- ### ObjectBox Go Entity with Default `Id` Field Recognition Source: https://golang.objectbox.io/entity-annotations This snippet illustrates the simplest method for defining an object's primary key in ObjectBox Go. By naming a `uint64` field `Id` (case-insensitive), ObjectBox automatically identifies it as the entity's unique identifier, which is used for efficient object retrieval and referencing within the database. ```Go type Task struct { Id uint64 } ``` -------------------------------- ### Retrieve Many-to-Many Related Entities in ObjectBox Go Source: https://golang.objectbox.io/relations Shows how to retrieve a `Student` entity by its ID and then access its associated `Teachers` slice. By default, ObjectBox automatically loads the related entities when the source entity is retrieved, allowing direct iteration. ```Go var student1 = model.BoxForStudent(ob).Get(1); for _, teacher := range student1.Teachers { fmt.PrintLn(teacher.Name) } ``` -------------------------------- ### Add New Property for Type Migration Source: https://golang.objectbox.io/schema-changes Illustrates a strategy for changing a property's type by adding a new property with a different name. This approach is useful when data migration is required or when the old data needs to be preserved alongside the new type. ```Go type Task struct { Id uint64 OldProperty string } // becomes type Task struct { Id uint64 OldProperty string NewProperty int } // Note, if the property already had an UID annotation, // don't add the same UID to the new property - skip the annotation instead. ``` -------------------------------- ### Define Many-to-Many Relation Model in ObjectBox Go Source: https://golang.objectbox.io/relations Illustrates how to define Go structs for a many-to-many relationship (Student to Teacher) in ObjectBox. A slice of entities (`[]*Teacher`) automatically signifies an N:M relation, eliminating the need for explicit `link` annotations. ```Go type Teacher struct { Id uint64 Name string } type Student struct { Id uint64 Name string Teachers []*Teacher } ``` -------------------------------- ### ObjectBox Generation Error: Property Data Reset UID Source: https://golang.objectbox.io/schema-changes Displays the command-line output from `go generate ./...` when attempting to reset property data. The error message provides the specific 'new UID' to apply to the property to clear its existing data. ```CLI can't merge binding model information: uid annotation value must not be empty on property Property, entity Task: [rename] apply the current UID 9141374017424160113 [change/reset] apply a new UID 6050128673802995827 ``` -------------------------------- ### ObjectBox Go: Querying Entities with Custom Converted Types Source: https://golang.objectbox.io/custom-types Illustrates how to perform a query on a field that uses a custom type converter. It shows that the query condition must use the converted database value (e.g., `int64` for `time.Time`) rather than the original Go type, ensuring correct comparison against stored data. ```Go // Create id, _ := box.Put(&model.Task{ Text: "Buy milk", DateCreated: time.Now().UTC() }) // Query minTime, _ := time.Parse(time.RFC3339, "2018-11-28T12:16:42.145+07:00") minTimeInt64, _ := objectbox.TimeInt64ConvertToDatabaseValue(minTime) tasks, _ := box.Query( model.Task_.DateCreated.GreaterThan(minTimeInt64) ).Find() ``` -------------------------------- ### Add Empty UID Annotation for Property Data Reset Source: https://golang.objectbox.io/schema-changes Shows how to add an empty `objectbox:"uid"` annotation to a property when the intention is to reset its stored data. This prepares ObjectBox to generate a new UID for the property, effectively clearing its data. ```Go type Task struct { Id uint64 Property string `objectbox:"uid"` } ``` -------------------------------- ### Add Empty UID Annotation for Renaming Source: https://golang.objectbox.io/schema-changes Demonstrates adding an empty `objectbox:"uid"` annotation to an entity struct or a property in Go. This initial step signals to ObjectBox that a rename operation might occur, allowing it to provide the necessary UID. ```Go // `objectbox:"uid"` type OldEntityName struct { Id uint64 } type Task struct { Id uint64 OldPropertyName string `objectbox:"uid"` } ``` -------------------------------- ### Update Lazy-Loaded Teacher Slice in Go ObjectBox Source: https://golang.objectbox.io/relations This Go code snippet demonstrates how to update a lazy-loaded slice of `Teachers` associated with a `Student` object in ObjectBox. It first retrieves a student by ID, then explicitly loads its related `Teachers` slice from the database using `GetRelated`. A new teacher is then appended to this existing slice, and finally, the updated student object is saved using `box.Put()`, which persists the changes to the `Teachers` slice. ```Go var box = model.BoxForStudent(ob) var student1 = box.Get(1); // propagate student1.Teachers based on the current data in DB box.GetRelated(student1, Student_.Teachers) // add a new teacher to the existing student1.Teachers = append(student1.Teachers, &model.Teacher{Name: "Peter Clever"}) // save the updated list, including a new teacher box.Put(student1) ``` -------------------------------- ### ObjectBox Go: Define Entity with Custom Type Converter Source: https://golang.objectbox.io/custom-types Demonstrates how to define an entity struct in Go, annotating a `time.Time` field to be stored as an `int64` using a custom converter named `timeInt64`. This annotation instructs ObjectBox to use specific conversion functions for persistence. ```Go type Task struct { Id uint64 Text string DateCreated time.Time `objectbox:"date type:int64 converter:timeInt64"` } ``` -------------------------------- ### Define Lazy-Loaded Many-to-Many Relation Model in ObjectBox Go Source: https://golang.objectbox.io/relations Updates the `Student` struct definition to include the `objectbox:"lazy"` annotation on the `Teachers` slice. This enables lazy loading, meaning the related `Teacher` entities are not loaded automatically when the `Student` is retrieved, optimizing performance for large relations. ```Go type Teacher struct { Id uint64 Name string } type Student struct { Id uint64 Name string Teachers []*Teacher `objectbox:"lazy"` } ``` -------------------------------- ### ObjectBox Go Entity Combining Internal and External IDs Source: https://golang.objectbox.io/entity-annotations This snippet showcases how to manage both an internal ObjectBox-assigned ID and an external unique identifier (UID) within the same entity definition. The `Id` field serves as the primary key for ObjectBox's internal operations, while the `Uid` field can store application-specific or server-assigned identifiers, providing flexibility for various data modeling needs. ```Go type Task struct { Id uint64 `objectbox:"id"` Uid string } ``` -------------------------------- ### Load and Access Lazy-Loaded Many-to-Many Relations in ObjectBox Go Source: https://golang.objectbox.io/relations Explains how to explicitly load lazy-loaded related entities using `Box.GetRelated()`. This method can load all lazy relations for an object or specifically load a single lazy-loaded property, after which the related entities can be accessed as usual. ```Go var box = model.BoxForStudent(ob) var student1 = box.Get(1); // at this point `student1.Teachers == nil`, so if we need it, we must load it first box.GetRelated(student1) // loads all lazy-loaded relations // or alternatively load just the Teachers property // (useful if there were other lazy-loaded relations we didn't care about this time) box.GetRelated(student1, Student_.Teachers) // now the teachers are loaded and we can access them as usual for _, teacher := range student1.Teachers { fmt.PrintLn(teacher.Name) } ``` -------------------------------- ### Inline Embedded Struct Fields in ObjectBox Entities in Go Source: https://golang.objectbox.io/entity-annotations The `objectbox:"inline"` annotation modifies the default behavior for embedded structs, causing their fields to be inlined without a prefix. This results in field names like `created` instead of `Meta_Created`. ```Go type Task struct { Id uint64 Meta Metadata `objectbox:"inline"` Text string } ``` -------------------------------- ### Enforce Unique Constraint on ObjectBox Property in Go Source: https://golang.objectbox.io/entity-annotations The `objectbox:"unique"` annotation ensures that a property's value is unique across all entities of that type. If a `put()` operation violates this constraint, it will abort and return an error. ```Go type Task struct { Uid string `objectbox:"unique"` } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.