Example #1
0
File: driver.go Project: rsc/sqlite
func (s *stmt) Query(args []driver.Value) (driver.Rows, error) {
	if s.closed {
		panic("database/sql/driver: misuse of sqlite driver: Query after Close")
	}
	if s.rows {
		panic("database/sql/driver: misuse of sqlite driver: Query with active Rows")
	}

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

	s.rows = true
	if s.colnames == nil {
		n := int64(C.sqlite3_column_count(s.stmt))
		s.colnames = make([]string, n)
		s.coltypes = make([]string, n)
		for i := range s.colnames {
			s.colnames[i] = C.GoString(C.sqlite3_column_name(s.stmt, C.int(i)))
			s.coltypes[i] = strings.ToLower(C.GoString(C.sqlite3_column_decltype(s.stmt, C.int(i))))
		}
	}
	return &rows{s}, nil
}
Example #2
0
func (s *SQLiteStmt) query(ctx context.Context, args []namedValue) (driver.Rows, error) {
	if err := s.bind(args); err != nil {
		return nil, err
	}

	rows := &SQLiteRows{
		s:        s,
		nc:       int(C.sqlite3_column_count(s.s)),
		cols:     nil,
		decltype: nil,
		cls:      s.cls,
		done:     make(chan struct{}),
	}

	go func() {
		select {
		case <-ctx.Done():
			C.sqlite3_interrupt(s.c.db)
			rows.Close()
		case <-rows.done:
		}
	}()

	return rows, nil
}
Example #3
0
// newStmt creates a new prepared statement.
func newStmt(c *Conn, sql string) (*Stmt, error) {
	zSql := sql + "\x00"

	var stmt *C.sqlite3_stmt
	var tail *C.char
	rc := C.sqlite3_prepare_v2(c.db, cStr(zSql), -1, &stmt, &tail)
	if rc != OK {
		return nil, libErr(rc, c.db)
	}

	// stmt will be nil if sql contained only comments or whitespace. s.Tail may
	// be useful to the caller, so s is still returned without an error.
	s := &Stmt{conn: c, stmt: stmt}
	if stmt != nil {
		if s.nVars = int(C.sqlite3_bind_parameter_count(stmt)); s.nVars == 0 {
			s.varNames = unnamedVars
		}
		s.nCols = int(C.sqlite3_column_count(stmt))
		runtime.SetFinalizer(s, (*Stmt).Close)
	}
	if tail != nil {
		if n := cStrOffset(zSql, tail); n < len(sql) {
			sql, s.Tail = sql[:n], sql[n:]
		}
	}
	s.text = sql
	return s, nil
}
Example #4
0
func (rows Rows) Columns() []string {
	count := int(C.sqlite3_column_count(rows.stmt))
	cols := make([]string, count)
	for i := 0; i < count; i++ {
		cols[i] = C.GoString(C.sqlite3_column_name(rows.stmt, C.int(i)))
	}
	return cols
}
Example #5
0
func (s *Stmt) Scan(args ...interface{}) error {
	n := int(C.sqlite3_column_count(s.stmt))
	if n != len(args) {
		return errors.New(fmt.Sprintf("incorrect argument count for Stmt.Scan: have %d want %d", len(args), n))
	}

	for i, v := range args {
		n := C.sqlite3_column_bytes(s.stmt, C.int(i))
		p := C.sqlite3_column_blob(s.stmt, C.int(i))
		if p == nil && n > 0 {
			return errors.New("got nil blob")
		}
		var data []byte
		if n > 0 {
			data = (*[1 << 30]byte)(unsafe.Pointer(p))[0:n]
		}
		switch v := v.(type) {
		case *[]byte:
			*v = data
		case *string:
			*v = string(data)
		case *bool:
			*v = string(data) == "1"
		case *int:
			x, err := strconv.Atoi(string(data))
			if err != nil {
				return errors.New("arg " + strconv.Itoa(i) + " as int: " + err.Error())
			}
			*v = x
		case *int64:
			x, err := strconv.ParseInt(string(data), 10, 64)
			if err != nil {
				return errors.New("arg " + strconv.Itoa(i) + " as int64: " + err.Error())
			}
			*v = x
		case *float64:
			x, err := strconv.ParseFloat(string(data), 64)
			if err != nil {
				return errors.New("arg " + strconv.Itoa(i) + " as float64: " + err.Error())
			}
			*v = x
		default:
			return errors.New("unsupported type in Scan: " + reflect.TypeOf(v).String())
		}
	}
	return nil
}
Example #6
0
// exec resets the prepared statement, binds new parameter values, and executes
// the first step.
func (s *Stmt) exec(args []interface{}) (err error) {
	if s.haveRow {
		s.Reset()
	}
	if named := namedArgs(args); named != nil {
		err = s.bindNamed(named)
	} else {
		err = s.bindUnnamed(args)
	}
	if err == nil {
		err = s.step()
		if s.nCols > 0 {
			// If the statement was recompiled (v2 interface, no indication),
			// then column counts, names, and declarations may have changed and
			// need to be reloaded.
			s.nCols = int(C.sqlite3_column_count(s.stmt))
			s.colNames = s.colNames[:0]
			s.colDecls = s.colDecls[:0]
		}
	} else if s.nVars > 0 {
		C.sqlite3_clear_bindings(s.stmt)
	}
	return
}
Example #7
0
// Query the statement with arguments. Return records.
func (s *SQLiteStmt) Query(args []driver.Value) (driver.Rows, error) {
	if err := s.bind(args); err != nil {
		return nil, err
	}
	return &SQLiteRows{s, int(C.sqlite3_column_count(s.s)), nil, nil, s.cls}, nil
}
Example #8
0
func (self *sqlStatement) sqlColumnCount() int {
	return int(C.sqlite3_column_count(self.handle))
}
Example #9
0
// ColumnCount returns the number of columns in the result set for the statement (with or without row).
// (See http://sqlite.org/c3ref/column_count.html)
func (s *Stmt) ColumnCount() int {
	if s.columnCount == -1 {
		s.columnCount = int(C.sqlite3_column_count(s.stmt))
	}
	return s.columnCount
}
Example #10
0
func (s *Statement) Columns() int {
	return int(C.sqlite3_column_count(s.cptr))
}
Example #11
0
// Return the number of columns in the result set returned by the prepared statement.
func (h *Statement) ColumnCount() int {
	return int(C.sqlite3_column_count(h.cptr))
}
Example #12
0
func Columns(stmnt *Stmt) int {
	return int(C.sqlite3_column_count(stmnt.stmt))
}
Example #13
0
func (s *Stmt) Scan(args ...interface{}) os.Error {
	n := int(C.sqlite3_column_count(s.stmt))
	if n != len(args) {
		return os.NewError("incorrect argument count")
	}

	for i, v := range args {
		n := C.sqlite3_column_bytes(s.stmt, C.int(i))
		p := C.sqlite3_column_blob(s.stmt, C.int(i))

		if p == nil && n > 0 {
			return os.NewError("got nil blob")
		}

		var data []byte
		if n > 0 {
			// fix(jimt): Must make a copy here. Once Stmt.Finalize() is called,
			// this memory becomes invalid. This was done on purpose according
			// to Russ: http://code.google.com/p/gosqlite/issues/detail?id=1
			// I prefer it with the copy statement here. Behaviour otherwise is
			// misleading and cost me 3 hours of hair pulling.
			data = make([]byte, n)
			copy(data, (*[1<<31 - 1]byte)(unsafe.Pointer(p))[0:n])
		}

		switch v := v.(type) {
		case *[]byte:
			*v = data
		case *string:
			*v = string(data)
		case *bool:
			*v = string(data) == "1"
		case *int:
			x, err := strconv.Atoi(string(data))
			if err != nil {
				return os.NewError("arg " + strconv.Itoa(i) + " as int: " + err.String())
			}
			*v = x
		case *int8:
			x, err := strconv.Atoi(string(data))
			if err != nil {
				return os.NewError("arg " + strconv.Itoa(i) + " as int: " + err.String())
			}
			*v = int8(x)
		case *int16:
			x, err := strconv.Atoi(string(data))
			if err != nil {
				return os.NewError("arg " + strconv.Itoa(i) + " as int: " + err.String())
			}
			*v = int16(x)
		case *int32:
			x, err := strconv.Atoi(string(data))
			if err != nil {
				return os.NewError("arg " + strconv.Itoa(i) + " as int: " + err.String())
			}
			*v = int32(x)
		case *int64:
			x, err := strconv.Atoi64(string(data))
			if err != nil {
				return os.NewError("arg " + strconv.Itoa(i) + " as int64: " + err.String())
			}
			*v = x
		case *uint:
			x, err := strconv.Atoui(string(data))
			if err != nil {
				return os.NewError("arg " + strconv.Itoa(i) + " as int: " + err.String())
			}
			*v = x
		case *uint8:
			x, err := strconv.Atoui(string(data))
			if err != nil {
				return os.NewError("arg " + strconv.Itoa(i) + " as int: " + err.String())
			}
			*v = uint8(x)
		case *uint16:
			x, err := strconv.Atoui(string(data))
			if err != nil {
				return os.NewError("arg " + strconv.Itoa(i) + " as int: " + err.String())
			}
			*v = uint16(x)
		case *uint32:
			x, err := strconv.Atoui(string(data))
			if err != nil {
				return os.NewError("arg " + strconv.Itoa(i) + " as int: " + err.String())
			}
			*v = uint32(x)
		case *uint64:
			x, err := strconv.Atoui64(string(data))
			if err != nil {
				return os.NewError("arg " + strconv.Itoa(i) + " as int64: " + err.String())
			}
			*v = x
		case *float:
			x, err := strconv.Atof(string(data))
			if err != nil {
				return os.NewError("arg " + strconv.Itoa(i) + " as float64: " + err.String())
			}
			*v = x
		case *float32:
			x, err := strconv.Atof32(string(data))
			if err != nil {
				return os.NewError("arg " + strconv.Itoa(i) + " as float64: " + err.String())
			}
			*v = x
		case *float64:
			x, err := strconv.Atof64(string(data))
			if err != nil {
				return os.NewError("arg " + strconv.Itoa(i) + " as float64: " + err.String())
			}
			*v = x
		default:
			return os.NewError("unsupported type in Scan: " + reflect.Typeof(v).String())
		}
	}
	return nil
}
Example #14
0
func (s *Stmt) NumColumns() int {
	return int(C.sqlite3_column_count(s.stmt))
}
Example #15
0
func (s *Stmt) Scan(args ...interface{}) error {
	n := int(C.sqlite3_column_count(s.stmt))
	if n != len(args) {
		return errors.New(fmt.Sprintf("incorrect argument count for Stmt.Scan: have %d want %d", len(args), n))
	}

	for i, v := range args {
		if C.sqlite3_column_type(s.stmt, C.int(i)) == C.SQLITE_NULL {
			switch v := v.(type) {
			case *[]byte:
				*v = nil
			case *string:
				*v = ""
			case *bool:
				*v = false
			case *int:
				*v = 0
			case *int64:
				*v = 0
			case *uint64:
				*v = 0
			case *uint32:
				*v = 0
			case *float64:
				*v = 0.0
			case *NullTime:
				*v = NullTime{Valid: false}
			default:
				return errors.New("unsupported type in Scan: " + reflect.TypeOf(v).String())
			}

		} else {

			n := C.sqlite3_column_bytes(s.stmt, C.int(i))
			p := C.sqlite3_column_blob(s.stmt, C.int(i))
			if p == nil && n > 0 {
				return errors.New("got nil blob")
			}
			var data []byte
			if n > 0 {
				data = (*[1 << 30]byte)(unsafe.Pointer(p))[0:n]
			}
			switch v := v.(type) {
			case *[]byte:
				*v = data
			case *string:
				*v = string(data)
			case *bool:
				*v = string(data) == "1"
			case *int:
				x, err := strconv.Atoi(string(data))
				if err != nil {
					return errors.New("arg " + strconv.Itoa(i) + " as int: " + err.Error())
				}
				*v = x
			case *int64:
				x, err := strconv.ParseInt(string(data), 10, 64)
				if err != nil {
					return errors.New("arg " + strconv.Itoa(i) + " as int64: " + err.Error())
				}
				*v = x
			case *uint64:
				x, err := strconv.ParseUint(string(data), 10, 64)
				if err != nil {
					return errors.New("arg " + strconv.Itoa(i) + " as int64: " + err.Error())
				}
				*v = x
			case *uint32:
				x, err := strconv.ParseUint(string(data), 10, 32)
				if err != nil {
					return errors.New("arg " + strconv.Itoa(i) + " as int64: " + err.Error())
				}
				*v = uint32(x)
			case *float64:
				x, err := strconv.ParseFloat(string(data), 64)
				if err != nil {
					return errors.New("arg " + strconv.Itoa(i) + " as float64: " + err.Error())
				}
				*v = x
			case *NullTime:
				x, err := time.Parse(ISO8601, string(data))
				if err != nil {
					return errors.New("arg " + strconv.Itoa(i) + " as time: " + err.Error())
				}
				*v = NullTime{Time: x, Valid: true}
			case *time.Time:
				x, err := time.Parse(ISO8601, string(data))
				if err != nil {
					return errors.New("arg " + strconv.Itoa(i) + " as time: " + err.Error())
				}
				*v = x

			default:
				return errors.New("unsupported type in Scan: " + reflect.TypeOf(v).String())
			}
		}
	}
	return nil
}