// NewCharmRelation creates a new local CharmRelation structure from  the
// charm.Relation structure. NOTE: when we update the database to not store a
// charm.Relation directly in the database, this method should take the state
// structure type.
963316
func NewCharmRelation(cr charm.Relation) CharmRelation {
	return CharmRelation{
		Name:      cr.Name,
		Role:      string(cr.Role),
		Interface: cr.Interface,
		Optional:  cr.Optional,
		Limit:     cr.Limit,
		Scope:     string(cr.Scope),
	}
}
1000440
func (col *CorrelatedColumn) Decorrelate(schema Schema) Expression {
	if schema.GetColumnIndex(&col.Column) == -1 {
		return col
	}
	return &col.Column
}
812125
func (s *DataSource) SetRelationalDatabaseConfig(v *RelationalDatabaseDataSourceConfig) *DataSource {
	s.RelationalDatabaseConfig = v
	return s
}
31268
func (s *RemoteApplication) Relations() (relations []*Relation, err error) {
	return applicationRelations(s.st, s.doc.Name)
}
1236252
func NewDependency(opts ...depConsOpt) *Dependency {
	d := new(Dependency)

	for _, opt := range opts {
		opt(d)
	}
	return d
}
992338
func NewCharmRevisionUpdaterAPI(
	st *state.State,
	resources facade.Resources,
	authorizer facade.Authorizer,
) (*CharmRevisionUpdaterAPI, error) {
	if !authorizer.AuthController() {
		return nil, common.ErrPerm
	}
	return &CharmRevisionUpdaterAPI{
		state: st, resources: resources, authorizer: authorizer}, nil
}
493845
func NewConstraintChecker(ctx Context, constraints []*structs.Constraint) *ConstraintChecker {
	return &ConstraintChecker{
		ctx:         ctx,
		constraints: constraints,
	}
}
1189476
func (st *State) AllCharms() ([]*Charm, error) {
	charmsCollection, closer := st.db().GetCollection(charmsC)
	defer closer()
	var cdoc charmDoc
	var charms []*Charm
	iter := charmsCollection.Find(nsLife.notDead()).Iter()
	for iter.Next(&cdoc) {
		ch := newCharm(st, &cdoc)
		charms = append(charms, ch)
	}
	return charms, errors.Trace(iter.Close())
}
1348756
func (st *State) EndpointsRelation(endpoints ...Endpoint) (*Relation, error) {
	return st.KeyRelation(relationKey(endpoints))
}
1057835
func (st *State) AddRelation(eps ...Endpoint) (r *Relation, err error) {
	key := relationKey(eps)
	defer errors.DeferredAnnotatef(&err, "cannot add relation %q", key)
	// Enforce basic endpoint sanity. The epCount restrictions may be relaxed
	// in the future; if so, this method is likely to need significant rework.
	if len(eps) != 2 {
		return nil, errors.Errorf("relation must have two endpoints")
	}
	if !eps[0].CanRelateTo(eps[1]) {
		return nil, errors.Errorf("endpoints do not relate")
	}

	// Check applications are alive and do checks if one is remote.
	app1, err := aliveApplication(st, eps[0].ApplicationName)
	if err != nil {
		return nil, err
	}
	app2, err := aliveApplication(st, eps[1].ApplicationName)
	if err != nil {
		return nil, err
	}
	if app1.IsRemote() && app2.IsRemote() {
		return nil, errors.Errorf("cannot add relation between remote applications %q and %q", eps[0].ApplicationName, eps[1].ApplicationName)
	}
	remoteRelation := app1.IsRemote() || app2.IsRemote()
	ep0ok := app1.IsRemote() || eps[0].Scope == charm.ScopeGlobal
	ep1ok := app2.IsRemote() || eps[1].Scope == charm.ScopeGlobal
	if remoteRelation && (!ep0ok || !ep1ok) {
		return nil, errors.Errorf("local endpoint must be globally scoped for remote relations")
	}

	// If either endpoint has container scope, so must the other; and the
	// applications's series must also match, because they'll be deployed to
	// the same machines.
	compatibleSeries := true
	if eps[0].Scope == charm.ScopeContainer {
		eps[1].Scope = charm.ScopeContainer
	} else if eps[1].Scope == charm.ScopeContainer {
		eps[0].Scope = charm.ScopeContainer
	} else {
		compatibleSeries = false
	}
	// We only get a unique relation id once, to save on roundtrips. If it's
	// -1, we haven't got it yet (we don't get it at this stage, because we
	// still don't know whether it's sane to even attempt creation).
	id := -1
	// If a application's charm is upgraded while we're trying to add a relation,
	// we'll need to re-validate application sanity.
	var doc *relationDoc
	now := st.clock().Now()
	buildTxn := func(attempt int) ([]txn.Op, error) {
		// Perform initial relation sanity check.
		if exists, err := isNotDead(st, relationsC, key); err != nil {
			return nil, errors.Trace(err)
		} else if exists {
			return nil, errors.AlreadyExistsf("relation %v", key)
		}
		// Collect per-application operations, checking sanity as we go.
		var ops []txn.Op
		var subordinateCount int
		appSeries := map[string][]string{}
		for _, ep := range eps {
			app, err := aliveApplication(st, ep.ApplicationName)
			if err != nil {
				return nil, err
			}
			if app.IsRemote() {
				// If the remote application is known to be terminated, we don't
				// allow a relation to it.
				statusInfo, err := app.Status()
				if err != nil && !errors.IsNotFound(err) {
					return nil, errors.Trace(err)
				}
				if err == nil && statusInfo.Status == status.Terminated {
					return nil, errors.Errorf("remote offer %s is terminated", ep.ApplicationName)
				}
				ops = append(ops, txn.Op{
					C:      remoteApplicationsC,
					Id:     st.docID(ep.ApplicationName),
					Assert: bson.D{{"life", Alive}},
					Update: bson.D{{"$inc", bson.D{{"relationcount", 1}}}},
				})
			} else {
				localApp := app.(*Application)
				if localApp.doc.Subordinate {
					subordinateCount++
				}
				ch, _, err := localApp.Charm()
				if err != nil {
					return nil, errors.Trace(err)
				}
				if !ep.ImplementedBy(ch) {
					return nil, errors.Errorf("%q does not implement %q", ep.ApplicationName, ep)
				}
				charmSeries := ch.Meta().Series
				if len(charmSeries) == 0 {
					charmSeries = []string{localApp.doc.Series}
				}
				appSeries[localApp.doc.Name] = charmSeries
				ops = append(ops, txn.Op{
					C:      applicationsC,
					Id:     st.docID(ep.ApplicationName),
					Assert: bson.D{{"life", Alive}, {"charmurl", ch.URL()}},
					Update: bson.D{{"$inc", bson.D{{"relationcount", 1}}}},
				})
			}
		}
		if compatibleSeries && len(appSeries) > 1 {
			// We need to ensure that there's intersection between the supported
			// series of both applications' charms.
			app1Series := set.NewStrings(appSeries[eps[0].ApplicationName]...)
			app2Series := set.NewStrings(appSeries[eps[1].ApplicationName]...)
			if app1Series.Intersection(app2Series).Size() == 0 {
				return nil, errors.Errorf("principal and subordinate applications' series must match")
			}
		}
		if eps[0].Scope == charm.ScopeContainer && subordinateCount < 1 {
			return nil, errors.Errorf("container scoped relation requires at least one subordinate application")
		}

		// Create a new unique id if that has not already been done, and add
		// an operation to create the relation document.
		if id == -1 {
			var err error
			if id, err = sequence(st, "relation"); err != nil {
				return nil, errors.Trace(err)
			}
		}
		docID := st.docID(key)
		doc = &relationDoc{
			DocID:     docID,
			Key:       key,
			ModelUUID: st.ModelUUID(),
			Id:        id,
			Endpoints: eps,
			Life:      Alive,
		}
		relationStatusDoc := statusDoc{
			Status:    status.Joining,
			ModelUUID: st.ModelUUID(),
			Updated:   now.UnixNano(),
		}
		ops = append(ops, txn.Op{
			C:      relationsC,
			Id:     docID,
			Assert: txn.DocMissing,
			Insert: doc,
		}, createStatusOp(st, relationGlobalScope(id), relationStatusDoc))
		return ops, nil
	}
	if err = st.db().Run(buildTxn); err == nil {
		return &Relation{st, *doc}, nil
	}
	return nil, errors.Trace(err)
}
335777
func NewRelationIdValue(ctx Context, result *int) (*relationIdValue, error) {
	v := &relationIdValue{result: result, ctx: ctx}
	id := -1
	if r, err := ctx.HookRelation(); err == nil {
		id = r.Id()
		v.value = r.FakeId()
	} else if !errors.IsNotFound(err) {
		return nil, errors.Trace(err)
	}
	*result = id
	return v, nil
}
1337941
func NewRelations(config RelationsConfig) (Relations, error) {
	unit, err := config.State.Unit(config.UnitTag)
	if err != nil {
		return nil, errors.Trace(err)
	}
	principalName, subordinate, err := unit.PrincipalName()
	if err != nil {
		return nil, errors.Trace(err)
	}
	leadershipContext := config.NewLeadershipContext(
		config.State.LeadershipSettings,
		config.Tracker,
		config.UnitTag.Id(),
	)
	r := &relations{
		st:            config.State,
		unit:          unit,
		leaderCtx:     leadershipContext,
		subordinate:   subordinate,
		principalName: principalName,
		charmDir:      config.CharmDir,
		relationsDir:  config.RelationsDir,
		relationers:   make(map[int]*Relationer),
		abort:         config.Abort,
	}
	if err := r.init(); err != nil {
		return nil, errors.Trace(err)
	}
	return r, nil
}
1003932
func (r Repository) AddLocalCharm(id *charm.URL, details charm.Charm, force bool) (*charm.URL, error) {
	return id, r.AddCharm(id, params.NoChannel, force)
}
747571
func (r Repository) AddCharm(id *charm.URL, channel params.Channel, force bool) error {
	withRevision := r.addRevision(id)
	alreadyAdded := r.added[string(channel)]

	for _, charm := range alreadyAdded {
		if *withRevision == charm {
			return nil
			// TODO(tsm) check expected behaviour
			//
			// if force {
			// 	return nil
			// } else {
			// 	return errors.NewAlreadyExists(errors.NewErr("%v already added in channel %v", id, channel))
			// }
		}
	}
	r.added[string(channel)] = append(alreadyAdded, *withRevision)
	return nil
}
1026013
func NewCCacheMetric(mkey schema.MKey) *CCacheMetric {
	return &CCacheMetric{
		MKey:   mkey,
		chunks: make(map[uint32]*CCacheChunk),
	}
}
862735
func decorrelate(p LogicalPlan) LogicalPlan {
	if apply, ok := p.(*Apply); ok {
		outerPlan := apply.children[0]
		innerPlan := apply.children[1].(LogicalPlan)
		apply.extractCorColumnsBySchema()
		if len(apply.corCols) == 0 {
			// If the inner plan is non-correlated, the apply will be simplified to join.
			join := &apply.Join
			innerPlan.SetParents(join)
			outerPlan.SetParents(join)
			p = join
		} else if sel, ok := innerPlan.(*Selection); ok {
			// If the inner plan is a selection, we add this condition to join predicates.
			// Notice that no matter what kind of join is, it's always right.
			newConds := make([]expression.Expression, 0, len(sel.Conditions))
			for _, cond := range sel.Conditions {
				newConds = append(newConds, cond.Decorrelate(outerPlan.GetSchema()))
			}
			apply.attachOnConds(newConds)
			innerPlan = sel.children[0].(LogicalPlan)
			apply.SetChildren(outerPlan, innerPlan)
			innerPlan.SetParents(apply)
			return decorrelate(p)
		}
		// TODO: Deal with aggregation and projection.
	}
	newChildren := make([]Plan, 0, len(p.GetChildren()))
	for _, child := range p.GetChildren() {
		newChildren = append(newChildren, decorrelate(child.(LogicalPlan)))
		child.SetParents(p)
	}
	p.SetChildren(newChildren...)
	return p
}
165705
func NewResumeRelationCommand() cmd.Command {
	cmd := &resumeRelationCommand{}
	cmd.newAPIFunc = func() (SetRelationSuspendedAPI, error) {
		root, err := cmd.NewAPIRoot()
		if err != nil {
			return nil, errors.Trace(err)
		}
		return application.NewClient(root), nil

	}
	return modelcmd.Wrap(cmd)
}