Compare commits
No commits in common. "561dfbc82747c740258e7b84bc0439e0f4cec4db" and "80f03102e2590b80bef871ec6c106eb24447cc26" have entirely different histories.
561dfbc827
...
80f03102e2
@ -1,50 +0,0 @@
|
|||||||
name: Go CI/CD
|
|
||||||
run-name: ${{ github.actor }} is running CI/CD basic
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches-ignore:
|
|
||||||
- main
|
|
||||||
- release/**
|
|
||||||
- develop
|
|
||||||
pull_request:
|
|
||||||
branches-ignore:
|
|
||||||
- main
|
|
||||||
- release/**
|
|
||||||
- develop
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
go-ci:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- name: Checkout code
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
with:
|
|
||||||
fetch-depth: 0
|
|
||||||
|
|
||||||
- name: Setup go
|
|
||||||
uses: actions/setup-go@v5
|
|
||||||
with:
|
|
||||||
go-version: '1.24'
|
|
||||||
|
|
||||||
- name: Download dependencies
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
go mod tidy -x
|
|
||||||
|
|
||||||
- name: Run tests
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
go test -json > test-report.out
|
|
||||||
go test -coverprofile=coverage.out
|
|
||||||
|
|
||||||
- name: SonarQube Analysis
|
|
||||||
uses: SonarSource/sonarqube-scan-action@v5
|
|
||||||
env:
|
|
||||||
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
|
|
||||||
SONAR_HOST_URL: ${{ vars.SONAR_HOST_URL }}
|
|
||||||
|
|
||||||
- name: Build binary
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
go build ./...
|
|
@ -1,50 +0,0 @@
|
|||||||
name: Go CI/CD
|
|
||||||
run-name: ${{ github.actor }} is running CI/CD protected
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- main
|
|
||||||
- release/**
|
|
||||||
- develop
|
|
||||||
pull_request:
|
|
||||||
branches:
|
|
||||||
- main
|
|
||||||
- release/**
|
|
||||||
- develop
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
go-ci:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- name: Checkout code
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
with:
|
|
||||||
fetch-depth: 0
|
|
||||||
|
|
||||||
- name: Setup go
|
|
||||||
uses: actions/setup-go@v5
|
|
||||||
with:
|
|
||||||
go-version: '1.24'
|
|
||||||
|
|
||||||
- name: Download dependencies
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
go mod tidy -x
|
|
||||||
|
|
||||||
- name: Run tests
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
go test -json > test-report.out
|
|
||||||
go test -coverprofile=coverage.out
|
|
||||||
|
|
||||||
- name: SonarQube Analysis
|
|
||||||
uses: SonarSource/sonarqube-scan-action@v5
|
|
||||||
env:
|
|
||||||
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
|
|
||||||
SONAR_HOST_URL: ${{ vars.SONAR_HOST_URL }}
|
|
||||||
|
|
||||||
- name: Build binary
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
go build ./...
|
|
@ -1,43 +0,0 @@
|
|||||||
name: Go CI/CD
|
|
||||||
run-name: ${{ github.actor }} is running CI/CD Tag
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
tags:
|
|
||||||
- '*'
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
go-ci:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- name: Checkout code
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
with:
|
|
||||||
fetch-depth: 0
|
|
||||||
|
|
||||||
- name: Setup go
|
|
||||||
uses: actions/setup-go@v5
|
|
||||||
with:
|
|
||||||
go-version: '1.24'
|
|
||||||
|
|
||||||
- name: Download dependencies
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
go mod tidy -x
|
|
||||||
|
|
||||||
- name: Run tests
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
go test -json > test-report.out
|
|
||||||
go test -coverprofile=coverage.out
|
|
||||||
|
|
||||||
- name: SonarQube Analysis
|
|
||||||
uses: SonarSource/sonarqube-scan-action@v5
|
|
||||||
env:
|
|
||||||
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
|
|
||||||
SONAR_HOST_URL: ${{ vars.SONAR_HOST_URL }}
|
|
||||||
|
|
||||||
- name: Build binary
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
go build ./...
|
|
8
.idea/.gitignore
generated
vendored
8
.idea/.gitignore
generated
vendored
@ -1,8 +0,0 @@
|
|||||||
# Default ignored files
|
|
||||||
/shelf/
|
|
||||||
/workspace.xml
|
|
||||||
# Editor-based HTTP Client requests
|
|
||||||
/httpRequests/
|
|
||||||
# Datasource local storage ignored files
|
|
||||||
/dataSources/
|
|
||||||
/dataSources.local.xml
|
|
4
.idea/misc.xml
generated
4
.idea/misc.xml
generated
@ -1,4 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="GOROOT" url="file:///usr/local/go" />
|
|
||||||
</project>
|
|
4
.idea/vcs.xml
generated
4
.idea/vcs.xml
generated
@ -1,4 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="VcsDirectoryMappings" defaultProject="true" />
|
|
||||||
</project>
|
|
83
README.md
83
README.md
@ -1,82 +1,3 @@
|
|||||||
# StoneSQL - **10 BILLION% MIGRATION PRECISION!**
|
# stonesql
|
||||||
|
|
||||||
Ultimate SQL Migration Engine! ⚡ Scientific database versioning with atomic precision. Embedded migration files, error tracking & stone-utils integration. 10 billion% more reliable schema changes! 🚀
|
StoneSQL - Ultimate SQL Migration Engine! ⚡ Scientific database versioning with atomic precision. Embedded migration files, error tracking & stone-utils integration. 10 billion% more reliable schema changes! 🚀
|
||||||
|
|
||||||
[]()
|
|
||||||
[]()
|
|
||||||
[]()
|
|
||||||
|
|
||||||
## 🚀 Why StoneSQL?
|
|
||||||
|
|
||||||
- **Embedded SQL migrations** with atomic precision
|
|
||||||
- **Scientifically versioned** schema changes
|
|
||||||
- **100% reproducible** database states
|
|
||||||
- **10 billion schema changes/sec** (theoretical)
|
|
||||||
|
|
||||||
## 💥 Installation
|
|
||||||
|
|
||||||
```bash
|
|
||||||
go get gitstormr.dev/stone-utils/stonesql@latest
|
|
||||||
```
|
|
||||||
|
|
||||||
## ⚡ Basic Usage
|
|
||||||
|
|
||||||
```go
|
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"embed"
|
|
||||||
"gitstormr.dev/stone-utils/stonesql"
|
|
||||||
)
|
|
||||||
|
|
||||||
//go:embed migrations/*.sql
|
|
||||||
var migrations embed.FS
|
|
||||||
|
|
||||||
type DBMigrator struct{}
|
|
||||||
|
|
||||||
func (m *DBMigrator) ExecuteMigration(ctx context.Context, name, sql string) error {
|
|
||||||
// Execute with your favorite database driver
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
if err := stonesql.RunMigrations(context.Background(), &DBMigrator{}, migrations, "migrations"); err != nil {
|
|
||||||
panic(err) // Handle error properly in production!
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## 🔬 Core Features
|
|
||||||
|
|
||||||
### Embedded migration files
|
|
||||||
|
|
||||||
```text
|
|
||||||
migrations/
|
|
||||||
├─ 001_init.sql
|
|
||||||
├─ 002_add_users.sql
|
|
||||||
└─ 003_add_indexes.sql
|
|
||||||
```
|
|
||||||
|
|
||||||
### Scientific error tracking
|
|
||||||
|
|
||||||
```go
|
|
||||||
ErrWalkDirFailed = stoneerror.New(2001, "failed walking migrations")
|
|
||||||
ErrReadMigrationFailed = stoneerror.New(2002, "failed reading SQL file")
|
|
||||||
// ...and more!
|
|
||||||
```
|
|
||||||
|
|
||||||
## ⚗️ Scientific Benchmarks
|
|
||||||
|
|
||||||
| METRIC | STANDARD LIB | STONESQL |
|
|
||||||
|-----------------|---------------|----------|
|
|
||||||
| Reliability | 80% | 10B% |
|
|
||||||
| Reproducibility | ❌ | ✅✅✅ |
|
|
||||||
| Atomicity | Maybe | ALWAYS |
|
|
||||||
|
|
||||||
**Join the Scientific Revolution!**
|
|
||||||
|
|
||||||
> "This isn't just schema management - it's revolutionizing database evolution like we revived civilization!" - Senku Ishigami
|
|
||||||
|
|
||||||
Kingdom of Science Approved
|
|
||||||
|
|
||||||
(Now with 100% more Chrome screaming "SO BADASS!")
|
|
5
go.mod
5
go.mod
@ -1,5 +0,0 @@
|
|||||||
module gitstormr.dev/stone-utils/stonesql
|
|
||||||
|
|
||||||
go 1.24
|
|
||||||
|
|
||||||
require gitstormr.dev/stone-utils/stoneerror v1.0.0
|
|
2
go.sum
2
go.sum
@ -1,2 +0,0 @@
|
|||||||
gitstormr.dev/stone-utils/stoneerror v1.0.0 h1:EJpn4MZBeYifWlCoQBEGmGdEtNABjOrUzJmQSqcXqY0=
|
|
||||||
gitstormr.dev/stone-utils/stoneerror v1.0.0/go.mod h1:Rs34Oz14ILsbkZ++Ov9PObTz7mRvyyvcCcML9AeyIyk=
|
|
106
migrator.go
106
migrator.go
@ -1,106 +0,0 @@
|
|||||||
package stonesql
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"embed"
|
|
||||||
"io/fs"
|
|
||||||
"path/filepath"
|
|
||||||
|
|
||||||
"gitstormr.dev/stone-utils/stoneerror"
|
|
||||||
)
|
|
||||||
|
|
||||||
// SQLFileExtension represents the file extension for SQL migration files.
|
|
||||||
const (
|
|
||||||
SQLFileExtension = ".sql"
|
|
||||||
)
|
|
||||||
|
|
||||||
// ErrWalkDirFailed represents an error for failed directory traversal.
|
|
||||||
// ErrReadMigrationFailed represents an error for reading migration files.
|
|
||||||
// ErrExecuteMigrationFailed represents an error during migration execution.
|
|
||||||
// ErrMigrationProcessFailed represents a general migration process failure.
|
|
||||||
var (
|
|
||||||
ErrWalkDirFailed = stoneerror.New(
|
|
||||||
2001,
|
|
||||||
"failed to walk migration directory",
|
|
||||||
)
|
|
||||||
ErrReadMigrationFailed = stoneerror.New(
|
|
||||||
2002,
|
|
||||||
"failed to read migration file",
|
|
||||||
)
|
|
||||||
ErrExecuteMigrationFailed = stoneerror.New(
|
|
||||||
2003,
|
|
||||||
"failed to execute migration",
|
|
||||||
)
|
|
||||||
ErrMigrationProcessFailed = stoneerror.New(
|
|
||||||
2004,
|
|
||||||
"migration process failed",
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
// Migrator defines the interface for executing SQL migrations.
|
|
||||||
// ExecuteMigration runs a migration given its name and SQL content.
|
|
||||||
type Migrator interface {
|
|
||||||
ExecuteMigration(ctx context.Context, name string, sqlContent string) error
|
|
||||||
}
|
|
||||||
|
|
||||||
// RunMigrations performs a series of database migrations from embedded files.
|
|
||||||
// It traverses the provided filesystem path, reads SQL files, and executes them.
|
|
||||||
// If an error occurs during traversal, reading, or execution, it wraps and returns it.
|
|
||||||
// Context to be used for execution is passed via the ctx parameter.
|
|
||||||
// The migrator parameter executes individual SQL content for migrations.
|
|
||||||
// The migrationsFS parameter provides an embedded filesystem for the SQL files.
|
|
||||||
// The path parameter specifies the directory within the embedded FS to search in.
|
|
||||||
// Returns an error if any step in the migration process fails.
|
|
||||||
func RunMigrations(
|
|
||||||
ctx context.Context,
|
|
||||||
migrator Migrator,
|
|
||||||
migrationsFS embed.FS,
|
|
||||||
path string,
|
|
||||||
) error {
|
|
||||||
walkErr := fs.WalkDir(
|
|
||||||
migrationsFS,
|
|
||||||
path,
|
|
||||||
func(path string, d fs.DirEntry, err error) error {
|
|
||||||
if err != nil {
|
|
||||||
return stoneerror.Wrap(
|
|
||||||
err, ErrWalkDirFailed.Code,
|
|
||||||
ErrWalkDirFailed.Message,
|
|
||||||
).
|
|
||||||
WithMetadata("path", path)
|
|
||||||
}
|
|
||||||
|
|
||||||
if !d.IsDir() && filepath.Ext(path) == SQLFileExtension {
|
|
||||||
sqlContent, readErr := migrationsFS.ReadFile(path)
|
|
||||||
if readErr != nil {
|
|
||||||
return stoneerror.Wrap(
|
|
||||||
readErr, ErrReadMigrationFailed.Code,
|
|
||||||
ErrReadMigrationFailed.Message,
|
|
||||||
).
|
|
||||||
WithMetadata("file", path)
|
|
||||||
}
|
|
||||||
|
|
||||||
if err = migrator.ExecuteMigration(
|
|
||||||
ctx, path, string(sqlContent),
|
|
||||||
); err != nil {
|
|
||||||
return stoneerror.Wrap(
|
|
||||||
err, ErrExecuteMigrationFailed.Code,
|
|
||||||
ErrExecuteMigrationFailed.Message,
|
|
||||||
).
|
|
||||||
WithMetadata("migration", path)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
if walkErr != nil {
|
|
||||||
return stoneerror.Wrap(
|
|
||||||
walkErr, ErrMigrationProcessFailed.Code,
|
|
||||||
ErrMigrationProcessFailed.Message,
|
|
||||||
).
|
|
||||||
WithMetadata("rootPath", path)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
@ -1,43 +0,0 @@
|
|||||||
package stonesql
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"fmt"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"gitstormr.dev/stone-utils/stonesql/test"
|
|
||||||
)
|
|
||||||
|
|
||||||
type migratorSuccessMock struct{}
|
|
||||||
|
|
||||||
func (m *migratorSuccessMock) ExecuteMigration(
|
|
||||||
ctx context.Context, name string, sqlContent string,
|
|
||||||
) error {
|
|
||||||
fmt.Println(name, sqlContent)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type migratorFailureMock struct{}
|
|
||||||
|
|
||||||
func (m *migratorFailureMock) ExecuteMigration(
|
|
||||||
ctx context.Context, name string, sqlContent string,
|
|
||||||
) error {
|
|
||||||
return fmt.Errorf("failed to execute migration %s", name)
|
|
||||||
}
|
|
||||||
|
|
||||||
func Test_MigrationSuccess(t *testing.T) {
|
|
||||||
migrator := &migratorSuccessMock{}
|
|
||||||
err := RunMigrations(context.Background(), migrator, test.TestFS, ".")
|
|
||||||
if err != nil {
|
|
||||||
t.Error(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func Test_MigrationFailure(t *testing.T) {
|
|
||||||
migrator := &migratorFailureMock{}
|
|
||||||
err := RunMigrations(context.Background(), migrator, test.TestFS, ".")
|
|
||||||
|
|
||||||
if err == nil {
|
|
||||||
t.Error("expected error")
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,10 +0,0 @@
|
|||||||
sonar.projectKey=9abe63b7-edeb-482a-ac71-9f4afb2947b1
|
|
||||||
sonar.projectName=stone-utils/stonesql
|
|
||||||
sonar.language=go
|
|
||||||
sonar.sources=.
|
|
||||||
sonar.exclusions=**/*_test.go, test/**
|
|
||||||
sonar.tests=.
|
|
||||||
sonar.test.inclusions=**/*_test.go
|
|
||||||
sonar.go.tests.reportPaths=test-report.out
|
|
||||||
sonar.go.coverage.reportPaths=coverage.out
|
|
||||||
sonar.qualitygate.wait=true
|
|
@ -1,8 +0,0 @@
|
|||||||
package test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"embed"
|
|
||||||
)
|
|
||||||
|
|
||||||
//go:embed *.sql
|
|
||||||
var TestFS embed.FS
|
|
@ -1 +0,0 @@
|
|||||||
SELECT 1 == 1;
|
|
Loading…
x
Reference in New Issue
Block a user