/* * Copyright (c) 2020, 2024 Jonathan Schleifer * * https://fl.nil.im/objsqlite3 * * 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 appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #import "SL3Connection.h" #import "SL3PreparedStatement.h" #import "SL3PreparedStatement+Private.h" #import "SL3ExecuteStatementFailedException.h" #import "SL3OpenFailedException.h" @implementation SL3Connection + (instancetype)connectionWithPath: (OFString *)path { return [[[self alloc] initWithPath: path] autorelease]; } + (instancetype)connectionWithPath: (OFString *)path flags: (int)flags { return [[[self alloc] initWithPath: path flags: flags] autorelease]; } - (instancetype)initWithPath: (OFString *)path { return [self initWithPath: path flags: SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE]; } - (instancetype)initWithPath: (OFString *)path flags: (int)flags { self = [super init]; @try { int code = sqlite3_open_v2(path.UTF8String, &_conn, flags, NULL); if (code != SQLITE_OK) @throw [SL3OpenFailedException exceptionWithPath: path flags: flags errorCode: code]; } @catch (id e) { [self release]; @throw e; } return self; } - (void)dealloc { sqlite3_close(_conn); [super dealloc]; } - (SL3PreparedStatement *)prepareStatement: (OFConstantString *)SQLStatement { return [[[SL3PreparedStatement alloc] sl3_initWithConnection: self SQLStatement: SQLStatement] autorelease]; } - (void)executeStatement: (OFConstantString *)SQLStatement { int code = sqlite3_exec(_conn, SQLStatement.UTF8String, NULL, NULL, NULL); if (code != SQLITE_OK) @throw [SL3ExecuteStatementFailedException exceptionWithConnection: self errorCode: code]; } #ifdef OF_HAVE_BLOCKS - (void)transactionWithBlock: (bool (^)(void))block { bool commit; [self executeStatement: @"BEGIN TRANSACTION"]; @try { commit = block(); } @catch (id e) { [self executeStatement: @"ROLLBACK TRANSACTION"]; @throw e; } if (commit) [self executeStatement: @"COMMIT TRANSACTION"]; else [self executeStatement: @"ROLLBACK TRANSACTION"]; } #endif @end