|
1 |
| -//go:build prql |
2 |
| - |
3 | 1 | package prql
|
4 | 2 |
|
5 |
| -// #cgo CFLAGS: -I. |
6 |
| -// #cgo darwin,arm64 LDFLAGS: -L${SRCDIR} -lprqlc-aarch64-apple-darwin |
7 |
| -// #cgo darwin,amd64 LDFLAGS: -L${SRCDIR} -lprqlc-x86_64-apple-darwin |
8 |
| -// #cgo linux,arm64 LDFLAGS: -L${SRCDIR} -lprqlc-aarch64-unknown-linux-musl |
9 |
| -// #cgo linux,amd64 LDFLAGS: -L${SRCDIR} -lprqlc-x86_64-unknown-linux-musl -lm |
10 |
| -// #cgo windows,amd64 LDFLAGS: -L${SRCDIR} -lprqlc-x86_64-pc-windows-gnu -lws2_32 -luserenv -lntdll |
11 |
| -/*#include <stdlib.h> |
12 |
| -#include "prqlc.h" |
13 |
| -
|
14 |
| -Options global_options = { |
15 |
| - false, // Remove the pretty print |
16 |
| - "sql.sqlite", // The dialect to use |
17 |
| - false // Remove the trailing comments |
18 |
| -}; |
19 |
| -
|
20 |
| -CompileResult to_sql(char *prql_query) { |
21 |
| - return compile(prql_query, &global_options); |
22 |
| -} |
23 |
| -
|
24 |
| -*/ |
25 |
| -import "C" |
26 |
| - |
27 | 3 | import (
|
28 |
| - "unsafe" |
| 4 | + "fmt" |
| 5 | + "os/exec" |
| 6 | + "strings" |
29 | 7 | )
|
30 | 8 |
|
| 9 | +// Calls the prqlc CLI to compile the PRQL query to SQL |
31 | 10 | func ToSQL(prqlQuery string) (string, []CompileMessage) {
|
32 |
| - res := C.to_sql(C.CString(prqlQuery)) |
33 |
| - a := res.messages |
34 |
| - if res.messages_len > 0 { |
35 |
| - messages := make([]CompileMessage, res.messages_len) |
36 |
| - // Convert the messages |
37 |
| - for i := 0; i < int(res.messages_len); i++ { |
38 |
| - message := (*C.struct_Message)(unsafe.Pointer(uintptr(unsafe.Pointer(a)) + uintptr(i)*unsafe.Sizeof(*res.messages))) |
39 |
| - compileMessage := CompileMessage{} |
40 |
| - if message.code != nil && *message.code != nil { |
41 |
| - compileMessage.ErrorCode = rune(**message.code) |
42 |
| - } |
43 |
| - |
44 |
| - if message.display != nil && *message.display != nil { |
45 |
| - compileMessage.Display = C.GoString(*message.display) |
46 |
| - } |
47 |
| - |
48 |
| - if message.location != nil { |
49 |
| - compileMessage.LocationError.StartLine = int(message.location.start_line) |
50 |
| - compileMessage.LocationError.StartColumn = int(message.location.start_col) |
51 |
| - compileMessage.LocationError.EndLine = int(message.location.end_line) |
52 |
| - compileMessage.LocationError.EndColumn = int(message.location.end_col) |
53 |
| - } |
54 |
| - |
55 |
| - messages[i] = compileMessage |
56 |
| - |
57 |
| - } |
| 11 | + _, err := exec.LookPath("prqlc") |
| 12 | + if err != nil { |
| 13 | + return "", []CompileMessage{{ |
| 14 | + ErrorCode: 'E', |
| 15 | + Display: "prqlc not found in PATH.\nMake sure it is installed: https://prql-lang.org/book/project/integrations/prqlc-cli.html#installation", |
| 16 | + }} |
| 17 | + } |
58 | 18 |
|
59 |
| - return "", messages |
| 19 | + // prqlc compile --target sql.sqlite" |
| 20 | + cmd := exec.Command("prqlc") |
| 21 | + cmd.Args = append(cmd.Args, "compile", "--target", "sql.sqlite") |
| 22 | + cmd.Stdin = strings.NewReader(prqlQuery) |
| 23 | + out, err := cmd.CombinedOutput() |
| 24 | + if err != nil { |
| 25 | + return "", []CompileMessage{{ |
| 26 | + ErrorCode: 'E', |
| 27 | + Display: fmt.Sprintf("prqlc failed with error %s: %s", err, string(out)), |
| 28 | + }} |
60 | 29 | }
|
61 |
| - return C.GoString(res.output), nil |
| 30 | + |
| 31 | + return string(out), nil |
62 | 32 | }
|
0 commit comments