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