From fd841e416881cc0392e61ec312c1870f3a0004bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Frings-F=C3=BCrst?= Date: Tue, 2 Dec 2014 10:06:21 +0100 Subject: Initial import of libmongo-client version 0.1.8-2 --- src/sync-gridfs.c | 345 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 345 insertions(+) create mode 100644 src/sync-gridfs.c (limited to 'src/sync-gridfs.c') diff --git a/src/sync-gridfs.c b/src/sync-gridfs.c new file mode 100644 index 0000000..7d1af24 --- /dev/null +++ b/src/sync-gridfs.c @@ -0,0 +1,345 @@ +/* sync-gridfs.c - libmongo-client GridFS implementation + * Copyright 2011, 2012 Gergely Nagy + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** @file src/sync-gridfs.c + * MongoDB GridFS implementation. + */ + +#include "sync-gridfs.h" +#include "libmongo-private.h" + +#include + +mongo_sync_gridfs * +mongo_sync_gridfs_new (mongo_sync_connection *conn, + const gchar *ns_prefix) +{ + mongo_sync_gridfs *gfs; + bson *index; + gchar *db; + + if (!conn) + { + errno = ENOTCONN; + return NULL; + } + if (!ns_prefix) + { + errno = EINVAL; + return NULL; + } + db = strchr (ns_prefix, '.'); + if (!db) + { + errno = EINVAL; + return NULL; + } + + gfs = g_new (mongo_sync_gridfs, 1); + gfs->conn = conn; + + gfs->ns.prefix = g_strdup (ns_prefix); + gfs->ns.files = g_strconcat (gfs->ns.prefix, ".files", NULL); + gfs->ns.chunks = g_strconcat (gfs->ns.prefix, ".chunks", NULL); + gfs->ns.db = g_strndup (ns_prefix, db - ns_prefix); + + gfs->chunk_size = 256 * 1024; + + index = bson_new_sized (256); + bson_append_int32 (index, "files_id", 1); + bson_append_int32 (index, "n", 1); + bson_finish (index); + + if (!mongo_sync_cmd_index_create (conn, gfs->ns.chunks, index, + MONGO_INDEX_UNIQUE)) + { + bson_free (index); + mongo_sync_gridfs_free (gfs, FALSE); + + errno = EPROTO; + return NULL; + } + bson_free (index); + + return gfs; +} + +void +mongo_sync_gridfs_free (mongo_sync_gridfs *gfs, gboolean disconnect) +{ + if (!gfs) + { + errno = ENOTCONN; + return; + } + + g_free (gfs->ns.prefix); + g_free (gfs->ns.files); + g_free (gfs->ns.chunks); + g_free (gfs->ns.db); + + if (disconnect) + mongo_sync_disconnect (gfs->conn); + + g_free (gfs); + errno = 0; +} + +gint32 +mongo_sync_gridfs_get_chunk_size (mongo_sync_gridfs *gfs) +{ + if (!gfs) + { + errno = ENOTCONN; + return -1; + } + return gfs->chunk_size; +} + +gboolean +mongo_sync_gridfs_set_chunk_size (mongo_sync_gridfs *gfs, + gint32 chunk_size) +{ + if (!gfs) + { + errno = ENOTCONN; + return FALSE; + } + if (chunk_size < 1) + { + errno = EINVAL; + return FALSE; + } + + gfs->chunk_size = chunk_size; + return TRUE; +} + +mongo_sync_cursor * +mongo_sync_gridfs_list (mongo_sync_gridfs *gfs, + const bson *query) +{ + mongo_sync_cursor *cursor; + bson *q = NULL; + + if (!gfs) + { + errno = ENOTCONN; + return NULL; + } + + if (!query) + { + q = bson_new (); + bson_finish (q); + } + + cursor = mongo_sync_cursor_new + (gfs->conn, gfs->ns.files, + mongo_sync_cmd_query (gfs->conn, gfs->ns.files, 0, 0, 0, + (q) ? q : query, NULL)); + if (!cursor) + { + int e = errno; + + bson_free (q); + errno = e; + return NULL; + } + bson_free (q); + return cursor; +} + +const guint8 * +mongo_sync_gridfs_file_get_id (gpointer gfile) +{ + mongo_sync_gridfs_chunked_file *c = (mongo_sync_gridfs_chunked_file *)gfile; + mongo_sync_gridfs_stream *s = (mongo_sync_gridfs_stream *)gfile; + + if (!gfile) + { + errno = ENOTCONN; + return NULL; + } + if (c->meta.type == LMC_GRIDFS_FILE_CHUNKED) + return c->meta.oid; + else + return s->file.id; +} + +gint64 +mongo_sync_gridfs_file_get_length (gpointer gfile) +{ + mongo_sync_gridfs_file_common *f = (mongo_sync_gridfs_file_common *)gfile; + + if (!gfile) + { + errno = ENOTCONN; + return -1; + } + return f->length; +} + +gint32 +mongo_sync_gridfs_file_get_chunk_size (gpointer gfile) +{ + mongo_sync_gridfs_file_common *f = (mongo_sync_gridfs_file_common *)gfile; + + if (!gfile) + { + errno = ENOTCONN; + return -1; + } + return f->chunk_size; +} + +const gchar * +mongo_sync_gridfs_file_get_md5 (gpointer gfile) +{ + mongo_sync_gridfs_chunked_file *f = (mongo_sync_gridfs_chunked_file *)gfile; + + if (!gfile) + { + errno = ENOTCONN; + return NULL; + } + if (f->meta.type != LMC_GRIDFS_FILE_CHUNKED) + { + errno = EOPNOTSUPP; + return NULL; + } + + return f->meta.md5; +} + +gint64 +mongo_sync_gridfs_file_get_date (gpointer gfile) +{ + mongo_sync_gridfs_chunked_file *f = (mongo_sync_gridfs_chunked_file *)gfile; + + if (!gfile) + { + errno = ENOTCONN; + return -1; + } + if (f->meta.type != LMC_GRIDFS_FILE_CHUNKED) + { + errno = EOPNOTSUPP; + return -1; + } + + return f->meta.date; +} + +const bson * +mongo_sync_gridfs_file_get_metadata (gpointer gfile) +{ + mongo_sync_gridfs_chunked_file *f = (mongo_sync_gridfs_chunked_file *)gfile; + + if (!gfile) + { + errno = ENOTCONN; + return NULL; + } + if (f->meta.type != LMC_GRIDFS_FILE_CHUNKED) + { + errno = EOPNOTSUPP; + return NULL; + } + + return f->meta.metadata; +} + +gint64 +mongo_sync_gridfs_file_get_chunks (gpointer gfile) +{ + mongo_sync_gridfs_file_common *f = (mongo_sync_gridfs_file_common *)gfile; + double chunk_count; + + if (!gfile) + { + errno = ENOTCONN; + return -1; + } + + chunk_count = (double)f->length / (double)f->chunk_size; + return (chunk_count - (gint64)chunk_count > 0) ? + (gint64)(chunk_count + 1) : (gint64)(chunk_count); +} + +gboolean +mongo_sync_gridfs_remove (mongo_sync_gridfs *gfs, + const bson *query) +{ + mongo_sync_cursor *fc; + + fc = mongo_sync_gridfs_list (gfs, query); + if (!fc) + { + if (errno != ENOTCONN) + errno = ENOENT; + return FALSE; + } + + while (mongo_sync_cursor_next (fc)) + { + bson *meta = mongo_sync_cursor_get_data (fc), *q; + bson_cursor *c; + const guint8 *ooid; + guint8 oid[12]; + + c = bson_find (meta, "_id"); + if (!bson_cursor_get_oid (c, &ooid)) + { + bson_free (meta); + bson_cursor_free (c); + mongo_sync_cursor_free (fc); + + errno = EPROTO; + return FALSE; + } + bson_cursor_free (c); + memcpy (oid, ooid, 12); + bson_free (meta); + + /* Delete metadata */ + q = bson_build (BSON_TYPE_OID, "_id", oid, + BSON_TYPE_NONE); + bson_finish (q); + + if (!mongo_sync_cmd_delete (gfs->conn, gfs->ns.files, 0, q)) + { + bson_free (q); + mongo_sync_cursor_free (fc); + return FALSE; + } + bson_free (q); + + /* Delete chunks */ + q = bson_build (BSON_TYPE_OID, "files_id", oid, + BSON_TYPE_NONE); + bson_finish (q); + + /* Chunks may or may not exist, an error in this case is + non-fatal. */ + mongo_sync_cmd_delete (gfs->conn, gfs->ns.chunks, 0, q); + bson_free (q); + } + + mongo_sync_cursor_free (fc); + + return TRUE; +} -- cgit v1.2.3