Skip to content
Merged
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
18 changes: 14 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,16 @@ endif
T_LDFLAGS += -fprofile-arcs -ftest-coverage
endif

# Native network support only for Apple platforms
ifdef NATIVE_NETWORK
RELEASE_OBJ += $(patsubst %.m, $(BUILD_RELEASE)/%_m.o, $(notdir $(wildcard $(SRC_DIR)/*.m)))
LDFLAGS += -framework Foundation
CFLAGS += -DCLOUDSYNC_OMIT_CURL

$(BUILD_RELEASE)/%_m.o: %.m
$(CC) $(CFLAGS) -fobjc-arc -O3 -fPIC -c $< -o $@
endif

# Windows .def file generation
$(DEF_FILE):
ifeq ($(PLATFORM),windows)
Expand Down Expand Up @@ -314,15 +324,15 @@ clean:
help:
@echo "SQLite Sync Extension Makefile"
@echo "Usage:"
@echo " make [PLATFORM=platform] [ARCH=arch] [ANDROID_NDK=\$$ANDROID_HOME/ndk/26.1.10909125] [target]"
@echo " make [PLATFORM=platform] [ARCH=arch] [ANDROID_NDK=\$$ANDROID_HOME/ndk/26.1.10909125] [NATIVE_NETWORK=ON] [target]"
@echo ""
@echo "Platforms:"
@echo " linux (default on Linux)"
@echo " macos (default on macOS)"
@echo " macos (default on macOS - can be compiled with native network support)"
@echo " windows (default on Windows)"
@echo " android (needs ARCH to be set to x86_64 or arm64-v8a and ANDROID_NDK to be set)"
@echo " ios (only on macOS)"
@echo " isim (only on macOS)"
@echo " ios (only on macOS - can be compiled with native network support)"
@echo " isim (only on macOS - can be compiled with native network support)"
@echo " wasm (needs wabt[brew install wabt/sudo apt install wabt])"
@echo ""
@echo "Targets:"
Expand Down
2 changes: 1 addition & 1 deletion examples/sport-tracker-app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
"vite": "^7.0.0"
},
"dependencies": {
"@sqliteai/sqlite-sync-wasm": "^3.49.2-sync-0.8.9",
"@sqliteai/sqlite-sync-wasm": "^3.49.2-sync-0.8.20",
"@types/react": "^19.1.8",
"@types/react-dom": "^19.1.6",
"@vitejs/plugin-react": "^4.6.0",
Expand Down
11 changes: 11 additions & 0 deletions examples/sport-tracker-app/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ const AppContent: React.FC = () => {
const [refreshTrigger, setRefreshTrigger] = useState(0);
const [sqliteSyncVersion, setSqliteSyncVersion] = useState<string>("");
const [sqliteVersion, setSqliteVersion] = useState<string>("");
const [loginError, setLoginError] = useState<string>("");

// Coach mode - true when logged in user is named "coach"
const isCoachMode = (session: UserSession | null): boolean => {
Expand Down Expand Up @@ -392,6 +393,15 @@ const AppContent: React.FC = () => {
);
}

if (loginError) {
return (
<div className="error-container">
<h2>Login Error</h2>
<p>{loginError}</p>
</div>
);
}

if (!isInitialized || loading) {
return (
<div className="loading-container">
Expand Down Expand Up @@ -425,6 +435,7 @@ const AppContent: React.FC = () => {
onLogout={handleLogout}
onUsersLoad={loadUsers}
onRefresh={handleRefreshData}
onError={setLoginError}
/>
<DatabaseStatus
onCountsLoad={loadCounts}
Expand Down
6 changes: 1 addition & 5 deletions examples/sport-tracker-app/src/SQLiteSync.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,11 +60,7 @@ export class SQLiteSync {
throw new Error("Database not available");
}

try {
await this.db.sqliteSyncNetworkSync();
} catch (e) {
console.error("Error checking SQLite Sync changes:", e);
}
await this.db.sqliteSyncNetworkSync();
}

/**
Expand Down
3 changes: 3 additions & 0 deletions examples/sport-tracker-app/src/components/UserLogin.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ interface UserLoginProps {
onLogout: () => Promise<void>;
onUsersLoad: () => void;
onRefresh: () => void;
onError?: (error: string) => void; // Optional error handler
}

const UserLogin: React.FC<UserLoginProps> = ({
Expand All @@ -24,6 +25,7 @@ const UserLogin: React.FC<UserLoginProps> = ({
onLogout,
onUsersLoad,
onRefresh,
onError
}) => {
const { db } = useDatabase();
const [selectedUserId, setSelectedUserId] = useState<string>("");
Expand Down Expand Up @@ -113,6 +115,7 @@ const UserLogin: React.FC<UserLoginProps> = ({
error
);
console.warn("SQLite Sync: Falling back to local refresh only");
if(onError) onError("SQLite Sync - Failed to sync with SQLite Cloud: " + error);
}
} else {
console.log(
Expand Down
1 change: 0 additions & 1 deletion examples/sport-tracker-app/src/db/database.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,6 @@ export class Database {
return this.sendMessage("sqliteSyncSetToken", token);
}


async sqliteSyncNetworkSync(): Promise<void> {
return this.sendMessage("sqliteSyncNetworkSync");
}
Expand Down
2 changes: 1 addition & 1 deletion src/cloudsync.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
#include "sqlite3.h"
#endif

#define CLOUDSYNC_VERSION "0.8.12"
#define CLOUDSYNC_VERSION "0.8.20"

int sqlite3_cloudsync_init (sqlite3 *db, char **pzErrMsg, const sqlite3_api_routines *pApi);

Expand Down
2 changes: 1 addition & 1 deletion src/dbutils.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//
// dbutils.c
// cloudsync_test
// cloudsync
//
// Created by Marco Bambini on 23/09/24.
//
Expand Down
36 changes: 27 additions & 9 deletions src/network.m
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//
// network.m
// cloudsync_network_test
// cloudsync
//
// Created by Marco Bambini on 23/05/25.
//
Expand Down Expand Up @@ -58,7 +58,7 @@ bool network_compute_endpoints (sqlite3_context *context, network_data *data, co
}

char *site_id = network_data_get_siteid(data);
char *port_or_default = (port) ? (char *)port.UTF8String : CLOUDSYNC_DEFAULT_ENDPOINT_PORT;
char *port_or_default = (port && strcmp(port.UTF8String, "8860") != 0) ? (char *)port.UTF8String : CLOUDSYNC_DEFAULT_ENDPOINT_PORT;

NSString *check_endpoint = [NSString stringWithFormat:@"%s://%s:%s/%s%s/%s", scheme.UTF8String, host.UTF8String, port_or_default, CLOUDSYNC_ENDPOINT_PREFIX, database.UTF8String, site_id];
NSString *upload_endpoint = [NSString stringWithFormat: @"%s://%s:%s/%s%s/%s/%s", scheme.UTF8String, host.UTF8String, port_or_default, CLOUDSYNC_ENDPOINT_PREFIX, database.UTF8String, site_id, CLOUDSYNC_ENDPOINT_UPLOAD];
Expand Down Expand Up @@ -147,15 +147,19 @@ NETWORK_RESULT network_receive_buffer(network_data *data, const char *endpoint,
}

__block NSData *responseData = nil;
__block NSError *responseError = nil;
__block NSString *responseError = nil;
__block NSInteger statusCode = 0;
__block NSInteger errorCode = 0;

dispatch_semaphore_t sema = dispatch_semaphore_create(0);

NSURLSession *session = [NSURLSession sharedSession];
NSURLSessionDataTask *task = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
responseData = data;
responseError = error;
if (error) {
responseError = [error localizedDescription];
errorCode = [error code];
}
if ([response isKindOfClass:[NSHTTPURLResponse class]]) {
statusCode = [(NSHTTPURLResponse *)response statusCode];
}
Expand All @@ -166,9 +170,10 @@ NETWORK_RESULT network_receive_buffer(network_data *data, const char *endpoint,
dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);

if (!responseError && (statusCode >= 200 && statusCode < 300)) {
size_t len = [responseData length];
// check if OK should be returned
if (len == 0) return (NETWORK_RESULT){CLOUDSYNC_NETWORK_OK, NULL, 0, NULL, NULL};
if (responseData == nil || [responseData length] == 0) {
return (NETWORK_RESULT){CLOUDSYNC_NETWORK_OK, NULL, 0, NULL, NULL};
}

// otherwise return a buffer
NETWORK_RESULT result = {};
Expand All @@ -181,18 +186,31 @@ NETWORK_RESULT network_receive_buffer(network_data *data, const char *endpoint,
result.buffer = (char *)responseData.bytes;
result.xdata = (void *)CFBridgingRetain(responseData);
}
result.blen = len;
result.blen = [responseData length];
result.xfree = network_buffer_cleanup;

return result;
}

// return error
NETWORK_RESULT result = {};
NSString *msg = (responseError) ? [responseError localizedDescription] : [NSString stringWithCString:"Unknown network URL" encoding:NSUTF8StringEncoding];
NSString *msg = nil;
if (responseError) {
msg = responseError;
} else if (responseData && [responseData length] > 0) {
// Use the actual response body as the error message
msg = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
if (!msg) {
msg = [NSString stringWithFormat:@"HTTP %ld error", (long)statusCode];
}
} else {
msg = [NSString stringWithFormat:@"HTTP %ld error", (long)statusCode];
}
result.code = CLOUDSYNC_NETWORK_ERROR;
result.buffer = (char *)msg.UTF8String;
result.xdata = (void *)CFBridgingRetain(msg);
result.xfree = network_buffer_cleanup;
result.blen = (responseError) ? (size_t)responseError.code : (size_t)statusCode;
result.blen = responseError ? (size_t)errorCode : (size_t)statusCode;

return result;
}
21 changes: 18 additions & 3 deletions src/wasm.c
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
//
// wasm.c
// cloudsync
//
// Created by Gioele Cantoni on 25/06/25.
//

#ifdef SQLITE_WASM_EXTRA_INIT
#define CLOUDSYNC_OMIT_CURL

Expand Down Expand Up @@ -96,7 +103,6 @@ NETWORK_RESULT network_receive_buffer (network_data *data, const char *endpoint,
}

if (fetch->status >= 200 && fetch->status < 300) {

if (blen > 0 && buffer) {
char *buf = (char*)malloc(blen + 1);
if (buf) {
Expand All @@ -112,9 +118,18 @@ NETWORK_RESULT network_receive_buffer (network_data *data, const char *endpoint,
result.code = CLOUDSYNC_NETWORK_ERROR;
if (fetch->statusText && fetch->statusText[0]) {
result.buffer = strdup(fetch->statusText);
result.blen = sizeof(fetch->statusText);
result.xfree = free;
} else if (blen > 0 && buffer) {
char *buf = (char*)malloc(blen + 1);
if (buf) {
memcpy(buf, buffer, blen);
buf[blen] = 0;
result.buffer = buf;
result.blen = blen;
result.xfree = free;
}
}
result.blen = sizeof(fetch->statusText);
result.xfree = free;
}

// cleanup
Expand Down
3 changes: 2 additions & 1 deletion test/main.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//
// main.c
// sqlite-sync
// cloudsync
//
// Created by Gioele Cantoni on 05/06/25.
// Set CONNECTION_STRING, APIKEY and WEBLITE environment variables before running this test.
Expand Down Expand Up @@ -358,6 +358,7 @@ void* worker(void* arg) {

int main (void) {
int rc = SQLITE_OK;
remove(DB_PATH); // remove the database file if it exists

cloudsync_memory_init(1);

Expand Down
Loading