Adds a database to the ServerContext. Attempts a read after it gets the write lock to see if it's already been added by another process. If so, returns either the existing DatabaseContext or an error based on the useExisting flag. Pass in a bucketFromBucketSpecFn to replace the default ConnectToBuc
(ctx context.Context, config DatabaseConfig, options getOrAddDatabaseConfigOptions)
| 656 | // existing DatabaseContext or an error based on the useExisting flag. |
| 657 | // Pass in a bucketFromBucketSpecFn to replace the default ConnectToBucket function. This will cause the failFast argument to be ignored |
| 658 | func (sc *ServerContext) _getOrAddDatabaseFromConfig(ctx context.Context, config DatabaseConfig, options getOrAddDatabaseConfigOptions) (dbcontext *db.DatabaseContext, returnedError error) { |
| 659 | var bucket base.Bucket |
| 660 | // Generate bucket spec and validate whether db already exists |
| 661 | spec, err := GetBucketSpec(ctx, &config, sc.Config) |
| 662 | if err != nil { |
| 663 | return nil, err |
| 664 | } |
| 665 | |
| 666 | dbName := config.Name |
| 667 | if dbName == "" { |
| 668 | dbName = spec.BucketName |
| 669 | } |
| 670 | |
| 671 | // we do not have per database logging parameters, but it is still useful to have the database name in the log context. This must be set again after dbcOptionsFromConfig is called. |
| 672 | ctx = base.DatabaseLogCtx(ctx, dbName, nil) |
| 673 | |
| 674 | defer func() { |
| 675 | if returnedError == nil { |
| 676 | return |
| 677 | } |
| 678 | // database exists in global map, management is deferred to REST api |
| 679 | _, dbRegistered := sc._databases[dbName] |
| 680 | if dbRegistered { |
| 681 | return |
| 682 | } |
| 683 | if dbcontext != nil { |
| 684 | dbcontext.Close(ctx) // will close underlying bucket |
| 685 | } else if bucket != nil { |
| 686 | bucket.Close(ctx) |
| 687 | } |
| 688 | }() |
| 689 | |
| 690 | if err := db.ValidateDatabaseName(dbName); err != nil { |
| 691 | return nil, err |
| 692 | } |
| 693 | |
| 694 | previousDatabase := sc._databases[dbName] |
| 695 | if previousDatabase != nil { |
| 696 | if options.useExisting { |
| 697 | return previousDatabase, nil |
| 698 | } |
| 699 | |
| 700 | return nil, base.HTTPErrorf(http.StatusPreconditionFailed, // what CouchDB returns |
| 701 | "Duplicate database name %q", dbName) |
| 702 | } |
| 703 | |
| 704 | if config.DbConfig.CacheConfig != nil { |
| 705 | if config.DbConfig.CacheConfig.ChannelCacheConfig != nil { |
| 706 | if config.DbConfig.CacheConfig.ChannelCacheConfig.EnableStarChannel != nil && !*config.DbConfig.CacheConfig.ChannelCacheConfig.EnableStarChannel { |
| 707 | base.WarnfCtx(ctx, `enable_star_channel config option is set to false, set it to true`) |
| 708 | sc._handleInvalidDatabaseConfig(ctx, spec.BucketName, config, db.NewDatabaseError(db.DatabaseEnableStarChannelFalseError)) |
| 709 | return nil, errors.New("enable_star_channel in cache config is set to false, please set the value to true") |
| 710 | } |
| 711 | } |
| 712 | } |
| 713 | |
| 714 | // Generate database context options from config and server context |
| 715 | contextOptions, err := dbcOptionsFromConfig(ctx, sc, &config.DbConfig, dbName) |