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 xmmsc_coll_t *xmms_collection_dbread_operator (xmms_medialib_session_t *session, gint id, xmmsc_coll_type_t type);
00037 static guint xmms_collection_dbwrite_operator (xmms_medialib_session_t *session, guint collid, xmmsc_coll_t *coll);
00038
00039 static void dbwrite_operator (void *key, void *value, void *udata);
00040 static void dbwrite_coll_attributes (const char *key, const char *value, void *udata);
00041 static void dbwrite_strip_tmpprops (void *key, void *value, void *udata);
00042
00043 static gint cmdval_get_hash_int (xmms_object_cmd_value_t *cmdval, const gchar *key);
00044 static const gchar *cmdval_get_hash_string (xmms_object_cmd_value_t *cmdval, 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 xmmsc_coll_t *coll = NULL;
00088 xmms_medialib_session_t *session;
00089 xmms_object_cmd_value_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 = (xmms_object_cmd_value_t*)res->data;
00111 id = cmdval_get_hash_int (cmdval, "id");
00112 type = cmdval_get_hash_int (cmdval, "type");
00113 nsid = cmdval_get_hash_int (cmdval, "nsid");
00114 label = cmdval_get_hash_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 xmmsc_coll_ref (coll);
00123 }
00124
00125 xmms_collection_dag_replace (dag, nsid, g_strdup (label), coll);
00126
00127 xmms_object_cmd_value_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 xmmsc_coll_t *
00148 xmms_collection_dbread_operator (xmms_medialib_session_t *session,
00149 gint id, xmmsc_coll_type_t type)
00150 {
00151 xmmsc_coll_t *coll;
00152 xmmsc_coll_t *op;
00153 GList *res;
00154 GList *n;
00155 xmms_object_cmd_value_t *cmdval;
00156 gchar query[256];
00157
00158 coll = xmmsc_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 = (xmms_object_cmd_value_t*)n->data;
00171 key = cmdval_get_hash_string (cmdval, "key");
00172 value = cmdval_get_hash_string (cmdval, "value");
00173 xmmsc_coll_attribute_set (coll, key, value);
00174
00175 xmms_object_cmd_value_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 = (xmms_object_cmd_value_t*)n->data;
00190 xmmsc_coll_idlist_append (coll, cmdval_get_hash_int (cmdval, "mid"));
00191
00192 xmms_object_cmd_value_unref (n->data);
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 = (xmms_object_cmd_value_t*)n->data;
00208 id = cmdval_get_hash_int (cmdval, "id");
00209 type = cmdval_get_hash_int (cmdval, "type");
00210
00211 op = xmms_collection_dbread_operator (session, id, type);
00212 xmmsc_coll_add_operand (coll, op);
00213
00214 xmmsc_coll_unref (op);
00215 xmms_object_cmd_value_unref (n->data);
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, xmmsc_coll_t *coll)
00232 {
00233 gchar query[128];
00234 guint *idlist;
00235 gint i;
00236 xmmsc_coll_t *op;
00237 gint newid, nextid;
00238 coll_dbwrite_t dbwrite_infos = { session, collid, 0 };
00239
00240
00241 g_snprintf (query, sizeof (query),
00242 "INSERT INTO CollectionOperators VALUES(%d, %d)",
00243 collid, xmmsc_coll_get_type (coll));
00244
00245 xmms_medialib_select (session, query, NULL);
00246
00247
00248 xmmsc_coll_attribute_foreach (coll, dbwrite_coll_attributes, &dbwrite_infos);
00249
00250
00251 idlist = xmmsc_coll_get_idlist (coll);
00252 for (i = 0; idlist[i] != 0; i++) {
00253 g_snprintf (query, sizeof (query),
00254 "INSERT INTO CollectionIdlists VALUES(%d, %d, %d)",
00255 collid, i, idlist[i]);
00256
00257 xmms_medialib_select (session, query, NULL);
00258 }
00259
00260
00261 newid = collid + 1;
00262 if (xmmsc_coll_get_type (coll) != XMMS_COLLECTION_TYPE_REFERENCE) {
00263 xmmsc_coll_operand_list_save (coll);
00264 xmmsc_coll_operand_list_first (coll);
00265 while (xmmsc_coll_operand_list_entry (coll, &op)) {
00266 nextid = xmms_collection_dbwrite_operator (session, newid, op);
00267 g_snprintf (query, sizeof (query),
00268 "INSERT INTO CollectionConnections VALUES(%d, %d)",
00269 newid, collid);
00270 xmms_medialib_select (session, query, NULL);
00271 newid = nextid;
00272 xmmsc_coll_operand_list_next (coll);
00273 }
00274 xmmsc_coll_operand_list_restore (coll);
00275 }
00276
00277
00278 return newid;
00279 }
00280
00281
00282
00283 static void
00284 dbwrite_operator (void *key, void *value, void *udata)
00285 {
00286 gchar *query;
00287 gchar *label = key;
00288 xmmsc_coll_t *coll = value;
00289 coll_dbwrite_t *dbinfos = udata;
00290 gchar *esc_label;
00291 gint serial_id;
00292
00293
00294 if (!xmms_collection_get_int_attr (coll, XMMS_COLLSERIAL_ATTR_ID, &serial_id)) {
00295 serial_id = dbinfos->collid;
00296 dbinfos->collid = xmms_collection_dbwrite_operator (dbinfos->session,
00297 dbinfos->collid, coll);
00298 xmms_collection_set_int_attr (coll, XMMS_COLLSERIAL_ATTR_ID, serial_id);
00299 }
00300
00301 esc_label = sqlite_prepare_string (label);
00302 query = g_strdup_printf ("INSERT INTO CollectionLabels VALUES(%d, %d, %s)",
00303 serial_id, dbinfos->nsid, esc_label);
00304 xmms_medialib_select (dbinfos->session, query, NULL);
00305
00306 g_free (query);
00307 g_free (esc_label);
00308 }
00309
00310
00311 static void
00312 dbwrite_coll_attributes (const char *key, const char *value, void *udata)
00313 {
00314 gchar *query;
00315 coll_dbwrite_t *dbwrite_infos = udata;
00316 gchar *esc_key;
00317 gchar *esc_val;
00318
00319 esc_key = sqlite_prepare_string (key);
00320 esc_val = sqlite_prepare_string (value);
00321 query = g_strdup_printf ("INSERT INTO CollectionAttributes VALUES(%d, %s, %s)",
00322 dbwrite_infos->collid, esc_key, esc_val);
00323 xmms_medialib_select (dbwrite_infos->session, query, NULL);
00324
00325 g_free (query);
00326 g_free (esc_key);
00327 g_free (esc_val);
00328 }
00329
00330
00331 static void
00332 dbwrite_strip_tmpprops (void *key, void *value, void *udata)
00333 {
00334 xmmsc_coll_t *coll = value;
00335 xmmsc_coll_attribute_remove (coll, XMMS_COLLSERIAL_ATTR_ID);
00336 }
00337
00338
00339
00340 static gint
00341 cmdval_get_hash_int (xmms_object_cmd_value_t *cmdval, const gchar *key)
00342 {
00343 xmms_object_cmd_value_t *buf;
00344 buf = g_hash_table_lookup (cmdval->value.hash, key);
00345 return buf->value.int32;
00346 }
00347
00348
00349 static const gchar *
00350 cmdval_get_hash_string (xmms_object_cmd_value_t *cmdval, const gchar *key)
00351 {
00352 xmms_object_cmd_value_t *buf;
00353 buf = g_hash_table_lookup (cmdval->value.hash, key);
00354 return buf->value.string;
00355 }