Overview
Comment: | Initial import. |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | descendants | trunk |
Files: | files | file ages | folders |
SHA3-256: |
de46b0e10c5d9f516acbbf2ea01d84d0 |
User & Date: | js 2012-10-03 13:20:06 |
Context
2012-10-03
| ||
16:04 | Add "make install". check-in: 58715a7dc6 user: js tags: trunk | |
13:20 | Initial import. check-in: de46b0e10c user: js tags: trunk | |
Changes
Added .gitignore.
> > > > > | 1 2 3 4 5 | build *.dll *.dylib *.so *~ |
Added Makefile.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 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 | SRCS = PGConnection.m \ PGResult.m \ PGResultRow.m \ exceptions/PGCommandFailedException.m \ exceptions/PGConnectionFailedException.m \ exceptions/PGException.m all: @objfw-compile \ --lib 0.0 \ -o objpgsql \ --builddir build \ -Iexceptions \ -I. \ -lpq \ ${SRCS} test: @objfw-compile \ -o test \ --builddir build \ -Iexceptions \ -I. \ -L. \ -lobjpgsql \ test.m clean: rm -f libobjpgsql.* exceptions/*~ *~ rm -fr build |
Added PGConnection.h.
> > > > > > > > > > > > > > > > > > > > > > > > > | 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 | #include <libpq-fe.h> #import <ObjFW/ObjFW.h> #import "PGResult.h" @interface PGConnection: OFObject { PGconn *conn; OFDictionary *parameters; } #ifdef OF_HAVE_PROPERTIES @property (copy) OFDictionary *parameters; #endif - (void)setParameters: (OFDictionary*)parameters; - (OFDictionary*)parameters; - (void)connect; - (void)reset; - (PGResult*)executeCommand: (OFString*)command; - (PGResult*)executeCommand: (OFString*)command parameters: (OFArray*)parameters; - (PGconn*)PG_connection; @end |
Added PGConnection.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 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 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 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 | #import "PGConnection.h" #import "PGConnectionFailedException.h" #import "PGCommandFailedException.h" @implementation PGConnection - (void)dealloc { [parameters release]; if (conn != NULL) PQfinish(conn); [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 *conninfo = nil; OFString *key, *object; while ((key = [keyEnumerator nextObject]) != nil && (object = [objectEnumerator nextObject]) != nil) { if (conninfo != nil) [conninfo appendFormat: @" %@=%@", key, object]; else conninfo = [OFMutableString stringWithFormat: @"%@=%@", key, object]; } if ((conn = PQconnectdb([conninfo UTF8String])) == NULL) @throw [OFOutOfMemoryException exceptionWithClass: [self class]]; if (PQstatus(conn) == CONNECTION_BAD) @throw [PGConnectionFailedException exceptionWithClass: [self class] connection: self]; [pool release]; } - (void)reset { PQreset(conn); } - (PGResult*)executeCommand: (OFString*)command { PGresult *result = PQexec(conn, [command UTF8String]); if (PQresultStatus(result) == PGRES_FATAL_ERROR) { PQclear(result); @throw [PGCommandFailedException exceptionWithClass: [self class] connection: self command: command]; } if (PQresultStatus(result) == PGRES_TUPLES_OK) return [PGResult PG_resultWithResult: result]; PQclear(result); return nil; } - (PGResult*)executeCommand: (OFString*)command parameters: (OFArray*)parameters_ { OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init]; PGresult *result; const char **values; values = [self allocMemoryWithSize: sizeof(*values) count: [parameters_ count]]; @try { OFEnumerator *enumerator = [parameters_ objectEnumerator]; size_t i = 0; id parameter; while ((parameter = [enumerator nextObject]) != nil) { if ([parameter isKindOfClass: [OFNull class]]) values[i++] = NULL; else values[i++] = [parameter UTF8String]; } result = PQexecParams(conn, [command UTF8String], [parameters_ count], NULL, values, NULL, NULL, 0); } @finally { [self freeMemory: values]; } [pool release]; if (PQresultStatus(result) == PGRES_FATAL_ERROR) { PQclear(result); @throw [PGCommandFailedException exceptionWithClass: [self class] connection: self command: command]; } if (PQresultStatus(result) == PGRES_TUPLES_OK) return [PGResult PG_resultWithResult: result]; PQclear(result); return nil; } - (PGconn*)PG_connection { return conn; } @end |
Added PGResult.h.
> > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 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 |
Added PGResult.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 | #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 exceptionWithClass: [self class]]; return [PGResultRow rowWithResult: self row: index]; } - (PGresult*)PG_result { return result; } @end |
Added PGResultRow.h.
> > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | #include <libpq-fe.h> #import <ObjFW/ObjFW.h> #import "PGResult.h" @interface PGResultRow: OFDictionary { PGResult *result; PGresult *res; size_t row; } + rowWithResult: (PGResult*)result row: (size_t)row; - initWithResult: (PGResult*)result row: (size_t)row; @end |
Added PGResultRow.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 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 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 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 | #import "PGResultRow.h" @interface PGResultRowEnumerator: OFEnumerator { PGResult *result; PGresult *res; size_t row, pos, count; } - initWithResult: (PGResult*)result row: (size_t)row; @end @interface PGResultRowKeyEnumerator: PGResultRowEnumerator @end @interface PGResultRowObjectEnumerator: PGResultRowEnumerator @end @implementation PGResultRow + rowWithResult: (PGResult*)result row: (size_t)row { return [[[self alloc] initWithResult: result row: row] autorelease]; } - initWithResult: (PGResult*)result_ row: (size_t)row_ { self = [super init]; result = [result_ retain]; res = [result PG_result]; row = row_; return self; } - (void)dealloc { [result release]; [super dealloc]; } - (size_t)count { return PQnfields(res); } - (id)objectForKey: (id)key { int col; if ([key isKindOfClass: [OFNumber class]]) col = [key intValue]; else col = PQfnumber(res, [key UTF8String]); return [OFString stringWithUTF8String: PQgetvalue(res, row, col)]; } - (OFEnumerator*)keyEnumerator { return [[[PGResultRowKeyEnumerator alloc] initWithResult: result row: row] autorelease]; } - (OFEnumerator*)objectEnumerator { return [[[PGResultRowObjectEnumerator alloc] initWithResult: result row: row] autorelease]; } @end @implementation PGResultRowEnumerator - initWithResult: (PGResult*)result_ row: (size_t)row_ { self = [super init]; result = [result_ retain]; res = [result PG_result]; row = row_; count = PQnfields(res); return self; } - (void)reset { pos = 0; } @end @implementation PGResultRowKeyEnumerator - (id)nextObject { if (pos >= count) return nil; return [OFString stringWithUTF8String: PQfname(res, pos++)]; } @end @implementation PGResultRowObjectEnumerator - (id)nextObject { if (pos >= count) return nil; return [OFString stringWithUTF8String: PQgetvalue(res, row, pos++)]; } @end |
Added 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 |
Added 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 50 51 52 53 | #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 { if (description != nil) return description; description = [[OFString alloc] initWithFormat: @"A PostgreSQL command in class %@ failed: %s\nCommand: %@", inClass, PQerrorMessage([connection PG_connection]), command]; return description; } - (OFString*)command { OF_GETTER(command, NO) } @end |
Added exceptions/PGConnectionFailedException.h.
> > > > | 1 2 3 4 | #import "PGException.h" @interface PGConnectionFailedException: PGException @end |
Added exceptions/PGConnectionFailedException.m.
> > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | #import "PGConnectionFailedException.h" @implementation PGConnectionFailedException - (OFString*)description { OFAutoreleasePool *pool; if (description != nil) return description; pool = [[OFAutoreleasePool alloc] init]; description = [[OFString alloc] initWithFormat: @"Establishing a PostgreSQL connection in class %@ failed:\n%s\n" "Parameters: %@", inClass, PQerrorMessage([connection PG_connection]), [connection parameters]]; [pool release]; return description; } @end |
Added 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 |
Added 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 40 41 42 43 44 | #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 { if (description != nil) return description; description = [[OFString alloc] initWithFormat: @"A PostgreSQL operation in class %@ failed: %s", inClass, PQerrorMessage([connection PG_connection])]; return description; } - (PGConnection*)connection { OF_GETTER(connection, NO) } @end |
Added test.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 | #import <ObjFW/ObjFW.h> #import "PGConnection.h" #import "PGConnectionFailedException.h" @interface Test: OFObject { PGConnection *connection; } @end OF_APPLICATION_DELEGATE(Test) @implementation Test - (void)applicationDidFinishLaunching { PGResult *result; connection = [[PGConnection alloc] init]; [connection setParameters: [OFDictionary dictionaryWithKeysAndObjects: @"user", @"js", @"dbname", @"js", nil]]; [connection connect]; [connection executeCommand: @"DROP TABLE IF EXISTS test"]; [connection executeCommand: @"CREATE TABLE test (" @" id integer," @" name varchar(255)," @" content text" @")"]; [connection executeCommand: @"INSERT INTO test (id, name, content) " @"VALUES($1, $2, $3)" parameters: @[@"1", @"foo", @"Hallo Welt!"]]; [connection executeCommand: @"INSERT INTO test (id, name, content) " @"VALUES($1, $2, $3)" parameters: @[@"2", @"bla", @"Blup!!"]]; result = [connection executeCommand: @"SELECT * FROM test"]; of_log(@"%@", result); of_log(@"JSON: %@", [result JSONRepresentation]); [OFApplication terminate]; } @end |