Skip to content

Commit b26e8ad

Browse files
committed
First implementation
1 parent 52b50ca commit b26e8ad

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

56 files changed

+296041
-2
lines changed

.github/workflows/main.yml

Lines changed: 219 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,219 @@
1+
name: build sqlitesync
2+
on:
3+
push:
4+
branches:
5+
- main
6+
7+
jobs:
8+
build:
9+
runs-on: ${{ matrix.os }}
10+
name: build for ${{ matrix.name }}-${{ matrix.arch }}
11+
timeout-minutes: 20
12+
strategy:
13+
fail-fast: false
14+
matrix:
15+
include:
16+
- os: ubuntu-latest
17+
arch: x86_64
18+
configure: --with-openssl
19+
name: linux
20+
- os: LinuxARM64
21+
arch: arm64
22+
configure: --with-openssl
23+
name: linux
24+
- os: macos-latest
25+
arch: arm64
26+
configure: --with-secure-transport
27+
name: macos
28+
- os: macos-13
29+
arch: x86_64
30+
configure: --with-secure-transport
31+
name: macos
32+
- os: windows-latest
33+
arch: x86_64
34+
configure: --with-schannel
35+
name: windows
36+
- os: ubuntu-latest
37+
arch: arm64
38+
configure:
39+
--host aarch64-linux-android26
40+
--with-openssl=$ANDROID_NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr
41+
LIBS="-lssl -lcrypto -lc++"
42+
AR=$ANDROID_NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-ar
43+
AS=$ANDROID_NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-as
44+
CC=$ANDROID_NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android26-clang
45+
CXX=$ANDROID_NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android26-clang++
46+
LD=$ANDROID_NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/ld
47+
RANLIB=$ANDROID_NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-ranlib
48+
STRIP=$ANDROID_NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-strip
49+
name: android
50+
- os: ubuntu-latest
51+
arch: x86_64
52+
configure:
53+
--host x86_64-linux-android26
54+
--with-openssl=$ANDROID_NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr
55+
LIBS="-lssl -lcrypto -lc++"
56+
AR=$ANDROID_NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-ar
57+
AS=$ANDROID_NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-as
58+
CC=$ANDROID_NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/x86_64-linux-android26-clang
59+
CXX=$ANDROID_NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/x86_64-linux-android26-clang++
60+
LD=$ANDROID_NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/ld
61+
RANLIB=$ANDROID_NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-ranlib
62+
STRIP=$ANDROID_NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-strip
63+
name: android
64+
- os: macos-latest
65+
arch: arm64
66+
configure:
67+
--host=arm64-apple-darwin
68+
--with-secure-transport
69+
CFLAGS="-arch arm64 -isysroot $(xcrun --sdk iphoneos --show-sdk-path) -miphoneos-version-min=11.0"
70+
name: ios
71+
- os: macos-latest
72+
arch: arm64
73+
configure:
74+
--host=arm64-apple-darwin
75+
--with-secure-transport
76+
CFLAGS="-arch arm64 -isysroot $(xcrun --sdk iphonesimulator --show-sdk-path) -miphonesimulator-version-min=11.0"
77+
name: isim
78+
- os: macos-latest
79+
arch: x86_64
80+
configure:
81+
--host=x86_64-apple-darwin
82+
--with-secure-transport
83+
CFLAGS="-arch x86_64 -isysroot $(xcrun --sdk iphonesimulator --show-sdk-path) -miphonesimulator-version-min=11.0"
84+
name: isim
85+
86+
defaults:
87+
run:
88+
shell: ${{ matrix.os == 'windows-latest' && 'msys2 {0}' || 'bash' }}
89+
env:
90+
MAKEFLAGS: -j 8
91+
92+
steps:
93+
94+
- uses: actions/[email protected]
95+
96+
- uses: msys2/[email protected]
97+
if: matrix.os == 'windows-latest'
98+
with:
99+
msystem: mingw64
100+
install: >-
101+
mingw-w64-x86_64-cc
102+
mingw-w64-x86_64-autotools make
103+
104+
- uses: robinraju/[email protected]
105+
with:
106+
repository: curl/curl
107+
tag: 'curl-8_12_1'
108+
extract: true
109+
fileName: curl-*.tar.gz
110+
111+
- name: build boringssl
112+
if: matrix.name == 'android'
113+
run: |
114+
git clone https://boringssl.googlesource.com/boringssl
115+
cd boringssl
116+
mkdir build
117+
cd build
118+
cmake \
119+
-DANDROID_ABI=${{ matrix.arch == 'arm64' && 'arm64-v8a' || 'x86_64' }} \
120+
-DANDROID_PLATFORM=android-26 \
121+
-DCMAKE_TOOLCHAIN_FILE=${ANDROID_NDK}/build/cmake/android.toolchain.cmake \
122+
-DOPENSSL_SMALL=1 \
123+
-DCMAKE_BUILD_TYPE=Release \
124+
..
125+
make
126+
127+
cd ..
128+
TOOLCHAIN="${ANDROID_NDK_HOME}/toolchains/llvm/prebuilt/linux-x86_64"
129+
cp build/libssl.a $TOOLCHAIN/sysroot/usr/lib/
130+
cp build/libcrypto.a $TOOLCHAIN/sysroot/usr/lib/
131+
cp -r include/openssl $TOOLCHAIN/sysroot/usr/include/
132+
133+
- name: build curl
134+
run: |
135+
136+
folder=$(ls -d curl-*/ 2>/dev/null | head -n 1)
137+
cd $folder
138+
139+
./configure \
140+
--without-libpsl \
141+
--disable-alt-svc \
142+
--disable-ares \
143+
--disable-cookies \
144+
--disable-basic-auth \
145+
--disable-digest-auth \
146+
--disable-kerberos-auth \
147+
--disable-negotiate-auth \
148+
--disable-aws \
149+
--disable-dateparse \
150+
--disable-dnsshuffle \
151+
--disable-doh \
152+
--disable-form-api \
153+
--disable-hsts \
154+
--disable-ipv6 \
155+
--disable-libcurl-option \
156+
--disable-manual \
157+
--disable-mime \
158+
--disable-netrc \
159+
--disable-ntlm \
160+
--disable-ntlm-wb \
161+
--disable-progress-meter \
162+
--disable-proxy \
163+
--disable-pthreads \
164+
--disable-socketpair \
165+
--disable-threaded-resolver \
166+
--disable-tls-srp \
167+
--disable-verbose \
168+
--disable-versioned-symbols \
169+
--enable-symbol-hiding \
170+
--without-brotli \
171+
--without-zstd \
172+
--without-libidn2 \
173+
--without-librtmp \
174+
--without-zlib \
175+
--without-nghttp2 \
176+
--without-ngtcp2 \
177+
--disable-shared \
178+
--disable-ftp \
179+
--disable-file \
180+
--disable-ipfs \
181+
--disable-ldap \
182+
--disable-ldaps \
183+
--disable-rtsp \
184+
--disable-dict \
185+
--disable-telnet \
186+
--disable-tftp \
187+
--disable-pop3 \
188+
--disable-imap \
189+
--disable-smb \
190+
--disable-smtp \
191+
--disable-gopher \
192+
--disable-mqtt \
193+
--disable-docs \
194+
--enable-static \
195+
${{matrix.configure}}
196+
make
197+
198+
# save avg 1kb more with these options
199+
# --disable-debug \
200+
# --enable-optimize \
201+
# --disable-curldebug \
202+
# --disable-get-easy-options \
203+
# --without-fish-functions-dir \
204+
# --without-zsh-functions-dir \
205+
# --without-libgsasl \
206+
207+
cd ..
208+
mkdir -p network/curl/${{ matrix.name }}
209+
mv $folder/lib/.libs/libcurl.a network/curl/${{ matrix.name }}/lib${{matrix.arch}}.a
210+
211+
- uses: actions/[email protected]
212+
with:
213+
name: libcurl-${{ matrix.name }}-${{ matrix.arch }}
214+
path: network/curl/${{ matrix.name }}/lib${{matrix.arch}}.a
215+
if-no-files-found: error
216+
217+
- name: build sqlitesync
218+
run: |
219+
echo "TODO: build sqlitesync"

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
.DS_Store

