Add Initial content.

This commit is contained in:
Jan Mercl
2017-04-21 01:17:29 +02:00
commit ed3807ab47
14 changed files with 3243 additions and 0 deletions

11
AUTHORS Normal file
View File

@@ -0,0 +1,11 @@
# This file lists authors for copyright purposes. This file is distinct from
# the CONTRIBUTORS files. See the latter for an explanation.
#
# Names should be added to this file as:
# Name or Organization <email address>
#
# The email address is not required for organizations.
#
# Please keep the list sorted.
Jan Mercl <0xjnml@gmail.com>

9
CONTRIBUTORS Normal file
View File

@@ -0,0 +1,9 @@
# This file lists people who contributed code to this repository. The AUTHORS
# file lists the copyright holders; this file lists people.
#
# Names should be added to this file like so:
# Name <email address>
#
# Please keep the list sorted.
Jan Mercl <0xjnml@gmail.com>

27
LICENSE Normal file
View File

@@ -0,0 +1,27 @@
Copyright (c) 2017 The Sqlite Authors. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the
distribution.
* Neither the names of the authors nor the names of the
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

58
Makefile Normal file
View File

@@ -0,0 +1,58 @@
# Copyright 2017 The Sqlite Authors. All rights reserved.
# Use of this source code is governed by a BSD-style
# license that can be found in the LICENSE file.
.PHONY: all clean cover cpu editor internalError later mem nuke todo edit
grep=--include=*.go --include=*.l --include=*.y --include=*.yy
ngrep='TODOOK\|parser\.go\|scanner\.go\|.*_string\.go'
all: editor
go vet 2>&1 | grep -v $(ngrep) || true
golint 2>&1 | grep -v $(ngrep) || true
make todo
unused . || true
misspell *.go
gosimple || true
maligned || true
unconvert -apply
clean:
go clean
rm -f *~ *.test *.out
cover:
t=$(shell tempfile) ; go test -coverprofile $$t && go tool cover -html $$t && unlink $$t
cpu: clean
go test -run @ -bench . -cpuprofile cpu.out
go tool pprof -lines *.test cpu.out
edit:
@ 1>/dev/null 2>/dev/null gvim -p Makefile main.c all_test.go sqlite.go
editor:
gofmt -l -s -w *.go
indent -linux *.c
go test 2>&1 | tee log
go build
internalError:
egrep -ho '"internal error.*"' *.go | sort | cat -n
later:
@grep -n $(grep) LATER * || true
@grep -n $(grep) MAYBE * || true
mem: clean
go test -run @ -bench . -memprofile mem.out -memprofilerate 1 -timeout 24h
go tool pprof -lines -web -alloc_space *.test mem.out
nuke: clean
go clean -i
todo:
@grep -nr $(grep) ^[[:space:]]*_[[:space:]]*=[[:space:]][[:alpha:]][[:alnum:]]* * | grep -v $(ngrep) || true
@grep -nr $(grep) TODO * | grep -v $(ngrep) || true
@grep -nr $(grep) BUG * | grep -v $(ngrep) || true
@grep -nr $(grep) [^[:alpha:]]println * | grep -v $(ngrep) || true

9
README.md Normal file
View File

