From 2f536fe73d0a98648752b9ac6ca2d2e469afbe4e Mon Sep 17 00:00:00 2001 From: Andreas Baumann Date: Tue, 17 Apr 2012 10:39:29 +0200 Subject: storing ctime,mtime,atime now, mtime and atime are not set correctly everywhere yet --- pgsql.c | 102 +++++++++++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 75 insertions(+), 27 deletions(-) (limited to 'pgsql.c') diff --git a/pgsql.c b/pgsql.c index f588319..44a09cd 100644 --- a/pgsql.c +++ b/pgsql.c @@ -23,19 +23,46 @@ #include /* for ERR_XXX */ #include /* for ENOENT and friends */ #include /* for htonl, ntohl */ +#include /* for uint64_t */ +#include /* 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 *)¶m1, (char *)¶m2, (char *)¶m3, (char *)¶m4, (char *)¶m5 }; - 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 *)¶m1, (const char *)¶m2, (const char *)¶m3, (const char *)¶m4, (const char *)¶m5, (const char *)¶m6, (const char *)¶m7, (const char *)¶m8 }; + 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 *)¶m1, new_file, path, (const char *)¶m2, (const char *)¶m3, (const char *)¶m4, (const char *)¶m5 }; - 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 *)¶m1, new_file, path, (const char *)¶m2, (const char *)¶m3, (const char *)¶m4, (const char *)¶m5, (const char *)¶m6, (const char *)¶m7, (const char *)¶m8 }; + 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 *)¶m1, new_dir, path, (char *)¶m2, (char *)¶m3, (char *)¶m4 }; - 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 *)¶m1, new_dir, path, (const char *)¶m2, (const char *)¶m3, (const char *)¶m4, (const char *)¶m5, (const char *)¶m6, (const char *)¶m7 }; + 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 ) ); -- cgit v1.2.3-54-g00ecf