示例#1
0
func (b *Backend) DefineField(db *sql.DB, m driver.Model, table *sql.Table, field *sql.Field) (string, []string, error) {
	if field.HasOption(sql.OptionAutoIncrement) {
		if field.Constraint(sql.ConstraintPrimaryKey) == nil {
			return "", nil, fmt.Errorf("%s can only auto increment the primary key", b.Name())
		}
	}
	def, constraints, err := b.SqlBackend.DefineField(db, m, table, field)
	if err == nil {
		def = strings.Replace(strings.Replace(def, "DEFAULT false", "DEFAULT 0", -1), "DEFAULT true", "DEFAULT 1", -1)
	}
	return def, constraints, err
}
示例#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) DefineField(db *sql.DB, m driver.Model, table *sql.Table, field *sql.Field) (string, []string, error) {
	def, cons, err := b.SqlBackend.DefineField(db, m, table, field)
	if err != nil {
		return "", nil, err
	}
	if ref := field.Constraint(sql.ConstraintForeignKey); ref != nil {
		if pos := strings.Index(def, " REFERENCES"); pos >= 0 {
			def = def[:pos]
		}
		refTable := ref.References.Table()
		refField := ref.References.Field()
		fkName := db.QuoteIdentifier(fmt.Sprintf("%s_%s_%s_%s", m.Table(), field.Name, refTable, refField))
		cons = append(cons, fmt.Sprintf("FOREIGN KEY %s(%s) REFERENCES %s(%s)", fkName, db.QuoteIdentifier(field.Name),
			db.QuoteIdentifier(refTable), db.QuoteIdentifier(refField)))
	}
	return strings.Replace(def, "AUTOINCREMENT", "AUTO_INCREMENT", -1), cons, nil
}
示例#4
0
func (b *Backend) Inspect(db *sql.DB, m driver.Model) (*sql.Table, error) {
	name := db.QuoteString(m.Table())
	rows, err := db.Query(fmt.Sprintf("PRAGMA table_info(%s)", name))
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	fieldsByName := make(map[string]*sql.Field)
	var fields []*sql.Field
	for rows.Next() {
		var cid int
		var f sql.Field
		var notnull int
		var def *string
		var pk int
		if err := rows.Scan(&cid, &f.Name, &f.Type, &notnull, &def, &pk); err != nil {
			return nil, err
		}
		f.Type = strings.ToUpper(f.Type)
		if notnull != 0 {
			f.AddConstraint(sql.ConstraintNotNull)
		}
		if def != nil {
			f.Default = *def
		}
		if pk != 0 {
			f.AddConstraint(sql.ConstraintPrimaryKey)
		}
		fields = append(fields, &f)
		fieldsByName[f.Name] = &f
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	rows, err = db.Query(fmt.Sprintf("PRAGMA foreign_key_list(%s)", name))
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	for rows.Next() {
		var id, seq int
		var table, from, to, onUpdate, onDelete, match string
		if err := rows.Scan(&id, &seq, &table, &from, &to, &onUpdate, &onDelete, &match); err != nil {
			return nil, err
		}
		field := fieldsByName[from]
		field.Constraints = append(field.Constraints, &sql.Constraint{Type: sql.ConstraintForeignKey, References: sql.MakeReference(table, to)})
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	if len(fields) > 0 {
		return &sql.Table{Fields: fields}, nil
	}
	return nil, nil
}
示例#5
0
func (b *Backend) canAddField(f *sql.Field) bool {
	// These are a supeset of the actual resctrictions, for
	// simplicity. See https://www.sqlite.org/lang_altertable.html
	// for more details.
	return f.Constraint(sql.ConstraintPrimaryKey) != nil && f.Constraint(sql.ConstraintUnique) == nil && f.Default == ""
}