@@ -0,0 +1,9 @@
# sqlite
Package sqlite is an in-process implementation of a self-contained, serverless, zero-configuration, transactional SQL database engine. (Work In Progress)
Installation
$ go get github.com/cznic/sqlite
Documentation: [godoc.org/github.com/cznic/sqlite](http://godoc.org/github.com/cznic/sqlite)

25
SQLITE-LICENSE Normal file
View File

@@ -0,0 +1,25 @@
SQLite Is Public Domain
All of the code and documentation in SQLite has been dedicated to the public
domain by the authors. All code authors, and representatives of the companies
they work for, have signed affidavits dedicating their contributions to the
public domain and originals of those signed affidavits are stored in a firesafe
at the main offices of Hwaci. Anyone is free to copy, modify, publish, use,
compile, sell, or distribute the original SQLite code, either in source code
form or as a compiled binary, for any purpose, commercial or non-commercial,
and by any means.
The previous paragraph applies to the deliverable code and documentation in
SQLite - those parts of the SQLite library that you actually bundle and ship
with a larger application. Some scripts used as part of the build process (for
example the "configure" scripts generated by autoconf) might fall under other
open-source licenses. Nothing from these build scripts ever reaches the final
deliverable SQLite library, however, and so the licenses associated with those
scripts should not be a factor in assessing your rights to copy and use the
SQLite library.
All of the deliverable code in SQLite has been written from scratch. No code
has been taken from other projects or from the open internet. Every line of
code can be traced back to its original author, and all of those authors have
public domain dedications on file. So the SQLite code base is clean and is
uncontaminated with licensed code from other projects.

190
all_test.go Normal file
View File

@@ -0,0 +1,190 @@
// Copyright 2017 The Sqlite Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package sqlite
import (
"bytes"
"database/sql"
"fmt"
"io/ioutil"
"os"
"path"
"path/filepath"
"runtime"
"strings"
"testing"
"time"
)
func caller(s string, va ...interface{}) {
if s == "" {
s = strings.Repeat("%v ", len(va))
}
_, fn, fl, _ := runtime.Caller(2)
fmt.Fprintf(os.Stderr, "# caller: %s:%d: ", path.Base(fn), fl)
fmt.Fprintf(os.Stderr, s, va...)
fmt.Fprintln(os.Stderr)
_, fn, fl, _ = runtime.Caller(1)
fmt.Fprintf(os.Stderr, "# \tcallee: %s:%d: ", path.Base(fn), fl)
fmt.Fprintln(os.Stderr)
os.Stderr.Sync()
}
func dbg(s string, va ...interface{}) {
if s == "" {
s = strings.Repeat("%v ", len(va))
}
_, fn, fl, _ := runtime.Caller(1)
fmt.Fprintf(os.Stderr, "# dbg %s:%d: ", path.Base(fn), fl)
fmt.Fprintf(os.Stderr, s, va...)
fmt.Fprintln(os.Stderr)
os.Stderr.Sync()
}
func TODO(...interface{}) string { //TODOOK
_, fn, fl, _ := runtime.Caller(1)
return fmt.Sprintf("# TODO: %s:%d:\n", path.Base(fn), fl) //TODOOK
}
func use(...interface{}) {}
func init() {
use(caller, dbg, TODO) //TODOOK
}
// ============================================================================
func tempDB(t *testing.T) (string, *sql.DB) {
dir, err := ioutil.TempDir("", "sqlite-test-")
if err != nil {
t.Fatal(err)
}
db, err := sql.Open(driverName, filepath.Join(dir, "tmp.db"))
if err != nil {
os.RemoveAll(dir)
t.Fatal(err)
}
return dir, db
}
func TestScalar(t *testing.T) {
dir, db := tempDB(t)
defer func() {
db.Close()
os.RemoveAll(dir)
}()
t1 := time.Date(2017, 4, 20, 1, 2, 3, 56789, time.UTC)
t2 := time.Date(2018, 5, 21, 2, 3, 4, 98765, time.UTC)
r, err := db.Exec(`
create table t(i int, f double, b bool, s text, t time);
insert into t values(12, 3.14, ?, "foo", ?), (34, 2.78, ?, "bar", ?);
`,
true, t1,
false, t2,
)
if err != nil {
t.Fatal(err)
}
n, err := r.RowsAffected()
if err != nil {
t.Fatal(err)
}
if g, e := n, int64(2); g != e {
t.Fatal(g, e)
}
rows, err := db.Query("select * from t")
if err != nil {
t.Fatal(err)
}
type rec struct {
i int
f float64
b bool
s string
t string
}
var a []rec
for rows.Next() {
var r rec
if err := rows.Scan(&r.i, &r.f, &r.b, &r.s, &r.t); err != nil {
t.Fatal(err)
}
a = append(a, r)
}
if err := rows.Err(); err != nil {
t.Fatal(err)
}
if g, e := len(a), 2; g != e {
t.Fatal(g, e)
}
if g, e := a[0], (rec{12, 3.14, true, "foo", t1.String()}); g != e {
t.Fatal(g, e)
}
if g, e := a[1], (rec{34, 2.78, false, "bar", t2.String()}); g != e {
t.Fatal(g, e)
}
}
func TestBlob(t *testing.T) {
dir, db := tempDB(t)
defer func() {
db.Close()
os.RemoveAll(dir)
}()
b1 := []byte(time.Now().String())
b2 := []byte("\x00foo\x00bar\x00")
if _, err := db.Exec(`
create table t(b blob);
insert into t values(?), (?);
`, b1, b2,
); err != nil {
t.Fatal(err)
}
rows, err := db.Query("select * from t")
if err != nil {
t.Fatal(err)
}
type rec struct {
b []byte
}
var a []rec
for rows.Next() {
var r rec
if err := rows.Scan(&r.b); err != nil {
t.Fatal(err)
}
a = append(a, r)
}
if err := rows.Err(); err != nil {
t.Fatal(err)
}
if g, e := len(a), 2; g != e {
t.Fatal(g, e)
}
if g, e := a[0].b, b1; !bytes.Equal(g, e) {
t.Fatal(g, e)
}
if g, e := a[1].b, b2; !bytes.Equal(g, e) {
t.Fatal(g, e)
}
}

364
generator.go Normal file
View File

@@ -0,0 +1,364 @@
// Copyright 2017 The Sqlite Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build ignore
package main
import (
"bytes"
"compress/gzip"
"encoding/gob"
"flag"
"fmt"
"go/format"
"go/scanner"
"go/token"
"io"
"io/ioutil"
"os"
"path/filepath"
"runtime"
"sort"
"strings"
"github.com/cznic/cc"
"github.com/cznic/ccir"
"github.com/cznic/internal/buffer"
"github.com/cznic/ir"
"github.com/cznic/strutil"
"github.com/cznic/virtual"
"github.com/cznic/xc"
"log"
)
var (
cpp = flag.Bool("cpp", false, "")
dict = xc.Dict
errLimit = flag.Int("errlimit", 10, "")
filter = flag.String("re", "", "")
ndebug = flag.Bool("ndebug", false, "")
noexec = flag.Bool("noexec", false, "")
oLog = flag.Bool("log", false, "")
trace = flag.Bool("trc", false, "")
yydebug = flag.Int("yydebug", 0, "")
)
func findRepo(s string) string {
s = filepath.FromSlash(s)
for _, v := range strings.Split(strutil.Gopath(), string(os.PathListSeparator)) {
p := filepath.Join(v, "src", s)
fi, err := os.Lstat(p)
if err != nil {
continue
}
if fi.IsDir() {
wd, err := os.Getwd()
if err != nil {
log.Fatal(err)
}
if p, err = filepath.Rel(wd, p); err != nil {
log.Fatal(err)
}
return p
}
}
return ""
}
func errStr(err error) string {
switch x := err.(type) {
case scanner.ErrorList:
if len(x) != 1 {
x.RemoveMultiples()
}
var b bytes.Buffer
for i, v := range x {
if i != 0 {
b.WriteByte('\n')
}
b.WriteString(v.Error())
if i == 9 {
fmt.Fprintf(&b, "\n\t... and %v more errors", len(x)-10)
break
}
}
return b.String()
default:
return err.Error()
}
}
func build(predef string, tus [][]string, opts ...cc.Opt) ([]*cc.TranslationUnit, *virtual.Binary) {
var b buffer.Bytes
var lpos token.Position
if *cpp {
opts = append(opts, cc.Cpp(func(toks []xc.Token) {
if len(toks) != 0 {
p := toks[0].Position()
if p.Filename != lpos.Filename {
fmt.Fprintf(&b, "# %d %q\n", p.Line, p.Filename)
}
lpos = p
}
for _, v := range toks {
b.WriteString(cc.TokSrc(v))
}
b.WriteByte('\n')
}))
}
ndbg := ""
if *ndebug {
ndbg = "#define NDEBUG 1"
}
var build [][]ir.Object
tus = append(tus, []string{ccir.CRT0Path})
var asta []*cc.TranslationUnit
for _, src := range tus {
model, err := ccir.NewModel()
if err != nil {
log.Fatal(err)
}
ast, err := cc.Parse(
fmt.Sprintf(`
%s
#define __arch__ %s
#define __os__ %s
#include <builtin.h>
%s
`, ndbg, runtime.GOARCH, runtime.GOOS, predef),
src,
model,
append([]cc.Opt{
cc.AllowCompatibleTypedefRedefinitions(),
cc.EnableImplicitFuncDef(),
cc.EnableNonConstStaticInitExpressions(),
cc.ErrLimit(*errLimit),
cc.SysIncludePaths([]string{ccir.LibcIncludePath}),
}, opts...)...,
)
if s := b.Bytes(); len(s) != 0 {
log.Printf("\n%s", s)
b.Close()
}
if err != nil {
log.Fatal(errStr(err))
}
asta = append(asta, ast)
objs, err := ccir.New(ast)
if err != nil {
log.Fatal(err)
}
if *oLog {
for i, v := range objs {
switch x := v.(type) {
case *ir.DataDefinition:
fmt.Fprintf(&b, "# [%v]: %T %v %v\n", i, x, x.ObjectBase, x.Value)
case *ir.FunctionDefinition:
fmt.Fprintf(&b, "# [%v]: %T %v %v\n", i, x, x.ObjectBase, x.Arguments)
for i, v := range x.Body {
fmt.Fprintf(&b, "%#05x\t%v\n", i, v)
}
default:
log.Fatalf("[%v]: %T %v: %v", i, x, x, err)
}
}
}
for i, v := range objs {
if err := v.Verify(); err != nil {
switch x := v.(type) {
case *ir.FunctionDefinition:
fmt.Fprintf(&b, "# [%v, err]: %T %v %v\n", i, x, x.ObjectBase, x.Arguments)
for i, v := range x.Body {
fmt.Fprintf(&b, "%#05x\t%v\n", i, v)
}
log.Fatalf("# [%v]: Verify (A): %v\n%s", i, err, b.Bytes())
default:
log.Fatalf("[%v]: %T %v: %v", i, x, x, err)
}
}
}
build = append(build, objs)
}
linked, err := ir.LinkMain(build...)
if err != nil {
log.Fatalf("ir.LinkMain: %s\n%s", err, b.Bytes())
}
for _, v := range linked {
if err := v.Verify(); err != nil {
log.Fatal(err)
}
}
bin, err := virtual.LoadMain(linked)
if err != nil {
log.Fatal(err)
}
return asta, bin
}
func macros(buf io.Writer, ast *cc.TranslationUnit) {
var a []string
for k, v := range ast.Macros {
if v.Value != nil && v.Type.Kind() != cc.Bool {
switch fn := v.DefTok.Position().Filename; {
case
fn == "builtin.h",
fn == "<predefine>",
strings.HasPrefix(fn, "predefined_"):
// ignore
default:
a = append(a, string(dict.S(k)))
}
}
}
sort.Strings(a)
for _, v := range a {
m := ast.Macros[dict.SID(v)]
if m.Value == nil {
log.Fatal("TODO")
}
switch t := m.Type; t.Kind() {
case
cc.Int, cc.UInt, cc.Long, cc.ULong, cc.LongLong, cc.ULongLong,
cc.Float, cc.LongDouble, cc.Bool:
fmt.Fprintf(buf, "X%s = %v\n", v, m.Value)
case cc.Ptr:
switch t := t.Element(); t.Kind() {
case cc.Char:
fmt.Fprintf(buf, "X%s = %q\n", v, dict.S(int(m.Value.(cc.StringLitID))))
default:
log.Fatalf("%v", t.Kind())
}
default:
log.Fatalf("%v", t.Kind())
}
}
a = a[:0]
for _, v := range ast.Declarations.Identifiers {
switch x := v.Node.(type) {
case *cc.DirectDeclarator:
d := x.TopDeclarator()
id, _ := d.Identifier()
if x.EnumVal == nil {
break
}
a = append(a, string(dict.S(id)))
default:
log.Fatalf("%T", x)
}
}
sort.Strings(a)
for _, v := range a {
dd := ast.Declarations.Identifiers[dict.SID(v)].Node.(*cc.DirectDeclarator)
fmt.Fprintf(buf, "X%s = %v\n", v, dd.EnumVal)
}
}
func main() {
const repo = "sqlite.org/sqlite-amalgamation-3180000/"
log.SetFlags(log.Lshortfile | log.Lmicroseconds)
flag.Parse()
pth := findRepo(repo)
if pth == "" {
log.Fatalf("repository not found: %v", repo)
return
}
asta, bin := build(
`
//#define SQLITE_DEBUG 1
//#define SQLITE_ENABLE_API_ARMOR 1
#define SQLITE_ENABLE_MEMSYS5 1
#define SQLITE_USE_URI 1
`,
[][]string{
{"main.c"},
{filepath.Join(pth, "sqlite3.c")},
},
cc.EnableAnonymousStructFields(),
cc.IncludePaths([]string{pth}),
)
var b0 bytes.Buffer
enc := gob.NewEncoder(&b0)
if err := enc.Encode(&bin); err != nil {
log.Fatal(err)
}
var b1 bytes.Buffer
comp := gzip.NewWriter(&b1)
if _, err := comp.Write(b0.Bytes()); err != nil {
log.Fatal(err)
}
if err := comp.Close(); err != nil {
log.Fatal(err)
}
var b2 buffer.Bytes
lic, err := ioutil.ReadFile("SQLITE-LICENSE")
if err != nil {
log.Fatal(err)
}
b2.WriteString(`// Code generated by running "go generate". DO NOT EDIT.
/*
`)
b2.Write(lic)
b2.WriteString(`
*/
package bin
const (
`)
macros(&b2, asta[0])
b2.WriteString(`
Data = "`)
b := b1.Bytes()
for _, v := range b {
switch {
case v == '\\':
b2.WriteString(`\\`)
case v == '"':
b2.WriteString(`\"`)
case v < ' ', v >= 0x7f:
fmt.Fprintf(&b2, `\x%02x`, v)
default:
b2.WriteByte(v)
}
}
b2.WriteString(`"
)
`)
b3, err := format.Source(b2.Bytes())
if err != nil {
b3 = b
}
os.MkdirAll("internal/bin", 0775)
if err := ioutil.WriteFile(fmt.Sprintf("internal/bin/bin_%s_%s.go", runtime.GOOS, runtime.GOARCH), b3, 0664); err != nil {
log.Fatal(err)
}
log.Printf("code %#08x, text %#08x, data %#08x, bss %#08x, pc2func %v, pc2line %v, symbols %v, gz %v\n",
len(bin.Code), len(bin.Text), len(bin.Data), bin.BSS, len(bin.Functions), len(bin.Lines), len(bin.Sym), b1.Len(),
)
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

62
main.c Normal file
View File

@@ -0,0 +1,62 @@
// +build ignore
// SQLite Is Public Domain
//
// All of the code and documentation in SQLite has been dedicated to the public
// domain by the authors. All code authors, and representatives of the
// companies they work for, have signed affidavits dedicating their
// contributions to the public domain and originals of those signed affidavits
// are stored in a firesafe at the main offices of Hwaci. Anyone is free to
// copy, modify, publish, use, compile, sell, or distribute the original SQLite
// code, either in source code form or as a compiled binary, for any purpose,
// commercial or non-commercial, and by any means.
//
// The previous paragraph applies to the deliverable code and documentation in
// SQLite - those parts of the SQLite library that you actually bundle and ship
// with a larger application. Some scripts used as part of the build process
// (for example the "configure" scripts generated by autoconf) might fall under
// other open-source licenses. Nothing from these build scripts ever reaches
// the final deliverable SQLite library, however, and so the licenses
// associated with those scripts should not be a factor in assessing your
// rights to copy and use the SQLite library.
//
// All of the deliverable code in SQLite has been written from scratch. No code
// has been taken from other projects or from the open internet. Every line of
// code can be traced back to its original author, and all of those authors
// have public domain dedications on file. So the SQLite code base is clean and
// is uncontaminated with licensed code from other projects.
#define minAlloc (2<<5)
#include <sqlite3.h>
#include <stdlib.h>
int main(int argc, char **argv)
{
if (argc != 2) {
return 1;
}
int heapSize = 0;
char *p = argv[1];
for (; *p; p++) {
heapSize = 10 * heapSize + *p - '0';
}
void *heap = malloc(heapSize);
if (heap == 0) {
return 1;
}
int rc = sqlite3_config(SQLITE_CONFIG_HEAP, heap, heapSize, minAlloc);
if (rc) {
return 2;
}
rc = sqlite3_threadsafe();
if (!rc) {
return 3;
}
return 0;
}

1305
sqlite.go Normal file

File diff suppressed because it is too large Load Diff

9
trace_disabled.go Normal file
View File

@@ -0,0 +1,9 @@
// Copyright 2017 The Virtual Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build !sqlite.trace
package sqlite
const trace = false

9
trace_enabled.go Normal file
View File

@@ -0,0 +1,9 @@
// Copyright 2017 The Virtual Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build sqlite.trace
package sqlite
const trace = true