Add a proper build system
FossilOrigin-Name: 8679c61b2c82da9daa316ed5eb90ba1b69e608127afa318cbdbff56b53d65a74
This commit is contained in:
parent
71342537cf
commit
35212e3305
28 changed files with 5118 additions and 76 deletions
22
src/Makefile
Normal file
22
src/Makefile
Normal file
|
@ -0,0 +1,22 @@
|
|||
include ../extra.mk
|
||||
|
||||
SUBDIRS = exceptions
|
||||
|
||||
SHARED_LIB = ${OBJPGSQL_SHARED_LIB}
|
||||
STATIC_LIB = ${OBJPGSQL_STATIC_LIB}
|
||||
LIB_MAJOR = 0
|
||||
LIB_MINOR = 1
|
||||
|
||||
SRCS = PGConnection.m \
|
||||
PGResult.m \
|
||||
PGResultRow.m
|
||||
INCLUDES := ${SRCS:.m=.h} \
|
||||
ObjPgSQL.h
|
||||
|
||||
OBJS_EXTRA = ${EXCEPTIONS_EXCEPTIONS_A}
|
||||
LIB_OBJS_EXTRA = ${EXCEPTIONS_EXCEPTIONS_LIB_A}
|
||||
|
||||
include ../buildsys.mk
|
||||
|
||||
CPPFLAGS += -I. -Iexceptions
|
||||
LD = ${OBJC}
|
7
src/ObjPgSQL.h
Normal file
7
src/ObjPgSQL.h
Normal file
|
@ -0,0 +1,7 @@
|
|||
#import "PGResult.h"
|
||||
#import "PGResultRow.h"
|
||||
#import "PGConnection.h"
|
||||
|
||||
#import "PGException.h"
|
||||
#import "PGCommandFailedException.h"
|
||||
#import "PGConnectionFailedException.h"
|
30
src/PGConnection.h
Normal file
30
src/PGConnection.h
Normal file
|
@ -0,0 +1,30 @@
|
|||
#include <libpq-fe.h>
|
||||
|
||||
#import <ObjFW/ObjFW.h>
|
||||
|
||||
#import "PGResult.h"
|
||||
|
||||
@interface PGConnection: OFObject
|
||||
{
|
||||
PGconn *_connnection;
|
||||
OFDictionary *_parameters;
|
||||
}
|
||||
|
||||
#ifdef OF_HAVE_PROPERTIES
|
||||
@property (copy) OFDictionary *parameters;
|
||||
#endif
|
||||
|
||||
- (void)setParameters: (OFDictionary*)parameters;
|
||||
- (OFDictionary*)parameters;
|
||||
- (void)connect;
|
||||
- (void)reset;
|
||||
- (void)close;
|
||||
- (PGResult*)executeCommand: (OFConstantString*)command;
|
||||
- (PGResult*)executeCommand: (OFConstantString*)command
|
||||
parameters: (id)firstParameter, ... OF_SENTINEL;
|
||||
- (PGconn*)PG_connection;
|
||||
- (void)insertRow: (OFDictionary*)row
|
||||
intoTable: (OFString*)table;
|
||||
- (void)insertRows: (OFArray*)rows
|
||||
intoTable: (OFString*)table;
|
||||
@end
|
239
src/PGConnection.m
Normal file
239
src/PGConnection.m
Normal file
|
@ -0,0 +1,239 @@
|
|||
#import "PGConnection.h"
|
||||
|
||||
#import "PGConnectionFailedException.h"
|
||||
#import "PGCommandFailedException.h"
|
||||
|
||||
@implementation PGConnection
|
||||
- (void)dealloc
|
||||
{
|
||||
[_parameters release];
|
||||
|
||||
[self close];
|
||||
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (void)setParameters: (OFDictionary*)parameters
|
||||
{
|
||||
OF_SETTER(_parameters, parameters, YES, YES)
|
||||
}
|
||||
|
||||
- (OFDictionary*)parameters
|
||||
{
|
||||
OF_GETTER(_parameters, YES)
|
||||
}
|
||||
|
||||
- (void)connect
|
||||
{
|
||||
OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
|
||||
OFEnumerator *keyEnumerator = [_parameters keyEnumerator];
|
||||
OFEnumerator *objectEnumerator = [_parameters objectEnumerator];
|
||||
OFMutableString *connectionInfo = nil;
|
||||
OFString *key, *object;
|
||||
|
||||
while ((key = [keyEnumerator nextObject]) != nil &&
|
||||
(object = [objectEnumerator nextObject]) != nil) {
|
||||
if (connectionInfo != nil)
|
||||
[connectionInfo appendFormat: @" %@=%@", key, object];
|
||||
else
|
||||
connectionInfo = [OFMutableString stringWithFormat:
|
||||
@"%@=%@", key, object];
|
||||
}
|
||||
|
||||
if ((_connnection = PQconnectdb([connectionInfo UTF8String])) == NULL)
|
||||
@throw [OFOutOfMemoryException exception];
|
||||
|
||||
if (PQstatus(_connnection) == CONNECTION_BAD)
|
||||
@throw [PGConnectionFailedException
|
||||
exceptionWithConnection: self];
|
||||
|
||||
[pool release];
|
||||
}
|
||||
|
||||
- (void)reset
|
||||
{
|
||||
PQreset(_connnection);
|
||||
}
|
||||
|
||||
- (void)close
|
||||
{
|
||||
if (_connnection != NULL)
|
||||
PQfinish(_connnection);
|
||||
|
||||
_connnection = NULL;
|
||||
}
|
||||
|
||||
- (PGResult*)executeCommand: (OFConstantString*)command
|
||||
{
|
||||
PGresult *result = PQexec(_connnection, [command UTF8String]);
|
||||
|
||||
if (PQresultStatus(result) == PGRES_FATAL_ERROR) {
|
||||
PQclear(result);
|
||||
@throw [PGCommandFailedException
|
||||
exceptionWithConnection: self
|
||||
command: command];
|
||||
}
|
||||
|
||||
switch (PQresultStatus(result)) {
|
||||
case PGRES_TUPLES_OK:
|
||||
return [PGResult PG_resultWithResult: result];
|
||||
case PGRES_COMMAND_OK:
|
||||
PQclear(result);
|
||||
return nil;
|
||||
default:
|
||||
PQclear(result);
|
||||
@throw [PGCommandFailedException
|
||||
exceptionWithConnection: self
|
||||
command: command];
|
||||
}
|
||||
}
|
||||
|
||||
- (PGResult*)executeCommand: (OFConstantString*)command
|
||||
parameters: (id)parameter, ...
|
||||
{
|
||||
OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
|
||||
PGresult *result;
|
||||
const char **values;
|
||||
va_list args, args2;
|
||||
int argsCount;
|
||||
|
||||
va_start(args, parameter);
|
||||
va_copy(args2, args);
|
||||
|
||||
for (argsCount = 1; va_arg(args2, id) != nil; argsCount++);
|
||||
|
||||
values = [self allocMemoryWithSize: sizeof(*values)
|
||||
count: argsCount];
|
||||
@try {
|
||||
size_t i = 0;
|
||||
|
||||
do {
|
||||
if ([parameter isKindOfClass: [OFString class]])
|
||||
values[i++] = [parameter UTF8String];
|
||||
else if ([parameter isKindOfClass: [OFNumber class]]) {
|
||||
OFNumber *number = parameter;
|
||||
|
||||
switch ([number type]) {
|
||||
case OF_NUMBER_TYPE_BOOL:
|
||||
if ([number boolValue])
|
||||
values[i++] = "t";
|
||||
else
|
||||
values[i++] = "f";
|
||||
break;
|
||||
default:
|
||||
values[i++] = [[number description]
|
||||
UTF8String];
|
||||
break;
|
||||
}
|
||||
} else if ([parameter isKindOfClass: [OFNull class]])
|
||||
values[i++] = NULL;
|
||||
else
|
||||
values[i++] = [[parameter description]
|
||||
UTF8String];
|
||||
} while ((parameter = va_arg(args, id)) != nil);
|
||||
|
||||
result = PQexecParams(_connnection, [command UTF8String],
|
||||
argsCount, NULL, values, NULL, NULL, 0);
|
||||
} @finally {
|
||||
[self freeMemory: values];
|
||||
}
|
||||
|
||||
[pool release];
|
||||
|
||||
switch (PQresultStatus(result)) {
|
||||
case PGRES_TUPLES_OK:
|
||||
return [PGResult PG_resultWithResult: result];
|
||||
case PGRES_COMMAND_OK:
|
||||
PQclear(result);
|
||||
return nil;
|
||||
default:
|
||||
PQclear(result);
|
||||
@throw [PGCommandFailedException
|
||||
exceptionWithConnection: self
|
||||
command: command];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)insertRow: (OFDictionary*)row
|
||||
intoTable: (OFString*)table
|
||||
{
|
||||
OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
|
||||
OFMutableString *command;
|
||||
OFEnumerator *enumerator;
|
||||
const char **values;
|
||||
PGresult *result;
|
||||
OFString *key, *value;
|
||||
size_t i, count;
|
||||
|
||||
command = [OFMutableString stringWithString: @"INSERT INTO "];
|
||||
[command appendString: table];
|
||||
[command appendString: @" ("];
|
||||
|
||||
count = [row count];
|
||||
|
||||
i = 0;
|
||||
enumerator = [row keyEnumerator];
|
||||
while ((key = [enumerator nextObject]) != nil) {
|
||||
if (i > 0)
|
||||
[command appendString: @", "];
|
||||
|
||||
[command appendString: key];
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
[command appendString: @") VALUES ("];
|
||||
|
||||
values = [self allocMemoryWithSize: sizeof(*values)
|
||||
count: count];
|
||||
@try {
|
||||
i = 0;
|
||||
enumerator = [row objectEnumerator];
|
||||
while ((value = [enumerator nextObject]) != nil) {
|
||||
if (i > 0)
|
||||
[command appendString: @", "];
|
||||
|
||||
values[i] = [value UTF8String];
|
||||
|
||||
[command appendFormat: @"$%zd", ++i];
|
||||
}
|
||||
|
||||
[command appendString: @")"];
|
||||
|
||||
result = PQexecParams(_connnection, [command UTF8String],
|
||||
(int)count, NULL, values, NULL, NULL, 0);
|
||||
} @finally {
|
||||
[self freeMemory: values];
|
||||
}
|
||||
|
||||
[pool release];
|
||||
|
||||
if (PQresultStatus(result) != PGRES_COMMAND_OK) {
|
||||
PQclear(result);
|
||||
@throw [PGCommandFailedException
|
||||
exceptionWithConnection: self
|
||||
command: command];
|
||||
}
|
||||
|
||||
PQclear(result);
|
||||
}
|
||||
|
||||
- (void)insertRows: (OFArray*)rows
|
||||
intoTable: (OFString*)table
|
||||
{
|
||||
OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
|
||||
OFEnumerator *enumerator = [rows objectEnumerator];
|
||||
OFDictionary *row;
|
||||
|
||||
while ((row = [enumerator nextObject]) != nil)
|
||||
[self insertRow: row
|
||||
intoTable: table];
|
||||
|
||||
[pool release];
|
||||
}
|
||||
|
||||
- (PGconn*)PG_connection
|
||||
{
|
||||
return _connnection;
|
||||
}
|
||||
@end
|
13
src/PGResult.h
Normal file
13
src/PGResult.h
Normal file
|
@ -0,0 +1,13 @@
|
|||
#include <libpq-fe.h>
|
||||
|
||||
#import <ObjFW/ObjFW.h>
|
||||
|
||||
@interface PGResult: OFArray
|
||||
{
|
||||
PGresult *_result;
|
||||
}
|
||||
|
||||
+ PG_resultWithResult: (PGresult*)result;
|
||||
- PG_initWithResult: (PGresult*)result;
|
||||
- (PGresult*)PG_result;
|
||||
@end
|
45
src/PGResult.m
Normal file
45
src/PGResult.m
Normal file
|
@ -0,0 +1,45 @@
|
|||
#import "PGResult.h"
|
||||
#import "PGResultRow.h"
|
||||
|
||||
@implementation PGResult
|
||||
+ PG_resultWithResult: (PGresult*)result
|
||||
{
|
||||
return [[[self alloc] PG_initWithResult: result] autorelease];
|
||||
}
|
||||
|
||||
- PG_initWithResult: (PGresult*)result
|
||||
{
|
||||
self = [super init];
|
||||
|
||||
_result = result;
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
if (_result != NULL)
|
||||
PQclear(_result);
|
||||
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (size_t)count
|
||||
{
|
||||
return PQntuples(_result);
|
||||
}
|
||||
|
||||
- (id)objectAtIndex: (size_t)index
|
||||
{
|
||||
if (index > PQntuples(_result))
|
||||
@throw [OFOutOfRangeException exception];
|
||||
|
||||
return [PGResultRow rowWithResult: self
|
||||
row: (int)index];
|
||||
}
|
||||
|
||||
- (PGresult*)PG_result
|
||||
{
|
||||
return _result;
|
||||
}
|
||||
@end
|
18
src/PGResultRow.h
Normal file
18
src/PGResultRow.h
Normal file
|
@ -0,0 +1,18 @@
|
|||
#include <libpq-fe.h>
|
||||
|
||||
#import <ObjFW/ObjFW.h>
|
||||
|
||||
#import "PGResult.h"
|
||||
|
||||
@interface PGResultRow: OFDictionary
|
||||
{
|
||||
PGResult *_result;
|
||||
PGresult *_res;
|
||||
int _row;
|
||||
}
|
||||
|
||||
+ rowWithResult: (PGResult*)result
|
||||
row: (int)row;
|
||||
- initWithResult: (PGResult*)result
|
||||
row: (int)row;
|
||||
@end
|
206
src/PGResultRow.m
Normal file
206
src/PGResultRow.m
Normal file
|
@ -0,0 +1,206 @@
|
|||
#import "PGResultRow.h"
|
||||
|
||||
static id
|
||||
convertType(PGresult *res, int column, OFString *string)
|
||||
{
|
||||
switch (PQftype(res, column)) {
|
||||
case 16: /* BOOLOID */
|
||||
if ([string isEqual: @"t"])
|
||||
return [OFNumber numberWithBool: YES];
|
||||
else
|
||||
return [OFNumber numberWithBool: NO];
|
||||
case 21: /* INT2OID */
|
||||
return [OFNumber numberWithInt16:
|
||||
(int16_t)[string decimalValue]];
|
||||
case 23: /* INT4OID */
|
||||
return [OFNumber numberWithInt32:
|
||||
(int32_t)[string decimalValue]];
|
||||
case 20: /* INT8OID */
|
||||
return [OFNumber numberWithInt64:
|
||||
(int64_t)[string decimalValue]];
|
||||
case 700: /* FLOAT4OID */
|
||||
return [OFNumber numberWithFloat: [string floatValue]];
|
||||
case 701: /* FLOAT8OID */
|
||||
return [OFNumber numberWithDouble: [string doubleValue]];
|
||||
}
|
||||
|
||||
return string;
|
||||
}
|
||||
|
||||
@interface PGResultRowEnumerator: OFEnumerator
|
||||
{
|
||||
PGResult *_result;
|
||||
PGresult *_res;
|
||||
int _row, _pos, _count;
|
||||
}
|
||||
|
||||
- initWithResult: (PGResult*)result
|
||||
row: (int)row;
|
||||
@end
|
||||
|
||||
@interface PGResultRowKeyEnumerator: PGResultRowEnumerator
|
||||
@end
|
||||
|
||||
@interface PGResultRowObjectEnumerator: PGResultRowEnumerator
|
||||
@end
|
||||
|
||||
@implementation PGResultRow
|
||||
+ rowWithResult: (PGResult*)result
|
||||
row: (int)row
|
||||
{
|
||||
return [[[self alloc] initWithResult: result
|
||||
row: row] autorelease];
|
||||
}
|
||||
|
||||
- initWithResult: (PGResult*)result
|
||||
row: (int)row
|
||||
{
|
||||
self = [super init];
|
||||
|
||||
_result = [result retain];
|
||||
_res = [result PG_result];
|
||||
_row = row;
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
[_result release];
|
||||
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (size_t)count
|
||||
{
|
||||
int i, count, fields = PQnfields(_res);
|
||||
|
||||
for (i = count = 0; i < fields; i++)
|
||||
if (!PQgetisnull(_res, _row, i))
|
||||
count++;
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
- (id)objectForKey: (id)key
|
||||
{
|
||||
int column;
|
||||
|
||||
if ([key isKindOfClass: [OFNumber class]])
|
||||
column = [key intValue];
|
||||
else
|
||||
column = PQfnumber(_res, [key UTF8String]);
|
||||
|
||||
if (PQgetisnull(_res, _row, column))
|
||||
return nil;
|
||||
|
||||
return convertType(_res, column,
|
||||
[OFString stringWithUTF8String: PQgetvalue(_res, _row, column)]);
|
||||
}
|
||||
|
||||
- (OFEnumerator*)keyEnumerator
|
||||
{
|
||||
return [[[PGResultRowKeyEnumerator alloc]
|
||||
initWithResult: _result
|
||||
row: _row] autorelease];
|
||||
}
|
||||
|
||||
- (OFEnumerator*)objectEnumerator
|
||||
{
|
||||
return [[[PGResultRowObjectEnumerator alloc]
|
||||
initWithResult: _result
|
||||
row: _row] autorelease];
|
||||
}
|
||||
|
||||
- (int)countByEnumeratingWithState: (of_fast_enumeration_state_t*)state
|
||||
objects: (id*)objects
|
||||
count: (int)count
|
||||
{
|
||||
int i, j;
|
||||
|
||||
if (state->extra[0] == 0) {
|
||||
state->extra[0] = 1;
|
||||
state->extra[1] = PQnfields(_res);
|
||||
}
|
||||
|
||||
if (count > SIZE_MAX - state->state)
|
||||
@throw [OFOutOfRangeException exception];
|
||||
|
||||
if (state->state + count > state->extra[1])
|
||||
count = state->extra[1] - state->state;
|
||||
|
||||
for (i = j = 0; i < count; i++) {
|
||||
if (PQgetisnull(_res, _row, state->state + i))
|
||||
continue;
|
||||
|
||||
objects[j++] = [OFString stringWithUTF8String:
|
||||
PQfname(_res, state->state + i)];
|
||||
}
|
||||
|
||||
state->state += count;
|
||||
state->itemsPtr = objects;
|
||||
state->mutationsPtr = (unsigned long*)self;
|
||||
|
||||
return j;
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation PGResultRowEnumerator
|
||||
- initWithResult: (PGResult*)result
|
||||
row: (int)row
|
||||
{
|
||||
self = [super init];
|
||||
|
||||
_result = [result retain];
|
||||
_res = [result PG_result];
|
||||
_row = row;
|
||||
_count = PQnfields(_res);
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
[_result release];
|
||||
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (void)reset
|
||||
{
|
||||
_pos = 0;
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation PGResultRowKeyEnumerator
|
||||
- (id)nextObject
|
||||
{
|
||||
if (_pos >= _count)
|
||||
return nil;
|
||||
|
||||
while (_pos < _count && PQgetisnull(_res, _row, _pos))
|
||||
_pos++;
|
||||
|
||||
if (_pos >= _count)
|
||||
return nil;
|
||||
|
||||
return [OFString stringWithUTF8String: PQfname(_res, _pos++)];
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation PGResultRowObjectEnumerator
|
||||
- (id)nextObject
|
||||
{
|
||||
if (_pos >= _count)
|
||||
return nil;
|
||||
|
||||
while (_pos < _count && PQgetisnull(_res, _row, _pos))
|
||||
_pos++;
|
||||
|
||||
if (_pos >= _count)
|
||||
return nil;
|
||||
|
||||
return convertType(_res, _pos,
|
||||
[OFString stringWithUTF8String: PQgetvalue(_res, _row, _pos++)]);
|
||||
}
|
||||
@end
|
14
src/exceptions/Makefile
Normal file
14
src/exceptions/Makefile
Normal file
|
@ -0,0 +1,14 @@
|
|||
include ../../extra.mk
|
||||
|
||||
STATIC_PIC_LIB_NOINST = ${EXCEPTIONS_LIB_A}
|
||||
STATIC_LIB_NOINST = ${EXCEPTIONS_A}
|
||||
|
||||
SRCS = PGCommandFailedException.m \
|
||||
PGConnectionFailedException.m \
|
||||
PGException.m
|
||||
|
||||
INCLUDES = ${SRCS:.m=.h}
|
||||
|
||||
include ../../buildsys.mk
|
||||
|
||||
CPPFLAGS += -I. -I..
|
17
src/exceptions/PGCommandFailedException.h
Normal file
17
src/exceptions/PGCommandFailedException.h
Normal file
|
@ -0,0 +1,17 @@
|
|||
#import "PGException.h"
|
||||
|
||||
@interface PGCommandFailedException: PGException
|
||||
{
|
||||
OFString *_command;
|
||||
}
|
||||
|
||||
#ifdef OF_HAVE_PROPERTIES
|
||||
@property (readonly, copy, nonatomic) OFString *command;
|
||||
#endif
|
||||
|
||||
+ (instancetype)exceptionWithConnection: (PGConnection*)connection
|
||||
command: (OFString*)command;
|
||||
- initWithConnection: (PGConnection*)connection
|
||||
command: (OFString*)command;
|
||||
- (OFString*)command;
|
||||
@end
|
43
src/exceptions/PGCommandFailedException.m
Normal file
43
src/exceptions/PGCommandFailedException.m
Normal file
|
@ -0,0 +1,43 @@
|
|||
#import "PGCommandFailedException.h"
|
||||
|
||||
@implementation PGCommandFailedException
|
||||
+ (instancetype)exceptionWithConnection: (PGConnection*)connection
|
||||
command: (OFString*)command
|
||||
{
|
||||
return [[[self alloc] initWithConnection: connection
|
||||
command: command] autorelease];
|
||||
}
|
||||
|
||||
- initWithConnection: (PGConnection*)connection
|
||||
command: (OFString*)command
|
||||
{
|
||||
self = [super initWithConnection: connection];
|
||||
|
||||
@try {
|
||||
_command = [command copy];
|
||||
} @catch (id e) {
|
||||
[self release];
|
||||
@throw e;
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
[_command release];
|
||||
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (OFString*)description
|
||||
{
|
||||
return [OFString stringWithFormat: @"A PostgreSQL command failed: %@\n"
|
||||
@"Command: %@", _error, _command];
|
||||
}
|
||||
|
||||
- (OFString*)command
|
||||
{
|
||||
OF_GETTER(_command, NO)
|
||||
}
|
||||
@end
|
4
src/exceptions/PGConnectionFailedException.h
Normal file
4
src/exceptions/PGConnectionFailedException.h
Normal file
|
@ -0,0 +1,4 @@
|
|||
#import "PGException.h"
|
||||
|
||||
@interface PGConnectionFailedException: PGException
|
||||
@end
|
10
src/exceptions/PGConnectionFailedException.m
Normal file
10
src/exceptions/PGConnectionFailedException.m
Normal file
|
@ -0,0 +1,10 @@
|
|||
#import "PGConnectionFailedException.h"
|
||||
|
||||
@implementation PGConnectionFailedException
|
||||
- (OFString*)description
|
||||
{
|
||||
return [OFString stringWithFormat:
|
||||
@"Establishing a PostgreSQL connection failed:\n%@\n"
|
||||
"Parameters: %@", _error, [_connection parameters]];
|
||||
}
|
||||
@end
|
18
src/exceptions/PGException.h
Normal file
18
src/exceptions/PGException.h
Normal file
|
@ -0,0 +1,18 @@
|
|||
#import <ObjFW/ObjFW.h>
|
||||
|
||||
#import "PGConnection.h"
|
||||
|
||||
@interface PGException: OFException
|
||||
{
|
||||
PGConnection *_connection;
|
||||
OFString *_error;
|
||||
}
|
||||
|
||||
#ifdef OF_HAVE_PROPERTIES
|
||||
@property (readonly, retain, nonatomic) PGConnection *connection;
|
||||
#endif
|
||||
|
||||
+ (instancetype)exceptionWithConnection: (PGConnection*)connection;
|
||||
- initWithConnection: (PGConnection*)connection;
|
||||
- (PGConnection*)connection;
|
||||
@end
|
44
src/exceptions/PGException.m
Normal file
44
src/exceptions/PGException.m
Normal file
|
@ -0,0 +1,44 @@
|
|||
#import "PGException.h"
|
||||
|
||||
@implementation PGException
|
||||
+ (instancetype)exceptionWithConnection: (PGConnection*)connection
|
||||
{
|
||||
return [[[self alloc] initWithConnection: connection] autorelease];
|
||||
}
|
||||
|
||||
- initWithConnection: (PGConnection*)connection
|
||||
{
|
||||
self = [super init];
|
||||
|
||||
@try {
|
||||
_connection = [connection retain];
|
||||
_error = [[OFString alloc]
|
||||
initWithCString: PQerrorMessage([_connection PG_connection])
|
||||
encoding: [OFString nativeOSEncoding]];
|
||||
} @catch (id e) {
|
||||
[self release];
|
||||
@throw e;
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
[_connection release];
|
||||
[_error release];
|
||||
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (OFString*)description
|
||||
{
|
||||
return [OFString stringWithFormat: @"A PostgreSQL operation failed: %@",
|
||||
_error];
|
||||
}
|
||||
|
||||
- (PGConnection*)connection
|
||||
{
|
||||
OF_GETTER(_connection, NO)
|
||||
}
|
||||
@end
|
Loading…
Add table
Add a link
Reference in a new issue