1 /***********************************************************************************************************************************
2 Storage Interface
3 ***********************************************************************************************************************************/
4 #ifndef STORAGE_STORAGE_H
5 #define STORAGE_STORAGE_H
6
7 #include <sys/types.h>
8
9 /***********************************************************************************************************************************
10 Object type
11 ***********************************************************************************************************************************/
12 typedef struct Storage Storage;
13
14 #include "common/type/buffer.h"
15 #include "common/type/stringList.h"
16 #include "common/io/filter/group.h"
17 #include "common/time.h"
18 #include "common/type/param.h"
19 #include "storage/info.h"
20 #include "storage/read.h"
21 #include "storage/storage.intern.h"
22 #include "storage/write.h"
23
24 /***********************************************************************************************************************************
25 Storage feature
26 ***********************************************************************************************************************************/
27 typedef enum
28 {
29 // Does the storage support paths/directories as something that needs to be created and deleted? Object stores (e.g. S3) often
30 // do not have paths/directories -- they are only inferred by the object name. Therefore it doesn't make sense to create or
31 // remove directories since this implies something is happening on the storage and in the case of objects stores it would be a
32 // noop. We'll error on any path operation (e.g. pathExists(), pathCreate(), non-recursive removes, error on missing paths,
33 // etc.) for storage that does not support paths.
34 storageFeaturePath,
35
36 // Do paths need to be synced to ensure contents are durable? storeageFeaturePath must also be enabled.
37 storageFeaturePathSync,
38
39 // Is the storage able to do compression and therefore store the file more efficiently than what was written? If so, the size
40 // will need to checked after write to see if it is different.
41 storageFeatureCompress,
42
43 // Does the storage support hardlinks? Hardlinks allow the same file to be linked into multiple paths to save space.
44 storageFeatureHardLink,
45
46 // Can the storage limit the amount of data read from a file?
47 storageFeatureLimitRead,
48
49 // Does the storage support symlinks? Symlinks allow paths/files/links to be accessed from another path.
50 storageFeatureSymLink,
51
52 // Does the storage support detailed info, i.e. user, group, mode, link destination, etc.
53 storageFeatureInfoDetail,
54 } StorageFeature;
55
56 /***********************************************************************************************************************************
57 Functions
58 ***********************************************************************************************************************************/
59 // Copy a file
60 #define storageCopyP(source, destination) \
61 storageCopy(source, destination)
62
63 bool storageCopy(StorageRead *source, StorageWrite *destination);
64
65 // Does a file exist? This function is only for files, not paths.
66 typedef struct StorageExistsParam
67 {
68 VAR_PARAM_HEADER;
69 TimeMSec timeout;
70 } StorageExistsParam;
71
72 #define storageExistsP(this, pathExp, ...) \
73 storageExists(this, pathExp, (StorageExistsParam){VAR_PARAM_INIT, __VA_ARGS__})
74
75 bool storageExists(const Storage *this, const String *pathExp, StorageExistsParam param);
76
77 // Read from storage into a buffer
78 typedef struct StorageGetParam
79 {
80 VAR_PARAM_HEADER;
81 size_t exactSize;
82 } StorageGetParam;
83
84 #define storageGetP(file, ...) \
85 storageGet(file, (StorageGetParam){VAR_PARAM_INIT, __VA_ARGS__})
86
87 Buffer *storageGet(StorageRead *file, StorageGetParam param);
88
89 // File/path info
90 typedef struct StorageInfoParam
91 {
92 VAR_PARAM_HEADER;
93 StorageInfoLevel level;
94 bool ignoreMissing;
95 bool followLink;
96 bool noPathEnforce;
97 } StorageInfoParam;
98
99 #define storageInfoP(this, fileExp, ...) \
100 storageInfo(this, fileExp, (StorageInfoParam){VAR_PARAM_INIT, __VA_ARGS__})
101
102 StorageInfo storageInfo(const Storage *this, const String *fileExp, StorageInfoParam param);
103
104 // Info for all files/paths in a path
105 typedef void (*StorageInfoListCallback)(void *callbackData, const StorageInfo *info);
106
107 typedef struct StorageInfoListParam
108 {
109 VAR_PARAM_HEADER;
110 StorageInfoLevel level;
111 bool errorOnMissing;
112 bool recurse;
113 SortOrder sortOrder;
114 const String *expression;
115 } StorageInfoListParam;
116
117 #define storageInfoListP(this, fileExp, callback, callbackData, ...) \
118 storageInfoList(this, fileExp, callback, callbackData, (StorageInfoListParam){VAR_PARAM_INIT, __VA_ARGS__})
119
120 bool storageInfoList(
121 const Storage *this, const String *pathExp, StorageInfoListCallback callback, void *callbackData, StorageInfoListParam param);
122
123 // Get a list of files from a directory
124 typedef struct StorageListParam
125 {
126 VAR_PARAM_HEADER;
127 bool errorOnMissing;
128 bool nullOnMissing;
129 const String *expression;
130 } StorageListParam;
131
132 #define storageListP(this, pathExp, ...) \
133 storageList(this, pathExp, (StorageListParam){VAR_PARAM_INIT, __VA_ARGS__})
134
135 StringList *storageList(const Storage *this, const String *pathExp, StorageListParam param);
136
137 // Move a file
138 #define storageMoveP(this, source, destination) \
139 storageMove(this, source, destination)
140
141 void storageMove(const Storage *this, StorageRead *source, StorageWrite *destination);
142
143 // Open a file for reading
144 typedef struct StorageNewReadParam
145 {
146 VAR_PARAM_HEADER;
147 bool ignoreMissing;
148 bool compressible;
149
150 // Limit bytes to read from the file (must be varTypeUInt64). NULL for no limit.
151 const Variant *limit;
152 } StorageNewReadParam;
153
154 #define storageNewReadP(this, pathExp, ...) \
155 storageNewRead(this, pathExp, (StorageNewReadParam){VAR_PARAM_INIT, __VA_ARGS__})
156
157 StorageRead *storageNewRead(const Storage *this, const String *fileExp, StorageNewReadParam param);
158
159 // Open a file for writing
160 typedef struct StorageNewWriteParam
161 {
162 VAR_PARAM_HEADER;
163 bool noCreatePath;
164 bool noSyncFile;
165 bool noSyncPath;
166 bool noAtomic;
167 bool compressible;
168 mode_t modeFile;
169 mode_t modePath;
170 time_t timeModified;
171 const String *user;
172 const String *group;
173 } StorageNewWriteParam;
174
175 #define storageNewWriteP(this, pathExp, ...) \
176 storageNewWrite(this, pathExp, (StorageNewWriteParam){VAR_PARAM_INIT, __VA_ARGS__})
177
178 StorageWrite *storageNewWrite(const Storage *this, const String *fileExp, StorageNewWriteParam param);
179
180 // Get absolute path in the storage
181 typedef struct StoragePathParam
182 {
183 VAR_PARAM_HEADER;
184 bool noEnforce;
185 } StoragePathParam;
186
187 #define storagePathP(this, pathExp, ...) \
188 storagePath(this, pathExp, (StoragePathParam){VAR_PARAM_INIT, __VA_ARGS__})
189
190 String *storagePath(const Storage *this, const String *pathExp, StoragePathParam param);
191
192 // Create a path
193 typedef struct StoragePathCreateParam
194 {
195 VAR_PARAM_HEADER;
196 bool errorOnExists;
197 bool noParentCreate;
198 mode_t mode;
199 } StoragePathCreateParam;
200
201 #define storagePathCreateP(this, pathExp, ...) \
202 storagePathCreate(this, pathExp, (StoragePathCreateParam){VAR_PARAM_INIT, __VA_ARGS__})
203
204 void storagePathCreate(const Storage *this, const String *pathExp, StoragePathCreateParam param);
205
206 // Does a path exist?
207 #define storagePathExistsP(this, pathExp) \
208 storagePathExists(this, pathExp)
209
210 bool storagePathExists(const Storage *this, const String *pathExp);
211
212 // Remove a path
213 typedef struct StoragePathRemoveParam
214 {
215 VAR_PARAM_HEADER;
216 bool errorOnMissing;
217 bool recurse;
218 } StoragePathRemoveParam;
219
220 #define storagePathRemoveP(this, pathExp, ...) \
221 storagePathRemove(this, pathExp, (StoragePathRemoveParam){VAR_PARAM_INIT, __VA_ARGS__})
222
223 void storagePathRemove(const Storage *this, const String *pathExp, StoragePathRemoveParam param);
224
225 // Sync a path
226 #define storagePathSyncP(this, pathExp) \
227 storagePathSync(this, pathExp)
228
229 void storagePathSync(const Storage *this, const String *pathExp);
230
231 // Write a buffer to storage
232 #define storagePutP(file, buffer) \
233 storagePut(file, buffer)
234
235 void storagePut(StorageWrite *file, const Buffer *buffer);
236
237 // Remove a file
238 typedef struct StorageRemoveParam
239 {
240 VAR_PARAM_HEADER;
241 bool errorOnMissing;
242 } StorageRemoveParam;
243
244 #define storageRemoveP(this, fileExp, ...) \
245 storageRemove(this, fileExp, (StorageRemoveParam){VAR_PARAM_INIT, __VA_ARGS__})
246
247 void storageRemove(const Storage *this, const String *fileExp, StorageRemoveParam param);
248
249 /***********************************************************************************************************************************
250 Getters/Setters
251 ***********************************************************************************************************************************/
252 // Is the feature supported by this storage?
253 __attribute__((always_inline)) static inline bool
storageFeature(const Storage * const this,const StorageFeature feature)254 storageFeature(const Storage *const this, const StorageFeature feature)
255 {
256 return THIS_PUB(Storage)->interface.feature >> feature & 1;
257 }
258
259 // Storage type (posix, cifs, etc.)
260 __attribute__((always_inline)) static inline StringId
storageType(const Storage * const this)261 storageType(const Storage *const this)
262 {
263 return THIS_PUB(Storage)->type;
264 }
265
266 /***********************************************************************************************************************************
267 Macros for function logging
268 ***********************************************************************************************************************************/
269 String *storageToLog(const Storage *this);
270
271 #define FUNCTION_LOG_STORAGE_TYPE \
272 Storage *
273 #define FUNCTION_LOG_STORAGE_FORMAT(value, buffer, bufferSize) \
274 FUNCTION_LOG_STRING_OBJECT_FORMAT(value, storageToLog, buffer, bufferSize)
275
276 #endif
277