Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cherry pick 3.2.1-3.2.2 to master #3363

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
233 changes: 210 additions & 23 deletions CouchbaseLite.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

49 changes: 37 additions & 12 deletions Objective-C/CBLConsoleLogger.m
Original file line number Diff line number Diff line change
Expand Up @@ -19,33 +19,58 @@

#import "CBLConsoleLogger.h"
#import "CBLLog+Internal.h"
#import "CBLLog+Admin.h"
#import "CBLLogSinks+Internal.h"

@implementation CBLConsoleLogger

@synthesize level=_level, domains=_domains;

- (instancetype) initWithLogLevel: (CBLLogLevel)level {
- (instancetype) initWithDefault {
self = [super init];
if (self) {
_level = level;
_level = kCBLLogLevelWarning;
_domains = kCBLLogDomainAll;
}
return self;
}

- (void) setLevel: (CBLLogLevel)level {
_level = level;
[[CBLLog sharedInstance] synchronizeCallbackLogLevel];
CBL_LOCK(self) {
_level = level;
[self updateConsoleLogSink];
}
}

- (CBLLogLevel) level {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this SOP? You need the lock on the set, but not on the get?

CBL_LOCK(self) {
return _level;
}
}

- (void) setDomains: (CBLLogDomain)domains {
CBL_LOCK(self) {
_domains = domains;
[self updateConsoleLogSink];
}
}

- (CBLLogDomain) domains {
CBL_LOCK(self) {
return _domains;
}
}

- (void) updateConsoleLogSink {
CBLConsoleLogSink* sink = [[CBLConsoleLogSink alloc] initWithLevel: _level domains: _domains];
sink.version = kCBLLogAPIOld;
CBLLogSinks.console = sink;
}

- (void) logWithLevel: (CBLLogLevel)level domain: (CBLLogDomain)domain message: (NSString*)message {
if (self.level > level || (self.domains & domain) == 0)
return;

NSString* levelName = CBLLog_GetLevelName(level);
NSString* domainName = CBLLog_GetDomainName(domain);
NSLog(@"CouchbaseLite %@ %@: %@", domainName, levelName, message);
- (void) logWithLevel: (CBLLogLevel)level
domain: (CBLLogDomain)domain
message: (nonnull NSString*)message
{
// Do nothing: Logging is an internal functionality.
}

@end
7 changes: 3 additions & 4 deletions Objective-C/CBLDatabase.mm
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@
#import "CBLIndexConfiguration+Internal.h"
#import "CBLIndexSpec.h"
#import "CBLIndex+Internal.h"
#import "CBLLog+Admin.h"
#import "CBLLog+Internal.h"
#import "CBLLogSinks+Internal.h"
#import "CBLMisc.h"
#import "CBLQuery+Internal.h"
#import "CBLQuery+N1QL.h"
Expand Down Expand Up @@ -131,9 +131,8 @@ + (void) CBLInit {

/** Check and show warning if file logging is not configured. */
+ (void) checkFileLogging {
if (!CBLDatabase.log.file.config) {
CBLWarn(Database, @"Database.log.file.config is nil, meaning file logging is disabled. "
"Log files required for product support are not being generated.");
if (!CBLLogSinks.file) {
CBLWarn(Database, @"File logging is disabled. Log files required for product support are not being generated.");
}
}

Expand Down
11 changes: 11 additions & 0 deletions Objective-C/CBLDefaults.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,17 @@ extern const uint64_t kCBLDefaultLogFileMaxSize;
/** [1] 1 rotated file present (2 total, including the currently active log file) */
extern const NSInteger kCBLDefaultLogFileMaxRotateCount;

#pragma mark - CBLFileLogSink

/** [NO] Plaintext is not used, and instead binary encoding is used in log files */
extern const BOOL kCBLDefaultFileLogSinkUsePlaintext;

/** [524288] 512 KiB for the size of a log file */
extern const long long kCBLDefaultFileLogSinkMaxSize;

/** [2] 2 files preserved during each log rotation */
extern const NSInteger kCBLDefaultFileLogSinkMaxKeptFiles;

#pragma mark - CBLFullTextIndexConfiguration

/** [NO] Accents and ligatures are not ignored when indexing via full text search */
Expand Down
8 changes: 8 additions & 0 deletions Objective-C/CBLDefaults.m
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,14 @@

const NSInteger kCBLDefaultLogFileMaxRotateCount = 1;

#pragma mark - CBLFileLogSink

const BOOL kCBLDefaultFileLogSinkUsePlaintext = NO;

const long long kCBLDefaultFileLogSinkMaxSize = 524288;

const NSInteger kCBLDefaultFileLogSinkMaxKeptFiles = 2;

#pragma mark - CBLFullTextIndexConfiguration

const BOOL kCBLDefaultFullTextIndexIgnoreAccents = NO;
Expand Down
109 changes: 50 additions & 59 deletions Objective-C/CBLFileLogger.mm
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,11 @@
// limitations under the License.
//

#import "CBLDefaults.h"
#import "CBLFileLogger.h"
#import "CBLLog+Internal.h"
#import "CBLLogFileConfiguration+Internal.h"
#import "CBLMisc.h"
#import "CBLStatus.h"
#import "CBLStringBytes.h"
#import "CBLVersion.h"
#import "CBLLogSinks+Internal.h"

@implementation CBLFileLogger

Expand All @@ -38,74 +36,67 @@ - (instancetype) initWithDefault {
}

- (void) setLevel: (CBLLogLevel)level {
if (_level != level) {
_level = level;
c4log_setBinaryFileLevel((C4LogLevel)level);
CBL_LOCK(self) {
if (_level != level) {
_level = level;
[self updateFileLogSink];
}
}
}

- (CBLLogLevel) level {
CBL_LOCK(self) {
return _level;
}
}

- (void) setConfig: (CBLLogFileConfiguration*)config {
if (_config != config) {
if (config) {
// Copy and mark as READONLY
config = [[CBLLogFileConfiguration alloc] initWithConfig: config readonly: YES];
CBL_LOCK(self) {
if (_config != config) {
if (config) {
// Copy and mark as READONLY
config = [[CBLLogFileConfiguration alloc] initWithConfig: config readonly: YES];
}
_config = config;
}
_config = config;
[self apply];
[self updateFileLogSink];
}
}

- (void) logWithLevel: (CBLLogLevel)level
domain: (CBLLogDomain)domain
message: (nonnull NSString*)message
{
// Do nothing: Logging will be done in Lite Core
- (CBLLogFileConfiguration*) config {
CBL_LOCK(self) {
return _config;
}
}

- (void) apply {
NSError* error;

if (!_config) {
c4log_setBinaryFileLevel(kC4LogNone);
return;
}

if (![self setupLogDirectory: _config.directory error: &error]) {
CBLWarnError(Database, @"Cannot setup log directory at %@: %@", _config.directory, error);
return;
}

CBLStringBytes directory(_config.directory);

C4LogFileOptions options = {
.log_level = (C4LogLevel)self.level,
.base_path = directory,
.max_size_bytes = (int64_t)_config.maxSize,
.max_rotate_count = (int32_t)_config.maxRotateCount,
.use_plaintext = (bool)_config.usePlainText,
.header = CBLStringBytes([CBLVersion userAgent])
};

C4Error c4err;
if (!c4log_writeToBinaryFile(options, &c4err)) {
convertError(c4err, &error);
CBLWarnError(Database, @"Cannot enable file logging: %@", error);
- (void) updateFileLogSink {
if(_config) {
NSInteger maxRotateCount = (_config.maxRotateCount > 0) ? _config.maxRotateCount : kCBLDefaultLogFileMaxRotateCount;
CBLFileLogSink* sink = [[CBLFileLogSink alloc] initWithLevel: _level
directory: _config.directory
usePlaintext: _config.usePlainText
maxKeptFiles: maxRotateCount + 1
maxFileSize: _config.maxSize
];
sink.version = kCBLLogAPIOld;
CBLLogSinks.file = sink;
} else {
CBLFileLogSink* sink = [[CBLFileLogSink alloc] initWithLevel: kCBLLogLevelNone
directory: @""
usePlaintext: false
maxKeptFiles: 0
maxFileSize: 0
];
sink.version = kCBLLogAPIOld;
CBLLogSinks.file = sink;
}
}

- (BOOL) setupLogDirectory: (NSString*)directory error: (NSError**)outError {
NSError* error;
if (![[NSFileManager defaultManager] createDirectoryAtPath: directory
withIntermediateDirectories: YES
attributes: nil
error: &error]) {
if (!CBLIsFileExistsError(error)) {
if (outError)
*outError = error;
return NO;
}
}
return YES;
- (void) logWithLevel: (CBLLogLevel)level
domain: (CBLLogDomain)domain
message: (nonnull NSString*)message
{
// Do nothing: Logging is an internal functionality.
}

@end
29 changes: 26 additions & 3 deletions Objective-C/CBLFullTextIndexConfiguration.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// CBLFullTextIndexConfiguration.h
// CouchbaseLite
//
// Copyright (c) 2024 Couchbase, Inc All rights reserved.
// Copyright (c) 2025 Couchbase, Inc All rights reserved.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that standard practice is to include them all: 2024, 2025

//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand All @@ -27,6 +27,12 @@ NS_ASSUME_NONNULL_BEGIN
*/
@interface CBLFullTextIndexConfiguration : CBLIndexConfiguration

/**
A predicate expression defining conditions for indexing documents.
Only documents satisfying the predicate are included, enabling partial indexes.
*/
@property (nonatomic, readonly, nullable) NSString* where;

/**
Set the true value to ignore accents/diacritical marks.
*/
Expand All @@ -41,11 +47,28 @@ NS_ASSUME_NONNULL_BEGIN
@property (nonatomic, readonly, nullable) NSString* language;

/**
Constructor for creating a full-text index by using an array of expression strings
Initializes a full-text index by using an array of expression strings
@param expressions The array of expression strings.
@param ignoreAccents The flag to ignore accents/diacritical marks.
@param language Optional language code which is an ISO-639 language such as "en", "fr", etc.
@return The full-text index configuration object.
*/
- (instancetype) initWithExpression: (NSArray<NSString*>*)expressions
ignoreAccents: (BOOL)ignoreAccents
language: (nullable NSString*)language;

/**
Initializes a full-text index with an array of expression strings and an optional where clause for a partial index.
@param where Optional where clause for partial indexing.
@param expressions The array of expression strings.
@param ignoreAccents The flag to ignore accents/diacritical marks.
@param language Optional language code which is an ISO-639 language such as "en", "fr", etc.
@return The full-text index configuration object.
*/
- (instancetype) initWithExpression: (NSArray<NSString*>*)expressions
where: (nullable NSString*)where
ignoreAccents: (BOOL)ignoreAccents
language: (NSString* __nullable)language;
language: (nullable NSString*)language;

@end

Expand Down
20 changes: 15 additions & 5 deletions Objective-C/CBLFullTextIndexConfiguration.m
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// CBLFullTextIndexConfiguration.m
// CouchbaseLite
//
// Copyright (c) 2021 Couchbase, Inc All rights reserved.
// Copyright (c) 2025 Couchbase, Inc All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand All @@ -22,14 +22,25 @@

@implementation CBLFullTextIndexConfiguration

@synthesize ignoreAccents=_ignoreAccents, language=_language;
@synthesize ignoreAccents=_ignoreAccents, language=_language, where=_where;

- (instancetype) initWithExpression: (NSArray<NSString*>*)expressions
ignoreAccents: (BOOL)ignoreAccents
language: (NSString* __nullable)language {
language: (nullable NSString*)language {
return [self initWithExpression: expressions
where: nil
ignoreAccents: ignoreAccents
language: language];
}

- (instancetype) initWithExpression: (NSArray<NSString*>*)expressions
where: (nullable NSString*)where
ignoreAccents: (BOOL)ignoreAccents
language: (nullable NSString*)language {
self = [super initWithIndexType: kC4FullTextIndex
expressions: expressions];
if (self) {
_where = where;
// there is no default 'ignoreAccents', since its NOT an optional argument.
_ignoreAccents = ignoreAccents;
_language = language;
Expand All @@ -39,12 +50,11 @@ - (instancetype) initWithExpression: (NSArray<NSString*>*)expressions

- (C4IndexOptions) indexOptions {
C4IndexOptions c4options = { };

if (!_language)
_language = [[NSLocale currentLocale] objectForKey: NSLocaleLanguageCode];
c4options.language = _language.UTF8String;

c4options.ignoreDiacritics = _ignoreAccents;
c4options.where = _where.UTF8String;
return c4options;
}

Expand Down
9 changes: 6 additions & 3 deletions Objective-C/CBLLog.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,17 @@ NS_ASSUME_NONNULL_BEGIN
@interface CBLLog : NSObject

/** Console logger writing log messages to the system console. */
@property (readonly, nonatomic) CBLConsoleLogger* console;
@property (readonly, nonatomic) CBLConsoleLogger* console
__deprecated_msg("Use CBLLogSinks.console instead.");

/** File logger writing log messages to files. */
@property (readonly, nonatomic) CBLFileLogger* file;
@property (readonly, nonatomic) CBLFileLogger* file
__deprecated_msg("Use CBLLogSinks.file instead.");

/** For setting a custom logger. Changing the log level of the assigned custom logger will require
the custom logger to be reassigned so that the change can be affected. */
@property (nonatomic, nullable) id<CBLLogger> custom;
@property (nonatomic, nullable) id<CBLLogger> custom
__deprecated_msg("Use CBLLogSinks.custom instead.");

/** Not available */
- (instancetype) init NS_UNAVAILABLE;
Expand Down
Loading