1 /*
2 * Copyright (C) 2009 Martin Robinson
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
13 *
14 * You should have received a copy of the GNU Library General Public License
15 * along with this library; see the file COPYING.LIB. If not, write to
16 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
18 */
19
20 #include "config.h"
21 #include "webkitwebdatabase.h"
22
23 #include "webkitprivate.h"
24
25 #include "CString.h"
26 #include "DatabaseDetails.h"
27 #include "DatabaseTracker.h"
28
29 #include <glib/gi18n-lib.h>
30
31 /**
32 * SECTION:webkitwebdatabase
33 * @short_description: A WebKit web application database
34 *
35 * #WebKitWebDatabase is a representation of a Web Database database. The
36 * proposed Web Database standard introduces support for SQL databases that web
37 * sites can create and access on a local computer through JavaScript.
38 *
39 * To get access to all databases defined by a security origin, use
40 * #webkit_security_origin_get_databases. Each database has a canonical
41 * name, as well as a user-friendly display name.
42 *
43 * WebKit uses SQLite to create and access the local SQL databases. The location
44 * of a #WebKitWebDatabase can be accessed wth #webkit_web_database_get_filename.
45 * You can configure the location of all databases with
46 * #webkit_set_database_directory_path.
47 *
48 * For each database the web site can define an estimated size which can be
49 * accessed with #webkit_web_database_get_expected_size. The current size of the
50 * database in bytes is returned by #webkit_web_database_get_size.
51 *
52 * For more information refer to the Web Database specification proposal at
53 * http://dev.w3.org/html5/webdatabase
54 */
55
56 using namespace WebKit;
57
58 enum {
59 PROP_0,
60
61 PROP_SECURITY_ORIGIN,
62 PROP_NAME,
63 PROP_DISPLAY_NAME,
64 PROP_EXPECTED_SIZE,
65 PROP_SIZE,
66 PROP_PATH
67 };
68
69 G_DEFINE_TYPE(WebKitWebDatabase, webkit_web_database, G_TYPE_OBJECT)
70
71 struct _WebKitWebDatabasePrivate {
72 WebKitSecurityOrigin* origin;
73 gchar* name;
74 gchar* displayName;
75 gchar* filename;
76 };
77
78 static gchar* webkit_database_directory_path = NULL;
79 static guint64 webkit_default_database_quota = 5 * 1024 * 1024;
80
81 #define WEBKIT_WEB_DATABASE_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), WEBKIT_TYPE_WEB_DATABASE, WebKitWebDatabasePrivate))
82
83 static void webkit_web_database_set_security_origin(WebKitWebDatabase* webDatabase, WebKitSecurityOrigin* security_origin);
84
85 static void webkit_web_database_set_name(WebKitWebDatabase* webDatabase, const gchar* name);
86
webkit_web_database_finalize(GObject * object)87 static void webkit_web_database_finalize(GObject* object)
88 {
89 WebKitWebDatabase* webDatabase = WEBKIT_WEB_DATABASE(object);
90 WebKitWebDatabasePrivate* priv = webDatabase->priv;
91
92 g_free(priv->name);
93 g_free(priv->displayName);
94 g_free(priv->filename);
95
96 G_OBJECT_CLASS(webkit_web_database_parent_class)->finalize(object);
97 }
98
webkit_web_database_dispose(GObject * object)99 static void webkit_web_database_dispose(GObject* object)
100 {
101 WebKitWebDatabase* webDatabase = WEBKIT_WEB_DATABASE(object);
102 WebKitWebDatabasePrivate* priv = webDatabase->priv;
103
104 if (priv->origin) {
105 g_object_unref(priv->origin);
106 priv->origin = NULL;
107 }
108
109 G_OBJECT_CLASS(webkit_web_database_parent_class)->dispose(object);
110 }
111
webkit_web_database_set_property(GObject * object,guint propId,const GValue * value,GParamSpec * pspec)112 static void webkit_web_database_set_property(GObject* object, guint propId, const GValue* value, GParamSpec* pspec)
113 {
114 WebKitWebDatabase* webDatabase = WEBKIT_WEB_DATABASE(object);
115
116 switch (propId) {
117 case PROP_SECURITY_ORIGIN:
118 webkit_web_database_set_security_origin(webDatabase, WEBKIT_SECURITY_ORIGIN(g_value_get_object(value)));
119 break;
120 case PROP_NAME:
121 webkit_web_database_set_name(webDatabase, g_value_get_string(value));
122 break;
123 default:
124 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propId, pspec);
125 break;
126 }
127 }
128
webkit_web_database_get_property(GObject * object,guint propId,GValue * value,GParamSpec * pspec)129 static void webkit_web_database_get_property(GObject* object, guint propId, GValue* value, GParamSpec* pspec)
130 {
131 WebKitWebDatabase* webDatabase = WEBKIT_WEB_DATABASE(object);
132 WebKitWebDatabasePrivate* priv = webDatabase->priv;
133
134 switch (propId) {
135 case PROP_SECURITY_ORIGIN:
136 g_value_set_object(value, priv->origin);
137 break;
138 case PROP_NAME:
139 g_value_set_string(value, webkit_web_database_get_name(webDatabase));
140 break;
141 case PROP_DISPLAY_NAME:
142 g_value_set_string(value, webkit_web_database_get_display_name(webDatabase));
143 break;
144 case PROP_EXPECTED_SIZE:
145 g_value_set_uint64(value, webkit_web_database_get_expected_size(webDatabase));
146 break;
147 case PROP_SIZE:
148 g_value_set_uint64(value, webkit_web_database_get_size(webDatabase));
149 break;
150 case PROP_PATH:
151 g_value_set_string(value, webkit_web_database_get_filename(webDatabase));
152 break;
153 default:
154 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propId, pspec);
155 break;
156 }
157 }
158
webkit_web_database_class_init(WebKitWebDatabaseClass * klass)159 static void webkit_web_database_class_init(WebKitWebDatabaseClass* klass)
160 {
161 GObjectClass* gobjectClass = G_OBJECT_CLASS(klass);
162 gobjectClass->dispose = webkit_web_database_dispose;
163 gobjectClass->finalize = webkit_web_database_finalize;
164 gobjectClass->set_property = webkit_web_database_set_property;
165 gobjectClass->get_property = webkit_web_database_get_property;
166
167 /**
168 * WebKitWebDatabase:security-origin:
169 *
170 * The security origin of the database.
171 *
172 * Since: 1.1.14
173 */
174 g_object_class_install_property(gobjectClass, PROP_SECURITY_ORIGIN,
175 g_param_spec_object("security-origin",
176 _("Security Origin"),
177 _("The security origin of the database"),
178 WEBKIT_TYPE_SECURITY_ORIGIN,
179 (GParamFlags) (G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)));
180
181 /**
182 * WebKitWebDatabase:name:
183 *
184 * The name of the Web Database database.
185 *
186 * Since: 1.1.14
187 */
188 g_object_class_install_property(gobjectClass, PROP_NAME,
189 g_param_spec_string("name",
190 _("Name"),
191 _("The name of the Web Database database"),
192 NULL,
193 (GParamFlags) (G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)));
194
195 /**
196 * WebKitWebDatabase:display-name:
197 *
198 * The display name of the Web Database database.
199 *
200 * Since: 1.1.14
201 */
202 g_object_class_install_property(gobjectClass, PROP_DISPLAY_NAME,
203 g_param_spec_string("display-name",
204 _("Display Name"),
205 _("The display name of the Web Storage database"),
206 NULL,
207 WEBKIT_PARAM_READABLE));
208
209 /**
210 * WebKitWebDatabase:expected-size:
211 *
212 * The expected size of the database in bytes as defined by the web author.
213 *
214 * Since: 1.1.14
215 */
216 g_object_class_install_property(gobjectClass, PROP_EXPECTED_SIZE,
217 g_param_spec_uint64("expected-size",
218 _("Expected Size"),
219 _("The expected size of the Web Database database"),
220 0, G_MAXUINT64, 0,
221 WEBKIT_PARAM_READABLE));
222 /**
223 * WebKitWebDatabase:size:
224 *
225 * The current size of the database in bytes.
226 *
227 * Since: 1.1.14
228 */
229 g_object_class_install_property(gobjectClass, PROP_SIZE,
230 g_param_spec_uint64("size",
231 _("Size"),
232 _("The current size of the Web Database database"),
233 0, G_MAXUINT64, 0,
234 WEBKIT_PARAM_READABLE));
235 /**
236 * WebKitWebDatabase:filename:
237 *
238 * The absolute filename of the Web Database database.
239 *
240 * Since: 1.1.14
241 */
242 g_object_class_install_property(gobjectClass, PROP_PATH,
243 g_param_spec_string("filename",
244 _("Filename"),
245 _("The absolute filename of the Web Storage database"),
246 NULL,
247 WEBKIT_PARAM_READABLE));
248
249 g_type_class_add_private(klass, sizeof(WebKitWebDatabasePrivate));
250 }
251
webkit_web_database_init(WebKitWebDatabase * webDatabase)252 static void webkit_web_database_init(WebKitWebDatabase* webDatabase)
253 {
254 webDatabase->priv = WEBKIT_WEB_DATABASE_GET_PRIVATE(webDatabase);
255 }
256
257 // Internal use only
webkit_web_database_set_security_origin(WebKitWebDatabase * webDatabase,WebKitSecurityOrigin * securityOrigin)258 static void webkit_web_database_set_security_origin(WebKitWebDatabase *webDatabase, WebKitSecurityOrigin *securityOrigin)
259 {
260 g_return_if_fail(WEBKIT_IS_WEB_DATABASE(webDatabase));
261 g_return_if_fail(WEBKIT_IS_SECURITY_ORIGIN(securityOrigin));
262
263 WebKitWebDatabasePrivate* priv = webDatabase->priv;
264
265 if (priv->origin)
266 g_object_unref(priv->origin);
267
268 g_object_ref(securityOrigin);
269 priv->origin = securityOrigin;
270 }
271
webkit_web_database_set_name(WebKitWebDatabase * webDatabase,const gchar * name)272 static void webkit_web_database_set_name(WebKitWebDatabase* webDatabase, const gchar* name)
273 {
274 g_return_if_fail(WEBKIT_IS_WEB_DATABASE(webDatabase));
275
276 WebKitWebDatabasePrivate* priv = webDatabase->priv;
277 g_free(priv->name);
278 priv->name = g_strdup(name);
279 }
280
281 /**
282 * webkit_web_database_get_security_origin:
283 * @web_database: a #WebKitWebDatabase
284 *
285 * Returns the security origin of the #WebKitWebDatabase.
286 *
287 * Returns: the security origin of the database
288 *
289 * Since: 1.1.14
290 **/
webkit_web_database_get_security_origin(WebKitWebDatabase * webDatabase)291 WebKitSecurityOrigin* webkit_web_database_get_security_origin(WebKitWebDatabase* webDatabase)
292 {
293 g_return_val_if_fail(WEBKIT_IS_WEB_DATABASE(webDatabase), NULL);
294 WebKitWebDatabasePrivate* priv = webDatabase->priv;
295
296 return priv->origin;
297 }
298
299 /**
300 * webkit_web_database_get_name:
301 * @web_database: a #WebKitWebDatabase
302 *
303 * Returns the canonical name of the #WebKitWebDatabase.
304 *
305 * Returns: the name of the database
306 *
307 * Since: 1.1.14
308 **/
webkit_web_database_get_name(WebKitWebDatabase * webDatabase)309 G_CONST_RETURN gchar* webkit_web_database_get_name(WebKitWebDatabase* webDatabase)
310 {
311 g_return_val_if_fail(WEBKIT_IS_WEB_DATABASE(webDatabase), NULL);
312 WebKitWebDatabasePrivate* priv = webDatabase->priv;
313
314 return priv->name;
315 }
316
317 /**
318 * webkit_web_database_get_display_name:
319 * @web_database: a #WebKitWebDatabase
320 *
321 * Returns the name of the #WebKitWebDatabase as seen by the user.
322 *
323 * Returns: the name of the database as seen by the user.
324 *
325 * Since: 1.1.14
326 **/
webkit_web_database_get_display_name(WebKitWebDatabase * webDatabase)327 G_CONST_RETURN gchar* webkit_web_database_get_display_name(WebKitWebDatabase* webDatabase)
328 {
329 g_return_val_if_fail(WEBKIT_IS_WEB_DATABASE(webDatabase), NULL);
330
331 #if ENABLE(DATABASE)
332 WebKitWebDatabasePrivate* priv = webDatabase->priv;
333 WebCore::DatabaseDetails details = WebCore::DatabaseTracker::tracker().detailsForNameAndOrigin(priv->name, core(priv->origin));
334 WebCore::String displayName = details.displayName();
335
336 if (displayName.isEmpty())
337 return "";
338
339 g_free(priv->displayName);
340 priv->displayName = g_strdup(displayName.utf8().data());
341 return priv->displayName;
342 #else
343 return "";
344 #endif
345 }
346
347 /**
348 * webkit_web_database_get_expected_size:
349 * @web_database: a #WebKitWebDatabase
350 *
351 * Returns the expected size of the #WebKitWebDatabase in bytes as defined by the
352 * web author. The Web Database standard allows web authors to specify an expected
353 * size of the database to optimize the user experience.
354 *
355 * Returns: the expected size of the database in bytes
356 *
357 * Since: 1.1.14
358 **/
webkit_web_database_get_expected_size(WebKitWebDatabase * webDatabase)359 guint64 webkit_web_database_get_expected_size(WebKitWebDatabase* webDatabase)
360 {
361 g_return_val_if_fail(WEBKIT_IS_WEB_DATABASE(webDatabase), 0);
362
363 #if ENABLE(DATABASE)
364 WebKitWebDatabasePrivate* priv = webDatabase->priv;
365 WebCore::DatabaseDetails details = WebCore::DatabaseTracker::tracker().detailsForNameAndOrigin(priv->name, core(priv->origin));
366 return details.expectedUsage();
367 #else
368 return 0;
369 #endif
370 }
371
372 /**
373 * webkit_web_database_get_size:
374 * @web_database: a #WebKitWebDatabase
375 *
376 * Returns the actual size of the #WebKitWebDatabase space on disk in bytes.
377 *
378 * Returns: the actual size of the database in bytes
379 *
380 * Since: 1.1.14
381 **/
webkit_web_database_get_size(WebKitWebDatabase * webDatabase)382 guint64 webkit_web_database_get_size(WebKitWebDatabase* webDatabase)
383 {
384 g_return_val_if_fail(WEBKIT_IS_WEB_DATABASE(webDatabase), 0);
385
386 #if ENABLE(DATABASE)
387 WebKitWebDatabasePrivate* priv = webDatabase->priv;
388 WebCore::DatabaseDetails details = WebCore::DatabaseTracker::tracker().detailsForNameAndOrigin(priv->name, core(priv->origin));
389 return details.currentUsage();
390 #else
391 return 0;
392 #endif
393 }
394
395 /**
396 * webkit_web_database_get_filename:
397 * @web_database: a #WebKitWebDatabase
398 *
399 * Returns the absolute filename to the #WebKitWebDatabase file on disk.
400 *
401 * Returns: the absolute filename of the database
402 *
403 * Since: 1.1.14
404 **/
webkit_web_database_get_filename(WebKitWebDatabase * webDatabase)405 G_CONST_RETURN gchar* webkit_web_database_get_filename(WebKitWebDatabase* webDatabase)
406 {
407 g_return_val_if_fail(WEBKIT_IS_WEB_DATABASE(webDatabase), NULL);
408
409 #if ENABLE(DATABASE)
410 WebKitWebDatabasePrivate* priv = webDatabase->priv;
411 WebCore::String coreName = WebCore::String::fromUTF8(priv->name);
412 WebCore::String corePath = WebCore::DatabaseTracker::tracker().fullPathForDatabase(core(priv->origin), coreName);
413
414 if (corePath.isEmpty())
415 return"";
416
417 g_free(priv->filename);
418 priv->filename = g_strdup(corePath.utf8().data());
419 return priv->filename;
420
421 #else
422 return "";
423 #endif
424 }
425
426 /**
427 * webkit_web_database_remove:
428 * @web_database: a #WebKitWebDatabase
429 *
430 * Removes the #WebKitWebDatabase from its security origin and destroys all data
431 * stored in the database.
432 *
433 * Since: 1.1.14
434 **/
webkit_web_database_remove(WebKitWebDatabase * webDatabase)435 void webkit_web_database_remove(WebKitWebDatabase* webDatabase)
436 {
437 g_return_if_fail(WEBKIT_IS_WEB_DATABASE(webDatabase));
438
439 #if ENABLE(DATABASE)
440 WebKitWebDatabasePrivate* priv = webDatabase->priv;
441 WebCore::DatabaseTracker::tracker().deleteDatabase(core(priv->origin), priv->name);
442 #endif
443 }
444
445 /**
446 * webkit_remove_all_web_databases:
447 *
448 * Removes all web databases from the current database directory path.
449 *
450 * Since: 1.1.14
451 **/
webkit_remove_all_web_databases()452 void webkit_remove_all_web_databases()
453 {
454 #if ENABLE(DATABASE)
455 WebCore::DatabaseTracker::tracker().deleteAllDatabases();
456 #endif
457 }
458
459 /**
460 * webkit_get_web_database_directory_path:
461 *
462 * Returns the current path to the directory WebKit will write Web
463 * Database databases. By default this path will be in the user data
464 * directory.
465 *
466 * Returns: the current database directory path
467 *
468 * Since: 1.1.14
469 **/
webkit_get_web_database_directory_path()470 G_CONST_RETURN gchar* webkit_get_web_database_directory_path()
471 {
472 #if ENABLE(DATABASE)
473 WebCore::String path = WebCore::DatabaseTracker::tracker().databaseDirectoryPath();
474
475 if (path.isEmpty())
476 return "";
477
478 g_free(webkit_database_directory_path);
479 webkit_database_directory_path = g_strdup(path.utf8().data());
480 return webkit_database_directory_path;
481 #else
482 return "";
483 #endif
484 }
485
486 /**
487 * webkit_set_web_database_directory_path:
488 * @path: the new database directory path
489 *
490 * Sets the current path to the directory WebKit will write Web
491 * Database databases.
492 *
493 * Since: 1.1.14
494 **/
webkit_set_web_database_directory_path(const gchar * path)495 void webkit_set_web_database_directory_path(const gchar* path)
496 {
497 #if ENABLE(DATABASE)
498 WebCore::String corePath = WebCore::String::fromUTF8(path);
499 WebCore::DatabaseTracker::tracker().setDatabaseDirectoryPath(corePath);
500
501 g_free(webkit_database_directory_path);
502 webkit_database_directory_path = g_strdup(corePath.utf8().data());
503 #endif
504 }
505
506 /**
507 * webkit_get_default_web_database_quota:
508 *
509 * Returns the default quota for Web Database databases. By default
510 * this value is 5MB.
511
512 * Returns: the current default database quota in bytes
513 *
514 * Since: 1.1.14
515 **/
webkit_get_default_web_database_quota()516 guint64 webkit_get_default_web_database_quota()
517 {
518 return webkit_default_database_quota;
519 }
520
521 /**
522 * webkit_set_default_web_database_quota:
523 * @default_quota: the new default database quota
524 *
525 * Sets the current path to the directory WebKit will write Web
526 * Database databases.
527 *
528 * Since: 1.1.14
529 **/
webkit_set_default_web_database_quota(guint64 defaultQuota)530 void webkit_set_default_web_database_quota(guint64 defaultQuota)
531 {
532 webkit_default_database_quota = defaultQuota;
533 }
534