Fork github.com/mattn/go-sqlite3 with adjustment for go1.16.2
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

231 lines
4.5 KiB

  1. //go:build !cgo && upgrade && ignore
  2. // +build !cgo,upgrade,ignore
  3. package main
  4. import (
  5. "archive/zip"
  6. "bufio"
  7. "bytes"
  8. "fmt"
  9. "io"
  10. "io/ioutil"
  11. "log"
  12. "net/http"
  13. "os"
  14. "path"
  15. "path/filepath"
  16. "strings"
  17. "time"
  18. "github.com/PuerkitoBio/goquery"
  19. )
  20. func download(prefix string) (url string, content []byte, err error) {
  21. year := time.Now().Year()
  22. site := "https://www.sqlite.org/download.html"
  23. //fmt.Printf("scraping %v\n", site)
  24. doc, err := goquery.NewDocument(site)
  25. if err != nil {
  26. log.Fatal(err)
  27. }
  28. doc.Find("a").Each(func(_ int, s *goquery.Selection) {
  29. if strings.HasPrefix(s.Text(), prefix) {
  30. url = fmt.Sprintf("https://www.sqlite.org/%d/", year) + s.Text()
  31. }
  32. })
  33. if url == "" {
  34. return "", nil, fmt.Errorf("Unable to find prefix '%s' on sqlite.org", prefix)
  35. }
  36. fmt.Printf("Downloading %v\n", url)
  37. resp, err := http.Get(url)
  38. if err != nil {
  39. log.Fatal(err)
  40. }
  41. // Ready Body Content
  42. content, err = ioutil.ReadAll(resp.Body)
  43. defer resp.Body.Close()
  44. if err != nil {
  45. return "", nil, err
  46. }
  47. return url, content, nil
  48. }
  49. func mergeFile(src string, dst string) error {
  50. defer func() error {
  51. fmt.Printf("Removing: %s\n", src)
  52. err := os.Remove(src)
  53. if err != nil {
  54. return err
  55. }
  56. return nil
  57. }()
  58. // Open destination
  59. fdst, err := os.OpenFile(dst, os.O_APPEND|os.O_WRONLY, 0666)
  60. if err != nil {
  61. return err
  62. }
  63. defer fdst.Close()
  64. // Read source content
  65. content, err := ioutil.ReadFile(src)
  66. if err != nil {
  67. return err
  68. }
  69. // Add Additional newline
  70. if _, err := fdst.WriteString("\n"); err != nil {
  71. return err
  72. }
  73. fmt.Printf("Merging: %s into %s\n", src, dst)
  74. if _, err = fdst.Write(content); err != nil {
  75. return err
  76. }
  77. return nil
  78. }
  79. func main() {
  80. fmt.Println("Go-SQLite3 Upgrade Tool")
  81. wd, err := os.Getwd()
  82. if err != nil {
  83. log.Fatal(err)
  84. }
  85. if filepath.Base(wd) != "upgrade" {
  86. log.Printf("Current directory is %q but should run in upgrade directory", wd)
  87. os.Exit(1)
  88. }
  89. // Download Amalgamation
  90. _, amalgamation, err := download("sqlite-amalgamation-")
  91. if err != nil {
  92. log.Fatalf("Failed to download: sqlite-amalgamation; %s", err)
  93. }
  94. // Download Source
  95. _, source, err := download("sqlite-src-")
  96. if err != nil {
  97. log.Fatalf("Failed to download: sqlite-src; %s", err)
  98. }
  99. // Create Amalgamation Zip Reader
  100. rAmalgamation, err := zip.NewReader(bytes.NewReader(amalgamation), int64(len(amalgamation)))
  101. if err != nil {
  102. log.Fatal(err)
  103. }
  104. // Create Source Zip Reader
  105. rSource, err := zip.NewReader(bytes.NewReader(source), int64(len(source)))
  106. if err != nil {
  107. log.Fatal(err)
  108. }
  109. // Extract Amalgamation
  110. for _, zf := range rAmalgamation.File {
  111. var f *os.File
  112. switch path.Base(zf.Name) {
  113. case "sqlite3.c":
  114. f, err = os.Create("../sqlite3-binding.c")
  115. case "sqlite3.h":
  116. f, err = os.Create("../sqlite3-binding.h")
  117. case "sqlite3ext.h":
  118. f, err = os.Create("../sqlite3ext.h")
  119. default:
  120. continue
  121. }
  122. if err != nil {
  123. log.Fatal(err)
  124. }
  125. zr, err := zf.Open()
  126. if err != nil {
  127. log.Fatal(err)
  128. }
  129. _, err = io.WriteString(f, "#ifndef USE_LIBSQLITE3\n")
  130. if err != nil {
  131. zr.Close()
  132. f.Close()
  133. log.Fatal(err)
  134. }
  135. scanner := bufio.NewScanner(zr)
  136. for scanner.Scan() {
  137. text := scanner.Text()
  138. if text == `#include "sqlite3.h"` {
  139. text = `#include "sqlite3-binding.h"
  140. #ifdef __clang__
  141. #define assert(condition) ((void)0)
  142. #endif
  143. `
  144. }
  145. _, err = fmt.Fprintln(f, text)
  146. if err != nil {
  147. break
  148. }
  149. }
  150. err = scanner.Err()
  151. if err != nil {
  152. zr.Close()
  153. f.Close()
  154. log.Fatal(err)
  155. }
  156. _, err = io.WriteString(f, "#else // USE_LIBSQLITE3\n // If users really want to link against the system sqlite3 we\n// need to make this file a noop.\n #endif")
  157. if err != nil {
  158. zr.Close()
  159. f.Close()
  160. log.Fatal(err)
  161. }
  162. zr.Close()
  163. f.Close()
  164. fmt.Printf("Extracted: %v\n", filepath.Base(f.Name()))
  165. }
  166. //Extract Source
  167. for _, zf := range rSource.File {
  168. var f *os.File
  169. switch path.Base(zf.Name) {
  170. case "userauth.c":
  171. f, err = os.Create("../userauth.c")
  172. case "sqlite3userauth.h":
  173. f, err = os.Create("../userauth.h")
  174. default:
  175. continue
  176. }
  177. if err != nil {
  178. log.Fatal(err)
  179. }
  180. zr, err := zf.Open()
  181. if err != nil {
  182. log.Fatal(err)
  183. }
  184. _, err = io.Copy(f, zr)
  185. if err != nil {
  186. log.Fatal(err)
  187. }
  188. zr.Close()
  189. f.Close()
  190. fmt.Printf("extracted %v\n", filepath.Base(f.Name()))
  191. }
  192. // Merge SQLite User Authentication into amalgamation
  193. if err := mergeFile("../userauth.c", "../sqlite3-binding.c"); err != nil {
  194. log.Fatal(err)
  195. }
  196. if err := mergeFile("../userauth.h", "../sqlite3-binding.h"); err != nil {
  197. log.Fatal(err)
  198. }
  199. os.Exit(0)
  200. }