Exemplo n.º 1
0
Arquivo: driver.go Projeto: rsc/sqlite
func (s *stmt) Exec(args []driver.Value) (driver.Result, error) {
	if s.closed {
		panic("database/sql/driver: misuse of sqlite driver: Exec after Close")
	}
	if s.rows {
		panic("database/sql/driver: misuse of sqlite driver: Exec with active Rows")
	}

	err := s.start(args)
	if err != nil {
		return nil, err
	}

	rv := C.sqlite3_step(s.stmt)
	if errno(rv) != stepDone {
		if rv == 0 {
			rv = 21 // errMisuse
		}
		return nil, s.c.error(rv)
	}

	id := int64(C.sqlite3_last_insert_rowid(s.c.db))
	rows := int64(C.sqlite3_changes(s.c.db))
	return &result{id, rows}, nil
}
Exemplo n.º 2
0
func (s *Statement) Step(f ...func(*Statement, ...interface{})) (e os.Error) {
	r := Errno(C.sqlite3_step(s.cptr))
	switch r {
	case DONE:
		e = nil
	case ROW:
		if f != nil {
			defer func() {
				switch x := recover().(type) {
				case nil:
					e = ROW
				case os.Error:
					e = x
				default:
					e = MISUSE
				}
			}()
			r := s.Row()
			for _, fn := range f {
				fn(s, r...)
			}
		}
	default:
		e = r
	}
	return
}
Exemplo n.º 3
0
func (rows Rows) Next(dest []driver.Value) error {
	r := C.sqlite3_step(rows.stmt)
	if r == C.SQLITE_DONE {
		return io.EOF
	}
	if r != C.SQLITE_ROW {
		return stmtError(rows.stmt)
	}

	count := len(dest)
	for i := 0; i < count; i++ {
		t := C.sqlite3_column_type(rows.stmt, C.int(i))
		switch t {
		case C.SQLITE_INTEGER:
			dest[i] = int64(C.sqlite3_column_int64(rows.stmt, C.int(i)))
		case C.SQLITE_FLOAT:
			dest[i] = float64(C.sqlite3_column_double(rows.stmt, C.int(i)))
		case C.SQLITE_NULL:
			dest[i] = nil
		case C.SQLITE_TEXT:
			n := C.sqlite3_column_bytes(rows.stmt, C.int(i))
			blob := C.sqlite3_column_blob(rows.stmt, C.int(i))
			dest[i] = C.GoBytes(blob, n)
		default:
			panic("unsupported type")
		}
	}
	return nil
}
Exemplo n.º 4
0
func (rc *SQLiteRows) Next(dest []driver.Value) error {
	rv := C.sqlite3_step(rc.s.s)
	if rv == C.SQLITE_DONE {
		return io.EOF
	}
	if rv != C.SQLITE_ROW {
		return errors.New(C.GoString(C.sqlite3_errmsg(rc.s.c.db)))
	}
	for i := range dest {
		switch C.sqlite3_column_type(rc.s.s, C.int(i)) {
		case C.SQLITE_INTEGER:
			dest[i] = int64(C.sqlite3_column_int64(rc.s.s, C.int(i)))
		case C.SQLITE_FLOAT:
			dest[i] = float64(C.sqlite3_column_double(rc.s.s, C.int(i)))
		case C.SQLITE_BLOB:
			n := int(C.sqlite3_column_bytes(rc.s.s, C.int(i)))
			p := C.sqlite3_column_blob(rc.s.s, C.int(i))
			dest[i] = (*[1 << 30]byte)(unsafe.Pointer(p))[0:n]
		case C.SQLITE_NULL:
			dest[i] = nil
		case C.SQLITE_TEXT:
			dest[i] = C.GoString((*C.char)(unsafe.Pointer(C.sqlite3_column_text(rc.s.s, C.int(i)))))
		}
	}
	return nil
}
Exemplo n.º 5
0
Arquivo: driver.go Projeto: rsc/sqlite
func (r *rows) Next(dst []driver.Value) error {
	if r.s == nil {
		panic("database/sql/driver: misuse of sqlite driver: Next of closed Rows")
	}

	rv := C.sqlite3_step(r.s.stmt)
	if errno(rv) != stepRow {
		if errno(rv) == stepDone {
			return io.EOF
		}
		if rv == 0 {
			rv = 21
		}
		return r.s.c.error(rv)
	}

	for i := range dst {
		switch typ := C.sqlite3_column_type(r.s.stmt, C.int(i)); typ {
		default:
			return fmt.Errorf("unexpected sqlite3 column type %d", typ)
		case C.SQLITE_INTEGER:
			val := int64(C.sqlite3_column_int64(r.s.stmt, C.int(i)))
			switch r.s.coltypes[i] {
			case "timestamp", "datetime":
				dst[i] = time.Unix(val, 0).UTC()
			case "boolean":
				dst[i] = val > 0
			default:
				dst[i] = val
			}

		case C.SQLITE_FLOAT:
			dst[i] = float64(C.sqlite3_column_double(r.s.stmt, C.int(i)))

		case C.SQLITE_BLOB, C.SQLITE_TEXT:
			n := int(C.sqlite3_column_bytes(r.s.stmt, C.int(i)))
			var b []byte
			if n > 0 {
				p := C.sqlite3_column_blob(r.s.stmt, C.int(i))
				b = (*[maxslice]byte)(unsafe.Pointer(p))[:n]
			}
			dst[i] = b
			switch r.s.coltypes[i] {
			case "timestamp", "datetime":
				dst[i] = time.Time{}
				s := string(b)
				for _, f := range timefmt {
					if t, err := time.Parse(f, s); err == nil {
						dst[i] = t
						break
					}
				}
			}

		case C.SQLITE_NULL:
			dst[i] = nil
		}
	}
	return nil
}
Exemplo n.º 6
0
Arquivo: stmt.go Projeto: pkf/gosqlite
func (s *Stmt) exec() error {
	rv := C.sqlite3_step(s.stmt)
	C.sqlite3_reset(s.stmt)
	if Errno(rv) != Done {
		return s.error(rv, "Stmt.exec")
	}
	return nil
}
Exemplo n.º 7
0
func (rc *SQLiteRows) Next(dest []driver.Value) error {
	rv := C.sqlite3_step(rc.s.s)
	if rv == C.SQLITE_DONE {
		return io.EOF
	}
	if rv != C.SQLITE_ROW {
		return errors.New(C.GoString(C.sqlite3_errmsg(rc.s.c.db)))
	}

	if rc.decltype == nil {
		rc.decltype = make([]string, rc.nc)
		for i := 0; i < rc.nc; i++ {
			rc.decltype[i] = strings.ToLower(C.GoString(C.sqlite3_column_decltype(rc.s.s, C.int(i))))
		}
	}

	for i := range dest {
		switch C.sqlite3_column_type(rc.s.s, C.int(i)) {
		case C.SQLITE_INTEGER:
			val := int64(C.sqlite3_column_int64(rc.s.s, C.int(i)))
			switch rc.decltype[i] {
			case "timestamp":
				dest[i] = time.Unix(val, 0)
			case "boolean":
				dest[i] = val > 0
			default:
				dest[i] = val
			}
		case C.SQLITE_FLOAT:
			dest[i] = float64(C.sqlite3_column_double(rc.s.s, C.int(i)))
		case C.SQLITE_BLOB:
			n := int(C.sqlite3_column_bytes(rc.s.s, C.int(i)))
			p := C.sqlite3_column_blob(rc.s.s, C.int(i))
			switch dest[i].(type) {
			case sql.RawBytes:
				dest[i] = (*[1 << 30]byte)(unsafe.Pointer(p))[0:n]
			default:
				slice := make([]byte, n)
				copy(slice[:], (*[1 << 30]byte)(unsafe.Pointer(p))[0:n])
				dest[i] = slice
			}
		case C.SQLITE_NULL:
			dest[i] = nil
		case C.SQLITE_TEXT:
			var err error
			s := C.GoString((*C.char)(unsafe.Pointer(C.sqlite3_column_text(rc.s.s, C.int(i)))))
			if rc.decltype[i] == "timestamp" {
				dest[i], err = time.Parse(SQLiteTimestampFormat, s)
				if err != nil {
					return err
				}
			} else {
				dest[i] = s
			}
		}
	}
	return nil
}
Exemplo n.º 8
0
// Execute the statement with arguments. Return result object.
func (s *SQLiteStmt) Exec(args []driver.Value) (driver.Result, error) {
	if err := s.bind(args); err != nil {
		return nil, err
	}
	rv := C.sqlite3_step(s.s)
	if rv != C.SQLITE_ROW && rv != C.SQLITE_OK && rv != C.SQLITE_DONE {
		return nil, errors.New(C.GoString(C.sqlite3_errmsg(s.c.db)))
	}
	return &SQLiteResult{s}, nil
}
Exemplo n.º 9
0
func (s *Stmt) Next() bool {
	rv := C.sqlite3_step(s.stmt)
	err := Errno(rv)
	if err == Row {
		return true
	}
	if err != Done {
		s.err = s.c.error(rv)
	}
	return false
}
Exemplo n.º 10
0
// Step must be called one or more times to evaluate the statement after the
// prepared statement has been prepared.
func (s *Statement) Step(f ...func(*Statement, ...interface{})) (e error) {
	switch e = SQLiteError(C.sqlite3_step(s.cptr)); e {
	case ROW:
		row := s.Row()
		for _, fn := range f {
			fn(s, row...)
		}
	case DONE:
		e = s.Reset()
	}
	return
}
Exemplo n.º 11
0
func (c *Conn) exec(cmd string) error {
	s, err := c.prepare(cmd)
	if err != nil {
		return err
	}
	defer s.finalize()
	rv := C.sqlite3_step(s.stmt)
	if Errno(rv) != Done {
		return s.error(rv, "Conn.exec(%q)", cmd)
	}
	return nil
}
Exemplo n.º 12
0
// Next evaluates an SQL statement
//
// With custom error handling:
//	for {
//		if ok, err := s.Next(); err != nil {
//			return nil, err
//		} else if !ok {
//			break
//		}
//		err = s.Scan(&fnum, &inum, &sstr)
//	}
//
// (See http://sqlite.org/c3ref/step.html)
func (s *Stmt) Next() (bool, error) {
	rv := C.sqlite3_step(s.stmt)
	err := Errno(rv)
	if err == Row {
		return true, nil
	}
	C.sqlite3_reset(s.stmt) // Release implicit lock as soon as possible (see dbEvalStep in tclsqlite3.c)
	if err != Done {
		return false, s.error(rv, "Stmt.Next")
	}
	// TODO Check column count > 0
	return false, nil
}
Exemplo n.º 13
0
Arquivo: stmt.go Projeto: pkf/gosqlite
// Next evaluates an SQL statement
//
// With custom error handling:
//	for {
//		if ok, err := s.Next(); err != nil {
//			return nil, err
//		} else if !ok {
//			break
//		}
//		err = s.Scan(&fnum, &inum, &sstr)
//	}
// With panic on error:
// 	for Must(s.Next()) {
//		err := s.Scan(&fnum, &inum, &sstr)
//	}
//
// (See http://sqlite.org/c3ref/step.html)
func (s *Stmt) Next() (bool, error) {
	rv := C.sqlite3_step(s.stmt)
	err := Errno(rv)
	if err == Row {
		return true, nil
	}
	C.sqlite3_reset(s.stmt)
	if err != Done {
		return false, s.error(rv, "Stmt.Next")
	}
	// TODO Check column count > 0
	return false, nil
}
Exemplo n.º 14
0
func (c *Conn) oneValue(query string, value interface{}) error { // no cache
	s, err := c.prepare(query)
	if err != nil {
		return err
	}
	defer s.finalize()
	rv := C.sqlite3_step(s.stmt)
	err = Errno(rv)
	if err == Row {
		return s.Scan(value)
	} else if err == Done {
		return io.EOF
	}
	return s.error(rv, fmt.Sprintf("Conn.oneValue(%q)", query))
}
Exemplo n.º 15
0
func (s *Stmt) exec() error {
	rv := C.sqlite3_step(s.stmt)
	C.sqlite3_reset(s.stmt)
	err := Errno(rv)
	if err != Done {
		if err == Row {
			return s.specificError("don't use exec with anything that returns data such as %q", s.SQL())
		}
		return s.error(rv, "Stmt.exec")
	}
	if s.ColumnCount() > 0 {
		return s.specificError("don't use exec with anything that returns data such as %q", s.SQL())
	}
	return nil
}
Exemplo n.º 16
0
// Execute the statement with arguments. Return result object.
func (s *SQLiteStmt) Exec(args []driver.Value) (driver.Result, error) {
	if err := s.bind(args); err != nil {
		return nil, err
	}
	rv := C.sqlite3_step(s.s)
	if rv != C.SQLITE_ROW && rv != C.SQLITE_OK && rv != C.SQLITE_DONE {
		return nil, s.c.lastError()
	}

	res := &SQLiteResult{
		int64(C._sqlite3_last_insert_rowid(s.c.db)),
		int64(C._sqlite3_changes(s.c.db)),
	}
	return res, nil
}
Exemplo n.º 17
0
func (c *Conn) Exec(cmd string, args ...interface{}) error {
	s, err := c.Prepare(cmd)
	if err != nil {
		return err
	}
	defer s.Finalize()
	err = s.Exec(args...)
	if err != nil {
		return err
	}
	rv := C.sqlite3_step(s.stmt)
	if Errno(rv) != Done {
		return c.error(rv)
	}
	return nil
}
Exemplo n.º 18
0
// step evaluates the next step in the statement's program, automatically
// resetting the statement if the result is anything other than SQLITE_ROW.
func (s *Stmt) step() error {
	s.colTypes = s.colTypes[:0]
	s.haveRow = C.sqlite3_step(s.stmt) == ROW
	if !s.haveRow {
		// If step returned DONE, reset returns OK. Otherwise, reset returns the
		// same error code as step (v2 interface).
		rc := C.sqlite3_reset(s.stmt)
		if s.nVars > 0 {
			C.sqlite3_clear_bindings(s.stmt)
		}
		if rc != OK {
			return libErr(rc, s.conn.db)
		}
	}
	return nil
}
Exemplo n.º 19
0
func (stmt Stmt) Exec(args []driver.Value) (driver.Result, error) {
	if err := stmt.bind(args); err != nil {
		return nil, err
	}

	r := C.sqlite3_step(stmt.stmt)
	db := C.sqlite3_db_handle(stmt.stmt)

	if r != C.SQLITE_DONE && r != C.SQLITE_ROW {
		return nil, dbError(db)
	}

	var result Result
	result.rowsAffected = int64(C.sqlite3_changes(db))
	result.lastInsertId = int64(C.sqlite3_last_insert_rowid(db))
	return &result, nil
}
Exemplo n.º 20
0
// Passing multiple sql commands in a single command string requires some extra
// work to make it go. Sqlite normally executes only one expression and returns
// the remainder in the @tail parameter of sqlite3_prepare(). This sqlite binding
// does not take that into account. We need to loop and process @tail until it
// is empty. This also means taking care of any parameters we pass to Stmt.Exec.
// We need to ensure that we offset the supplied argument list after every
// execution.
func (c *Conn) ExecRange(cmd string, argv ...interface{}) (err os.Error) {
	var tail *C.char
	var rv C.int
	var errno Errno

	cmdlen := len(cmd) + 1
	s := new(Stmt)
	s.c = c

	cmdstr := C.CString(strings.TrimSpace(cmd))
	defer C.free(unsafe.Pointer(cmdstr))

	for {
		if rv = C.sqlite3_prepare_v2(c.db, cmdstr, C.int(cmdlen), &s.stmt, &tail); rv != 0 {
			return c.error(rv)
		}

		if rv = C.sqlite3_bind_parameter_count(s.stmt); int(rv) > len(argv) {
			return os.NewError(fmt.Sprintf("incorrect argument count: have %d, want %d", len(argv), rv))
		}

		if err = s.Exec(argv[0:rv]...); err != nil {
			s.Finalize()
			return
		}

		argv = argv[rv:]

		if errno = Errno(C.sqlite3_step(s.stmt)); errno != Done {
			s.Finalize()
			return errno
		}

		s.Finalize()

		if C.GoString(tail) == "" {
			break
		}

		cmdstr = tail
		cmdlen = len(C.GoString(cmdstr)) + 1
	}

	return
}
Exemplo n.º 21
0
func (c *Conn) Exec(cmd string, args ...interface{}) os.Error {
	s, err := c.Prepare(cmd)
	if err != nil {
		return err
	}

	defer s.Finalize()

	if err = s.Exec(args...); err != nil {
		return err
	}

	if errno := Errno(C.sqlite3_step(s.stmt)); errno != Done {
		return errno
	}

	return nil
}
Exemplo n.º 22
0
func (self *sqlStatement) sqlStep() int {
	return int(C.sqlite3_step(self.handle))
}
Exemplo n.º 23
0
// this function must be called one or more times to evaluate a prepated statement
func (h *Statement) Step() int {
	return int(C.sqlite3_step(h.cptr))
}
Exemplo n.º 24
0
// Move cursor to next.
func (rc *SQLiteRows) Next(dest []driver.Value) error {
	rv := C.sqlite3_step(rc.s.s)
	if rv == C.SQLITE_DONE {
		return io.EOF
	}
	if rv != C.SQLITE_ROW {
		rv = C.sqlite3_reset(rc.s.s)
		if rv != C.SQLITE_OK {
			return rc.s.c.lastError()
		}
		return nil
	}

	if rc.decltype == nil {
		rc.decltype = make([]string, rc.nc)
		for i := 0; i < rc.nc; i++ {
			rc.decltype[i] = strings.ToLower(C.GoString(C.sqlite3_column_decltype(rc.s.s, C.int(i))))
		}
	}

	for i := range dest {
		switch C.sqlite3_column_type(rc.s.s, C.int(i)) {
		case C.SQLITE_INTEGER:
			val := int64(C.sqlite3_column_int64(rc.s.s, C.int(i)))
			switch rc.decltype[i] {
			case "timestamp", "datetime", "date":
				var t time.Time
				// Assume a millisecond unix timestamp if it's 13 digits -- too
				// large to be a reasonable timestamp in seconds.
				if val > 1e12 || val < -1e12 {
					val *= int64(time.Millisecond) // convert ms to nsec
				} else {
					val *= int64(time.Second) // convert sec to nsec
				}
				t = time.Unix(0, val).UTC()
				if rc.s.c.loc != nil {
					t = t.In(rc.s.c.loc)
				}
				dest[i] = t
			case "boolean":
				dest[i] = val > 0
			default:
				dest[i] = val
			}
		case C.SQLITE_FLOAT:
			dest[i] = float64(C.sqlite3_column_double(rc.s.s, C.int(i)))
		case C.SQLITE_BLOB:
			p := C.sqlite3_column_blob(rc.s.s, C.int(i))
			if p == nil {
				dest[i] = nil
				continue
			}
			n := int(C.sqlite3_column_bytes(rc.s.s, C.int(i)))
			switch dest[i].(type) {
			case sql.RawBytes:
				dest[i] = (*[1 << 30]byte)(unsafe.Pointer(p))[0:n]
			default:
				slice := make([]byte, n)
				copy(slice[:], (*[1 << 30]byte)(unsafe.Pointer(p))[0:n])
				dest[i] = slice
			}
		case C.SQLITE_NULL:
			dest[i] = nil
		case C.SQLITE_TEXT:
			var err error
			var timeVal time.Time

			n := int(C.sqlite3_column_bytes(rc.s.s, C.int(i)))
			s := C.GoStringN((*C.char)(unsafe.Pointer(C.sqlite3_column_text(rc.s.s, C.int(i)))), C.int(n))

			switch rc.decltype[i] {
			case "timestamp", "datetime", "date":
				var t time.Time
				s = strings.TrimSuffix(s, "Z")
				for _, format := range SQLiteTimestampFormats {
					if timeVal, err = time.ParseInLocation(format, s, time.UTC); err == nil {
						t = timeVal
						break
					}
				}
				if err != nil {
					// The column is a time value, so return the zero time on parse failure.
					t = time.Time{}
				}
				if rc.s.c.loc != nil {
					t = t.In(rc.s.c.loc)
				}
				dest[i] = t
			default:
				dest[i] = []byte(s)
			}

		}
	}
	return nil
}
Exemplo n.º 25
0
// Move cursor to next.
func (rc *SQLiteRows) Next(dest []driver.Value) error {
	rv := C.sqlite3_step(rc.s.s)
	if rv == C.SQLITE_DONE {
		return io.EOF
	}
	if rv != C.SQLITE_ROW {
		return errors.New(C.GoString(C.sqlite3_errmsg(rc.s.c.db)))
	}

	if rc.decltype == nil {
		rc.decltype = make([]string, rc.nc)
		for i := 0; i < rc.nc; i++ {
			rc.decltype[i] = strings.ToLower(C.GoString(C.sqlite3_column_decltype(rc.s.s, C.int(i))))
		}
	}

	for i := range dest {
		switch C.sqlite3_column_type(rc.s.s, C.int(i)) {
		case C.SQLITE_INTEGER:
			val := int64(C.sqlite3_column_int64(rc.s.s, C.int(i)))
			switch rc.decltype[i] {
			case "timestamp", "datetime":
				dest[i] = time.Unix(val, 0)
			case "boolean":
				dest[i] = val > 0
			default:
				dest[i] = val
			}
		case C.SQLITE_FLOAT:
			dest[i] = float64(C.sqlite3_column_double(rc.s.s, C.int(i)))
		case C.SQLITE_BLOB:
			n := int(C.sqlite3_column_bytes(rc.s.s, C.int(i)))
			p := C.sqlite3_column_blob(rc.s.s, C.int(i))
			switch dest[i].(type) {
			case sql.RawBytes:
				dest[i] = (*[1 << 30]byte)(unsafe.Pointer(p))[0:n]
			default:
				slice := make([]byte, n)
				copy(slice[:], (*[1 << 30]byte)(unsafe.Pointer(p))[0:n])
				dest[i] = slice
			}
		case C.SQLITE_NULL:
			dest[i] = nil
		case C.SQLITE_TEXT:
			var err error
			s := C.GoString((*C.char)(unsafe.Pointer(C.sqlite3_column_text(rc.s.s, C.int(i)))))

			switch rc.decltype[i] {
			case "timestamp", "datetime":
				for _, format := range SQLiteTimestampFormats {
					if dest[i], err = time.Parse(format, s); err == nil {
						break
					}
				}
				if err != nil {
					// The column is a time value, so return the zero time on parse failure.
					dest[i] = time.Time{}
				}
			default:
				// NOTE(bradfitz): local hack, without internet access. I imagine
				// this has been fixed upstream properly. (the database/sql/driver
				// docs say that you can't return strings here)
				dest[i] = []byte(s)
			}

		}
	}
	return nil
}
Exemplo n.º 26
0
// Move cursor to next.
func (rc *SQLiteRows) Next(dest []driver.Value) error {
	rv := C.sqlite3_step(rc.s.s)
	if rv == C.SQLITE_DONE {
		return io.EOF
	}
	if rv != C.SQLITE_ROW {
		rv = C.sqlite3_reset(rc.s.s)
		if rv != C.SQLITE_OK {
			return rc.s.c.lastError()
		}
		return nil
	}

	if rc.decltype == nil {
		rc.decltype = make([]string, rc.nc)
		for i := 0; i < rc.nc; i++ {
			rc.decltype[i] = strings.ToLower(C.GoString(C.sqlite3_column_decltype(rc.s.s, C.int(i))))
		}
	}

	for i := range dest {
		switch C.sqlite3_column_type(rc.s.s, C.int(i)) {
		case C.SQLITE_INTEGER:
			val := int64(C.sqlite3_column_int64(rc.s.s, C.int(i)))
			switch rc.decltype[i] {
			case "timestamp", "datetime", "date":
				unixTimestamp := strconv.FormatInt(val, 10)
				var t time.Time
				if len(unixTimestamp) == 13 {
					duration, err := time.ParseDuration(unixTimestamp + "ms")
					if err != nil {
						return fmt.Errorf("error parsing %s value %d, %s", rc.decltype[i], val, err)
					}
					epoch := time.Date(1970, 1, 1, 0, 0, 0, 0, time.UTC)
					t = epoch.Add(duration)
				} else {
					t = time.Unix(val, 0)
				}
				if rc.s.c.loc != nil {
					t = t.In(rc.s.c.loc)
				}
				dest[i] = t
			case "boolean":
				dest[i] = val > 0
			default:
				dest[i] = val
			}
		case C.SQLITE_FLOAT:
			dest[i] = float64(C.sqlite3_column_double(rc.s.s, C.int(i)))
		case C.SQLITE_BLOB:
			p := C.sqlite3_column_blob(rc.s.s, C.int(i))
			if p == nil {
				dest[i] = nil
				continue
			}
			n := int(C.sqlite3_column_bytes(rc.s.s, C.int(i)))
			switch dest[i].(type) {
			case sql.RawBytes:
				dest[i] = (*[1 << 30]byte)(unsafe.Pointer(p))[0:n]
			default:
				slice := make([]byte, n)
				copy(slice[:], (*[1 << 30]byte)(unsafe.Pointer(p))[0:n])
				dest[i] = slice
			}
		case C.SQLITE_NULL:
			dest[i] = nil
		case C.SQLITE_TEXT:
			var err error
			var timeVal time.Time

			n := int(C.sqlite3_column_bytes(rc.s.s, C.int(i)))
			s := C.GoStringN((*C.char)(unsafe.Pointer(C.sqlite3_column_text(rc.s.s, C.int(i)))), C.int(n))

			switch rc.decltype[i] {
			case "timestamp", "datetime", "date":
				var t time.Time
				s = strings.TrimSuffix(s, "Z")
				for _, format := range SQLiteTimestampFormats {
					if timeVal, err = time.ParseInLocation(format, s, time.UTC); err == nil {
						t = timeVal
						break
					}
				}
				if err != nil {
					// The column is a time value, so return the zero time on parse failure.
					t = time.Time{}
				}
				if rc.s.c.loc != nil {
					t = t.In(rc.s.c.loc)
				}
				dest[i] = t
			default:
				dest[i] = []byte(s)
			}

		}
	}
	return nil
}
Exemplo n.º 27
0
// Move cursor to next.
func (rc *SQLiteRows) Next(dest []driver.Value) error {
	rv := C.sqlite3_step(rc.s.s)
	if rv == C.SQLITE_DONE {
		return io.EOF
	}
	if rv != C.SQLITE_ROW {
		rv = C.sqlite3_reset(rc.s.s)
		if rv != C.SQLITE_OK {
			return rc.s.c.lastError()
		}
		return nil
	}

	if rc.decltype == nil {
		rc.decltype = make([]string, rc.nc)
		for i := 0; i < rc.nc; i++ {
			rc.decltype[i] = strings.ToLower(C.GoString(C.sqlite3_column_decltype(rc.s.s, C.int(i))))
		}
	}

	for i := range dest {
		switch C.sqlite3_column_type(rc.s.s, C.int(i)) {
		case C.SQLITE_INTEGER:
			val := int64(C.sqlite3_column_int64(rc.s.s, C.int(i)))
			switch rc.decltype[i] {
			case "timestamp", "datetime":
				dest[i] = time.Unix(val, 0)
			case "boolean":
				dest[i] = val > 0
			default:
				dest[i] = val
			}
		case C.SQLITE_FLOAT:
			dest[i] = float64(C.sqlite3_column_double(rc.s.s, C.int(i)))
		case C.SQLITE_BLOB:
			p := C.sqlite3_column_blob(rc.s.s, C.int(i))
			if p == nil {
				dest[i] = nil
				continue
			}
			n := int(C.sqlite3_column_bytes(rc.s.s, C.int(i)))
			switch dest[i].(type) {
			case sql.RawBytes:
				dest[i] = (*[1 << 30]byte)(unsafe.Pointer(p))[0:n]
			default:
				slice := make([]byte, n)
				copy(slice[:], (*[1 << 30]byte)(unsafe.Pointer(p))[0:n])
				dest[i] = slice
			}
		case C.SQLITE_NULL:
			dest[i] = nil
		case C.SQLITE_TEXT:
			var err error
			s := C.GoString((*C.char)(unsafe.Pointer(C.sqlite3_column_text(rc.s.s, C.int(i)))))

			switch rc.decltype[i] {
			case "timestamp", "datetime":
				for _, format := range SQLiteTimestampFormats {
					if dest[i], err = time.Parse(format, s); err == nil {
						break
					}
				}
				if err != nil {
					// The column is a time value, so return the zero time on parse failure.
					dest[i] = time.Time{}
				}
			default:
				dest[i] = s
			}

		}
	}
	return nil
}