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 }) }