From 08932336972c29773cfdf5f210cca7ec99b05703 Mon Sep 17 00:00:00 2001 From: Jonathan Schleifer Date: Sat, 3 Oct 2020 19:47:26 +0000 Subject: [PATCH] Add support for storage FossilOrigin-Name: 3c84d235e55a6f4481f3ccfb4007113716902901544f9a1f011723767ecaa1e4 --- .fossil-settings/ignore-glob | 1 + ObjMatrix.oc | 1 + README.md | 7 +++-- configure.ac | 5 ++++ src/MTXClient.h | 27 +++++++++++++++-- src/MTXClient.m | 18 ++++++++---- src/MTXSQLite3Storage.h | 48 ++++++++++++++++++++++++++++++ src/MTXSQLite3Storage.m | 57 ++++++++++++++++++++++++++++++++++++ src/MTXStorage.h | 33 +++++++++++++++++++++ src/Makefile | 4 ++- src/ObjMatrix.h | 2 ++ tests/tests.m | 3 ++ 12 files changed, 194 insertions(+), 12 deletions(-) create mode 100644 src/MTXSQLite3Storage.h create mode 100644 src/MTXSQLite3Storage.m create mode 100644 src/MTXStorage.h diff --git a/.fossil-settings/ignore-glob b/.fossil-settings/ignore-glob index a7569ab..5d6e1e6 100644 --- a/.fossil-settings/ignore-glob +++ b/.fossil-settings/ignore-glob @@ -19,3 +19,4 @@ config.status configure extra.mk tests/tests +tests/tests.db diff --git a/ObjMatrix.oc b/ObjMatrix.oc index 07e81f6..35a9b4b 100644 --- a/ObjMatrix.oc +++ b/ObjMatrix.oc @@ -1,4 +1,5 @@ package_format 1 package_depends_on ObjOpenSSL +package_depends_on ObjSQLite3 LIBS="-lobjmatrix $LIBS" FRAMEWORK_LIBS="-framework ObjMatrix $FRAMEWORK_LIBS" diff --git a/README.md b/README.md index 87709dc..ea31c46 100644 --- a/README.md +++ b/README.md @@ -9,15 +9,16 @@ It is currently in early development stages. ## How to build it? -You need [ObjFW](https://objfw.nil.im) and -[ObjOpenSSL](https://fossil.nil.im/objopenssl) installed in order to do this. +You need [ObjFW](https://objfw.nil.im), +[ObjOpenSSL](https://fossil.nil.im/objopenssl) and +[ObjSQLite3](https://fossil.nil.im/objsqlite3) installed in order to do this. ObjMatrix uses modern Objective-C, and hence cannot be compiled with GCC, but only with Clang. So install Clang first and ObjFW will automatically pick it up. You can install them all like this: - $ for i in objfw objopenssl objmatrix; do + $ for i in objfw objopenssl objsqlite3 objmatrix; do fossil clone https://fossil.nil.im/$i $i.fossil && mkdir $i && cd $i && diff --git a/configure.ac b/configure.ac index 6bfd96b..b1597ea 100644 --- a/configure.ac +++ b/configure.ac @@ -21,6 +21,11 @@ AS_IF([$OBJFW_CONFIG --package ObjOpenSSL], [ ], [ AC_MSG_ERROR(ObjOpenSSL not found!) ]) +AS_IF([$OBJFW_CONFIG --package ObjSQLite3], [ + OBJFW_CONFIG_FLAGS="$OBJFW_CONFIG_FLAGS --package ObjSQLite3" +], [ + AC_MSG_ERROR(ObjSQLite3 not found!) +]) test x"$OBJC" = x"" && OBJC="$($OBJFW_CONFIG --objc)" diff --git a/src/MTXClient.h b/src/MTXClient.h index 6339f9f..476d73f 100644 --- a/src/MTXClient.h +++ b/src/MTXClient.h @@ -22,6 +22,8 @@ #import +#import "MTXStorage.h" + OF_ASSUME_NONNULL_BEGIN @class MTXClient; @@ -85,39 +87,60 @@ typedef void (^mtx_client_room_join_block_t)(OFString *_Nullable roomID, */ @property (readonly, nonatomic) OFURL *homeserver; +/** + * @brief The storage used by the client. + */ +@property (readonly, nonatomic) id storage; + /** * @brief Creates a new client with the specified access token on the specified * homeserver. * + * @param userID The user ID for the client + * @param deviceID The device ID for the client * @param accessToken The access token for the client * @param homeserver The URL of the homeserver + * @param storage The storage the client should use * @return An autoreleased MTXClient */ + (instancetype)clientWithUserID: (OFString *)userID deviceID: (OFString *)deviceID accessToken: (OFString *)accessToken - homeserver: (OFURL *)homeserver; + homeserver: (OFURL *)homeserver + storage: (id )storage; /** * @brief Logs into the homeserver and creates a new client. + * + * @param user The user to log into + * @param password The password to log in with + * @param homeserver The homeserver to log into + * @param storage The storage the client should use + * @param block A block to call once login succeeded or failed */ + (void)logInWithUser: (OFString *)user password: (OFString *)password homeserver: (OFURL *)homeserver + storage: (id )storage block: (mtx_client_login_block_t)block; /** * @brief Initializes an already allocated client with the specified access * token on the specified homeserver. * + * @param userID The user ID for the client + * @param deviceID The device ID for the client * @param accessToken The access token for the client * @param homeserver The URL of the homeserver + * @param storage The storage the client should use * @return An initialized MTXClient */ - (instancetype)initWithUserID: (OFString *)userID deviceID: (OFString *)deviceID accessToken: (OFString *)accessToken - homeserver: (OFURL *)homeserver OF_DESIGNATED_INITIALIZER; + homeserver: (OFURL *)homeserver + storage: (id )storage + OF_DESIGNATED_INITIALIZER; /** * @brief Logs out the device and invalidates the access token. diff --git a/src/MTXClient.m b/src/MTXClient.m index a2423c9..d62ffd9 100644 --- a/src/MTXClient.m +++ b/src/MTXClient.m @@ -51,16 +51,19 @@ validateHomeserver(OFURL *homeserver) deviceID: (OFString *)deviceID accessToken: (OFString *)accessToken homeserver: (OFURL *)homeserver + storage: (id )storage { return [[[self alloc] initWithUserID: userID deviceID: deviceID accessToken: accessToken - homeserver: homeserver] autorelease]; + homeserver: homeserver + storage: storage] autorelease]; } + (void)logInWithUser: (OFString *)user password: (OFString *)password homeserver: (OFURL *)homeserver + storage: (id )storage block: (mtx_client_login_block_t)block { void *pool = objc_autoreleasePoolPush(); @@ -127,11 +130,11 @@ validateHomeserver(OFURL *homeserver) } else realHomeserver = homeserver; - MTXClient *client = [MTXClient - clientWithUserID: userID - deviceID: deviceID - accessToken: accessToken - homeserver: realHomeserver]; + MTXClient *client = [MTXClient clientWithUserID: userID + deviceID: deviceID + accessToken: accessToken + homeserver: realHomeserver + storage: storage]; block(client, nil); }]; @@ -142,6 +145,7 @@ validateHomeserver(OFURL *homeserver) deviceID: (OFString *)deviceID accessToken: (OFString *)accessToken homeserver: (OFURL *)homeserver + storage: (id )storage { self = [super init]; @@ -152,6 +156,7 @@ validateHomeserver(OFURL *homeserver) _deviceID = [deviceID copy]; _accessToken = [accessToken copy]; _homeserver = [homeserver copy]; + _storage = [storage retain]; } @catch (id e) { [self release]; @throw e; @@ -166,6 +171,7 @@ validateHomeserver(OFURL *homeserver) [_deviceID release]; [_accessToken release]; [_homeserver release]; + [_storage release]; [super dealloc]; } diff --git a/src/MTXSQLite3Storage.h b/src/MTXSQLite3Storage.h new file mode 100644 index 0000000..d44999b --- /dev/null +++ b/src/MTXSQLite3Storage.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2020, Jonathan Schleifer + * + * https://fossil.nil.im/objmatrix + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice is present in all copies. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#import "MTXStorage.h" + +OF_ASSUME_NONNULL_BEGIN + +/** + * @brief SQLite3-based storage for @ref MTXClient. + */ +@interface MTXSQLite3Storage: OFObject +/** + * @brief Creates a new SQLite3-based storage for @ref MTXClient. + * + * @param path The path for the SQLite3 database + * @return An autoreleased MTXSQLite3Storage + */ ++ (instancetype)storageWithPath: (OFString *)path; + +/** + * @brief Initializes an already allocated MTXSQLite3Storage. + * + * @param path The path for the SQLite3 database + * @return An initialized MTXSQLite3Storage + */ +- (instancetype)initWithPath: (OFString *)path OF_DESIGNATED_INITIALIZER; +@end + +OF_ASSUME_NONNULL_END diff --git a/src/MTXSQLite3Storage.m b/src/MTXSQLite3Storage.m new file mode 100644 index 0000000..46bfb6b --- /dev/null +++ b/src/MTXSQLite3Storage.m @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2020, Jonathan Schleifer + * + * https://fossil.nil.im/objmatrix + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice is present in all copies. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#import + +#import "MTXSQLite3Storage.h" + +@implementation MTXSQLite3Storage +{ + SL3Connection *_conn; +} + ++ (instancetype)storageWithPath: (OFString *)path +{ + return [[[self alloc] initWithPath: path] autorelease]; +} + +- (instancetype)initWithPath: (OFString *)path +{ + self = [super init]; + + @try { + _conn = [[SL3Connection alloc] initWithPath: path]; + } @catch (id e) { + [self release]; + @throw e; + } + + return self; +} + +- (void)dealloc +{ + [_conn release]; + + [super dealloc]; +} +@end diff --git a/src/MTXStorage.h b/src/MTXStorage.h new file mode 100644 index 0000000..17a99c3 --- /dev/null +++ b/src/MTXStorage.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2020, Jonathan Schleifer + * + * https://fossil.nil.im/objmatrix + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice is present in all copies. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#import + +OF_ASSUME_NONNULL_BEGIN + +/** + * @brief A protocol for a storage to be used by @ref MTXClient. + */ +@protocol MTXStorage +@end + +OF_ASSUME_NONNULL_END diff --git a/src/Makefile b/src/Makefile index 93ca883..b59be13 100644 --- a/src/Makefile +++ b/src/Makefile @@ -8,9 +8,11 @@ FRAMEWORK = ${OBJMATRIX_FRAMEWORK} LIB_MAJOR = ${OBJMATRIX_LIB_MAJOR} LIB_MINOR = ${OBJMATRIX_LIB_MINOR} -SRCS = MTXClient.m \ +SRCS = MTXClient.m \ + MTXSQLite3Storage.m \ MTXRequest.m INCLUDES := ${SRCS:.m=.h} \ + MTXStorage.h \ ObjMatrix.h OBJS_EXTRA = ${EXCEPTIONS_EXCEPTIONS_A} diff --git a/src/ObjMatrix.h b/src/ObjMatrix.h index 237c639..9ff8407 100644 --- a/src/ObjMatrix.h +++ b/src/ObjMatrix.h @@ -22,6 +22,8 @@ #import "MTXClient.h" #import "MTXRequest.h" +#import "MTXSQLite3Storage.h" +#import "MTXStorage.h" #import "MTXFetchRoomListFailedException.h" #import "MTXJoinRoomFailedException.h" diff --git a/tests/tests.m b/tests/tests.m index a248a57..c49abf4 100644 --- a/tests/tests.m +++ b/tests/tests.m @@ -47,9 +47,12 @@ OF_APPLICATION_DELEGATE(Tests) } OFURL *homeserver = [OFURL URLWithString: environment[@"OBJMATRIX_HS"]]; + id storage = + [MTXSQLite3Storage storageWithPath: @"tests.db"]; [MTXClient logInWithUser: environment[@"OBJMATRIX_USER"] password: environment[@"OBJMATRIX_PASS"] homeserver: homeserver + storage: storage block: ^ (MTXClient *client, id exception) { if (exception != nil) { of_log(@"Error logging in: %@", exception);