func do() (err error) { oDB := flag.String("db", "ql.db", "The DB file to open. It'll be created if missing") oFlds := flag.Bool("fld", false, "Show recordset's field names.") flag.Parse() var src string switch n := flag.NArg(); n { case 0: b, err := ioutil.ReadAll(bufio.NewReader(os.Stdin)) if err != nil { return err } src = string(b) default: a := make([]string, n) for i := range a { a[i] = flag.Arg(i) } src = strings.Join(a, " ") } db, err := ql.OpenFile(*oDB, &ql.Options{CanCreate: true}) if err != nil { return err } defer func() { ec := db.Close() switch { case ec != nil && err != nil: log.Println(ec) case ec != nil: err = ec } }() src = "BEGIN TRANSACTION; " + src + "; COMMIT;" l, err := ql.Compile(src) if err != nil { log.Println(src) return err } rs, i, err := db.Execute(ql.NewRWCtx(), l) if err != nil { a := strings.Split(strings.TrimSpace(fmt.Sprint(l)), "\n") return fmt.Errorf("%v: %s", err, a[i]) } if len(rs) == 0 { return } return rs[len(rs)-1].Do(*oFlds, func(data []interface{}) (bool, error) { fmt.Println(str(data)) return true, nil }) }
// qlCompile provides a wrapper to create safe, transaction-encased queries func qlCompile(key string, wraptx bool) (list ql.List, err error) { var src string if l, ok := qlc[key]; !ok { if src, ok = qlq[key]; !ok { src = key } if wraptx { src = "BEGIN TRANSACTION; " + src + "; COMMIT;" } if l, e := ql.Compile(src); err != nil { err = e } else { list = l } } else { list = l } return }
func (i *Installer) dbInsertItem(tableName string, item interface{}, typeMap map[string]interface{}) error { i.dbMtx.Lock() defer i.dbMtx.Unlock() fields, err := i.dbMarshalItem(tableName, item, typeMap) if err != nil { return err } vStr := make([]string, 0, len(fields)) for idx := range fields { vStr = append(vStr, fmt.Sprintf("$%d", idx+1)) } list, err := ql.Compile(fmt.Sprintf(` INSERT INTO %s VALUES(%s); `, tableName, strings.Join(vStr, ", "))) if err != nil { return err } return i.txExec(list.String(), fields...) }
func do() (err error) { oDB := flag.String("db", "ql.db", "The DB file to open. It'll be created if missing.") oFlds := flag.Bool("fld", false, "Show recordset's field names.") oSchema := flag.String("schema", "", "If non empty, show the CREATE statements of matching tables and exit.") oTables := flag.String("tables", "", "If non empty, list matching table names and exit.") flag.Parse() db, err := ql.OpenFile(*oDB, &ql.Options{CanCreate: true}) if err != nil { return err } defer func() { ec := db.Close() switch { case ec != nil && err != nil: log.Println(ec) case ec != nil: err = ec } }() if pat := *oSchema; pat != "" { re, err := regexp.Compile(pat) if err != nil { return err } nfo, err := db.Info() if err != nil { return err } r := []string{} for _, ti := range nfo.Tables { if !re.MatchString(ti.Name) { continue } a := []string{} for _, ci := range ti.Columns { a = append(a, fmt.Sprintf("%s %s", ci.Name, ci.Type)) } r = append(r, fmt.Sprintf("CREATE TABLE %s (%s);", ti.Name, strings.Join(a, ", "))) } sort.Strings(r) if len(r) != 0 { fmt.Println(strings.Join(r, "\n")) } return nil } if pat := *oTables; pat != "" { re, err := regexp.Compile(pat) if err != nil { return err } nfo, err := db.Info() if err != nil { return err } r := []string{} for _, ti := range nfo.Tables { if !re.MatchString(ti.Name) { continue } r = append(r, ti.Name) } sort.Strings(r) if len(r) != 0 { fmt.Println(strings.Join(r, "\n")) } return nil } var src string switch n := flag.NArg(); n { case 0: b, err := ioutil.ReadAll(bufio.NewReader(os.Stdin)) if err != nil { return err } src = string(b) default: a := make([]string, n) for i := range a { a[i] = flag.Arg(i) } src = strings.Join(a, " ") } src = "BEGIN TRANSACTION; " + src + "; COMMIT;" l, err := ql.Compile(src) if err != nil { log.Println(src) return err } rs, i, err := db.Execute(ql.NewRWCtx(), l) if err != nil { a := strings.Split(strings.TrimSpace(fmt.Sprint(l)), "\n") return fmt.Errorf("%v: %s", err, a[i]) } if len(rs) == 0 { return } return rs[len(rs)-1].Do(*oFlds, func(data []interface{}) (bool, error) { fmt.Println(str(data)) return true, nil }) }
if l, e := ql.Compile(src); err != nil { err = e } else { list = l } qlc[key] = list } else { list = l } return } // Pre-compiled begin transaction, commit and rollback statements var ( qlBeginTransaction, _ = ql.Compile("BEGIN TRANSACTION;") qlCommit, _ = ql.Compile("COMMIT;") qlRollback, _ = ql.Compile("ROLLBACK;") ) // qltx contains a ql context and database connection type qltx struct { ctx *ql.TCtx db *qlw } // Execute allows for execution via ql context in a transaction func (t *qltx) Execute(list ql.List, arg ...interface{}) ([]ql.Recordset, int, error) { return t.db.Execute(t.ctx, list, arg...) }