In this guide, we'll walk you through the process of building a custom ORM integrator for the Go Advanced Admin panel. If your project uses an ORM that is not currently supported, you can create an integrator to make it compatible with the admin panel.
By the end of this guide, you'll learn how to:
Implement the required interface for ORM integration.
Handle database interactions specific to your ORM.
Register your custom ORM with the admin panel.
Note: If you build a custom integrator, we encourage you to contribute it to the community!
The admin panel communicates with your ORM through the ORMIntegrator interface. This interface defines the methods necessary for CRUD operations and data retrieval.
GetPrimaryKeyValue: Retrieve the primary key value from a model instance.
GetPrimaryKeyType: Get the type of the primary key field.
FetchInstances: Retrieve all instances of a model.
FetchInstancesOnlyFields: Retrieve instances with selected fields.
FetchInstancesOnlyFieldWithSearch: Retrieve instances based on a search query.
DeleteInstance: Delete a model instance by ID.
FetchInstanceOnlyFields: Retrieve a single instance with selected fields.
FetchInstance: Retrieve a single instance by ID.
CreateInstance: Create a new instance in the database.
UpdateInstance: Update an existing instance.
CreateInstanceOnlyFields: Create a new instance with selected fields.
UpdateInstanceOnlyFields: Update an instance with selected fields.
Implementing the Interface
To build your custom integrator, you'll need to implement all the methods defined in the ORMIntegrator interface.
1. Create the Integrator Struct
Start by creating a new package for your ORM integrator. Define a struct that holds your ORM's database connection.
package admincustomorm
import (
"reflect"
// Import your ORM's package
"github.com/yourusername/customorm"
)
// Integrator implements the ORMIntegrator interface using CustomORM.
type Integrator struct {
// DB is the CustomORM database connection used by the integrator.
DB *customorm.DB
}
// NewIntegrator creates a new Integrator with the provided CustomORM database connection.
func NewIntegrator(db *customorm.DB) *Integrator {
return &Integrator{DB: db}
}
2. Implement Required Methods
Implement each method of the ORMIntegrator interface. Below are examples using a hypothetical CustomORM. Replace CustomORM methods with those of your ORM.
GetPrimaryKeyValue
Retrieve the primary key value from a model instance.
func (i *Integrator) GetPrimaryKeyValue(model interface{}) (interface{}, error) {
// Use reflection to access the primary key field
modelValue := reflect.ValueOf(model)
if modelValue.Kind() == reflect.Ptr {
modelValue = modelValue.Elem()
}
primaryKeyField := modelValue.FieldByName("ID") // Replace "ID" with your primary key field name
if !primaryKeyField.IsValid() {
return nil, fmt.Errorf("primary key field not found")
}
return primaryKeyField.Interface(), nil
}
GetPrimaryKeyType
Get the type of the primary key field.
func (i *Integrator) GetPrimaryKeyType(model interface{}) (reflect.Type, error) {
modelType := reflect.TypeOf(model)
if modelType.Kind() == reflect.Ptr {
modelType = modelType.Elem()
}
primaryKeyField, found := modelType.FieldByName("ID") // Replace "ID" with your primary key field name
if !found {
return nil, fmt.Errorf("primary key field not found")
}
return primaryKeyField.Type, nil
}
Use Reflection Carefully: Since models can be pointers or structs, handle both cases.
Manage Errors: Return clear and informative errors for better debugging.
Optimize Queries: Use your ORM's features to optimize data retrieval, especially when selecting specific fields or searching.
Test Thoroughly: Write tests to verify that each method works as expected with your ORM.
Registering the Custom ORM
After implementing your integrator, you need to register it with the admin panel.
package main
import (
"log"
"github.com/go-advanced-admin/admin"
"github.com/go-advanced-admin/web-echo"
"github.com/labstack/echo/v4"
"github.com/yourusername/admincustomorm"
// Import your ORM package
"github.com/yourusername/customorm"
)
func main() {
// Initialize your ORM's database connection
db, err := customorm.Open("your_connection_string")
if err != nil {
log.Fatalf("Failed to connect to the database: %v", err)
}
// Create the ORM integrator
ormIntegrator := admincustomorm.NewIntegrator(db)
// Initialize the web framework integrator (e.g., Echo)
e := echo.New()
webIntegrator := adminecho.NewIntegrator(e.Group(""))
// Define the permission function
permissionFunc := func(
req admin.PermissionRequest, ctx interface{},
) (bool, error) {
// Implement your permission logic here
return true, nil
}
// Create the admin panel
panel, err := admin.NewPanel(
ormIntegrator, webIntegrator, permissionFunc, nil,
)
if err != nil {
log.Fatal(err)
}
// Register an app and models
app, err := panel.RegisterApp("MyApp", "My Application", nil)
if err != nil {
log.Fatal(err)
}
// Register models with the app
_, err = app.RegisterModel(&MyModel{}, nil)
if err != nil {
log.Fatal(err)
}
// Start the web server
e.Logger.Fatal(e.Start(":8080"))
}
Contributing Your Integrator
We encourage you to contribute your custom ORM integrator to the community! By sharing your integrator, you help others who might be using the same ORM.