{"id":35059267,"url":"https://github.com/piyushkumar96/generic-orm","last_synced_at":"2026-01-13T21:59:58.078Z","repository":{"id":330674138,"uuid":"1061975272","full_name":"piyushkumar96/generic-orm","owner":"piyushkumar96","description":"A comprehensive, high-level ORM wrapper for Go built on top of GORM that provides a generic interface for database operations with PostgreSQL and other SQL databases.","archived":false,"fork":false,"pushed_at":"2025-12-27T05:21:32.000Z","size":8539,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-12-28T21:36:16.118Z","etag":null,"topics":["generic","go","golang","gorm","mysql","orm","postgres","postgresql","sql"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/piyushkumar96.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-09-22T16:27:02.000Z","updated_at":"2025-12-27T12:08:59.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/piyushkumar96/generic-orm","commit_stats":null,"previous_names":["piyushkumar96/generic-orm"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/piyushkumar96/generic-orm","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/piyushkumar96%2Fgeneric-orm","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/piyushkumar96%2Fgeneric-orm/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/piyushkumar96%2Fgeneric-orm/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/piyushkumar96%2Fgeneric-orm/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/piyushkumar96","download_url":"https://codeload.github.com/piyushkumar96/generic-orm/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/piyushkumar96%2Fgeneric-orm/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28400397,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-13T14:36:09.778Z","status":"ssl_error","status_checked_at":"2026-01-13T14:35:19.697Z","response_time":56,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["generic","go","golang","gorm","mysql","orm","postgres","postgresql","sql"],"created_at":"2025-12-27T10:11:38.704Z","updated_at":"2026-01-13T21:59:58.072Z","avatar_url":"https://github.com/piyushkumar96.png","language":"Go","readme":"# Generic ORM\n\nA comprehensive, high-level ORM wrapper for Go built on top of GORM that provides a generic interface for database operations with PostgreSQL and other SQL databases.\n\n## Table of Contents\n\n- [Features](#features)\n- [Installation](#installation)\n- [Quick Start](#quick-start)\n- [Configuration](#configuration)\n- [Usage Examples](#usage-examples)\n- [API Reference](#api-reference)\n- [Advanced Features](#advanced-features)\n- [Testing](#testing)\n- [Contributing](#contributing)\n- [License](#license)\n\n## Features\n\nThis generic ORM provides a unified interface for database operations with the following key features:\n\n- **Generic Interface**: Consistent API across different models and database operations\n- **CRUD Operations**: Complete support for Create, Read, Update, Delete operations\n- **Transaction Management**: Built-in support for database transactions with rollback capabilities  \n- **Pagination Support**: Easy pagination with configurable page size and sorting\n- **Batch Operations**: Efficient bulk create and upsert operations\n- **Soft Deletes**: Built-in soft delete functionality with permanent delete options\n- **Query Builder**: Flexible querying with conditions, raw SQL, and object-based queries\n- **Connection Pooling**: Configurable connection pool management\n- **Context Support**: Full context support for timeouts and cancellation\n- **Error Handling**: Comprehensive error handling with custom error types\n- **Debug Mode**: Built-in debug logging for development\n- **PostgreSQL First**: Optimized for PostgreSQL with extensibility for other databases\n- **Multi-Schema Support**: Built-in support for PostgreSQL schemas with context-based switching\n- **Multi-Tenant Ready**: Schema-based tenant isolation for SaaS applications\n\n## Installation\n\n```bash\n# Set up private module access if needed\nexport GOPRIVATE=github.com/piyushkumar96/generic-orm\n\n# Install the package\ngo get github.com/piyushkumar96/generic-orm\n```\n\n## Quick Start\n\n```go\npackage main\n\nimport (\n    \"context\"\n    \"log\"\n    \"time\"\n\n    orm \"github.com/piyushkumar96/generic-orm\"\n    \"github.com/piyushkumar96/generic-orm/config\"\n    \"github.com/piyushkumar96/generic-orm/interfaces\"\n)\n\n// Define your model\ntype User struct {\n    ID        uint      `gorm:\"primaryKey\"`\n    Name      string    `gorm:\"size:100;not null\"`\n    Email     string    `gorm:\"unique;not null\"`\n    CreatedAt time.Time\n    UpdatedAt time.Time\n    DeletedAt *time.Time `gorm:\"index\"`\n}\n\nfunc main() {\n    // 1. Create database connection\n    client := orm.SQLClient{\n        Config: config.DBConnectionConfigurations{\n            DatabaseName:       \"myapp\",\n            DatabaseUser:       \"postgres\",\n            DatabasePassword:   \"password\",\n            DatabaseHost:       \"localhost\",\n            DatabasePort:       5432,\n            DatabaseSchema:     \"public\",\n            DatabaseDriver:     \"postgres\",\n            MaxOpenConnections: 100,\n            MaxIdleConnections: 10,\n            ConnMaxLifetime:    1 * time.Hour,\n        },\n    }\n    \n    db, err := client.Init()\n    if err != nil {\n        log.Fatal(\"Failed to connect to database:\", err)\n    }\n\n    // 2. Initialize ORM handler\n    userHandler := \u0026orm.SQLGORM{\n        DB:        db,\n        DataModel: \u0026User{},\n        Config: config.GORMConfig{\n            AppPaginationDefaultPageSize:      10,\n            AppPaginationDefaultPageIndex:     1,\n            AppPaginationDefaultOrderBy:       []string{\"id\", \"desc\"},\n            DebugModeEnabled:                  true,\n            DBOperationDefaultTimeoutInSecond: 30 * time.Second,\n        },\n    }\n\n    // 3. Create a new user\n    ctx := context.Background()\n    newUser := \u0026User{\n        Name:  \"John Doe\",\n        Email: \"john@example.com\",\n    }\n    \n    meta, err := userHandler.CreateRecord(ctx, newUser)\n    if err != nil {\n        log.Fatal(\"Failed to create user:\", err)\n    }\n    log.Printf(\"Created user, affected rows: %d\", meta.RowsAffected)\n}\n```\n\n## Configuration\n\n### Database Connection Configuration\n\n```go\ntype DBConnectionConfigurations struct {\n    DatabaseName       string        // Database name\n    DatabaseUser       string        // Database username\n    DatabasePassword   string        // Database password\n    DatabaseHost       string        // Database host\n    DatabasePort       int           // Database port\n    DatabaseSchemas     string        // Database schemas comma separated (for PostgreSQL)\n    DatabaseDriver     string        // Database driver (\"postgres\")\n    MaxOpenConnections int           // Maximum open connections\n    MaxIdleConnections int           // Maximum idle connections\n    ConnMaxLifetime    time.Duration // Connection maximum lifetime\n}\n```\n\n### GORM Configuration\n\n```go\ntype GORMConfig struct {\n    AppPaginationDefaultPageSize      int           // Default page size (e.g., 10)\n    AppPaginationDefaultPageIndex     int           // Default page index (e.g., 1)\n    AppPaginationDefaultOrderBy       []string      // Default ordering (e.g., []string{\"id\", \"desc\"})\n    DebugModeEnabled                  bool          // Enable debug logging\n    DBOperationDefaultTimeoutInSecond time.Duration // Default timeout for operations\n}\n```\n\n## Usage Examples\n\nFor comprehensive examples, see the [examples/](examples/) directory:\n- **Basic Examples**: [examples/examples.go](examples/examples.go) - Complete CRUD, transactions, pagination, etc.\n- **Multi-Schema Examples**: [examples/multi-schema-example.go](examples/multi-schema-example.go) - Multi-tenant schema isolation\n- **Build Instructions**: [examples/README.md](examples/README.md) - How to build and run examples\n\nHere are some key usage patterns:\n\n### Basic CRUD Operations\n\n```go\n// Create\nuser := \u0026User{Name: \"Alice\", Email: \"alice@example.com\"}\nmeta, err := handler.CreateRecord(ctx, user)\n\n// Read by ID\nvar user User\nmeta, err := handler.GetRecordByID(ctx, \u0026user, 1)\n\n// Update\nuser.Name = \"Alice Updated\"\nmeta, err := handler.UpdateRecord(ctx, \u0026user)\n\n// Soft Delete\nupdates := map[string]interface{}{\"deleted_by\": \"admin\"}\nmeta, err := handler.DeleteRecord(ctx, \u0026user, updates)\n\n// Permanent Delete\nmeta, err := handler.DeleteRecordPermanently(ctx, \u0026user)\n```\n\n### Querying with Conditions\n\n```go\n// Query with WHERE conditions\nvar users []User\nmeta, err := handler.GetRecordsByWhereCondition(ctx, \u0026users, \"name LIKE ?\", \"%john%\")\n\n// Query with object conditions\nquery := User{Active: true}\nmeta, err := handler.GetRecordsByObject(ctx, \u0026users, query)\n\n// Raw SQL query\nvar result []CustomResult\nmeta, err := handler.GetRecordByRawSQL(ctx, \u0026result, \"SELECT id, name FROM users WHERE created_at \u003e ?\", time.Now().AddDate(-1, 0, 0))\n```\n\n### Pagination\n\n```go\npagination := \u0026models.Pagination{\n    Records: \u0026[]User{},\n    Page:    1,\n    Size:    10,\n    Enabled: true,\n    OrderBy: []string{\"created_at desc\"},\n}\n\npaginationResult, meta, err := handler.GetRecords(ctx, pagination)\nlog.Printf(\"Total records: %d, Page: %d/%d\", paginationResult.Total, paginationResult.Page, (paginationResult.Total+int64(paginationResult.Size)-1)/int64(paginationResult.Size))\n```\n\n### Transaction Management\n\n```go\n// Define transaction operations\ndbTxns := []*models.DBTxn{\n    {\n        Op:     models.Create,\n        Model:  \u0026User{},\n        Record: \u0026User{Name: \"Transaction User 1\", Email: \"tx1@example.com\"},\n    },\n    {\n        Op:     models.Update,\n        Model:  \u0026User{},\n        Record: \u0026User{ID: 1, Name: \"Updated Name\"},\n    },\n    {\n        Op:     models.Delete,\n        Model:  \u0026User{},\n        Record: \u0026User{ID: 2},\n    },\n}\n\n// Execute transaction\nmetas, err := handler.ExecuteDBTxn(ctx, dbTxns)\nif err != nil {\n    log.Fatal(\"Transaction failed:\", err)\n}\n```\n\n### Multi-Schema/Multi-Tenant Operations\n\n```go\nimport \"github.com/piyushkumar96/generic-orm/helper\"\n\n// Set schema in context for tenant isolation\ntenantACtx := helper.SetSchemaInContext(ctx, \"tenant_a\")\ntenantBCtx := helper.SetSchemaInContext(ctx, \"tenant_b\")\n\n// Create user in Tenant A schema\nuserA := \u0026User{Name: \"Alice\", Email: \"alice@tenanta.com\"}\nmeta, err := handler.CreateRecord(tenantACtx, userA)\n\n// Create user in Tenant B schema (completely isolated)\nuserB := \u0026User{Name: \"Bob\", Email: \"bob@tenantb.com\"}\nmeta, err = handler.CreateRecord(tenantBCtx, userB)\n\n// Retrieve schema from context\nif schema, ok := helper.GetSchemaFromContext(tenantACtx); ok {\n    fmt.Printf(\"Current schema: %s\", schema)\n}\n\n// Set multiple schemas in search path\nmultiSchemaCtx := helper.SetMultipleSchemasInContext(ctx, []string{\"tenant_a\", \"tenant_b\", \"public\"})\n```\n\n## API Reference\n\n### Core Interface Methods\n\nThe `IORMHandler` interface provides the following methods:\n\n#### Create Operations\n- `CreateRecord(ctx, record)` - Create a single record\n- `CreateRecordInBatches(ctx, record, batchSize)` - Create records in batches\n- `UpsertRecord(ctx, record)` - Insert or update on conflict\n- `UpsertRecordInBatches(ctx, record, batchSize)` - Batch upsert operations\n\n#### Read Operations\n- `GetRecordByID(ctx, record, id)` - Get single record by primary key\n- `GetRecords(ctx, pagination)` - Get records with pagination\n- `GetRecordsWithoutPagination(ctx, record)` - Get all records without pagination\n- `GetRecordByWhereCondition(ctx, record, condition, values...)` - Query with WHERE clause\n- `GetRecordByObject(ctx, record, object)` - Query using object as condition\n- `GetRecordsByObject(ctx, record, query, values...)` - Query multiple records by object\n- `GetRecordsByWhereCondition(ctx, record, condition, values...)` - Query multiple with WHERE\n- `GetRecordByRawSQL(ctx, record, sql, values...)` - Execute raw SQL query\n\n#### Update Operations  \n- `UpdateRecord(ctx, record)` - Update record with all fields\n- `UpdateRecordWithCondition(ctx, record, query)` - Conditional update\n- `UpdateRecordWithSelectedColumns(ctx, record, updates)` - Update specific columns\n\n#### Delete Operations\n- `DeleteRecord(ctx, record, updates)` - Soft delete with optional updates\n- `DeleteRecordWithCondition(ctx, record, updates, query)` - Conditional soft delete\n- `DeleteRecordPermanently(ctx, record)` - Permanent delete\n- `DeleteRecordPermanentlyWithCondition(ctx, record, query)` - Conditional permanent delete\n\n#### Transaction Operations\n- `ExecuteDBTxn(ctx, transactions)` - Execute multiple operations as transaction\n\n#### Multi-Schema Operations\nThe ORM provides built-in support for PostgreSQL schemas through context-based schema switching:\n\n```go\nimport \"github.com/piyushkumar96/generic-orm/helper\"\n\n// Schema context functions\nhelper.SetSchemaInContext(ctx, \"schema_name\")           // Set single schema\nhelper.GetSchemaFromContext(ctx)                        // Get schema from context  \nhelper.SetMultipleSchemasInContext(ctx, []string{...})  // Set search path with multiple schemas\n```\n\n## Advanced Features\n\n### Custom Error Handling\n\nThe package includes comprehensive error handling with custom error types that wrap GORM errors and provide additional context.\n\n### Debug Mode\n\nEnable debug mode to see all SQL queries and execution details:\n\n```go\nconfig := config.GORMConfig{\n    DebugModeEnabled: true,\n    // other config...\n}\n```\n\n### Context Timeouts\n\nAll operations support context-based timeouts and cancellation:\n\n```go\nctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)\ndefer cancel()\n\nmeta, err := handler.CreateRecord(ctx, record)\n```\n\n### Connection Pool Management\n\nConfigure connection pooling for optimal performance:\n\n```go\nconfig := config.DBConnectionConfigurations{\n    MaxOpenConnections: 100,           // Maximum open connections\n    MaxIdleConnections: 10,            // Maximum idle connections  \n    ConnMaxLifetime:    1 * time.Hour, // Connection lifetime\n    // other config...\n}\n```\n\n### Multi-Schema Support\n\nThe ORM provides comprehensive multi-schema support for PostgreSQL, enabling schema-based multi-tenancy:\n\n#### Schema Context Management\n\n```go\nimport \"github.com/piyushkumar96/generic-orm/helper\"\n\n// Set schema for operations\nctx := helper.SetSchemaInContext(context.Background(), \"tenant_schema\")\n\n// All database operations will use the specified schema\nuser := \u0026User{Name: \"John\", Email: \"john@tenant.com\"}\nmeta, err := handler.CreateRecord(ctx, user)\n\n// Retrieve current schema\nif schema, ok := helper.GetSchemaFromContext(ctx); ok {\n    fmt.Printf(\"Current schema: %s\", schema)\n}\n```\n\n#### Multi-Tenant Isolation\n\n```go\n// Tenant A operations\ntenantACtx := helper.SetSchemaInContext(ctx, \"tenant_a\")\nuserA := \u0026User{Name: \"Alice\", TenantID: \"tenant-a\"}\nhandler.CreateRecord(tenantACtx, userA)\n\n// Tenant B operations (completely isolated)\ntenantBCtx := helper.SetSchemaInContext(ctx, \"tenant_b\") \nuserB := \u0026User{Name: \"Bob\", TenantID: \"tenant-b\"}\nhandler.CreateRecord(tenantBCtx, userB)\n\n// Each tenant's data is isolated in separate schemas\n```\n\n#### Multiple Schema Search Path\n\n```go\n// Set multiple schemas in search path\nschemas := []string{\"tenant_a\", \"tenant_b\", \"public\"}\nmultiCtx := helper.SetMultipleSchemasInContext(ctx, schemas)\n\n// Operations will search across all specified schemas\nvar users []User\nhandler.GetRecordsWithoutPagination(multiCtx, \u0026users)\n```\n\n#### Database Configuration for Multi-Schema\n\n```go\nconfig := config.DBConnectionConfigurations{\n    DatabaseSchemas: \"tenant_a,tenant_b,tenant_c,public\", // Comma-separated schemas\n    // other config...\n}\n```\n\n## Testing\n\nThe package includes comprehensive test coverage. Run tests with:\n\n```bash\ngo test ./...\n```\n\nFor integration tests with a real database:\n\n```bash\n# Set up test database environment variables\nexport DB_HOST=localhost\nexport DB_PORT=5432  \nexport DB_NAME=test_db\nexport DB_USER=postgres\nexport DB_PASSWORD=password\n\ngo test -tags=integration ./...\n```\n\n## Contributing\n\n1. Fork the repository\n2. Create your feature branch (`git checkout -b feature/amazing-feature`)\n3. Commit your changes (`git commit -m 'Add amazing feature'`)\n4. Push to the branch (`git push origin feature/amazing-feature`)\n5. Open a Pull Request\n\n## License\n\nThis project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpiyushkumar96%2Fgeneric-orm","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpiyushkumar96%2Fgeneric-orm","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpiyushkumar96%2Fgeneric-orm/lists"}