Skip to content

Commit 26a39ca

Browse files
authored
Merge pull request #27 from sqlrsync/v0.0.6
V0.0.6
2 parents ecf39e5 + e82aceb commit 26a39ca

File tree

13 files changed

+3748
-81
lines changed

13 files changed

+3748
-81
lines changed

bridge/cgo_sqldiff.go

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
package bridge
2+
3+
/*
4+
#cgo CFLAGS: -I${SRCDIR}
5+
#cgo LDFLAGS: -lsqlite3
6+
7+
#include <stdlib.h>
8+
#include <string.h>
9+
#include "sqldiff_wrapper.h"
10+
*/
11+
import "C"
12+
import (
13+
"fmt"
14+
"unsafe"
15+
)
16+
17+
// DiffResult contains the result of a diff operation
18+
type DiffResult struct {
19+
SQL string // SQL statements to transform db1 to db2
20+
HasChanges bool // Whether there are any differences
21+
Operations []DiffOperation // Parsed operations from the diff
22+
Conflicts []PrimaryKeyConflict // Detected primary key conflicts
23+
}
24+
25+
// DiffOperation represents a single SQL operation from the diff
26+
type DiffOperation struct {
27+
Type string // INSERT, UPDATE, DELETE
28+
Table string // Table name
29+
PrimaryKey map[string]interface{} // Primary key values
30+
SQL string // The actual SQL statement
31+
}
32+
33+
// PrimaryKeyConflict represents a conflict on the same primary key
34+
type PrimaryKeyConflict struct {
35+
Table string
36+
PrimaryKey map[string]interface{}
37+
Operation1 string // First operation (from db1)
38+
Operation2 string // Second operation (from db2)
39+
}
40+
41+
// RunSQLDiff compares two SQLite databases and returns the differences
42+
// db1Path: path to first database (baseline/old version)
43+
// db2Path: path to second database (new version with changes)
44+
// Returns SQL statements that would transform db1 into db2
45+
func RunSQLDiff(db1Path, db2Path string) (*DiffResult, error) {
46+
cDb1 := C.CString(db1Path)
47+
cDb2 := C.CString(db2Path)
48+
defer C.free(unsafe.Pointer(cDb1))
49+
defer C.free(unsafe.Pointer(cDb2))
50+
51+
var cResult *C.char
52+
var cError *C.char
53+
54+
// Call the C wrapper function
55+
rc := C.sqldiff_run(cDb1, cDb2, &cResult, &cError)
56+
57+
if rc != 0 {
58+
if cError != nil {
59+
errMsg := C.GoString(cError)
60+
C.free(unsafe.Pointer(cError))
61+
return nil, fmt.Errorf("sqldiff failed: %s", errMsg)
62+
}
63+
return nil, fmt.Errorf("sqldiff failed with code %d", rc)
64+
}
65+
66+
result := &DiffResult{
67+
HasChanges: false,
68+
Operations: []DiffOperation{},
69+
Conflicts: []PrimaryKeyConflict{},
70+
}
71+
72+
if cResult != nil {
73+
result.SQL = C.GoString(cResult)
74+
result.HasChanges = len(result.SQL) > 0
75+
C.free(unsafe.Pointer(cResult))
76+
77+
// Parse the SQL to extract operations
78+
result.Operations = parseSQL(result.SQL)
79+
80+
// Detect primary key conflicts
81+
result.Conflicts = detectConflicts(result.Operations)
82+
}
83+
84+
return result, nil
85+
}
86+
87+
// parseSQL parses SQL diff output into individual operations
88+
func parseSQL(sql string) []DiffOperation {
89+
// TODO: Implement SQL parsing
90+
// For now, return empty slice
91+
// This would parse INSERT, UPDATE, DELETE statements
92+
// and extract table names and primary keys
93+
return []DiffOperation{}
94+
}
95+
96+
// detectConflicts finds operations that conflict on the same primary key
97+
func detectConflicts(operations []DiffOperation) []PrimaryKeyConflict {
98+
// TODO: Implement conflict detection
99+
// This would find cases where:
100+
// - Same PK has multiple UPDATE/DELETE operations
101+
// - INSERT on existing PK
102+
// etc.
103+
return []PrimaryKeyConflict{}
104+
}
105+
106+
// ApplyDiff applies a diff to a database
107+
// This executes the SQL statements from a DiffResult
108+
func ApplyDiff(dbPath string, diff *DiffResult) error {
109+
if !diff.HasChanges {
110+
return nil // Nothing to apply
111+
}
112+
113+
if len(diff.Conflicts) > 0 {
114+
return fmt.Errorf("cannot apply diff with %d conflicts", len(diff.Conflicts))
115+
}
116+
117+
// TODO: Open database and execute SQL
118+
// For now, we'll need to implement this using the bridge
119+
return fmt.Errorf("ApplyDiff not yet implemented")
120+
}

0 commit comments

Comments
 (0)