gen_sqlc_docker.sh
1 #!/bin/bash 2 3 set -e 4 5 SQLC_VERSION="1.29.0" 6 7 # restore_files is a function to restore original schema files. 8 restore_files() { 9 echo "Restoring SQLite bigint patch..." 10 for file in sqldb/sqlc/migrations/*.up.sql.bak; do 11 mv "$file" "${file%.bak}" 12 done 13 } 14 15 16 # Set trap to call restore_files on script exit. This makes sure the old files 17 # are always restored. 18 trap restore_files EXIT 19 20 # Directory of the script file, independent of where it's called from. 21 DIR="$(cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd)" 22 # Use the user's cache directories 23 GOCACHE=`go env GOCACHE` 24 GOMODCACHE=`go env GOMODCACHE` 25 26 # SQLite doesn't support "BIGINT PRIMARY KEY" for auto-incrementing primary 27 # keys, only "INTEGER PRIMARY KEY". Internally it uses 64-bit integers for 28 # numbers anyway, independent of the column type. So we can just use 29 # "INTEGER PRIMARY KEY" and it will work the same under the hood, giving us 30 # auto incrementing 64-bit integers. 31 # _BUT_, sqlc will generate Go code with int32 if we use "INTEGER PRIMARY KEY", 32 # even though we want int64. So before we run sqlc, we need to patch the 33 # source schema SQL files to use "BIGINT PRIMARY KEY" instead of "INTEGER 34 # PRIMARY KEY". 35 echo "Applying SQLite bigint patch..." 36 for file in sqldb/sqlc/migrations/*.up.sql; do 37 echo "Patching $file" 38 sed -i.bak -E 's/INTEGER PRIMARY KEY/BIGINT PRIMARY KEY/g' "$file" 39 done 40 41 echo "Generating sql models and queries in go..." 42 43 docker run \ 44 --rm \ 45 --user "$UID:$(id -g)" \ 46 -e UID=$UID \ 47 -v "$DIR/../:/build" \ 48 -w /build \ 49 "sqlc/sqlc:${SQLC_VERSION}" generate 50 51 # Because we're using the Postgres dialect of sqlc, we can't use sqlc.slice() 52 # normally, because sqlc just thinks it can pass the Golang slice directly to 53 # the database driver. So it doesn't put the /*SLICE:<field_name>*/ workaround 54 # comment into the actual SQL query. But we add the comment ourselves and now 55 # just need to replace the '$X/*SLICE:<field_name>*/' placeholders with the 56 # actual placeholder that's going to be replaced by the sqlc generated code. 57 echo "Applying sqlc.slice() workaround..." 58 for file in sqldb/sqlc/*.sql.go; do 59 echo "Patching $file" 60 61 # First, we replace the `$X/*SLICE:<field_name>*/` placeholders with 62 # the actual placeholder that sqlc will use: `/*SLICE:<field_name>*/?`. 63 sed -i.bak -E 's/\$([0-9]+)\/\*SLICE:([a-zA-Z_][a-zA-Z0-9_]*)\*\//\/\*SLICE:\2\*\/\?/g' "$file" 64 65 # Then, we replace the `strings.Repeat(",?", len(arg.<golang_name>))[1:]` with 66 # a function call that generates the correct number of placeholders: 67 # `makeQueryParams(len(queryParams), len(arg.<golang_name>))`. 68 sed -i.bak -E 's/strings\.Repeat\(",\?", len\(([^)]+)\)\)\[1:\]/makeQueryParams(len(queryParams), len(\1))/g' "$file" 69 70 rm "$file.bak" 71 done