예제 #1
0
func (b *Backend) Insert(db *sql.DB, m driver.Model, query string, args ...interface{}) (driver.Result, error) {
	fields := m.Fields()
	if fields.AutoincrementPk {
		q := query + " RETURNING " + fields.MNames[fields.PrimaryKey]
		var id int64
		err := db.QueryRow(q, args...).Scan(&id)
		// We need to perform a "real" insert to find the real error, so
		// just let the code fall to the Exec at the end of the function
		// if there's an error.
		if err == nil {
			return insertResult(id), nil
		}
	}
	return db.Exec(query, args...)
}
예제 #2
0
func (b *Backend) AlterField(db *sql.DB, m driver.Model, table *sql.Table, oldField *sql.Field, newField *sql.Field) error {
	fsql, cons, err := newField.SQL(db, m, table)
	if err != nil {
		return err
	}
	tableName := db.QuoteIdentifier(m.Table())
	if _, err = db.Exec(fmt.Sprintf("ALTER TABLE %s CHANGE COLUMN %s %s", tableName, db.QuoteIdentifier(oldField.Name), fsql)); err != nil {
		return err
	}
	for _, c := range cons {
		if _, err = db.Exec(fmt.Sprintf("ALTER TABLE %s ADD CONSTRAINT %s", tableName, c)); err != nil {
			return err
		}
	}
	return err
}
예제 #3
0
func (b *Backend) AddFields(db *sql.DB, m driver.Model, prevTable *sql.Table, newTable *sql.Table, fields []*sql.Field) error {
	rewrite := false
	for _, v := range fields {
		if !b.canAddField(v) {
			rewrite = true
			break
		}
	}
	if rewrite {
		name := db.QuoteIdentifier(m.Table())
		tmpName := fmt.Sprintf("%s_%s", m.Table(), stringutil.Random(8))
		quotedTmpName := db.QuoteIdentifier(tmpName)
		createSql, err := newTable.SQL(db, b, m, tmpName)
		if err != nil {
			return err
		}
		if _, err := db.Exec(createSql); err != nil {
			return err
		}
		fieldNames := generic.Map(prevTable.Fields, func(f *sql.Field) string { return f.Name }).([]string)
		// The previous table might have fields that we're not part
		// of the new table.
		fieldSet := make(map[string]bool)
		for _, v := range newTable.Fields {
			fieldSet[v.Name] = true
		}
		fieldNames = generic.Filter(fieldNames, func(n string) bool { return fieldSet[n] }).([]string)
		sqlFields := strings.Join(generic.Map(fieldNames, db.QuoteIdentifier).([]string), ", ")
		copySql := fmt.Sprintf("INSERT INTO %s (%s) SELECT %s FROM %s", quotedTmpName, sqlFields, sqlFields, name)
		if _, err := db.Exec(copySql); err != nil {
			return err
		}
		if _, err := db.Exec(fmt.Sprintf("DROP TABLE %s", name)); err != nil {
			return err
		}
		if _, err := db.Exec(fmt.Sprintf("ALTER TABLE %s RENAME TO %s", quotedTmpName, name)); err != nil {
			return err
		}
		return nil
	}
	return b.SqlBackend.AddFields(db, m, prevTable, newTable, fields)
}