{"id":43122624,"url":"https://github.com/grandbusta/jone","last_synced_at":"2026-01-31T20:03:09.743Z","repository":{"id":323323806,"uuid":"952250101","full_name":"Grandbusta/jone","owner":"Grandbusta","description":"A @knex inspired SQL migration and schema builder for Go. Supports PostgreSQL today, Others coming soon. Designed to be flexible, and fun to use.","archived":false,"fork":false,"pushed_at":"2026-01-25T18:47:55.000Z","size":145,"stargazers_count":16,"open_issues_count":2,"forks_count":2,"subscribers_count":3,"default_branch":"main","last_synced_at":"2026-01-26T10:45:42.009Z","etag":null,"topics":["golang","knex","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/Grandbusta.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","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-03-21T01:16:54.000Z","updated_at":"2026-01-25T18:47:59.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/Grandbusta/jone","commit_stats":null,"previous_names":["grandbusta/jone"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/Grandbusta/jone","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Grandbusta%2Fjone","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Grandbusta%2Fjone/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Grandbusta%2Fjone/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Grandbusta%2Fjone/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Grandbusta","download_url":"https://codeload.github.com/Grandbusta/jone/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Grandbusta%2Fjone/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28952578,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-31T18:30:42.805Z","status":"ssl_error","status_checked_at":"2026-01-31T18:30:19.593Z","response_time":128,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: 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":["golang","knex","postgresql","sql"],"created_at":"2026-01-31T20:03:07.432Z","updated_at":"2026-01-31T20:03:09.735Z","avatar_url":"https://github.com/Grandbusta.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Jone\n\nA Go database migration tool with a fluent schema builder. Supports PostgreSQL and MySQL.\n\n## 📦 Installation\n\n**1. Install the CLI** (one-time, adds `jone` command to your system):\n\n```bash\ngo install github.com/Grandbusta/jone/cmd/jone@latest\n```\n\n**2. Add library to your project** (run in your project directory):\n\n```bash\ngo get github.com/Grandbusta/jone\n```\n\n## 🚀 Quick Start\n\n```bash\n# Initialize jone in your project (defaults to postgres)\njone init\n\n# Create a migration\njone migrate:make create_users\n\n# Run all pending migrations\njone migrate:latest\n\n# View migration status\njone migrate:list\n```\n\n## 💻 CLI Commands\n\n| Command | Description |\n|---------|-------------|\n| `jone init` | Initialize jone project. Creates `jone/` folder and config. |\n| `jone migrate:make \u003cname\u003e` | Create a new migration file. |\n| `jone migrate:latest` | Run all pending migrations. |\n| `jone migrate:up [name]` | Run next pending migration (or specific one). |\n| `jone migrate:down [name]` | Rollback last migration (or specific one). |\n| `jone migrate:rollback` | Rollback last batch of migrations. |\n| `jone migrate:list` | List all migrations with status. |\n| `jone migrate:status` | Alias for `migrate:list`. |\n\n### Flags\n\n**`jone init`**\n- `--db`, `-d` — Database type: `postgres`, `mysql`, `sqlite` (default: `postgres`)\n\n**`jone migrate:latest`**, **`migrate:up`**, **`migrate:down`**, **`migrate:rollback`**\n- `--dry-run` — Show SQL that would be executed without running it\n\n**`jone migrate:rollback`**\n- `--all`, `-a` — Rollback all migrations (not just last batch)\n\n## ⚙️ Configuration\n\nAfter running `jone init`, edit `jone/jonefile.go`:\n\n**PostgreSQL:**\n```go\npackage jone\n\nimport (\n    \"github.com/Grandbusta/jone\"\n    _ \"github.com/jackc/pgx/v5/stdlib\" // PostgreSQL driver\n)\n\nvar Config = jone.Config{\n    Client: \"postgresql\",\n    Connection: jone.Connection{\n        Host:     \"localhost\",\n        Port:     \"5432\",\n        User:     \"postgres\",\n        Password: \"password\",\n        Database: \"my_db\",\n    },\n    Migrations: jone.Migrations{\n        TableName: \"jone_migrations\",\n    },\n}\n```\n\n**MySQL:**\n```go\npackage jone\n\nimport (\n    \"github.com/Grandbusta/jone\"\n    _ \"github.com/go-sql-driver/mysql\" // MySQL driver\n)\n\nvar Config = jone.Config{\n    Client: \"mysql\",\n    Connection: jone.Connection{\n        Host:     \"localhost\",\n        Port:     \"3306\",\n        User:     \"root\",\n        Password: \"password\",\n        Database: \"my_db\",\n    },\n    Migrations: jone.Migrations{\n        TableName: \"jone_migrations\",\n    },\n}\n```\n\n## 🔗 Connection Pooling\n\nJone leverages Go's built-in `database/sql` connection pool. You can configure pool behavior by adding a `Pool` field to your config:\n\n```go\nimport (\n    \"time\"\n\n    \"github.com/Grandbusta/jone\"\n    _ \"github.com/jackc/pgx/v5/stdlib\" // Driver\n)\n\nvar Config = jone.Config{\n    Client: \"postgresql\",\n    Connection: jone.Connection{\n        Host:     \"localhost\",\n        Port:     \"5432\",\n        User:     \"postgres\",\n        Password: \"password\",\n        Database: \"my_db\",\n    },\n    Pool: jone.Pool{\n        MaxOpenConns:    10,              // Max open connections (0 = unlimited)\n        MaxIdleConns:    5,               // Max idle connections (0 = default 2)\n        ConnMaxLifetime: 30 * time.Minute, // Max connection reuse time (0 = no limit)\n        ConnMaxIdleTime: 5 * time.Minute,  // Max idle time before close (0 = no limit)\n    },\n    Migrations: jone.Migrations{\n        TableName: \"jone_migrations\",\n    },\n}\n```\n\nAll fields are optional. Omitting `Pool` (or using zero values) preserves the `database/sql` defaults.\n\n## 🏗️ Schema Builder\n\n### Creating Tables\n\n```go\nfunc Up(s *jone.Schema) {\n    s.CreateTable(\"users\", func(t *jone.Table) {\n        t.Increments(\"id\")\n        t.String(\"name\").Length(100).NotNullable()\n        t.String(\"email\").Length(255).NotNullable().Unique()\n        t.Text(\"bio\").Nullable()\n        t.Boolean(\"active\").Default(true)\n        t.Timestamps() // created_at, updated_at\n    })\n}\n```\n\n### Column Types\n\n| Method | SQL Type |\n|--------|----------|\n| `Increments(name)` | SERIAL / AUTO_INCREMENT PRIMARY KEY |\n| `String(name)` | VARCHAR(255) |\n| `Text(name)` | TEXT |\n| `Int(name)` | INTEGER |\n| `BigInt(name)` | BIGINT |\n| `SmallInt(name)` | SMALLINT |\n| `Boolean(name)` | BOOLEAN |\n| `Float(name)` | REAL / FLOAT |\n| `Double(name)` | DOUBLE PRECISION |\n| `Decimal(name)` | DECIMAL |\n| `Date(name)` | DATE |\n| `Time(name)` | TIME |\n| `Timestamp(name)` | TIMESTAMP |\n| `UUID(name)` | UUID |\n| `JSON(name)` | JSON |\n| `JSONB(name)` | JSONB |\n| `Binary(name)` | BYTEA / BLOB |\n\n### Column Modifiers\n\n```go\nt.String(\"name\").Length(100)         // Set length\nt.String(\"email\").NotNullable()      // NOT NULL\nt.String(\"status\").Default(\"new\")    // Default value\nt.String(\"code\").Unique()            // Unique constraint\nt.String(\"notes\").Nullable()         // Explicitly nullable\nt.String(\"title\").Comment(\"...\")     // Column comment\nt.BigInt(\"user_id\").Unsigned()       // Unsigned (MySQL)\nt.BigInt(\"id\").Primary()             // Primary key\nt.Decimal(\"price\").Precision(10).Scale(2) // DECIMAL(10,2)\n```\n\n### Indexes\n\n```go\n// Create index\nt.Index(\"email\")\nt.Index(\"first_name\", \"last_name\").Name(\"idx_full_name\")\nt.Index(\"data\").Using(\"gin\")  // Index method (btree, hash, gin, gist)\n\n// Unique index\nt.Unique(\"email\")\nt.Unique(\"org_id\", \"slug\").Name(\"uq_org_slug\")\n```\n\n### Foreign Keys\n\n```go\nt.BigInt(\"user_id\").NotNullable()\nt.Foreign(\"user_id\").References(\"users\", \"id\").OnDelete(\"CASCADE\")\nt.Foreign(\"org_id\").References(\"orgs\", \"id\").OnDelete(\"SET NULL\").OnUpdate(\"CASCADE\")\nt.Foreign(\"custom\").References(\"table\", \"col\").Name(\"fk_custom_name\")\n```\n\n### Timestamps\n\n```go\nt.Timestamps() // Adds created_at and updated_at\n```\n\n### Altering Tables\n\n```go\nfunc Up(s *jone.Schema) {\n    s.Table(\"users\", func(t *jone.Table) {\n        t.String(\"phone\").Nullable()        // Add column\n        t.DropColumn(\"legacy_field\")        // Drop column\n        t.RenameColumn(\"name\", \"full_name\") // Rename column\n        t.SetNullable(\"bio\")                // Make nullable\n        t.DropNullable(\"email\")             // Make not nullable\n        t.SetDefault(\"active\", true)        // Set default\n        t.DropDefault(\"active\")             // Drop default\n        t.DropIndex(\"email\")                // Drop index\n        t.DropForeign(\"user_id\")            // Drop foreign key\n    })\n}\n```\n\n### Dropping Tables\n\n```go\nfunc Down(s *jone.Schema) {\n    s.DropTable(\"users\")\n    // or\n    s.DropTableIfExists(\"users\")\n}\n```\n\n### Other Operations\n\n```go\ns.RenameTable(\"old_name\", \"new_name\")\ns.HasTable(\"users\")           // Check if table exists\ns.HasColumn(\"users\", \"email\") // Check if column exists\n```\n\n### Raw SQL\n\nFor custom statements the schema builder doesn't support:\n\n```go\n// DDL statements\ns.Raw(\"CREATE EXTENSION IF NOT EXISTS \\\"uuid-ossp\\\"\")\ns.Raw(\"CREATE INDEX CONCURRENTLY idx_users_email ON users(email)\")\n\n// Data migrations with parameters\ns.Raw(\"INSERT INTO settings (key, value) VALUES ($1, $2)\", \"version\", \"1.0\")\ns.Raw(\"UPDATE users SET status = $1 WHERE created_at \u003c $2\", \"legacy\", \"2020-01-01\")\n```\n\n## 📝 Migration Example\n\n```go\n// jone/migrations/20260123000000_create_users/migration.go\npackage m20260123000000\n\nimport \"github.com/Grandbusta/jone\"\n\nfunc Up(s *jone.Schema) {\n    s.CreateTable(\"users\", func(t *jone.Table) {\n        t.Increments(\"id\")\n        t.String(\"email\").NotNullable().Unique()\n        t.String(\"password_hash\").NotNullable()\n        t.String(\"name\").Length(100)\n        t.Boolean(\"verified\").Default(false)\n        t.Timestamps()\n    })\n\n    s.CreateTable(\"posts\", func(t *jone.Table) {\n        t.Increments(\"id\")\n        t.BigInt(\"user_id\").NotNullable()\n        t.String(\"title\").NotNullable()\n        t.Text(\"content\")\n        t.Timestamps()\n\n        t.Foreign(\"user_id\").References(\"users\", \"id\").OnDelete(\"CASCADE\")\n        t.Index(\"user_id\")\n    })\n}\n\nfunc Down(s *jone.Schema) {\n    s.DropTableIfExists(\"posts\")\n    s.DropTableIfExists(\"users\")\n}\n```\n\n## 🗄️ Supported Databases\n\n| Database | Driver Package | Status |\n|----------|----------------|--------|\n| PostgreSQL | `github.com/jackc/pgx/v5/stdlib` | ✅ Supported |\n| MySQL | `github.com/go-sql-driver/mysql` | ✅ Supported |\n| SQLite | `github.com/mattn/go-sqlite3` | 🚧 Planned |\n\n## 🤝 Contributing\n\nContributions are welcome! Please see our [Contributing Guide](CONTRIBUTING.md) for more details.\n\n## 📄 License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgrandbusta%2Fjone","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgrandbusta%2Fjone","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgrandbusta%2Fjone/lists"}