summaryrefslogtreecommitdiff
path: root/pgsql.c
diff options
context:
space:
mode:
authorAndreas Baumann <abaumann@yahoo.com>2012-04-17 10:39:29 +0200
committerAndreas Baumann <abaumann@yahoo.com>2012-04-17 10:39:29 +0200
commit2f536fe73d0a98648752b9ac6ca2d2e469afbe4e (patch)
treefa020353bc5b6edabfd97ec903cd322785aeeec7 /pgsql.c
parent0548acb4159a3348b8467189bdc6f2eafa9649d8 (diff)
downloadpgfuse-2f536fe73d0a98648752b9ac6ca2d2e469afbe4e.tar.gz
pgfuse-2f536fe73d0a98648752b9ac6ca2d2e469afbe4e.tar.bz2
storing ctime,mtime,atime now, mtime and atime are not set correctly everywhere yet
Diffstat (limited to 'pgsql.c')
-rw-r--r--pgsql.c102
1 files changed, 75 insertions, 27 deletions
diff --git a/pgsql.c b/pgsql.c
index f588319..44a09cd 100644
--- a/pgsql.c
+++ b/pgsql.c
@@ -23,19 +23,46 @@
#include <syslog.h> /* for ERR_XXX */
#include <errno.h> /* for ENOENT and friends */
#include <arpa/inet.h> /* for htonl, ntohl */
+#include <stdint.h> /* for uint64_t */
+#include <endian.h> /* for be64toh (GNU/BSD-ism, but easy to port if necessary) */
+
+/* --- helper functions --- */
+
+/* January 1, 2000, 00:00:00 UTC (in Unix epoch seconds) */
+#define POSTGRES_EPOCH_DATE 946684800
+
+static uint64_t convert_to_timestamp( struct timespec t )
+{
+ return htobe64( ( (uint64_t)t.tv_sec - POSTGRES_EPOCH_DATE ) * 1000000 + t.tv_nsec / 1000 );
+}
+
+static struct timespec convert_from_timestamp( uint64_t raw )
+{
+ uint64_t t;
+ struct timespec ts;
+
+ t = be64toh( raw );
+
+ ts.tv_sec = POSTGRES_EPOCH_DATE + t / 1000000;
+ ts.tv_nsec = ( t % 1000000 ) * 1000;
+
+ return ts;
+}
+
+/* --- postgresql implementation --- */
int psql_get_meta( PGconn *conn, const char *path, PgMeta *meta )
{
PGresult *res;
int idx;
- char *iptr;
+ char *data;
int id;
const char *values[1] = { path };
int lengths[1] = { strlen( path ) };
int binary[1] = { 1 };
- res = PQexecParams( conn, "SELECT id, size, mode, uid, gid FROM dir WHERE path = $1::varchar",
+ res = PQexecParams( conn, "SELECT id, size, mode, uid, gid, ctime, mtime, atime FROM dir WHERE path = $1::varchar",
1, NULL, values, lengths, binary, 1 );
if( PQresultStatus( res ) != PGRES_TUPLES_OK ) {
@@ -56,24 +83,36 @@ int psql_get_meta( PGconn *conn, const char *path, PgMeta *meta )
}
idx = PQfnumber( res, "id" );
- iptr = PQgetvalue( res, 0, idx );
- id = ntohl( *( (uint32_t *)iptr ) );
+ data = PQgetvalue( res, 0, idx );
+ id = ntohl( *( (uint32_t *)data ) );
idx = PQfnumber( res, "size" );
- iptr = PQgetvalue( res, 0, idx );
- meta->size = ntohl( *( (uint32_t *)iptr ) );
+ data = PQgetvalue( res, 0, idx );
+ meta->size = ntohl( *( (uint32_t *)data ) );
idx = PQfnumber( res, "mode" );
- iptr = PQgetvalue( res, 0, idx );
- meta->mode = ntohl( *( (uint32_t *)iptr ) );
+ data = PQgetvalue( res, 0, idx );
+ meta->mode = ntohl( *( (uint32_t *)data ) );
idx = PQfnumber( res, "uid" );
- iptr = PQgetvalue( res, 0, idx );
- meta->uid = ntohl( *( (uint32_t *)iptr ) );
+ data = PQgetvalue( res, 0, idx );
+ meta->uid = ntohl( *( (uint32_t *)data ) );
idx = PQfnumber( res, "gid" );
- iptr = PQgetvalue( res, 0, idx );
- meta->gid = ntohl( *( (uint32_t *)iptr ) );
+ data = PQgetvalue( res, 0, idx );
+ meta->gid = ntohl( *( (uint32_t *)data ) );
+
+ idx = PQfnumber( res, "ctime" );
+ data = PQgetvalue( res, 0, idx );
+ meta->ctime = convert_from_timestamp( *( (uint64_t *)data ) );
+
+ idx = PQfnumber( res, "mtime" );
+ data = PQgetvalue( res, 0, idx );
+ meta->mtime = convert_from_timestamp( *( (uint64_t *)data ) );
+
+ idx = PQfnumber( res, "atime" );
+ data = PQgetvalue( res, 0, idx );
+ meta->atime = convert_from_timestamp( *( (uint64_t *)data ) );
PQclear( res );
@@ -87,13 +126,16 @@ int psql_write_meta( PGconn *conn, const int id, const char *path, PgMeta meta )
int param3 = htonl( meta.mode );
int param4 = htonl( meta.uid );
int param5 = htonl( meta.gid );
- const char *values[5] = { (char *)&param1, (char *)&param2, (char *)&param3, (char *)&param4, (char *)&param5 };
- int lengths[5] = { sizeof( param1 ), sizeof( param2 ), sizeof( param3 ), sizeof( param4 ), sizeof( param5 ) };
- int binary[5] = { 1, 1, 1, 1, 1 };
+ uint64_t param6 = convert_to_timestamp( meta.ctime );
+ uint64_t param7 = convert_to_timestamp( meta.mtime );
+ uint64_t param8 = convert_to_timestamp( meta.atime );
+ const char *values[8] = { (const char *)&param1, (const char *)&param2, (const char *)&param3, (const char *)&param4, (const char *)&param5, (const char *)&param6, (const char *)&param7, (const char *)&param8 };
+ int lengths[8] = { sizeof( param1 ), sizeof( param2 ), sizeof( param3 ), sizeof( param4 ), sizeof( param5 ), sizeof( param6 ), sizeof( param7 ), sizeof( param8 ) };
+ int binary[8] = { 1, 1, 1, 1, 1, 1, 1, 1 };
PGresult *res;
- res = PQexecParams( conn, "UPDATE dir SET size=$2::int4, mode=$3::int4, uid=$4::int4, gid=$5::int4 WHERE id=$1::int4",
- 5, NULL, values, lengths, binary, 1 );
+ res = PQexecParams( conn, "UPDATE dir SET size=$2::int4, mode=$3::int4, uid=$4::int4, gid=$5::int4, ctime=$6::timestamp, mtime=$7::timestamp, atime=$8::timestamp WHERE id=$1::int4",
+ 8, NULL, values, lengths, binary, 1 );
if( PQresultStatus( res ) != PGRES_COMMAND_OK ) {
syslog( LOG_ERR, "Error in psql_write_meta for file '%s': %s", path, PQerrorMessage( conn ) );
@@ -113,13 +155,16 @@ int psql_create_file( PGconn *conn, const int parent_id, const char *path, const
int param3 = htonl( meta.mode );
int param4 = htonl( meta.uid );
int param5 = htonl( meta.gid );
- const char *values[7] = { (const char *)&param1, new_file, path, (const char *)&param2, (const char *)&param3, (const char *)&param4, (const char *)&param5 };
- int lengths[7] = { sizeof( param1 ), strlen( new_file ), strlen( path ), sizeof( param2 ), sizeof( param3 ), sizeof( param4 ), sizeof( param5 ) };
- int binary[7] = { 1, 0, 0, 1, 1, 1, 1 };
+ uint64_t param6 = convert_to_timestamp( meta.ctime );
+ uint64_t param7 = convert_to_timestamp( meta.mtime );
+ uint64_t param8 = convert_to_timestamp( meta.atime );
+ const char *values[10] = { (const char *)&param1, new_file, path, (const char *)&param2, (const char *)&param3, (const char *)&param4, (const char *)&param5, (const char *)&param6, (const char *)&param7, (const char *)&param8 };
+ int lengths[10] = { sizeof( param1 ), strlen( new_file ), strlen( path ), sizeof( param2 ), sizeof( param3 ), sizeof( param4 ), sizeof( param5 ), sizeof( param6 ), sizeof( param7 ), sizeof( param8 ) };
+ int binary[10] = { 1, 0, 0, 1, 1, 1, 1, 1, 1, 1 };
PGresult *res;
- res = PQexecParams( conn, "INSERT INTO dir( parent_id, name, path, size, mode, uid, gid ) VALUES ($1::int4, $2::varchar, $3::varchar, $4::int4, $5::int4, $6::int4, $7::int4 )",
- 7, NULL, values, lengths, binary, 1 );
+ res = PQexecParams( conn, "INSERT INTO dir( parent_id, name, path, size, mode, uid, gid, ctime, mtime, atime ) VALUES ($1::int4, $2::varchar, $3::varchar, $4::int4, $5::int4, $6::int4, $7::int4, $8::timestamp, $9::timestamp, $10::timestamp )",
+ 10, NULL, values, lengths, binary, 1 );
if( PQresultStatus( res ) != PGRES_COMMAND_OK ) {
syslog( LOG_ERR, "Error in psql_create_file for path '%s': %s",
@@ -206,13 +251,16 @@ int psql_create_dir( PGconn *conn, const int parent_id, const char *path, const
int param2 = htonl( meta.mode );
int param3 = htonl( meta.uid );
int param4 = htonl( meta.gid );
- const char *values[6] = { (char *)&param1, new_dir, path, (char *)&param2, (char *)&param3, (char *)&param4 };
- int lengths[6] = { sizeof( param1 ), strlen( new_dir ), strlen( path ), sizeof( param2 ), sizeof( param3 ), sizeof( param4 ) };
- int binary[6] = { 1, 0, 0, 1, 1, 1 };
+ uint64_t param5 = convert_to_timestamp( meta.ctime );
+ uint64_t param6 = convert_to_timestamp( meta.mtime );
+ uint64_t param7 = convert_to_timestamp( meta.atime );
+ const char *values[9] = { (const char *)&param1, new_dir, path, (const char *)&param2, (const char *)&param3, (const char *)&param4, (const char *)&param5, (const char *)&param6, (const char *)&param7 };
+ int lengths[9] = { sizeof( param1 ), strlen( new_dir ), strlen( path ), sizeof( param2 ), sizeof( param3 ), sizeof( param4 ), sizeof( param5 ), sizeof( param6 ), sizeof( param7 ) };
+ int binary[9] = { 1, 0, 0, 1, 1, 1, 1, 1, 1 };
PGresult *res;
- res = PQexecParams( conn, "INSERT INTO dir( parent_id, name, path, mode, uid, gid ) VALUES ($1::int4, $2::varchar, $3::varchar, $4::int4, $5::int4, $6::int4 )",
- 6, NULL, values, lengths, binary, 1 );
+ res = PQexecParams( conn, "INSERT INTO dir( parent_id, name, path, mode, uid, gid, ctime, mtime, atime ) VALUES ($1::int4, $2::varchar, $3::varchar, $4::int4, $5::int4, $6::int4, $7::timestamp, $8::timestamp, $9::timestamp )",
+ 9, NULL, values, lengths, binary, 1 );
if( PQresultStatus( res ) != PGRES_COMMAND_OK ) {
syslog( LOG_ERR, "Error in psql_create_dir for path '%s': %s", path, PQerrorMessage( conn ) );