Example #1
0
func (s *Stmt) Exec(args ...interface{}) error {
	s.args = fmt.Sprintf(" %v", []interface{}(args))
	rv := C.sqlite3_reset(s.stmt)
	if rv != 0 {
		return s.c.error(rv)
	}

	n := int(C.sqlite3_bind_parameter_count(s.stmt))
	if n != len(args) {
		return errors.New(fmt.Sprintf("incorrect argument count for Stmt.Exec: have %d want %d", len(args), n))
	}

	for i, v := range args {
		var str string
		switch v := v.(type) {
		case []byte:
			var p *byte
			if len(v) > 0 {
				p = &v[0]
			}
			if rv := C.my_bind_blob(s.stmt, C.int(i+1), unsafe.Pointer(p), C.int(len(v))); rv != 0 {
				return s.c.error(rv)
			}
			continue

		case nil:
			if rv := C.sqlite3_bind_null(s.stmt, C.int(i+1)); rv != 0 {
				return s.c.error(rv)
			}
			continue

		case int:
			if rv := C.sqlite3_bind_int(s.stmt, C.int(i+1), C.int(v)); rv != 0 {
				return s.c.error(rv)
			}
			continue

		case bool:
			intVal := 0
			if v {
				intVal = 1
			}
			if rv := C.sqlite3_bind_int(s.stmt, C.int(i+1), C.int(intVal)); rv != 0 {
				return s.c.error(rv)
			}
			continue

		default:
			str = fmt.Sprint(v)
		}

		cstr := C.CString(str)
		rv := C.my_bind_text(s.stmt, C.int(i+1), cstr, C.int(len(str)))
		C.free(unsafe.Pointer(cstr))
		if rv != 0 {
			return s.c.error(rv)
		}
	}
	return nil
}
Example #2
0
// Prepare query string. Return a new statement.
func (c *SQLiteConn) Prepare(query string) (driver.Stmt, error) {
	pquery := C.CString(query)
	defer C.free(unsafe.Pointer(pquery))
	var s *C.sqlite3_stmt
	var tail *C.char
	rv := C.sqlite3_prepare_v2(c.db, pquery, -1, &s, &tail)
	if rv != C.SQLITE_OK {
		return nil, c.lastError()
	}
	var t string
	if tail != nil && *tail != '\000' {
		t = strings.TrimSpace(C.GoString(tail))
	}
	nv := int(C.sqlite3_bind_parameter_count(s))
	var nn []string
	for i := 0; i < nv; i++ {
		pn := C.GoString(C.sqlite3_bind_parameter_name(s, C.int(i+1)))
		if len(pn) > 1 && pn[0] == '$' && 48 <= pn[1] && pn[1] <= 57 {
			nn = append(nn, C.GoString(C.sqlite3_bind_parameter_name(s, C.int(i+1))))
		}
	}
	ss := &SQLiteStmt{c: c, s: s, nv: nv, nn: nn, t: t}
	runtime.SetFinalizer(ss, (*SQLiteStmt).Close)
	return ss, nil
}
Example #3
0
func (s *Stmt) Exec(args ...interface{}) error {
	s.args = fmt.Sprintf(" %v", []interface{}(args))
	rv := C.sqlite3_reset(s.stmt)
	if rv != 0 {
		return s.c.error(rv)
	}

	n := int(C.sqlite3_bind_parameter_count(s.stmt))
	if n != len(args) {
		return errors.New(fmt.Sprintf("incorrect argument count for Stmt.Exec: have %d want %d", len(args), n))
	}

	for i, v := range args {
		var str string
		var rv C.int
		if v == nil {
			rv = C.sqlite3_bind_null(s.stmt, C.int(i+1))
		} else {
			switch v := v.(type) {
			case []byte:
				var p *byte
				if len(v) > 0 {
					p = &v[0]
				}
				if rv := C.my_bind_blob(s.stmt, C.int(i+1), unsafe.Pointer(p), C.int(len(v))); rv != 0 {
					return s.c.error(rv)
				}
				continue

			case bool:
				if v {
					str = "1"
				} else {
					str = "0"
				}
			case time.Time:
				str = v.In(time.UTC).Format(ISO8601)
			case NullTime:
				if v.Valid {
					str = v.Time.Format(ISO8601)
				} else {
					if rv := C.sqlite3_bind_null(s.stmt, C.int(i+1)); rv != 0 {
						return s.c.error(rv)
					}
					continue
				}
			default:
				str = fmt.Sprint(v)
			}

			cstr := C.CString(str)
			rv = C.my_bind_text(s.stmt, C.int(i+1), cstr, C.int(len(str)))
			C.free(unsafe.Pointer(cstr))
		}
		if rv != 0 {
			return s.c.error(rv)
		}
	}
	return nil
}
Example #4
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 #5
0
func (s *Stmt) Exec(args ...interface{}) os.Error {
	var rv C.int
	var str string
	var cstr *C.char

	if rv = C.sqlite3_reset(s.stmt); rv != 0 {
		return s.c.error(rv)
	}

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

	for i, v := range args {
		switch v := v.(type) {
		case []byte:
			var p *byte

			if len(v) > 0 {
				p = &v[0]
			}

			if rv = C.my_bind_blob(s.stmt, C.int(i+1), unsafe.Pointer(p), C.int(len(v))); rv != 0 {
				return s.c.error(rv)
			}
			continue

		case bool:
			if v {
				str = "1"
			} else {
				str = "0"
			}

		default:
			str = fmt.Sprint(v)
		}

		cstr = C.CString(str)
		rv = C.my_bind_text(s.stmt, C.int(i+1), cstr, C.int(len(str)))
		C.free(unsafe.Pointer(cstr))

		if rv != 0 {
			return s.c.error(rv)
		}
	}
	return nil
}
Example #6
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
}
Example #7
0
func (self *sqlStatement) sqlBindParameterCount() int {
	return int(C.sqlite3_bind_parameter_count(self.handle))
}
Example #8
0
// Return a number of parameters.
func (s *SQLiteStmt) NumInput() int {
	return int(C.sqlite3_bind_parameter_count(s.s))
}
Example #9
0
// BindParameterCount returns the number of SQL parameters.
// FIXME If parameters of the ?NNN form are used, there may be gaps in the list.
// (See http://sqlite.org/c3ref/bind_parameter_count.html)
func (s *Stmt) BindParameterCount() int {
	if s.bindParameterCount == -1 {
		s.bindParameterCount = int(C.sqlite3_bind_parameter_count(s.stmt))
	}
	return s.bindParameterCount
}
Example #10
0
func (s *Statement) Parameters() int {
	return int(C.sqlite3_bind_parameter_count(s.cptr))
}
Example #11
0
File: driver.go Project: rsc/sqlite
func (s *stmt) start(args []driver.Value) error {
	if err := s.reset(); err != nil {
		return err
	}

	n := int(C.sqlite3_bind_parameter_count(s.stmt))
	if n != len(args) {
		return fmt.Errorf("incorrect argument count for command: have %d want %d", len(args), n)
	}

	for i, v := range args {
		var str string
		switch v := v.(type) {
		case nil:
			if rv := C.sqlite3_bind_null(s.stmt, C.int(i+1)); rv != 0 {
				return s.c.error(rv)
			}
			continue

		case float64:
			if rv := C.sqlite3_bind_double(s.stmt, C.int(i+1), C.double(v)); rv != 0 {
				return s.c.error(rv)
			}
			continue

		case int64:
			if rv := C.sqlite3_bind_int64(s.stmt, C.int(i+1), C.sqlite3_int64(v)); rv != 0 {
				return s.c.error(rv)
			}
			continue

		case []byte:
			var p *byte
			if len(v) > 0 {
				p = &v[0]
			}
			if rv := C.my_bind_blob(s.stmt, C.int(i+1), unsafe.Pointer(p), C.int(len(v))); rv != 0 {
				return s.c.error(rv)
			}
			continue

		case bool:
			var vi int64
			if v {
				vi = 1
			}
			if rv := C.sqlite3_bind_int64(s.stmt, C.int(i+1), C.sqlite3_int64(vi)); rv != 0 {
				return s.c.error(rv)
			}
			continue

		case time.Time:
			str = v.UTC().Format(timefmt[0])

		case string:
			str = v

		default:
			str = fmt.Sprint(v)
		}

		cstr := C.CString(str)
		rv := C.my_bind_text(s.stmt, C.int(i+1), cstr, C.int(len(str)))
		C.free(unsafe.Pointer(cstr))
		if rv != 0 {
			return s.c.error(rv)
		}
	}

	return nil
}
Example #12
0
File: driver.go Project: rsc/sqlite
func (s *stmt) NumInput() int {
	if s.closed {
		panic("database/sql/driver: misuse of sqlite driver: NumInput after Close")
	}
	return int(C.sqlite3_bind_parameter_count(s.stmt))
}
Example #13
0
func (stmt Stmt) NumInput() int {
	return int(C.sqlite3_bind_parameter_count(stmt.stmt))
}