Makefile

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
# Makefile
2+
3+
# Compiler and flags
4+
CC = gcc
5+
NO_COVERAGE_FLAGS = -Wall -Wextra -Wno-unused-parameter -I$(SRC_DIR) -I$(TEST_DIR) -I$(SQLITE_DIR) -I$(CURL_DIR)
6+
CFLAGS = $(NO_COVERAGE_FLAGS) -DCLOUDSYNC_OMIT_NETWORK=1 -DCLOUDSYNC_OMIT_PRINT_RESULT=1 -fprofile-arcs -ftest-coverage
7+
EXTENSION_FLAGS = $(NO_COVERAGE_FLAGS) -O3 -fPIC
8+
9+
ifeq ($(shell uname -s),Darwin)
10+
CONFIG_DARWIN=y
11+
else ifeq ($(OS),Windows_NT)
12+
CONFIG_WINDOWS=y
13+
else
14+
CONFIG_LINUX=y
15+
endif
16+
17+
ifdef CONFIG_DARWIN
18+
LOADABLE_EXTENSION=dylib
19+
endif
20+
21+
ifdef CONFIG_LINUX
22+
LOADABLE_EXTENSION=so
23+
CFLAGS += -lm
24+
endif
25+
26+
ifdef CONFIG_WINDOWS
27+
LOADABLE_EXTENSION=dll
28+
endif
29+
30+
LDFLAGS = -lcurl
31+
32+
# setting the -lgcov flag on macOS leads to a linker error
33+
ifeq ($(shell uname), Linux)
34+
LDFLAGS += -lgcov
35+
DYLIB_LDFLAGS =
36+
else
37+
LDFLAGS +=
38+
DYLIB_LDFLAGS = -dynamiclib
39+
endif
40+
41+
# Directories and files
42+
SRC_DIR = src
43+
TEST_DIR = test
44+
SQLITE_DIR = sqlite
45+
OBJ_DIR = obj
46+
CURL_DIR = network/curl/macos
47+
COV_DIR = coverage
48+
CUSTOM_CSS = $(TEST_DIR)/sqlitecloud.css
49+
TARGET_PREFIX=dist
50+
51+
TARGET_NAME=cloudsync
52+
TARGET_LOADABLE=$(TARGET_PREFIX)/$(TARGET_NAME).$(LOADABLE_EXTENSION)
53+
TARGET_STATIC=$(TARGET_PREFIX)/libsqlite_$(TARGET_NAME)0.a
54+
TARGET_STATIC_H=$(TARGET_PREFIX)/sqlite-$(TARGET_NAME).h
55+
TARGET_CLI=$(TARGET_PREFIX)/sqlite3
56+
57+
# Files and objects
58+
LIB_HEADERS = $(wildcard $(SRC_DIR)/*.h) $(wildcard $(SQLITE_DIR)/*.h)
59+
SRC_FILES = $(filter-out $(SQLITE_DIR)/sqlite3.c $(TEST_DIR)/unittest.c $(SRC_DIR)/lz4.c, $(wildcard $(SRC_DIR)/*.c) $(wildcard $(TEST_DIR)/*.c) $(wildcard $(SQLITE_DIR)/*.c))
60+
LIB_OBJ_FILES = $(patsubst %.c, $(TARGET_PREFIX)/$(OBJ_DIR)/%.o, $(notdir $(SRC_FILES)))
61+
LIB_SQLITE_OBJ = $(TARGET_PREFIX)/$(OBJ_DIR)/sqlite3.o
62+
63+
SRC_FILES = $(filter-out $(SQLITE_DIR)/sqlite3.c $(TEST_DIR)/unittest.c $(SRC_DIR)/lz4.c, $(wildcard $(SRC_DIR)/*.c) $(wildcard $(TEST_DIR)/*.c) $(wildcard $(SQLITE_DIR)/*.c))
64+
OBJ_FILES = $(patsubst %.c, $(OBJ_DIR)/%.o, $(notdir $(SRC_FILES)))
65+
LZ4_OBJ = $(OBJ_DIR)/lz4.o
66+
SQLITE_OBJ = $(OBJ_DIR)/sqlite3.o
67+
UNIT_TEST_OBJ = $(OBJ_DIR)/unittest.o
68+
HEADERS = $(wildcard $(SRC_DIR)/*.h) $(wildcard $(TEST_DIR)/*.h) $(wildcard $(SQLITE_DIR)/*.h)
69+
70+
# Default target
71+
extension: $(TARGET_LOADABLE)
72+
all: $(TARGET_LOADABLE)
73+
74+
# Loadable library
75+
$(TARGET_LOADABLE): $(LIB_OBJ_FILES) $(LIB_SQLITE_OBJ) $(LZ4_OBJ) $(TARGET_PREFIX)
76+
$(CC) $(LIB_OBJ_FILES) $(LZ4_OBJ) $(LIB_SQLITE_OBJ) -o $@ $(LDFLAGS) $(DYLIB_LDFLAGS)
77+
78+
# Object files for the lib (with coverage flags)
79+
$(TARGET_PREFIX)/$(OBJ_DIR)/%.o: $(SRC_DIR)/%.c $(LIB_HEADERS) | $(TARGET_PREFIX)/$(OBJ_DIR)
80+
$(CC) $(EXTENSION_FLAGS) -c $< -o $@
81+
$(LIB_SQLITE_OBJ): $(SQLITE_DIR)/sqlite3.c $(LIB_HEADERS) | $(TARGET_PREFIX)/$(OBJ_DIR)
82+
$(CC) $(EXTENSION_FLAGS) -c $< -o $@
83+
84+
# Object files (with coverage flags)
85+
$(OBJ_DIR)/%.o: $(SRC_DIR)/%.c $(HEADERS) | $(OBJ_DIR)
86+
$(CC) $(CFLAGS) -c $< -o $@
87+
88+
$(OBJ_DIR)/%.o: $(TEST_DIR)/%.c $(HEADERS) | $(OBJ_DIR)
89+
$(CC) $(CFLAGS) -c $< -o $@
90+
91+
$(OBJ_DIR)/%.o: $(SQLITE_DIR)/%.c $(HEADERS) | $(OBJ_DIR)
92+
$(CC) $(CFLAGS) -c $< -o $@
93+
94+
# Compile lz4.c without coverage flags
95+
$(LZ4_OBJ): $(SRC_DIR)/lz4.c $(HEADERS) | $(OBJ_DIR)
96+
$(CC) $(NO_COVERAGE_FLAGS) -c $< -o $@
97+
98+
# Compile sqlite3.c without coverage flags
99+
$(SQLITE_OBJ): $(SQLITE_DIR)/sqlite3.c $(HEADERS) | $(OBJ_DIR)
100+
$(CC) $(NO_COVERAGE_FLAGS) -DSQLITE_CORE=1 -c $< -o $@
101+
102+
# Compile unittest.c without coverage flags
103+
$(UNIT_TEST_OBJ): $(TEST_DIR)/unittest.c $(HEADERS) | $(OBJ_DIR)
104+
$(CC) $(CFLAGS) -c $< -o $@
105+
106+
# Create object directory if not exists
107+
$(OBJ_DIR):
108+
mkdir -p $(OBJ_DIR)
109+
$(TARGET_PREFIX)/$(OBJ_DIR):
110+
mkdir -p $(TARGET_PREFIX)/$(OBJ_DIR)
111+
112+
$(TARGET_PREFIX):
113+
mkdir -p $(TARGET_PREFIX)
114+
115+
# Build unit test executable
116+
UNIT_TEST = unittest
117+
$(UNIT_TEST): CFLAGS += -DSQLITE_CORE=1 -DCLOUDSYNC_UNITTEST=1
118+
$(UNIT_TEST): $(OBJ_FILES) $(SQLITE_OBJ) $(LZ4_OBJ) $(UNIT_TEST_OBJ)
119+
$(CC) $(CFLAGS) $(OBJ_FILES) $(LZ4_OBJ) $(SQLITE_OBJ) $(UNIT_TEST_OBJ) -o $@ $(LDFLAGS)
120+
121+
# Run code coverage (--css-file $(CUSTOM_CSS))
122+
coverage: $(UNIT_TEST)
123+
./$(UNIT_TEST)
124+
mkdir -p $(COV_DIR)
125+
lcov --capture --directory . --output-file $(COV_DIR)/coverage.info
126+
genhtml $(COV_DIR)/coverage.info --output-directory $(COV_DIR)
127+
128+
# Clean up generated files
129+
clean:
130+
rm -rf $(OBJ_DIR) $(UNIT_TEST) $(COV_DIR) *.gcda *.gcno *.gcov dist/*
131+
132+
.PHONY: all clean coverage extension $(DEPS)

README.md

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,30 @@
1-
# sqlite-sync
2-
SQLiteSync is a local-first SQLite extension using CRDTs for seamless, conflict-free data sync and real-time collaboration across devices.
1+
# SQLiteSync
2+
3+
SQLiteSync is a powerful SQLite extension that provides a local-first experience using Conflict-Free Replicated Data Types (CRDTs). Designed to enable seamless data synchronization and collaboration, SQLiteSync allows developers to build distributed applications with minimal effort while leveraging the reliability and simplicity of SQLite.
4+
5+
## Key Features
6+
7+
- **Local-First Approach**: Work offline with confidence. SQLiteSync ensures data integrity and merges changes effortlessly when devices reconnect.
8+
- **CRDT Algorithms**: Resolve conflicts automatically with proven CRDT techniques, eliminating the need for manual resolution.
9+
- **Lightweight and Efficient**: As a SQLite extension, SQLiteSync retains the minimal overhead and speed SQLite is known for.
10+
- **Flexible Integration**: Add synchronization capabilities to existing SQLite-based applications with minimal modifications.
11+
- **Reliable Data Sharing**: Enable collaboration across devices and users without compromising performance or data consistency.
12+
13+
## Installation
14+
15+
To use SQLiteSync, you need SQLite version 3.x or later.
16+
17+
### Build from Source
18+
19+
1. Clone the repository:
20+
21+
```bash
22+
git clone https://github.com/sqlitecloud/sqlitesync.git
23+
cd sqlitesync
24+
```
25+
26+
2. Build the extension:
27+
28+
```bash
29+
make
30+
```

0 commit comments

Comments
 (0)