ObjPgSQL  Check-in [12b5ef483a]

Overview
Comment:Improve exceptions.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 12b5ef483a1f9eae92df83cf8a6aded299ef10dd2972059a36c79d299e676a0d
User & Date: js 2013-07-23 14:11:42
Context
2014-07-18
21:40
Adjust to ObjFW changes check-in: bec524d06b user: js tags: trunk
2013-07-23
14:11
Improve exceptions. check-in: 12b5ef483a user: js tags: trunk
2013-05-18
01:37
Add -[PGConnection close]. check-in: 52b090139e user: js tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to PGConnection.m.

37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
			[connectionInfo appendFormat: @" %@=%@", key, object];
		else
			connectionInfo = [OFMutableString stringWithFormat:
			    @"%@=%@", key, object];
	}

	if ((_connnection = PQconnectdb([connectionInfo UTF8String])) == NULL)
		@throw [OFOutOfMemoryException
		    exceptionWithClass: [self class]];

	if (PQstatus(_connnection) == CONNECTION_BAD)
		@throw [PGConnectionFailedException
		    exceptionWithClass: [self class]
			    connection: self];

	[pool release];
}

- (void)reset
{
	PQreset(_connnection);







|
<



<
|







37
38
39
40
41
42
43
44

45
46
47

48
49
50
51
52
53
54
55
			[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);
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
- (PGResult*)executeCommand: (OFConstantString*)command
{
	PGresult *result = PQexec(_connnection, [command UTF8String]);

	if (PQresultStatus(result) == PGRES_FATAL_ERROR) {
		PQclear(result);
		@throw [PGCommandFailedException
		    exceptionWithClass: [self class]
			    connection: 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
		    exceptionWithClass: [self class]
			    connection: self
			       command: command];
	}
}

- (PGResult*)executeCommand: (OFConstantString*)command
		 parameters: (id)parameter, ...
{
	OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];







<
|
|











<
|
|







66
67
68
69
70
71
72

73
74
75
76
77
78
79
80
81
82
83
84
85

86
87
88
89
90
91
92
93
94
- (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];
111
112
113
114
115
116
117


118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
	@try {
		size_t i = 0;

		do {
			if ([parameter isKindOfClass: [OFString class]])
				values[i++] = [parameter UTF8String];
			else if ([parameter isKindOfClass: [OFNumber class]]) {


				switch ([parameter type]) {
				case OF_NUMBER_BOOL:
					if ([parameter boolValue])
						values[i++] = "t";
					else
						values[i++] = "f";
					break;
				default:
					values[i++] = [[parameter description]
					    UTF8String];
					break;
				}
			} else if ([parameter isKindOfClass: [OFNull class]])
				values[i++] = NULL;
			else
				values[i++] = [[parameter description]







>
>
|

|





|







107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
	@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_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]
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
		return [PGResult PG_resultWithResult: result];
	case PGRES_COMMAND_OK:
		PQclear(result);
		return nil;
	default:
		PQclear(result);
		@throw [PGCommandFailedException
		    exceptionWithClass: [self class]
			    connection: self
			       command: command];
	}
}

- (void)insertRow: (OFDictionary*)row
	intoTable: (OFString*)table
{
	OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];







<
|
|







145
146
147
148
149
150
151

152
153
154
155
156
157
158
159
160
		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];
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
	}

	[pool release];

	if (PQresultStatus(result) != PGRES_COMMAND_OK) {
		PQclear(result);
		@throw [PGCommandFailedException
		    exceptionWithClass: [self class]
			    connection: self
			       command: command];
	}

	PQclear(result);
}

- (void)insertRows: (OFArray*)rows
	 intoTable: (OFString*)table







<
|
|







207
208
209
210
211
212
213

