mirror of
				https://github.com/superseriousbusiness/gotosocial.git
				synced 2025-11-04 09:12:24 -06:00 
			
		
		
		
	This allows for building GoToSocial with [SQLite transpiled to WASM](https://github.com/ncruces/go-sqlite3) and accessed through [Wazero](https://wazero.io/).
		
			
				
	
	
		
			112 lines
		
	
	
	
		
			1.9 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			112 lines
		
	
	
	
		
			1.9 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
package sqlite3
 | 
						|
 | 
						|
import (
 | 
						|
	"bytes"
 | 
						|
	"math"
 | 
						|
	"strconv"
 | 
						|
	"strings"
 | 
						|
	"time"
 | 
						|
	"unsafe"
 | 
						|
 | 
						|
	"github.com/ncruces/go-sqlite3/internal/util"
 | 
						|
)
 | 
						|
 | 
						|
// Quote escapes and quotes a value
 | 
						|
// making it safe to embed in SQL text.
 | 
						|
func Quote(value any) string {
 | 
						|
	switch v := value.(type) {
 | 
						|
	case nil:
 | 
						|
		return "NULL"
 | 
						|
	case bool:
 | 
						|
		if v {
 | 
						|
			return "1"
 | 
						|
		} else {
 | 
						|
			return "0"
 | 
						|
		}
 | 
						|
 | 
						|
	case int:
 | 
						|
		return strconv.Itoa(v)
 | 
						|
	case int64:
 | 
						|
		return strconv.FormatInt(v, 10)
 | 
						|
	case float64:
 | 
						|
		switch {
 | 
						|
		case math.IsNaN(v):
 | 
						|
			return "NULL"
 | 
						|
		case math.IsInf(v, 1):
 | 
						|
			return "9.0e999"
 | 
						|
		case math.IsInf(v, -1):
 | 
						|
			return "-9.0e999"
 | 
						|
		}
 | 
						|
		return strconv.FormatFloat(v, 'g', -1, 64)
 | 
						|
	case time.Time:
 | 
						|
		return "'" + v.Format(time.RFC3339Nano) + "'"
 | 
						|
 | 
						|
	case string:
 | 
						|
		if strings.IndexByte(v, 0) >= 0 {
 | 
						|
			break
 | 
						|
		}
 | 
						|
 | 
						|
		buf := make([]byte, 2+len(v)+strings.Count(v, "'"))
 | 
						|
		buf[0] = '\''
 | 
						|
		i := 1
 | 
						|
		for _, b := range []byte(v) {
 | 
						|
			if b == '\'' {
 | 
						|
				buf[i] = b
 | 
						|
				i += 1
 | 
						|
			}
 | 
						|
			buf[i] = b
 | 
						|
			i += 1
 | 
						|
		}
 | 
						|
		buf[i] = '\''
 | 
						|
		return unsafe.String(&buf[0], len(buf))
 | 
						|
 | 
						|
	case []byte:
 | 
						|
		buf := make([]byte, 3+2*len(v))
 | 
						|
		buf[0] = 'x'
 | 
						|
		buf[1] = '\''
 | 
						|
		i := 2
 | 
						|
		for _, b := range v {
 | 
						|
			const hex = "0123456789ABCDEF"
 | 
						|
			buf[i+0] = hex[b/16]
 | 
						|
			buf[i+1] = hex[b%16]
 | 
						|
			i += 2
 | 
						|
		}
 | 
						|
		buf[i] = '\''
 | 
						|
		return unsafe.String(&buf[0], len(buf))
 | 
						|
 | 
						|
	case ZeroBlob:
 | 
						|
		if v > ZeroBlob(1e9-3)/2 {
 | 
						|
			break
 | 
						|
		}
 | 
						|
 | 
						|
		buf := bytes.Repeat([]byte("0"), int(3+2*int64(v)))
 | 
						|
		buf[0] = 'x'
 | 
						|
		buf[1] = '\''
 | 
						|
		buf[len(buf)-1] = '\''
 | 
						|
		return unsafe.String(&buf[0], len(buf))
 | 
						|
	}
 | 
						|
 | 
						|
	panic(util.ValueErr)
 | 
						|
}
 | 
						|
 | 
						|
// QuoteIdentifier escapes and quotes an identifier
 | 
						|
// making it safe to embed in SQL text.
 | 
						|
func QuoteIdentifier(id string) string {
 | 
						|
	if strings.IndexByte(id, 0) >= 0 {
 | 
						|
		panic(util.ValueErr)
 | 
						|
	}
 | 
						|
 | 
						|
	buf := make([]byte, 2+len(id)+strings.Count(id, `"`))
 | 
						|
	buf[0] = '"'
 | 
						|
	i := 1
 | 
						|
	for _, b := range []byte(id) {
 | 
						|
		if b == '"' {
 | 
						|
			buf[i] = b
 | 
						|
			i += 1
 | 
						|
		}
 | 
						|
		buf[i] = b
 | 
						|
		i += 1
 | 
						|
	}
 | 
						|
	buf[i] = '"'
 | 
						|
	return unsafe.String(&buf[0], len(buf))
 | 
						|
}
 |