summaryrefslogtreecommitdiff
path: root/client/gridfs.h
blob: 9aeab0257fd6d0b841bfcf7b4bf512339ea63dee (plain)
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
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
/** @file gridfs.h */

#pragma once

#include "dbclient.h"

namespace mongo {

    typedef unsigned long long gridfs_offset;

    class GridFS;
    class GridFile;

    class Chunk {
    public:
        Chunk( BSONObj data );
        Chunk( BSONElement fileId , int chunkNumber , const char * data , int len );
        
        int len(){
            int len;
            const char * data = _data["data"].binData( len );
            int * foo = (int*)data;
            assert( len - 4 == foo[0] );
            return len - 4;
        }
            
        const char * data( int & len ){
            const char * data = _data["data"].binData( len );
            int * foo = (int*)data;
            assert( len - 4 == foo[0] );
            
            len = len - 4;
            return data + 4;
        }
        
    private:
        BSONObj _data;
        friend class GridFS;
    };


    /**
       this is the main entry point into the mongo grid fs
     */
    class GridFS{
    public:
        /**
         * @param client - db connection
         * @param dbName - root database name
         * @param prefix - if you want your data somewhere beisdes <dbname>.fs
         */
        GridFS( DBClientBase& client , string dbName , string prefix="fs" );
        ~GridFS();

        /**
         * puts the file reference by fileName into the db
         * @param fileName relative to process
         * @return the id file
         */
        BSONElement storeFile( string fileName );
        
        /**
         * returns a file object matching the query
         */
        GridFile findFile( BSONObj query );

        /**
         * equiv to findFile( { filename : filename } )
         */
        GridFile findFile( string filename);

        /**
         * convenience method to get all the files
         */
        auto_ptr<DBClientCursor> list();

        /**
         * convenience method to get all the files with a filter
         */
        auto_ptr<DBClientCursor> list( BSONObj query );

    private:
        DBClientBase& _client;
        string _filesNS;
        string _chunksNS;

        friend class GridFile;
    };
    
    /**
       wrapper for a file stored in the Mongo database
     */
    class GridFile {
    public:
        /**
         * @return whether or not this file exists
         * findFile will always return a GriFile, so need to check this
         */
        bool exists(){
            return ! _obj.isEmpty();
        }
        
        string getFilename(){
            return _obj["filename"].str();
        }
        
        int getChunkSize(){
            return (int)(_obj["chunkSize"].number());
        }

        gridfs_offset getContentLength(){
            return (gridfs_offset)(_obj["length"].number());
        }

        int getNumChunks(){
            return (int) ceil( (double)getContentLength() / (double)getChunkSize() );
        }

        Chunk getChunk( int n );

        /**
           write the file to the ouput stream
         */
        gridfs_offset write( ostream & out );

        /**
           write the file to this filename
         */
        gridfs_offset write( string where );
        
    private:
        GridFile( GridFS * grid , BSONObj obj );

        void _exists();
        
        GridFS * _grid;
        BSONObj _obj;

        friend class GridFS;
    };
}