214
215
216
217
218
219
220
221
222
	}

	[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

Changes to PGResult.m.

28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
{
	return PQntuples(_result);
}

- (id)objectAtIndex: (size_t)index
{
	if (index > PQntuples(_result))
		@throw [OFOutOfRangeException
		    exceptionWithClass: [self class]];

	return [PGResultRow rowWithResult: self
				      row: (int)index];
}

- (PGresult*)PG_result
{







|
<







28
29
30
31
32
33
34
35

36
37
38
39
40
41
42
{
	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
{

Changes to PGResultRow.m.

120
121
122
123
124
125
126
127
128
129
130
131
132
133
134

	if (state->extra[0] == 0) {
		state->extra[0] = 1;
		state->extra[1] = PQnfields(_res);
	}

	if (count > SIZE_MAX - state->state)
		@throw [OFOutOfRangeException exceptionWithClass: [self class]];

	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;







|







120
121
122
123
124
125
126
127
128
129
130
131
132
133
134

	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;

Changes to exceptions/PGCommandFailedException.h.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#import "PGException.h"

@interface PGCommandFailedException: PGException
{
	OFString *_command;
}

#ifdef OF_HAVE_PROPERTIES
@property (readonly, copy, nonatomic) OFString *command;
#endif

+ exceptionWithClass: (Class)class_
	  connection: (PGConnection*)connection
	     command: (OFString*)command;
- initWithClass: (Class)class_
     connection: (PGConnection*)connection
	command: (OFString*)command;
- (OFString*)command;
@end











<
|
|
<
|
|


1
2
3
4
5
6
7
8
9
10
11

12
13

14
15
16
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

Changes to exceptions/PGCommandFailedException.m.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#import "PGCommandFailedException.h"

@implementation PGCommandFailedException
+ exceptionWithClass: (Class)class
	  connection: (PGConnection*)connection
	     command: (OFString*)command
{
	return [[[self alloc] initWithClass: class
				 connection: connection
				    command: command] autorelease];
}

- initWithClass: (Class)class
     connection: (PGConnection*)connection
	command: (OFString*)command
{
	self = [super initWithClass: class
			 connection: 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 in class %@ failed: %s\nCommand: %@",
	    [self inClass], PQerrorMessage([_connection PG_connection]),
	    _command];
}

- (OFString*)command
{
	OF_GETTER(_command, NO)
}
@end



<
|
|

|
<
|


<
|
|

|
<




















|
<
<
|







1
2
3

4
5
6
7

8
9
10

11
12
13
14

15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35


36
37
38
39
40
41
42
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

Changes to exceptions/PGConnectionFailedException.m.

1
2
3
4
5
6
7
8
9
10
11
12
#import "PGConnectionFailedException.h"

@implementation PGConnectionFailedException
- (OFString*)description
{
	return [OFString stringWithFormat:
	    @"Establishing a PostgreSQL connection in class %@ failed:\n%s\n"
	    "Parameters: %@", [self inClass],
	    PQerrorMessage([_connection PG_connection]),
	    [_connection parameters]];
}
@end






|
<
<
|


1
2
3
4
5
6
7


8
9
10
#import "PGConnectionFailedException.h"

@implementation PGConnectionFailedException
- (OFString*)description
{
	return [OFString stringWithFormat:
	    @"Establishing a PostgreSQL connection failed:\n%@\n"


	    "Parameters: %@", _error, [_connection parameters]];
}
@end

Changes to exceptions/PGException.h.

1
2
3
4
5
6
7

8
9
10
11
12
13
14
15
16
17
18
19
#import <ObjFW/ObjFW.h>

#import "PGConnection.h"

@interface PGException: OFException
{
	PGConnection *_connection;

}

#ifdef OF_HAVE_PROPERTIES
@property (readonly, retain, nonatomic) PGConnection *connection;
#endif

+ exceptionWithClass: (Class)class_
	  connection: (PGConnection*)connection;
- initWithClass: (Class)class_
     connection: (PGConnection*)connection;
- (PGConnection*)connection;
@end







>






<
|
<
|


1
2
3
4
5
6
7
8
9
10
11
12
13
14

15

16
17
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

Changes to exceptions/PGException.m.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

16







17
18
19
20
21
22
23

24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#import "PGException.h"

@implementation PGException
+ exceptionWithClass: (Class)class
	  connection: (PGConnection*)connection
{
	return [[[self alloc] initWithClass: class
				 connection: connection] autorelease];
}

- initWithClass: (Class)class
     connection: (PGConnection*)connection
{
	self = [super initWithClass: class];


	_connection = [connection retain];








	return self;
}

- (void)dealloc
{
	[_connection release];


	[super dealloc];
}

- (OFString*)description
{
	return [OFString stringWithFormat:
	    @"A PostgreSQL operation in class %@ failed: %s", [self inClass],
	    PQerrorMessage([_connection PG_connection])];
}

- (PGConnection*)connection
{
	OF_GETTER(_connection, NO)
}
@end



<
|

|
<


<
|

|

>
|
>
>
>
>
>
>
>







>






|
<
|







1
2
3

4
5
6

7
8

9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36

37
38
39
40
41
42
43
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: OF_STRING_ENCODING_NATIVE];
	} @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