Selaa lähdekoodia

database: fully switch over to pure-Go SQLite driver (#8115)

ᴊᴏᴇ ᴄʜᴇɴ 1 viikko sitten
vanhempi
säilyke
2316b09eaf

+ 0 - 19
.github/workflows/go.yml

@@ -195,22 +195,3 @@ jobs:
           MYSQL_PASSWORD: root
           MYSQL_HOST: localhost
           MYSQL_PORT: 3306
-
-  sqlite-go:
-    name: SQLite - Go
-    strategy:
-      matrix:
-        go-version: [ 1.25.x ]
-        platform: [ ubuntu-latest ]
-    runs-on: ${{ matrix.platform }}
-    steps:
-      - name: Checkout code
-        uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
-      - name: Install Go
-        uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0
-        with:
-          go-version: ${{ matrix.go-version }}
-      - name: Run tests with coverage
-        run: go test -shuffle=on -v -race -parallel=1 -coverprofile=coverage -covermode=atomic ./internal/database/...
-        env:
-          GOGS_DATABASE_TYPE: sqlite

+ 1 - 0
CHANGELOG.md

@@ -15,6 +15,7 @@ All notable changes to Gogs are documented in this file.
 
 - The required Go version to compile source code changed to 1.25.
 - The build tag `cert` has been removed, and the `gogs cert` subcommand is now always available. [#7883](https://github.com/gogs/gogs/pull/7883)
+- Switched to pure-Go SQLite driver, CGO is no longer required to compile Gogs. [#7882](https://github.com/gogs/gogs/issues/7882)
 - Updated Mermaid JS to 11.9.0. [#8009](https://github.com/gogs/gogs/pull/8009)
 - Halt the repository creation and leave the directory untouched if the repository root already exists. [#8091](https://github.com/gogs/gogs/pull/8091)
 

+ 1 - 0
CLAUDE.md

@@ -0,0 +1 @@
+AGENTS.md

+ 30 - 30
docs/dev/database_schema.md

@@ -1,12 +1,12 @@
 # Table "access"
 
 ```
-  FIELD  | COLUMN  |   POSTGRESQL    |         MYSQL         |     SQLITE3       
----------+---------+-----------------+-----------------------+-------------------
-  ID     | id      | BIGSERIAL       | BIGINT AUTO_INCREMENT | INTEGER           
-  UserID | user_id | BIGINT NOT NULL | BIGINT NOT NULL       | INTEGER NOT NULL  
-  RepoID | repo_id | BIGINT NOT NULL | BIGINT NOT NULL       | INTEGER NOT NULL  
-  Mode   | mode    | BIGINT NOT NULL | BIGINT NOT NULL       | INTEGER NOT NULL  
+  FIELD  | COLUMN  |   POSTGRESQL    |         MYSQL         |        SQLITE3         
+---------+---------+-----------------+-----------------------+------------------------
+  ID     | id      | BIGSERIAL       | BIGINT AUTO_INCREMENT | INTEGER AUTOINCREMENT  
+  UserID | user_id | BIGINT NOT NULL | BIGINT NOT NULL       | INTEGER NOT NULL       
+  RepoID | repo_id | BIGINT NOT NULL | BIGINT NOT NULL       | INTEGER NOT NULL       
+  Mode   | mode    | BIGINT NOT NULL | BIGINT NOT NULL       | INTEGER NOT NULL       
 
 Primary keys: id
 Indexes: 
@@ -18,7 +18,7 @@ Indexes:
 ```
      FIELD    |    COLUMN    |         POSTGRESQL          |            MYSQL            |           SQLITE3            
 --------------+--------------+-----------------------------+-----------------------------+------------------------------
-  ID          | id           | BIGSERIAL                   | BIGINT AUTO_INCREMENT       | INTEGER                      
+  ID          | id           | BIGSERIAL                   | BIGINT AUTO_INCREMENT       | INTEGER AUTOINCREMENT        
   UserID      | uid          | BIGINT                      | BIGINT                      | INTEGER                      
   Name        | name         | TEXT                        | LONGTEXT                    | TEXT                         
   Sha1        | sha1         | VARCHAR(40) UNIQUE          | VARCHAR(40) UNIQUE          | VARCHAR(40) UNIQUE           
@@ -36,7 +36,7 @@ Indexes:
 ```
      FIELD     |     COLUMN     |           POSTGRESQL           |             MYSQL              |            SQLITE3              
 ---------------+----------------+--------------------------------+--------------------------------+---------------------------------
-  ID           | id             | BIGSERIAL                      | BIGINT AUTO_INCREMENT          | INTEGER                         
+  ID           | id             | BIGSERIAL                      | BIGINT AUTO_INCREMENT          | INTEGER AUTOINCREMENT           
   UserID       | user_id        | BIGINT                         | BIGINT                         | INTEGER                         
   OpType       | op_type        | BIGINT                         | BIGINT                         | INTEGER                         
   ActUserID    | act_user_id    | BIGINT                         | BIGINT                         | INTEGER                         
@@ -60,7 +60,7 @@ Indexes:
 ```
      FIELD    |    COLUMN    |           POSTGRESQL           |             MYSQL              |            SQLITE3              
 --------------+--------------+--------------------------------+--------------------------------+---------------------------------
-  ID          | id           | BIGSERIAL                      | BIGINT AUTO_INCREMENT          | INTEGER                         
+  ID          | id           | BIGSERIAL                      | BIGINT AUTO_INCREMENT          | INTEGER AUTOINCREMENT           
   UserID      | uid          | BIGINT NOT NULL                | BIGINT NOT NULL                | INTEGER NOT NULL                
   Email       | email        | VARCHAR(254) NOT NULL          | VARCHAR(254) NOT NULL          | TEXT NOT NULL                   
   IsActivated | is_activated | BOOLEAN NOT NULL DEFAULT FALSE | BOOLEAN NOT NULL DEFAULT FALSE | NUMERIC NOT NULL DEFAULT FALSE  
@@ -74,11 +74,11 @@ Indexes:
 # Table "follow"
 
 ```
-   FIELD   |  COLUMN   |   POSTGRESQL    |         MYSQL         |     SQLITE3       
------------+-----------+-----------------+-----------------------+-------------------
-  ID       | id        | BIGSERIAL       | BIGINT AUTO_INCREMENT | INTEGER           
-  UserID   | user_id   | BIGINT NOT NULL | BIGINT NOT NULL       | INTEGER NOT NULL  
-  FollowID | follow_id | BIGINT NOT NULL | BIGINT NOT NULL       | INTEGER NOT NULL  
+   FIELD   |  COLUMN   |   POSTGRESQL    |         MYSQL         |        SQLITE3         
+-----------+-----------+-----------------+-----------------------+------------------------
+  ID       | id        | BIGSERIAL       | BIGINT AUTO_INCREMENT | INTEGER AUTOINCREMENT  
+  UserID   | user_id   | BIGINT NOT NULL | BIGINT NOT NULL       | INTEGER NOT NULL       
+  FollowID | follow_id | BIGINT NOT NULL | BIGINT NOT NULL       | INTEGER NOT NULL       
 
 Primary keys: id
 Indexes: 
@@ -102,16 +102,16 @@ Primary keys: repo_id, oid
 # Table "login_source"
 
 ```
-     FIELD    |    COLUMN    |    POSTGRESQL    |         MYSQL         |     SQLITE3       
---------------+--------------+------------------+-----------------------+-------------------
-  ID          | id           | BIGSERIAL        | BIGINT AUTO_INCREMENT | INTEGER           
-  Type        | type         | BIGINT           | BIGINT                | INTEGER           
-  Name        | name         | TEXT UNIQUE      | VARCHAR(191) UNIQUE   | TEXT UNIQUE       
-  IsActived   | is_actived   | BOOLEAN NOT NULL | BOOLEAN NOT NULL      | NUMERIC NOT NULL  
-  IsDefault   | is_default   | BOOLEAN          | BOOLEAN               | NUMERIC           
-  Config      | cfg          | TEXT             | TEXT                  | TEXT              
-  CreatedUnix | created_unix | BIGINT           | BIGINT                | INTEGER           
-  UpdatedUnix | updated_unix | BIGINT           | BIGINT                | INTEGER           
+     FIELD    |    COLUMN    |    POSTGRESQL    |         MYSQL         |        SQLITE3         
+--------------+--------------+------------------+-----------------------+------------------------
+  ID          | id           | BIGSERIAL        | BIGINT AUTO_INCREMENT | INTEGER AUTOINCREMENT  
+  Type        | type         | BIGINT           | BIGINT                | INTEGER                
+  Name        | name         | TEXT UNIQUE      | VARCHAR(191) UNIQUE   | TEXT UNIQUE            
+  IsActived   | is_actived   | BOOLEAN NOT NULL | BOOLEAN NOT NULL      | NUMERIC NOT NULL       
+  IsDefault   | is_default   | BOOLEAN          | BOOLEAN               | NUMERIC                
+  Config      | cfg          | TEXT             | TEXT                  | TEXT                   
+  CreatedUnix | created_unix | BIGINT           | BIGINT                | INTEGER                
+  UpdatedUnix | updated_unix | BIGINT           | BIGINT                | INTEGER                
 
 Primary keys: id
 ```
@@ -119,12 +119,12 @@ Primary keys: id
 # Table "notice"
 
 ```
-     FIELD    |    COLUMN    | POSTGRESQL |         MYSQL         | SQLITE3  
---------------+--------------+------------+-----------------------+----------
-  ID          | id           | BIGSERIAL  | BIGINT AUTO_INCREMENT | INTEGER  
-  Type        | type         | BIGINT     | BIGINT                | INTEGER  
-  Description | description  | TEXT       | TEXT                  | TEXT     
-  CreatedUnix | created_unix | BIGINT     | BIGINT                | INTEGER  
+     FIELD    |    COLUMN    | POSTGRESQL |         MYSQL         |        SQLITE3         
+--------------+--------------+------------+-----------------------+------------------------
+  ID          | id           | BIGSERIAL  | BIGINT AUTO_INCREMENT | INTEGER AUTOINCREMENT  
+  Type        | type         | BIGINT     | BIGINT                | INTEGER                
+  Description | description  | TEXT       | TEXT                  | TEXT                   
+  CreatedUnix | created_unix | BIGINT     | BIGINT                | INTEGER                
 
 Primary keys: id
 ```

+ 3 - 2
go.mod

@@ -7,6 +7,7 @@ require (
 	github.com/cockroachdb/errors v1.12.0
 	github.com/derision-test/go-mockgen/v2 v2.1.1
 	github.com/editorconfig/editorconfig-core-go/v2 v2.6.3
+	github.com/glebarez/sqlite v1.11.0
 	github.com/go-ldap/ldap/v3 v3.4.11
 	github.com/go-macaron/binding v1.2.0
 	github.com/go-macaron/cache v0.0.0-20190810181446-10f7c57e2196
@@ -52,10 +53,8 @@ require (
 	gopkg.in/macaron.v1 v1.5.0
 	gorm.io/driver/mysql v1.5.2
 	gorm.io/driver/postgres v1.6.0
-	gorm.io/driver/sqlite v1.4.2
 	gorm.io/driver/sqlserver v1.4.1
 	gorm.io/gorm v1.25.12
-	modernc.org/sqlite v1.38.2
 	unknwon.dev/clog/v2 v2.2.0
 	xorm.io/builder v0.3.6
 	xorm.io/core v0.7.2
@@ -81,6 +80,7 @@ require (
 	github.com/dustin/go-humanize v1.0.1 // indirect
 	github.com/fatih/color v1.13.0 // indirect
 	github.com/getsentry/sentry-go v0.27.0 // indirect
+	github.com/glebarez/go-sqlite v1.21.2 // indirect
 	github.com/go-asn1-ber/asn1-ber v1.5.8-0.20250403174932-29230038a667 // indirect
 	github.com/go-logr/logr v1.2.3 // indirect
 	github.com/go-logr/stdr v1.2.2 // indirect
@@ -141,6 +141,7 @@ require (
 	modernc.org/libc v1.66.3 // indirect
 	modernc.org/mathutil v1.7.1 // indirect
 	modernc.org/memory v1.11.0 // indirect
+	modernc.org/sqlite v1.38.2 // indirect
 )
 
 // +heroku goVersion go1.25

+ 4 - 3
go.sum

@@ -92,6 +92,10 @@ github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWo
 github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
 github.com/getsentry/sentry-go v0.27.0 h1:Pv98CIbtB3LkMWmXi4Joa5OOcwbmnX88sF5qbK3r3Ps=
 github.com/getsentry/sentry-go v0.27.0/go.mod h1:lc76E2QywIyW8WuBnwl8Lc4bkmQH4+w1gwTf25trprY=
+github.com/glebarez/go-sqlite v1.21.2 h1:3a6LFC4sKahUunAmynQKLZceZCOzUthkRkEAl9gAXWo=
+github.com/glebarez/go-sqlite v1.21.2/go.mod h1:sfxdZyhQjTM2Wry3gVYWaW072Ri1WMdWJi0k6+3382k=
+github.com/glebarez/sqlite v1.11.0 h1:wSG0irqzP6VurnMEpFGer5Li19RpIRi2qvQz++w0GMw=
+github.com/glebarez/sqlite v1.11.0/go.mod h1:h8/o8j5wiAsqSPoWELDUdJXhjAhsVliSn7bWZjOhrgQ=
 github.com/go-asn1-ber/asn1-ber v1.5.8-0.20250403174932-29230038a667 h1:BP4M0CvQ4S3TGls2FvczZtj5Re/2ZzkV9VwqPHH/3Bo=
 github.com/go-asn1-ber/asn1-ber v1.5.8-0.20250403174932-29230038a667/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0=
 github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA=
@@ -297,7 +301,6 @@ github.com/mattn/go-runewidth v0.0.14 h1:+xnbZSEeDbOIg5/mE6JF0w6n9duR1l3/WmbinWV
 github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
 github.com/mattn/go-sqlite3 v1.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
 github.com/mattn/go-sqlite3 v1.11.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
-github.com/mattn/go-sqlite3 v1.14.15/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
 github.com/mattn/go-sqlite3 v1.14.24 h1:tpSp2G2KyMnnQu99ngJ47EIkWVmliIizyZBfPrBWDRM=
 github.com/mattn/go-sqlite3 v1.14.24/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
 github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
@@ -648,8 +651,6 @@ gorm.io/driver/mysql v1.5.2 h1:QC2HRskSE75wBuOxe0+iCkyJZ+RqpudsQtqkp+IMuXs=
 gorm.io/driver/mysql v1.5.2/go.mod h1:pQLhh1Ut/WUAySdTHwBpBv6+JKcj+ua4ZFx1QQTBzb8=
 gorm.io/driver/postgres v1.6.0 h1:2dxzU8xJ+ivvqTRph34QX+WrRaJlmfyPqXmoGVjMBa4=
 gorm.io/driver/postgres v1.6.0/go.mod h1:vUw0mrGgrTK+uPHEhAdV4sfFELrByKVGnaVRkXDhtWo=
-gorm.io/driver/sqlite v1.4.2 h1:F6vYJcmR4Cnh0ErLyoY8JSfabBGyR0epIGuhgHJuNws=
-gorm.io/driver/sqlite v1.4.2/go.mod h1:0Aq3iPO+v9ZKbcdiz8gLWRw5VOPcBOPUQJFLq5e2ecI=
 gorm.io/driver/sqlserver v1.4.1 h1:t4r4r6Jam5E6ejqP7N82qAJIJAht27EGT41HyPfXRw0=
 gorm.io/driver/sqlserver v1.4.1/go.mod h1:DJ4P+MeZbc5rvY58PnmN1Lnyvb5gw5NPzGshHDnJLig=
 gorm.io/gorm v1.24.0/go.mod h1:DVrVomtaYTbqs7gB/x2uVvqnXzv0nqjB396B8cG4dBA=

+ 0 - 1
internal/database/main_test.go

@@ -8,7 +8,6 @@ import (
 
 	"gorm.io/gorm"
 	"gorm.io/gorm/logger"
-	_ "modernc.org/sqlite"
 	log "unknwon.dev/clog/v2"
 
 	"gogs.io/gogs/internal/conf"

+ 0 - 1
internal/database/migrations/main_test.go

@@ -7,7 +7,6 @@ import (
 	"testing"
 
 	"gorm.io/gorm/logger"
-	_ "modernc.org/sqlite"
 	log "unknwon.dev/clog/v2"
 
 	"gogs.io/gogs/internal/testutil"

+ 4 - 2
internal/database/schemadoc/main.go

@@ -8,11 +8,11 @@ import (
 	"strings"
 
 	"github.com/cockroachdb/errors"
+	"github.com/glebarez/sqlite"
 	"github.com/olekukonko/tablewriter"
 	"gopkg.in/DATA-DOG/go-sqlmock.v2"
 	"gorm.io/driver/mysql"
 	"gorm.io/driver/postgres"
-	"gorm.io/driver/sqlite"
 	"gorm.io/gorm"
 	"gorm.io/gorm/clause"
 	"gorm.io/gorm/schema"
@@ -65,11 +65,13 @@ func main() {
 		table.SetHeader([]string{"Field", "Column", "PostgreSQL", "MySQL", "SQLite3"})
 		table.SetBorder(false)
 		for j, f := range ti.Fields {
+			sqlite3Type := strings.ToUpper(collected[2][i].Fields[j].Type)
+			sqlite3Type = strings.ReplaceAll(sqlite3Type, "PRIMARY KEY ", "")
 			table.Append([]string{
 				f.Name, f.Column,
 				strings.ToUpper(f.Type),                         // PostgreSQL
 				strings.ToUpper(collected[1][i].Fields[j].Type), // MySQL
-				strings.ToUpper(collected[2][i].Fields[j].Type), // SQLite3
+				sqlite3Type,
 			})
 		}
 		table.Render()

+ 0 - 13
internal/dbtest/dbtest.go

@@ -96,19 +96,6 @@ func NewDB(t *testing.T, suite string, tables ...any) *gorm.DB {
 			_, _ = sqlDB.Exec(fmt.Sprintf(`DROP DATABASE %q`, dbName))
 			_ = sqlDB.Close()
 		}
-	case "sqlite":
-		dbName = filepath.Join(os.TempDir(), fmt.Sprintf("gogs-%s-%d.db", suite, time.Now().Unix()))
-		dbOpts = conf.DatabaseOpts{
-			Type: "sqlite",
-			Path: dbName,
-		}
-		cleanup = func(db *gorm.DB) {
-			sqlDB, err := db.DB()
-			if err == nil {
-				_ = sqlDB.Close()
-			}
-			_ = os.Remove(dbName)
-		}
 	default:
 		dbName = filepath.Join(os.TempDir(), fmt.Sprintf("gogs-%s-%d.db", suite, time.Now().Unix()))
 		dbOpts = conf.DatabaseOpts{

+ 2 - 5
internal/dbutil/dsn.go

@@ -5,9 +5,9 @@ import (
 	"strings"
 
 	"github.com/cockroachdb/errors"
+	"github.com/glebarez/sqlite"
 	"gorm.io/driver/mysql"
 	"gorm.io/driver/postgres"
-	"gorm.io/driver/sqlite"
 	"gorm.io/driver/sqlserver"
 	"gorm.io/gorm"
 
@@ -73,7 +73,7 @@ func NewDSN(opts conf.DatabaseOpts) (dsn string, err error) {
 		dsn = fmt.Sprintf("server=%s; port=%s; database=%s; user id=%s; password=%s;",
 			host, port, opts.Name, opts.User, opts.Password)
 
-	case "sqlite3", "sqlite":
+	case "sqlite3":
 		dsn = "file:" + opts.Path + "?cache=shared&mode=rwc"
 
 	default:
@@ -101,9 +101,6 @@ func OpenDB(opts conf.DatabaseOpts, cfg *gorm.Config) (*gorm.DB, error) {
 		dialector = sqlserver.Open(dsn)
 	case "sqlite3":
 		dialector = sqlite.Open(dsn)
-	case "sqlite":
-		dialector = sqlite.Open(dsn)
-		dialector.(*sqlite.Dialector).DriverName = "sqlite"
 	default:
 		panic("unreachable")
 	}