docs: Add CLAUDE.md with codebase guidance

Create comprehensive documentation for future Claude Code instances working in this repository, including:
- Development commands for testing, building, and code quality
- Core architecture overview of the SQL query builder system
- Directory structure and component explanations
- Testing patterns and conventions
- Key dependencies and their purposes

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-09-27 15:47:28 +08:00
co-authored by Claude
parent 764eccfafd
commit 304d553b3c
113 changed files with 914 additions and 432 deletions
+20 -10
View File
@@ -3,11 +3,11 @@ package mysql
import (
"strings"
"git.fsdpf.net/go/db/v2"
"git.fsdpf.net/go/db/v2/dialect/mysql"
"git.fsdpf.net/go/db/v2/internal/sb"
"git.fsdpf.net/go/db/v2/schema"
"git.fsdpf.net/go/db/v2/sqlgen"
"git.fsdpf.net/go/db"
"git.fsdpf.net/go/db/dialect/mysql"
"git.fsdpf.net/go/db/internal/sb"
"git.fsdpf.net/go/db/schema"
"git.fsdpf.net/go/db/sqlgen"
)
type Mysql struct {
@@ -16,6 +16,7 @@ type Mysql struct {
}
var mysqlDefaultModifiers = []string{
"Unsigned", "Charset", "Collate", "VirtualAs", "StoredAs",
"Nullable", "Default", "Increment", "Comment", "After", "First",
}
@@ -47,29 +48,33 @@ func (this Mysql) TableExists(table string) (bool, error) {
// 创建表
func (this Mysql) CompileCreate(bp *schema.Blueprint) []string {
temporary := db.L("CREATE")
if bp.IsTemporary() {
if bp.Temporary {
temporary = db.L("CREATE TEMPORARY")
}
columns := strings.Join(this.getAddedColumns(bp), ",\n")
sql := this.GenerateSQL("? TABLE ? (\n?\n)", temporary, db.T(bp.GetTable()), db.L(columns))
charset := bp.GetCharset()
charset := bp.Charset
if charset == "" {
charset = "utf8mb4"
}
collation := bp.GetCollation()
collation := bp.Collation
if collation == "" {
collation = "utf8mb4_general_ci"
}
sql += this.GenerateSQL(" default charset=? collate=?", charset, collation)
if engine := bp.GetEngine(); engine != "" {
if engine := bp.Engine; engine != "" {
sql += this.GenerateSQL(" engine=?", engine)
}
if comment := bp.Comment; comment != "" {
sql += this.GenerateSQL(" comment=?", comment)
}
return []string{sql}
}
@@ -121,13 +126,18 @@ func (this Mysql) CompileRename(bp *schema.Blueprint) []string {
if len(commands) == 0 {
panic("new table undefined")
}
toName = bp.GetCommands()[0].To
toName = commands[0].To
if toName == "" {
panic("new table undefined")
}
return []string{this.GenerateSQL("RENAME TABLE ? TO ?", db.T(bp.GetTable()), db.T(toName))}
}
// 修改表备注
func (this Mysql) CompileModifyComment(bp *schema.Blueprint) []string {
return []string{this.GenerateSQL("ALTER TABLE ? COMMENT = ?", db.T(bp.GetTable()), db.V(bp.Comment))}
}
func (this Mysql) addModifiers(sql string, bp *schema.Blueprint, column *schema.ColumnDefinition) string {
for _, modifier := range mysqlDefaultModifiers {
sql += this.GetColumnModifier(modifier, bp, column)
+4 -4
View File
@@ -3,9 +3,9 @@ package mysql_test
import (
"os"
"git.fsdpf.net/go/db/v2"
"git.fsdpf.net/go/db/v2/engine"
"git.fsdpf.net/go/db/v2/schema"
"git.fsdpf.net/go/db"
"git.fsdpf.net/go/db/engine"
"git.fsdpf.net/go/db/schema"
"github.com/stretchr/testify/suite"
)
@@ -40,7 +40,7 @@ func (t *mysqlBuilderTest) TestGetColumnListing() {
// 创建表
func (t *mysqlBuilderTest) TestCreateTable() {
if err := t.builder.Create("users", func(table *schema.Blueprint) {
table.Charset("utf8mb4")
table.Charset = "utf8mb4"
table.BigIncrements("id").Comment("ID")
table.Boolean("enabled").Default("1").Comment("是否有效")
+6 -4
View File
@@ -4,9 +4,9 @@ import (
"os"
"testing"
"git.fsdpf.net/go/db/v2"
"git.fsdpf.net/go/db/v2/engine"
"git.fsdpf.net/go/db/v2/schema"
"git.fsdpf.net/go/db"
"git.fsdpf.net/go/db/engine"
"git.fsdpf.net/go/db/schema"
"github.com/stretchr/testify/suite"
_ "github.com/go-sql-driver/mysql"
@@ -71,7 +71,7 @@ func (t *mysqlTest) TestTableExists() {
func (t *mysqlTest) TestCompileCreate() {
bp := schema.NewBlueprint("users")
bp.Create()
bp.Charset("utf8mb4")
bp.Charset = "utf8mb4"
bp.BigIncrements("id").AutoIncrement().Comment("ID")
bp.Boolean("enabled").Default("1").Comment("是否有效")
@@ -188,3 +188,5 @@ func (t *mysqlTest) TestCompileRename() {
t.T().Log(sql)
}
// 修改表备注
+11 -6
View File
@@ -3,11 +3,11 @@ package postgres
import (
"strings"
"git.fsdpf.net/go/db/v2"
"git.fsdpf.net/go/db/v2/dialect/postgres"
"git.fsdpf.net/go/db/v2/internal/sb"
"git.fsdpf.net/go/db/v2/schema"
"git.fsdpf.net/go/db/v2/sqlgen"
"git.fsdpf.net/go/db"
"git.fsdpf.net/go/db/dialect/postgres"
"git.fsdpf.net/go/db/internal/sb"
"git.fsdpf.net/go/db/schema"
"git.fsdpf.net/go/db/sqlgen"
)
type Postgres struct {
@@ -41,7 +41,7 @@ func (this Postgres) TableExists(table string) (bool, error) {
func (this Postgres) CompileCreate(bp *schema.Blueprint) []string {
temporary := db.L("CREATE")
if bp.IsTemporary() {
if bp.Temporary {
temporary = db.L("CREATE TEMPORARY")
}
columns := strings.Join(this.getAddedColumns(bp), ",\n")
@@ -96,6 +96,11 @@ func (this Postgres) CompileRename(bp *schema.Blueprint) []string {
return []string{this.GenerateSQL("ALTER TABLE ? RENAME TO ?", db.T(bp.GetTable()), db.T(toName))}
}
// 修改表备注
func (this Postgres) CompileModifyComment(bp *schema.Blueprint) []string {
return []string{this.GenerateSQL("COMMENT ON TABLE ? IS ?", db.T(bp.GetTable()), db.V(bp.Comment))}
}
func (this Postgres) addModifiers(sql string, bp *schema.Blueprint, column *schema.ColumnDefinition) string {
for _, modifier := range pgDefaultModifiers {
sql += this.GetColumnModifier(modifier, bp, column)
+2 -2
View File
@@ -4,8 +4,8 @@ import (
"os"
"testing"
"git.fsdpf.net/go/db/v2/engine"
"git.fsdpf.net/go/db/v2/schema"
"git.fsdpf.net/go/db/engine"
"git.fsdpf.net/go/db/schema"
"github.com/stretchr/testify/suite"
_ "github.com/lib/pq"
+18 -6
View File
@@ -5,11 +5,11 @@ import (
"strings"
"time"
"git.fsdpf.net/go/db/v2"
"git.fsdpf.net/go/db/v2/dialect/sqlite3"
"git.fsdpf.net/go/db/v2/internal/sb"
"git.fsdpf.net/go/db/v2/schema"
"git.fsdpf.net/go/db/v2/sqlgen"
"git.fsdpf.net/go/db"
"git.fsdpf.net/go/db/dialect/sqlite3"
"git.fsdpf.net/go/db/internal/sb"
"git.fsdpf.net/go/db/schema"
"git.fsdpf.net/go/db/sqlgen"
)
var (
@@ -72,8 +72,15 @@ func (this Sqlite3) CompileCreate(bp *schema.Blueprint) (sqls []string) {
}
columns = append(columns, sql)
}
prefix := "? TABLE ? (\n?\n)"
if comment := bp.Comment; comment != "" {
prefix = "? TABLE ? ( -- " + comment + "\n?\n)"
}
sqls = append(sqls,
this.GenerateSQL("? TABLE ? (\n?\n)",
this.GenerateSQL(prefix,
temporary,
db.T(bp.GetTable()),
db.L(strings.Join(columns, "\n")),
@@ -152,6 +159,11 @@ func (this Sqlite3) CompileRename(bp *schema.Blueprint) []string {
return []string{this.GenerateSQL("RENAME TABLE ? TO ?", db.T(bp.GetTable()), db.T(toName))}
}
// 修改表备注
func (this Sqlite3) CompileModifyComment(bp *schema.Blueprint) []string {
return []string{}
}
func (this Sqlite3) GetColumnModifier(modifier string, bp *schema.Blueprint, column *schema.ColumnDefinition) string {
switch modifier {
case "Collate":
+4 -4
View File
@@ -4,9 +4,9 @@ import (
"os"
"testing"
"git.fsdpf.net/go/db/v2"
"git.fsdpf.net/go/db/v2/engine"
"git.fsdpf.net/go/db/v2/schema"
"git.fsdpf.net/go/db"
"git.fsdpf.net/go/db/engine"
"git.fsdpf.net/go/db/schema"
"github.com/stretchr/testify/suite"
_ "github.com/mattn/go-sqlite3"
@@ -68,7 +68,7 @@ func (t *sqlite3Test) TestGetColumnListing() {
func (t *sqlite3Test) TestCompileCreate() {
bp := schema.NewBlueprint("users")
bp.Create()
bp.Charset("utf8mb4")
bp.Charset = "utf8mb4"
bp.BigIncrements("id").AutoIncrement().Comment("ID")
bp.Boolean("enabled").Default("1").Comment("是否有效")
+35 -6
View File
@@ -3,11 +3,11 @@ package sqlserver
import (
"strings"
"git.fsdpf.net/go/db/v2"
"git.fsdpf.net/go/db/v2/dialect/sqlserver"
"git.fsdpf.net/go/db/v2/internal/sb"
"git.fsdpf.net/go/db/v2/schema"
"git.fsdpf.net/go/db/v2/sqlgen"
"git.fsdpf.net/go/db"
"git.fsdpf.net/go/db/dialect/sqlserver"
"git.fsdpf.net/go/db/internal/sb"
"git.fsdpf.net/go/db/schema"
"git.fsdpf.net/go/db/sqlgen"
)
type SQLServer struct {
@@ -39,7 +39,7 @@ func (this SQLServer) TableExists(table string) (bool, error) {
func (this SQLServer) CompileCreate(bp *schema.Blueprint) []string {
temporary := db.L("CREATE")
if bp.IsTemporary() {
if bp.Temporary {
temporary = db.L("CREATE")
}
columns := strings.Join(this.getAddedColumns(bp), ",\n")
@@ -94,6 +94,35 @@ func (this SQLServer) CompileRename(bp *schema.Blueprint) []string {
return []string{this.GenerateSQL("EXEC sp_rename ?, ?", db.T(bp.GetTable()), db.T(toName))}
}
// 修改表备注
func (this SQLServer) CompileModifyComment(bp *schema.Blueprint) []string {
return []string{
this.GenerateSQL(`
IF EXISTS (
SELECT 1 FROM sys.extended_properties
WHERE major_id = OBJECT_ID(?)
AND name = 'MS_Description'
AND minor_id = 0
)
BEGIN
EXEC sp_updateextendedproperty
@name = N'MS_Description',
@value = ?,
@level0type = N'SCHEMA', @level0name = 'dbo',
@level1type = N'TABLE', @level1name = ?
END
ELSE
BEGIN
EXEC sp_addextendedproperty
@name = N'MS_Description',
@value = ?,
@level0type = N'SCHEMA', @level0name = 'dbo',
@level1type = N'TABLE', @level1name = ?
END
`, db.T(bp.GetTable()), db.V(bp.Comment), db.T(bp.GetTable()), db.V(bp.Comment), db.T(bp.GetTable())),
}
}
func (this SQLServer) addModifiers(sql string, bp *schema.Blueprint, column *schema.ColumnDefinition) string {
for _, modifier := range sqlServerDefaultModifiers {
sql += this.GetColumnModifier(modifier, bp, column)
+2 -2
View File
@@ -4,8 +4,8 @@ import (
"os"
"testing"
"git.fsdpf.net/go/db/v2/engine"
"git.fsdpf.net/go/db/v2/schema"
"git.fsdpf.net/go/db/engine"
"git.fsdpf.net/go/db/schema"
"github.com/stretchr/testify/suite"
_ "github.com/denisenkom/go-mssqldb"