// Model returns a new ModelQuery object that can be used to perform model-based DB operations.
// The model passed to this method should be a pointer to a model struct.
483505
func (b *SqliteBuilder) Model(model interface{}) *ModelQuery {
	return NewModelQuery(model, b.db.FieldMapper, b.db, b)
}
581454
func (b *MssqlBuilder) Model(model interface{}) *ModelQuery {
	return NewModelQuery(model, b.db.FieldMapper, b.db, b)
}
875081
func Load(filename string) (*Model, error) {
	f, err := os.Open(filename)
	if err != nil {
		return nil, err
	}
	defer f.Close()
	model, err := FromReader(f)
	if err != nil {
		model = new(Model)
		if err1 := model.convertOldFormat(filename); err1 != nil {
			return model, err1
		}
		return model, nil
	}
	return model, nil
}
754683
func (st stateShim) Model() (Model, error) {
	m, err := st.State.Model()
	return m, err
}
313417
func (c *ModelCommandBase) ModelName() (string, error) {
	c.assertRunStarted()
	if err := c.maybeInitModel(); err != nil {
		return "", errors.Trace(err)
	}
	return c._modelName, nil
}
660967
func (st *State) modelQueryForUser(user names.UserTag, isSuperuser bool) (mongo.Query, SessionCloser, error) {
	var modelQuery mongo.Query
	models, closer := st.db().GetCollection(modelsC)
	if isSuperuser {
		// Fast path, we just return all the models that aren't Importing
		modelQuery = models.Find(bson.M{"migration-mode": bson.M{"$ne": MigrationModeImporting}})
	} else {
		// Start by looking up model uuids that the user has access to, and then load only the records that are
		// included in that set
		var modelUUID struct {
			UUID string `bson:"object-uuid"`
		}
		modelUsers, userCloser := st.db().GetRawCollection(modelUsersC)
		defer userCloser()
		query := modelUsers.Find(bson.D{{"user", user.Id()}})
		query.Select(bson.M{"object-uuid": 1, "_id": 0})
		query.Batch(100)
		iter := query.Iter()
		var modelUUIDs []string
		for iter.Next(&modelUUID) {
			modelUUIDs = append(modelUUIDs, modelUUID.UUID)
		}
		if err := iter.Close(); err != nil {
			closer()
			return nil, nil, errors.Trace(err)
		}
		modelQuery = models.Find(bson.M{
			"_id":            bson.M{"$in": modelUUIDs},
			"migration-mode": bson.M{"$ne": MigrationModeImporting},
		})
	}
	modelQuery.Sort("name", "owner")
	return modelQuery, closer, nil
}
935623
func (b *PgsqlBuilder) Model(model interface{}) *ModelQuery {
	return NewModelQuery(model, b.db.FieldMapper, b.db, b)
}
138031
func deleteModel(ctx context.Context, model *Model, exec Executor, list []interface{}) (int64, error) {
	// Note: you might be tempted to think that the DELETE statement
	// could have the form:
	//
	//   DELETE FROM <table> WHERE (<col1>=<val1> AND <col2>=<val2>) OR (<col1>=<val3> ...)
	//
	// This works well when the number of rows to delete is smallish,
	// but somewhere around 500 rows (or perhaps it is the size of the
	// WHERE expression), MySQL switches to an inefficient form of
	// processing this statement. The result is that batch deletions
	// would switchover from being faster than single deletions, to
	// being much slower.

	// This is unfortunately complex. How do we group by the n-1 prefix
	// of primary key columns? First off, we generate the encoded SQL
	// values for all of the primary keys. Mildly complicated because we
	// want to avoid excessive memory allocation here.

	// buf will contain all of the encoded SQL values. We keep pointers
	// into it for each of the rows and each of the keys within the
	// row. But because the underlying []byte in buf can change when we
	// append more values, we have to use integer indices instead of
	// byte slices.
	var buf bytes.Buffer
	n := len(model.delete.traversals)
	keybuf := make([]keyInfo, len(list)*n)
	rows := make([]rowInfo, len(list))
	hooks := model.delete.hooks

	for j, obj := range list {
		v := reflect.Indirect(reflect.ValueOf(obj))
		if err := hooks.pre(obj, exec); err != nil {
			return -1, err
		}
		keys := keybuf[j*n : (j+1)*n]
		for i, traversal := range model.delete.traversals {
			start := buf.Len()
			err := encodeSQLValue(&buf, v.FieldByIndex(traversal).Interface())
			if err != nil {
				return -1, err
			}
			keys[i] = keyInfo{start, buf.Len()}
		}
		rows[j].keys = keys
		rows[j].obj = obj
	}

	// We've encoded all the row keys. Now sort the rows. This will
	// allow us to easily find all of the rows that are identical for
	// the prefix of n-1 columns.
	grouper := &rowGrouper{
		n:    n,
		buf:  buf.Bytes(),
		rows: rows,
	}
	sort.Sort(grouper)

	// Buffers for the encoded vals and arguments that will be used for
	// the AND and IN expression. The buffers are the max size to
	// minimize reallocations, though it is possible we'll only use a
	// handful of values in the same batch.
	valbuf := make([]EncodedVal, len(rows)+n-1)
	argbuf := make(ValExprs, 0, len(rows))
	var inTuple ValTuple
	inTuple.Exprs = argbuf

	// Initialize the and-expr. The and-expr is reused across all
	// batches, but we change the values for each batch. The andVals are
	// the last n-1 elements of valBuf.
	andVals := valbuf[len(rows):]
	var andExpr BoolExprBuilder
	for j := 0; j < n-1; j++ {
		key := model.delete.keyColumns[j].Eq(&andVals[j])
		if j == 0 {
			andExpr = key
		} else {
			andExpr = andExpr.And(key)
		}
	}

	var count int64
	var start int
	for i := range rows {
		// Add the IN value for the current row.
		valbuf[i].Val = grouper.rowKey(i, n-1, n-1)
		inTuple.Exprs = append(inTuple.Exprs, &valbuf[i])

		// Flush the batch if this is the last row or if the and-vals (the
		// first n-1 columns) differ from the next row.
		if i == len(rows)-1 ||
			(n > 1 && grouper.compare(i, i+1, n-2) != 0) {
			b := *model.delete.deleteBuilder
			inExpr := model.delete.keyColumns[n-1].InTuple(inTuple)
			if andExpr.BoolExpr == nil {
				b.Where(inExpr)
			} else {
				// Set the and-expr values for the first n-1 columns. These
				// values are identical for the rows in the range [start,i].
				for j := 0; j < n-1; j++ {
					andVals[j].Val = grouper.rowKey(i, j, j)
				}
				b.Where(andExpr.And(inExpr))
			}

			res, err := exec.ExecContext(ctx, &b)
			if err != nil {
				return -1, err
			}

			nrows, err := res.RowsAffected()
			if err != nil {
				return -1, err
			}
			count += nrows

			// Run the hooks immediately for the objects that have been
			// deleted.
			for j := start; j <= i; j++ {
				if err := hooks.post(rows[j].obj, exec); err != nil {
					return -1, err
				}
			}

			// Reset for the next batch.
			start = i + 1
			inTuple.Exprs = argbuf
		}
	}

	return count, nil
}
548303
func (c *Client) DumpModel(model names.ModelTag, simplified bool) (map[string]interface{}, error) {
	if bestVer := c.BestAPIVersion(); bestVer < 3 {
		logger.Debugf("calling older dump model on v%d", bestVer)
		if simplified {
			logger.Warningf("simplified dump-model not available, server too old")
		}
		return c.dumpModelV2(model)
	}

	var results params.StringResults
	entities := params.DumpModelRequest{
		Entities:   []params.Entity{{Tag: model.String()}},
		Simplified: simplified,
	}

	err := c.facade.FacadeCall("DumpModels", entities, &results)
	if err != nil {
		return nil, errors.Trace(err)
	}
	if count := len(results.Results); count != 1 {
		return nil, errors.Errorf("unexpected result count: %d", count)
	}
	result := results.Results[0]
	if result.Error != nil {
		return nil, result.Error
	}
	// Parse back into a map.
	var asMap map[string]interface{}
	err = yaml.Unmarshal([]byte(result.Result), &asMap)
	if err != nil {
		return nil, errors.Trace(err)
	}

	return asMap, nil
}
737030
func (db *baseDB) Query(model, query interface{}, params ...interface{}) (res Result, err error) {
	return db.query(context.TODO(), model, query, params...)
}
1068295
func (q *Query) Find(model interface{}, id interface{}) error {
	m := &Model{Value: model}
	idq := m.whereID()
	switch t := id.(type) {
	case uuid.UUID:
		return q.Where(idq, t.String()).First(model)
	case string:
		l := len(t)
		if l > 0 {
			// Handle leading '0':
			// if the string have a leading '0' and is not "0", prevent parsing to int
			if t[0] != '0' || l == 1 {
				var err error
				id, err = strconv.Atoi(t)
				if err != nil {
					return q.Where(idq, t).First(model)
				}
			}
		}
	}

	return q.Where(idq, id).First(model)
}
33638
func (a *MovAvgAggregation) Model(model MovAvgModel) *MovAvgAggregation {
	a.model = model
	return a
}
903529
func (st *State) Model() (*Model, error) {
	model := &Model{
		st: st,
	}
	if err := model.refresh(st.modelTag.Id()); err != nil {
		return nil, errors.Trace(err)
	}
	return model, nil
}
1202797
func (m *Model) CAASModel() (*CAASModel, error) {
	if m.Type() != ModelTypeCAAS {
		return nil, errors.NotSupportedf("called CAASModel() on a non-CAAS Model")
	}
	return &CAASModel{
		Model: m,
		mb:    m.st,
	}, nil
}
634887
func (tx *Tx) Model(model ...interface{}) *orm.Query {
	return orm.NewQuery(tx, model...)
}
932091
func (c *Client) ModelInfo() (params.ModelInfo, error) {
	if err := c.checkCanRead(); err != nil {
		return params.ModelInfo{}, err
	}
	state := c.api.stateAccessor
	conf, err := state.ModelConfig()
	if err != nil {
		return params.ModelInfo{}, err
	}
	model, err := state.Model()
	if err != nil {
		return params.ModelInfo{}, err
	}

	info := params.ModelInfo{
		DefaultSeries:  config.PreferredSeries(conf),
		CloudTag:       names.NewCloudTag(model.Cloud()).String(),
		CloudRegion:    model.CloudRegion(),
		ProviderType:   conf.Type(),
		Name:           conf.Name(),
		Type:           string(model.Type()),
		UUID:           model.UUID(),
		OwnerTag:       model.Owner().String(),
		Life:           params.Life(model.Life().String()),
		ControllerUUID: state.ControllerTag().String(),
		IsController:   state.IsController(),
	}
	if agentVersion, exists := conf.AgentVersion(); exists {
		info.AgentVersion = &agentVersion
	}
	if tag, ok := model.CloudCredential(); ok {
		info.CloudCredentialTag = tag.String()
	}
	info.SLA = &params.ModelSLAInfo{
		Level: model.SLALevel(),
		Owner: model.SLAOwner(),
	}
	return info, nil
}
1170921
func (self *Model) Get(id interface{}, into interface{}) error {
	if record, err := self.db.Retrieve(self.collection.Name, id); err == nil {
		return record.Populate(into, self.collection)
	} else {
		return err
	}
}