00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "xmmspriv/xmms_collserial.h"
00023 #include "xmmspriv/xmms_collection.h"
00024 #include "xmmspriv/xmms_medialib.h"
00025
00026
00027
00028
00029 typedef struct {
00030 xmms_medialib_session_t *session;
00031 guint collid;
00032 xmms_collection_namespace_id_t nsid;
00033 } coll_dbwrite_t;
00034
00035
00036 static xmmsv_coll_t *xmms_collection_dbread_operator (xmms_medialib_session_t *session, gint id, xmmsv_coll_type_t type);
00037 static guint xmms_collection_dbwrite_operator (xmms_medialib_session_t *session, guint collid, xmmsv_coll_t *coll);
00038
00039 static void dbwrite_operator (void *key, void *value, void *udata);
00040 static void dbwrite_coll_attributes (const char *key, xmmsv_t *value, void *udata);
00041 static void dbwrite_strip_tmpprops (void *key, void *value, void *udata);
00042
00043 static gint value_get_dict_int (xmmsv_t *val, const gchar *key);
00044 static const gchar *value_get_dict_string (xmmsv_t *val, const gchar *key);
00045
00046
00047
00048
00049
00050
00051
00052 void
00053 xmms_collection_dag_save (xmms_coll_dag_t *dag)
00054 {
00055 gint i;
00056 xmms_medialib_session_t *session;
00057
00058 session = xmms_medialib_begin_write ();
00059
00060
00061 xmms_medialib_select (session, "DELETE FROM CollectionAttributes", NULL);
00062 xmms_medialib_select (session, "DELETE FROM CollectionConnections", NULL);
00063 xmms_medialib_select (session, "DELETE FROM CollectionIdlists", NULL);
00064 xmms_medialib_select (session, "DELETE FROM CollectionLabels", NULL);
00065 xmms_medialib_select (session, "DELETE FROM CollectionOperators", NULL);
00066
00067
00068 coll_dbwrite_t dbinfos = { session, 1, 0 };
00069 for (i = 0; i < XMMS_COLLECTION_NUM_NAMESPACES; ++i) {
00070 dbinfos.nsid = i;
00071 xmms_collection_foreach_in_namespace (dag, i, dbwrite_operator, &dbinfos);
00072 }
00073
00074 xmms_collection_foreach_in_namespace (dag, XMMS_COLLECTION_NSID_ALL,
00075 dbwrite_strip_tmpprops, NULL);
00076
00077 xmms_medialib_end (session);
00078 }
00079
00080
00081
00082
00083
00084 void
00085 xmms_collection_dag_restore (xmms_coll_dag_t *dag)
00086 {
00087 xmmsv_coll_t *coll = NULL;
00088 xmms_medialib_session_t *session;
00089 xmmsv_t *cmdval;
00090 const gchar *query;
00091 GList *res;
00092 gint previd;
00093
00094 session = xmms_medialib_begin ();
00095
00096
00097 query = "SELECT op.id AS id, lbl.name AS label, "
00098 " lbl.namespace AS nsid, op.type AS type "
00099 "FROM CollectionOperators AS op, CollectionLabels as lbl "
00100 "WHERE op.id=lbl.collid "
00101 "ORDER BY id";
00102 res = xmms_medialib_select (session, query, NULL);
00103
00104 previd = -1;
00105
00106 while (res) {
00107 gint id, type, nsid;
00108 const gchar *label;
00109
00110 cmdval = (xmmsv_t*) res->data;
00111 id = value_get_dict_int (cmdval, "id");
00112 type = value_get_dict_int (cmdval, "type");
00113 nsid = value_get_dict_int (cmdval, "nsid");
00114 label = value_get_dict_string (cmdval, "label");
00115
00116
00117 if (previd < 0 || id != previd) {
00118 coll = xmms_collection_dbread_operator (session, id, type);
00119 previd = id;
00120 }
00121 else {
00122 xmmsv_coll_ref (coll);
00123 }
00124
00125 xmms_collection_dag_replace (dag, nsid, g_strdup (label), coll);
00126
00127 xmmsv_unref (cmdval);
00128 res = g_list_delete_link (res, res);
00129 }
00130
00131 xmms_medialib_end (session);
00132
00133
00134
00135
00136 xmms_collection_apply_to_all_collections (dag, bind_all_references, NULL);
00137 }
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147 static xmmsv_coll_t *
00148 xmms_collection_dbread_operator (xmms_medialib_session_t *session,
00149 gint id, xmmsv_coll_type_t type)
00150 {
00151 xmmsv_coll_t *coll;
00152 xmmsv_coll_t *op;
00153 GList *res;
00154 GList *n;
00155 xmmsv_t *cmdval;
00156 gchar query[256];
00157
00158 coll = xmmsv_coll_new (type);
00159
00160
00161 g_snprintf (query, sizeof (query),
00162 "SELECT attr.key AS key, attr.value AS value "
00163 "FROM CollectionOperators AS op, CollectionAttributes AS attr "
00164 "WHERE op.id=%d AND attr.collid=op.id", id);
00165
00166 res = xmms_medialib_select (session, query, NULL);
00167 for (n = res; n; n = n->next) {
00168 const gchar *key, *value;
00169
00170 cmdval = (xmmsv_t*) n->data;
00171 key = value_get_dict_string (cmdval, "key");
00172 value = value_get_dict_string (cmdval, "value");
00173 xmmsv_coll_attribute_set (coll, key, value);
00174
00175 xmmsv_unref (n->data);
00176 }
00177 g_list_free (res);
00178
00179
00180 g_snprintf (query, sizeof (query),
00181 "SELECT idl.mid AS mid "
00182 "FROM CollectionOperators AS op, CollectionIdlists AS idl "
00183 "WHERE op.id=%d AND idl.collid=op.id "
00184 "ORDER BY idl.position", id);
00185
00186 res = xmms_medialib_select (session, query, NULL);
00187 for (n = res; n; n = n->next) {
00188
00189 cmdval = (xmmsv_t *) n->data;
00190 xmmsv_coll_idlist_append (coll, value_get_dict_int (cmdval, "mid"));
00191
00192 xmmsv_unref (cmdval);
00193 }
00194 g_list_free (res);
00195
00196
00197 g_snprintf (query, sizeof (query),
00198 "SELECT op.id AS id, op.type AS type "
00199 "FROM CollectionOperators AS op, CollectionConnections AS conn "
00200 "WHERE conn.to_id=%d AND conn.from_id=op.id", id);
00201
00202 res = xmms_medialib_select (session, query, NULL);
00203 for (n = res; n; n = n->next) {
00204 gint _id;
00205 gint type;
00206
00207 cmdval = (xmmsv_t *) n->data;
00208 _id = value_get_dict_int (cmdval, "id");
00209 type = value_get_dict_int (cmdval, "type");
00210
00211 op = xmms_collection_dbread_operator (session, _id, type);
00212 xmmsv_coll_add_operand (coll, op);
00213
00214 xmmsv_coll_unref (op);
00215 xmmsv_unref (cmdval);
00216 }
00217 g_list_free (res);
00218
00219 return coll;
00220 }
00221
00222
00223
00224
00225
00226
00227
00228
00229 static guint
00230 xmms_collection_dbwrite_operator (xmms_medialib_session_t *session,
00231 guint collid, xmmsv_coll_t *coll)
00232 {
00233 gchar query[128];
00234 guint *idlist;
00235 gint i;
00236 xmmsv_coll_t *op;
00237 xmmsv_t *attrs;
00238 gint newid, nextid;
00239 coll_dbwrite_t dbwrite_infos = { session, collid, 0 };
00240
00241
00242 g_snprintf (query, sizeof (query),
00243 "INSERT INTO CollectionOperators VALUES(%d, %d)",
00244 collid, xmmsv_coll_get_type (coll));
00245
00246 xmms_medialib_select (session, query, NULL);
00247
00248
00249 attrs = xmmsv_coll_attributes_get (coll);
00250 xmmsv_dict_foreach (attrs, dbwrite_coll_attributes, &dbwrite_infos);
00251 attrs = NULL;
00252
00253
00254 idlist = xmmsv_coll_get_idlist (coll);
00255 for (i = 0; idlist[i] != 0; i++) {
00256 g_snprintf (query, sizeof (query),
00257 "INSERT INTO CollectionIdlists VALUES(%d, %d, %d)",
00258 collid, i, idlist[i]);
00259
00260 xmms_medialib_select (session, query, NULL);
00261 }
00262
00263
00264 newid = collid + 1;
00265 if (xmmsv_coll_get_type (coll) != XMMS_COLLECTION_TYPE_REFERENCE) {
00266 xmmsv_t *tmp;
00267 xmmsv_list_iter_t *iter;
00268
00269 xmmsv_get_list_iter (xmmsv_coll_operands_get (coll), &iter);
00270
00271 for (xmmsv_list_iter_first (iter);
00272 xmmsv_list_iter_valid (iter);
00273 xmmsv_list_iter_next (iter)) {
00274
00275 xmmsv_list_iter_entry (iter, &tmp);
00276 xmmsv_get_coll (tmp, &op);
00277
00278 nextid = xmms_collection_dbwrite_operator (session, newid, op);
00279 g_snprintf (query, sizeof (query),
00280 "INSERT INTO CollectionConnections VALUES(%d, %d)",
00281 newid, collid);
00282 xmms_medialib_select (session, query, NULL);
00283 newid = nextid;
00284 }
00285 xmmsv_list_iter_explicit_destroy (iter);
00286 }
00287
00288
00289 return newid;
00290 }
00291
00292
00293
00294 static void
00295 dbwrite_operator (void *key, void *value, void *udata)
00296 {
00297 gchar *query;
00298 gchar *label = key;
00299 xmmsv_coll_t *coll = value;
00300 coll_dbwrite_t *dbinfos = udata;
00301 gchar *esc_label;
00302 gint serial_id;
00303
00304
00305 if (!xmms_collection_get_int_attr (coll, XMMS_COLLSERIAL_ATTR_ID, &serial_id)) {
00306 serial_id = dbinfos->collid;
00307 dbinfos->collid = xmms_collection_dbwrite_operator (dbinfos->session,
00308 dbinfos->collid, coll);
00309 xmms_collection_set_int_attr (coll, XMMS_COLLSERIAL_ATTR_ID, serial_id);
00310 }
00311
00312 esc_label = sqlite_prepare_string (label);
00313 query = g_strdup_printf ("INSERT INTO CollectionLabels VALUES(%d, %d, %s)",
00314 serial_id, dbinfos->nsid, esc_label);
00315 xmms_medialib_select (dbinfos->session, query, NULL);
00316
00317 g_free (query);
00318 g_free (esc_label);
00319 }
00320
00321
00322 static void
00323 dbwrite_coll_attributes (const char *key, xmmsv_t *value, void *udata)
00324 {
00325 gchar *query;
00326 coll_dbwrite_t *dbwrite_infos = udata;
00327 gchar *esc_key;
00328 gchar *esc_val;
00329 const gchar *s;
00330 int r;
00331
00332 r = xmmsv_get_string (value, &s);
00333 g_return_if_fail (r);
00334
00335 esc_key = sqlite_prepare_string (key);
00336 esc_val = sqlite_prepare_string (s);
00337 query = g_strdup_printf ("INSERT INTO CollectionAttributes VALUES(%d, %s, %s)",
00338 dbwrite_infos->collid, esc_key, esc_val);
00339 xmms_medialib_select (dbwrite_infos->session, query, NULL);
00340
00341 g_free (query);
00342 g_free (esc_key);
00343 g_free (esc_val);
00344 }
00345
00346
00347 static void
00348 dbwrite_strip_tmpprops (void *key, void *value, void *udata)
00349 {
00350 xmmsv_coll_t *coll = value;
00351 xmmsv_coll_attribute_remove (coll, XMMS_COLLSERIAL_ATTR_ID);
00352 }
00353
00354
00355
00356 static gint
00357 value_get_dict_int (xmmsv_t *val, const gchar *key)
00358 {
00359 gint i;
00360 xmmsv_dict_entry_get_int (val, key, &i);
00361 return i;
00362 }
00363
00364
00365 static const gchar *
00366 value_get_dict_string (xmmsv_t *val, const gchar *key)
00367 {
00368 const gchar *s;
00369 xmmsv_dict_entry_get_string (val, key, &s);
00370 return s;
00371 }