コード例 #1
0
ファイル: context.go プロジェクト: kless/datautil
// ExecFile executes the SQL commands read from a file.
// Skips lines starting with "#".
//
// 'msg' is the message used to logging, if any.
func (cx *DBContext) ExecFile(filename, msg string) (err error) {
	f, err := os.Open(filename)
	if err != nil {
		return err
	}
	defer func() {
		if err1 := f.Close(); err == nil {
			err = err1
		}
	}()
	buf := bufio.NewReader(f)

	// Handle multiple lines
	for fullLine := ""; ; {
		line, err := buf.ReadString('\n')
		if err == io.EOF {
			break
		}

		line = strings.TrimSpace(line)
		if line == "" || strings.HasPrefix(line, "#") {
			continue
		}
		fullLine += line

		if !strings.HasSuffix(line, ";") { // Multiple line
			continue
		}

		if _, err = cx.DB.Exec(fullLine); err != nil {
			return fmt.Errorf("SQL code: %q\n%s", fullLine, err)
		}
		fullLine = ""
	}

	if datautil.VERBOSE {
		log.WithFields(log.Fields{
			"db":   cx.Conn.GetDBName(),
			"file": packer.RelativeDir(filename),
		}).Info(msg)
	}
	return nil
}
コード例 #2
0
ファイル: getsql.go プロジェクト: kless/datautil
// Write writes the SQL code to a file got from the one given.
func (s *SQLInfo) Write(dir string) error {
	tmpl := template.Must(template.New("createtb").Parse(tmplCreatetb))
	srcDir, srcFile := filepath.Split(s.SrcFilePath)

	data := tmplData{
		Info: s,
		Header: fmt.Sprintf("# Code generated by getsql from %q\n# DO NOT EDIT",
			filepath.Join(filepath.Base(srcDir), srcFile)),
	}

	createFile := func(path, tmplName string) error {
		file, err := os.Create(path)
		if err != nil {
			return err
		}

		err = tmpl.ExecuteTemplate(file, tmplName, data)
		file.Close()
		if err != nil {
			return err
		}

		if datautil.VERBOSE {
			log.Printf("Write file: '%s'", packer.RelativeDir(path))
		}
		return nil
	}

	// Directory for SQL files
	err := os.MkdirAll(dir, 0775)
	if err != nil && !os.IsExist(err) {
		return err
	}
	// Create the SQL file
	return createFile(dbutil.GetSQLFilename(dir, "table", s.DBMS), "createtb")
}
コード例 #3
0
ファイル: context.go プロジェクト: kless/datautil
// LoadJSON loads data from a JSON file in the database table.
//
// If src != nil, LoadJSON loads the source from src and the filename is only used
// when recording file information. The type of the argument for the src parameter
// must be []byte, or io.Reader. If src == nil, LoadJSON loads the file
// specified by filename.
func (cx *DBContext) LoadJSON(src interface{}, filename, table string) (err error) {
	var dec *json.Decoder

	if src != nil {
		switch s := src.(type) {
		case []byte:
			dec = json.NewDecoder(bytes.NewReader(s))
		case io.Reader:
			dec = json.NewDecoder(s)
		default:
			return fmt.Errorf("invalid source")
		}
	} else {
		f, err := os.Open(filename)
		if err != nil {
			return err
		}
		defer func() {
			if err1 := f.Close(); err == nil {
				err = err1
			}
		}()

		dec = json.NewDecoder(f)
	}

	// The first row must have the name of the columns.
	firstRecord := make([]string, 0)
	if err = dec.Decode(&firstRecord); err != nil {
		return err
	}

	tx, err := cx.DB.Begin()
	if err != nil {
		return err
	}
	defer func() {
		if err != nil {
			err1 := tx.Rollback()
			if err1 != nil && datautil.VERBOSE {
				log.WithFields(log.Fields{
					"file":  filename,
					"table": table,
				}).Warn(err1)
			}
		}
	}()

	insertCode := fmt.Sprintf("INSERT INTO %s (%s) VALUES(%s)",
		table,
		strings.Join(firstRecord, ", "),
		cx.bindChars(len(firstRecord)),
	)
	insert, err := tx.Prepare(insertCode)
	if err != nil {
		return fmt.Errorf("SQL code: %q\n%s", insertCode, err)
	}

	list := make([]interface{}, 0)

	for line := 2; dec.More(); line++ {
		if err = dec.Decode(&list); err != nil {
			return fmt.Errorf("%q line %d: %s", filename, line, err)
		}

		_, err = tx.Stmt(insert).Exec(list...)
		if err != nil {
			return fmt.Errorf("code: %q vars: %v => %s", insertCode, list, err)
		}
	}

	if err = insert.Close(); err != nil && datautil.VERBOSE {
		log.WithFields(log.Fields{
			"file":  filename,
			"table": table,
		}).Warn(err)
	}

	if err = tx.Commit(); err != nil {
		return err
	}
	if datautil.VERBOSE {
		log.WithFields(log.Fields{
			"file":  packer.RelativeDir(filename),
			"db":    cx.Conn.GetDBName(),
			"table": table,
		}).Info("Load JSON file")
	}
	return nil
}