callbacks: Add initial callbacks

This patch adds library callbacks for adding a new path and for updating
tracks in a path.

Signed-off-by: Anna Schumaker <schumaker.anna@gmail.com>
This commit is contained in:
Anna Schumaker 2014-01-15 20:40:24 -05:00 committed by Anna Schumaker
parent 11704b2bfa
commit c2e7772ebe
11 changed files with 386 additions and 17 deletions

1
config
View File

@ -37,6 +37,7 @@ class Config:
def reset(self, TEST = False, ALL = False):
self.AUDIO = ALL
self.CALLBACK = ALL
self.DATABASE = ALL
self.DECK = ALL
self.FILE = ALL

View File

@ -33,6 +33,7 @@ Files:
ocarina6.glade
ocarina/include/
audio.h
callback.h
database.h
database.hpp
deck.h
@ -48,6 +49,7 @@ Files:
version.h
ocarina/lib/
audio.cpp
callback.cpp
database.cpp
deck.cpp
file.cpp
@ -104,6 +106,26 @@ API:
Callbacks: (lib/callback.cpp)
Callbacks are used to notify a unit test or the gui that something in
the backend has changed. The callbacks structure should be initialized
with no-op default values and filled in by the user through the
get_callbacks() function.
- Callback functions:
struct Callbacks {
void (*on_library_add)(unsigned int, library :: Library *);
void (*on_library_update)(unsigned int, library :: Library *);
};
static struct Callbacks callbacks;
- API:
struct Callbacks *get_callbacks();
Return the Callbacks structure;
On-disk files: (lib/file.cpp)
Data will be stored in the user's home directory according to the
XDG / freedesktop.org specification. This means storing data in
@ -690,6 +712,8 @@ Library: (lib/library.cpp)
If dir is not a directory:
throw -EINVAL
Trigger the on_library_add() callback on success.
void library :: del_path(unsigned int lib_id);
Invalidate a library_db row and all tracks owned by that path
if lib_id is not valid, throw -EEXIST.
@ -698,8 +722,11 @@ Library: (lib/library.cpp)
Update the given library_db row.
If lib_id is not valid, throw -EEXIST.
Trigger the on_library_update() callback.
void library :: update_all();
Update all library paths.
Trigger the on_library_update() callback for each path.
struct Song library :: lookup(track_id);
Fill out a Song structure for the provided track_id.
@ -1085,6 +1112,8 @@ Future work:
to update the library information and the on-disk file.
- Album art: (6.1)
(easy) Start with album art fetching script
(hard) Build in to Ocarina
- Playlist custom sorting: (6.1)
Click column headers to choos sort order
@ -1098,6 +1127,7 @@ Future work:
keep it in each individual section instead.
XML?
Code formatting?
Checkbox for when features are done? (reference commit)
- Copy a song group to a different directory: (6.x)
This can be useful for keeping an external device (like an
@ -1118,3 +1148,21 @@ Future work:
- Some way to enable / disable tests during development
- Run tests based on dependencies
- Fix tests that will only work on my computer
- Double check that all inputs and outputs are tested
- Simple testing library?
- Preferences:
- Set default sort
- Save window size
- Set album art size
- Rip out Ocarina 5.x importing and legacy file support
- AirPlay / remote audio support
- Media keys
- Replaygain support
External script to calculate values?
Calculate value after first playback?
Store in library :: Track structure

26
design/callback.txt Normal file
View File

@ -0,0 +1,26 @@
== Files ==
ocarina/include/
callback.h
ocarina/lib/
callback.cpp
== Depends ==
version print
Callbacks: (lib/callback.cpp)
Callbacks are used to notify a unit test or the gui that something in
the backend has changed. The callbacks structure should be initialized
with no-op default values and filled in by the user through the
get_callbacks() function.
- Callback functions:
struct Callbacks {
void (*on_library_add)(unsigned int, library :: Library *);
void (*on_library_update)(unsigned int, library :: Library *);
};
static struct Callbacks callbacks;
- API:
struct Callbacks *get_callbacks();
Return the Callbacks structure;

View File

@ -46,6 +46,8 @@ Future work:
to update the library information and the on-disk file.
- Album art: (6.1)
(easy) Start with album art fetching script
(hard) Build in to Ocarina
- Playlist custom sorting: (6.1)
Click column headers to choos sort order
@ -59,6 +61,7 @@ Future work:
keep it in each individual section instead.
XML?
Code formatting?
Checkbox for when features are done? (reference commit)
- Copy a song group to a different directory: (6.x)
This can be useful for keeping an external device (like an
@ -79,3 +82,21 @@ Future work:
- Some way to enable / disable tests during development
- Run tests based on dependencies
- Fix tests that will only work on my computer
- Double check that all inputs and outputs are tested
- Simple testing library?
- Preferences:
- Set default sort
- Save window size
- Set album art size
- Rip out Ocarina 5.x importing and legacy file support
- AirPlay / remote audio support
- Media keys
- Replaygain support
External script to calculate values?
Calculate value after first playback?
Store in library :: Track structure

View File

@ -163,6 +163,8 @@ Library: (lib/library.cpp)
If dir is not a directory:
throw -EINVAL
Trigger the on_library_add() callback on success.
void library :: del_path(unsigned int lib_id);
Invalidate a library_db row and all tracks owned by that path
if lib_id is not valid, throw -EEXIST.
@ -171,8 +173,11 @@ Library: (lib/library.cpp)
Update the given library_db row.
If lib_id is not valid, throw -EEXIST.
Trigger the on_library_update() callback.
void library :: update_all();
Update all library paths.
Trigger the on_library_update() callback for each path.
struct Song library :: lookup(track_id);
Fill out a Song structure for the provided track_id.

19
include/callback.h Normal file
View File

@ -0,0 +1,19 @@
/*
* Copyright 2014 (c) Anna Schumaker.
*/
#ifndef OCARINA_CALLBACK_H
#define OCARINA_CALLBACK_H
#include <library.h>
struct Callbacks {
void (*on_library_add)(unsigned int, library :: Library *);
void (*on_library_update)(unsigned int, library :: Library *);
};
struct Callbacks *get_callbacks();
#endif /* OCARINA_CALLBACK_H */

View File

@ -16,12 +16,13 @@ modules = {
###########################
"AUDIO" : Module("audio.cpp", package = "gstreamer-1.0", depends = [ "DECK" ]),
"CALLBACK" : Module("callback.cpp"),
"DATABASE" : Module("database.cpp", depends = [ "FILE" ]),
"DECK" : Module("deck.cpp", depends = [ "PLAYQUEUE" ]),
"FILE" : Module("file.cpp", package = "glib-2.0"),
"FILTER" : Module("filter.cpp", depends = [ "DATABASE" ]),
"IDLE" : Module("idle.cpp"),
"LIBRARY" : Module("library.cpp", package = "taglib", depends = [ "DATABASE", "FILTER", "IDLE" ]),
"LIBRARY" : Module("library.cpp", package = "taglib", depends = [ "CALLBACK", "DATABASE", "FILTER", "IDLE" ]),
"PLAYLIST" : Module("playlist.cpp", depends = [ "DATABASE" ]),
"PLAYQUEUE" : Module("playqueue.cpp", depends = [ "LIBRARY" ]),

19
lib/callback.cpp Normal file
View File

@ -0,0 +1,19 @@
/*
* Copyright 2014 (c) Anna Schumaker.
*/
#include <callback.h>
static void no_op(unsigned int id, library :: Library *path) {}
static struct Callbacks callbacks = {
.on_library_add = no_op,
.on_library_update = no_op,
};
struct Callbacks *get_callbacks()
{
return &callbacks;
}

View File

@ -1,6 +1,7 @@
/*
* Copyright 2013 (c) Anna Schumaker.
*/
#include <callback.h>
#include <filter.h>
#include <idle.h>
#include <library.h>
@ -28,7 +29,6 @@ struct ImportData {
};
/*
* library :: Artist: Artist tag information
*/
@ -298,10 +298,11 @@ static void read_tags(unsigned int lib_id, const std :: string &path)
library_db[lib_id].size++;
}
static void process_path(unsigned int lib_id, const std :: string &dir,
static bool process_path(unsigned int lib_id, const std :: string &dir,
const std :: string &name)
{
struct scan_info scan;
bool changed = false;
std :: string path = dir + "/" + name;
if (g_file_test(path.c_str(), G_FILE_TEST_IS_DIR) == true) {
@ -309,9 +310,13 @@ static void process_path(unsigned int lib_id, const std :: string &dir,
scan.path = path;
idle :: schedule (do_scan_path, scan);
} else {
if (track_db.has_key(path) == false)
if (track_db.has_key(path) == false) {
read_tags(lib_id, path);
changed = true;
}
}
return changed;
}
static void save_all_dbs()
@ -326,6 +331,7 @@ static void do_scan_path(struct scan_info &scan)
{
GDir *dir;
const char *name;
bool changed = false;
dir = g_dir_open(scan.path.c_str(), 0, NULL);
if (dir == NULL)
@ -333,15 +339,22 @@ static void do_scan_path(struct scan_info &scan)
name = g_dir_read_name(dir);
while (name != NULL) {
process_path(scan.lib_id, scan.path, name);
save_all_dbs();
if (process_path(scan.lib_id, scan.path, name))
changed = true;
name = g_dir_read_name(dir);
}
if (changed == true) {
save_all_dbs();
get_callbacks()->on_library_update(scan.lib_id,
&library_db[scan.lib_id]);
}
}
static void do_validate_library(unsigned int &lib_id)
{
std :: string path;
bool changed = false;
if (track_db.size() == 0)
return;
@ -355,8 +368,12 @@ static void do_validate_library(unsigned int &lib_id)
dprint("Removing file: %s\n", path.c_str());
track_db.remove(i);
library_db[lib_id].size--;
changed = true;
}
}
if (changed == true)
get_callbacks()->on_library_update(lib_id, &library_db[lib_id]);
}
static void do_update_library(unsigned int lib_id)
@ -417,12 +434,14 @@ static void do_import_library(std::string &s)
}
print("Adding path: %s\n", path.c_str());
id = library_db.insert(library :: Library(path, enabled));
get_callbacks()->on_library_add(id, &library_db[id]);
library_db.save();
f.getline(); /* Get rest of line */
for (unsigned int i = 0; i < size; i++)
do_import_track(f, id);
save_all_dbs();
get_callbacks()->on_library_update(id, &library_db[id]);
library :: update_path(id);
}
@ -435,7 +454,10 @@ static void do_import_library(std::string &s)
void library :: init()
{
unsigned int i;
library_db.load();
for (i = library_db.first(); i < library_db.num_rows(); i = library_db.next(i))
get_callbacks()->on_library_add(i, &library_db[i]);
}
void library :: add_path(const std::string &dir)
@ -446,6 +468,8 @@ void library :: add_path(const std::string &dir)
id = library_db.insert(library :: Library(dir, true));
library_db.save();
get_callbacks()->on_library_add(id, &library_db[id]);
update_path(id);
}

View File

@ -1,6 +1,7 @@
/*
* Copyright 2013 (c) Anna Schumaker.
*/
#include <callback.h>
#include <idle.h>
#include <library.h>
#include <print.h>
@ -28,6 +29,17 @@ bool check_add_dir(const std::string &dir)
}
}
void library_added(unsigned int id, library :: Library *path)
{
print("Added library %u: %s\n", id, path->root_path.c_str());
}
void library_updated(unsigned int id, library :: Library *path)
{
print("Updated library %u: %s (size: %u)\n",
id, path->root_path.c_str(), path->size);
}
void test_add_dir(const std::string &test, const std::string &dir, bool expected)
{
print("Test %s: ", test.c_str());
@ -252,10 +264,16 @@ void test_7()
library :: print_db(library :: DB_LIBRARY);
}
int main(int argc, char **argv)
{
struct Callbacks *cb;
gen_library();
cb = get_callbacks();
cb->on_library_add = library_added;
cb->on_library_update = library_updated;
test_0();
test_1();
test_2();

View File

@ -11,7 +11,23 @@ Test 0b: PASSED
Allocated rows: 0
Valid rows: 0
Test 1a: PASSED
Test 1a: Added library 0: /tmp/library/0
PASSED
Updated library 0: /tmp/library/0 (size: 10)
Updated library 0: /tmp/library/0 (size: 20)
Updated library 0: /tmp/library/0 (size: 30)
Updated library 0: /tmp/library/0 (size: 40)
Updated library 0: /tmp/library/0 (size: 50)
Updated library 0: /tmp/library/0 (size: 60)
Updated library 0: /tmp/library/0 (size: 70)
Updated library 0: /tmp/library/0 (size: 80)
Updated library 0: /tmp/library/0 (size: 90)
Updated library 0: /tmp/library/0 (size: 100)
Updated library 0: /tmp/library/0 (size: 110)
Updated library 0: /tmp/library/0 (size: 120)
Updated library 0: /tmp/library/0 (size: 130)
Updated library 0: /tmp/library/0 (size: 140)
Updated library 0: /tmp/library/0 (size: 150)
Allocated rows: 1
Valid rows: 1
db[0] = /tmp/library/0 (enabled), size = 150
@ -19,16 +35,64 @@ Test 1b
Allocated rows: 1
Valid rows: 0
Test 2a: PASSED
Test 2a: Added library 0: /tmp/library/0
PASSED
Updated library 0: /tmp/library/0 (size: 10)
Updated library 0: /tmp/library/0 (size: 20)
Updated library 0: /tmp/library/0 (size: 30)
Updated library 0: /tmp/library/0 (size: 40)
Updated library 0: /tmp/library/0 (size: 50)
Updated library 0: /tmp/library/0 (size: 60)
Updated library 0: /tmp/library/0 (size: 70)
Updated library 0: /tmp/library/0 (size: 80)
Updated library 0: /tmp/library/0 (size: 90)
Updated library 0: /tmp/library/0 (size: 100)
Updated library 0: /tmp/library/0 (size: 110)
Updated library 0: /tmp/library/0 (size: 120)
Updated library 0: /tmp/library/0 (size: 130)
Updated library 0: /tmp/library/0 (size: 140)
Updated library 0: /tmp/library/0 (size: 150)
Allocated rows: 1
Valid rows: 1
db[0] = /tmp/library/0 (enabled), size = 150
Test 2b: PASSED
Test 2b: Added library 1: /tmp/library/1
PASSED
Updated library 1: /tmp/library/1 (size: 10)
Updated library 1: /tmp/library/1 (size: 20)
Updated library 1: /tmp/library/1 (size: 30)
Updated library 1: /tmp/library/1 (size: 40)
Updated library 1: /tmp/library/1 (size: 50)
Updated library 1: /tmp/library/1 (size: 60)
Updated library 1: /tmp/library/1 (size: 70)
Updated library 1: /tmp/library/1 (size: 80)
Updated library 1: /tmp/library/1 (size: 90)
Updated library 1: /tmp/library/1 (size: 100)
Updated library 1: /tmp/library/1 (size: 110)
Updated library 1: /tmp/library/1 (size: 120)
Updated library 1: /tmp/library/1 (size: 130)
Updated library 1: /tmp/library/1 (size: 140)
Updated library 1: /tmp/library/1 (size: 150)
Allocated rows: 2
Valid rows: 2
db[0] = /tmp/library/0 (enabled), size = 150
db[1] = /tmp/library/1 (enabled), size = 150
Test 2c: PASSED
Test 2c: Added library 2: /tmp/library/2
PASSED
Updated library 2: /tmp/library/2 (size: 10)
Updated library 2: /tmp/library/2 (size: 20)
Updated library 2: /tmp/library/2 (size: 30)
Updated library 2: /tmp/library/2 (size: 40)
Updated library 2: /tmp/library/2 (size: 50)
Updated library 2: /tmp/library/2 (size: 60)
Updated library 2: /tmp/library/2 (size: 70)
Updated library 2: /tmp/library/2 (size: 80)
Updated library 2: /tmp/library/2 (size: 90)
Updated library 2: /tmp/library/2 (size: 100)
Updated library 2: /tmp/library/2 (size: 110)
Updated library 2: /tmp/library/2 (size: 120)
Updated library 2: /tmp/library/2 (size: 130)
Updated library 2: /tmp/library/2 (size: 140)
Updated library 2: /tmp/library/2 (size: 150)
Allocated rows: 3
Valid rows: 3
db[0] = /tmp/library/0 (enabled), size = 150
@ -47,16 +111,64 @@ Test 2f
Allocated rows: 3
Valid rows: 0
Test 3a: PASSED
Test 3a: Added library 0: /tmp/library/0
PASSED
Updated library 0: /tmp/library/0 (size: 10)
Updated library 0: /tmp/library/0 (size: 20)
Updated library 0: /tmp/library/0 (size: 30)
Updated library 0: /tmp/library/0 (size: 40)
Updated library 0: /tmp/library/0 (size: 50)
Updated library 0: /tmp/library/0 (size: 60)
Updated library 0: /tmp/library/0 (size: 70)
Updated library 0: /tmp/library/0 (size: 80)
Updated library 0: /tmp/library/0 (size: 90)
Updated library 0: /tmp/library/0 (size: 100)
Updated library 0: /tmp/library/0 (size: 110)
Updated library 0: /tmp/library/0 (size: 120)
Updated library 0: /tmp/library/0 (size: 130)
Updated library 0: /tmp/library/0 (size: 140)
Updated library 0: /tmp/library/0 (size: 150)
Allocated rows: 1
Valid rows: 1
db[0] = /tmp/library/0 (enabled), size = 150
Test 3b: PASSED
Test 3b: Added library 1: /tmp/library/1
PASSED
Updated library 1: /tmp/library/1 (size: 10)
Updated library 1: /tmp/library/1 (size: 20)
Updated library 1: /tmp/library/1 (size: 30)
Updated library 1: /tmp/library/1 (size: 40)
Updated library 1: /tmp/library/1 (size: 50)
Updated library 1: /tmp/library/1 (size: 60)
Updated library 1: /tmp/library/1 (size: 70)
Updated library 1: /tmp/library/1 (size: 80)
Updated library 1: /tmp/library/1 (size: 90)
Updated library 1: /tmp/library/1 (size: 100)
Updated library 1: /tmp/library/1 (size: 110)
Updated library 1: /tmp/library/1 (size: 120)
Updated library 1: /tmp/library/1 (size: 130)
Updated library 1: /tmp/library/1 (size: 140)
Updated library 1: /tmp/library/1 (size: 150)
Allocated rows: 2
Valid rows: 2
db[0] = /tmp/library/0 (enabled), size = 150
db[1] = /tmp/library/1 (enabled), size = 150
Test 3c: PASSED
Test 3c: Added library 2: /tmp/library/2
PASSED
Updated library 2: /tmp/library/2 (size: 10)
Updated library 2: /tmp/library/2 (size: 20)
Updated library 2: /tmp/library/2 (size: 30)
Updated library 2: /tmp/library/2 (size: 40)
Updated library 2: /tmp/library/2 (size: 50)
Updated library 2: /tmp/library/2 (size: 60)
Updated library 2: /tmp/library/2 (size: 70)
Updated library 2: /tmp/library/2 (size: 80)
Updated library 2: /tmp/library/2 (size: 90)
Updated library 2: /tmp/library/2 (size: 100)
Updated library 2: /tmp/library/2 (size: 110)
Updated library 2: /tmp/library/2 (size: 120)
Updated library 2: /tmp/library/2 (size: 130)
Updated library 2: /tmp/library/2 (size: 140)
Updated library 2: /tmp/library/2 (size: 150)
Allocated rows: 3
Valid rows: 3
db[0] = /tmp/library/0 (enabled), size = 150
@ -66,13 +178,32 @@ Test 3d
Allocated rows: 0
Valid rows: 0
Test 3e
Added library 0: /tmp/library/0
Added library 1: /tmp/library/1
Added library 2: /tmp/library/2
Allocated rows: 3
Valid rows: 3
db[0] = /tmp/library/0 (enabled), size = 0
db[1] = /tmp/library/1 (enabled), size = 0
db[2] = /tmp/library/2 (enabled), size = 0
Test 4a: PASSED
Test 4a: Added library 0: /tmp/library/0
PASSED
Updated library 0: /tmp/library/0 (size: 10)
Updated library 0: /tmp/library/0 (size: 20)
Updated library 0: /tmp/library/0 (size: 30)
Updated library 0: /tmp/library/0 (size: 40)
Updated library 0: /tmp/library/0 (size: 50)
Updated library 0: /tmp/library/0 (size: 60)
Updated library 0: /tmp/library/0 (size: 70)
Updated library 0: /tmp/library/0 (size: 80)
Updated library 0: /tmp/library/0 (size: 90)
Updated library 0: /tmp/library/0 (size: 100)
Updated library 0: /tmp/library/0 (size: 110)
Updated library 0: /tmp/library/0 (size: 120)
Updated library 0: /tmp/library/0 (size: 130)
Updated library 0: /tmp/library/0 (size: 140)
Updated library 0: /tmp/library/0 (size: 150)
Allocated rows: 1
Valid rows: 1
db[0] = /tmp/library/0 (enabled), size = 150
@ -712,7 +843,23 @@ db[149] = 1. Track 1 by Artist 0 from Album 0 (2011)
Artist 0/Album 0/1 - Track 1.ogg
Test 5a (track_id == 0): PASSED
Test 5b: PASSED
Test 5b: Added library 0: /tmp/library/0
PASSED
Updated library 0: /tmp/library/0 (size: 10)
Updated library 0: /tmp/library/0 (size: 20)
Updated library 0: /tmp/library/0 (size: 30)
Updated library 0: /tmp/library/0 (size: 40)
Updated library 0: /tmp/library/0 (size: 50)
Updated library 0: /tmp/library/0 (size: 60)
Updated library 0: /tmp/library/0 (size: 70)
Updated library 0: /tmp/library/0 (size: 80)
Updated library 0: /tmp/library/0 (size: 90)
Updated library 0: /tmp/library/0 (size: 100)
Updated library 0: /tmp/library/0 (size: 110)
Updated library 0: /tmp/library/0 (size: 120)
Updated library 0: /tmp/library/0 (size: 130)
Updated library 0: /tmp/library/0 (size: 140)
Updated library 0: /tmp/library/0 (size: 150)
Allocated rows: 1
Valid rows: 1
db[0] = /tmp/library/0 (enabled), size = 150
@ -727,7 +874,23 @@ Test 5f (lib_id == 0): PASSED
/tmp/library/0 (enabled) size = 150
Test 5g (lib_id == 1): PASSED
Test 6a: PASSED
Test 6a: Added library 0: /tmp/library/0
PASSED
Updated library 0: /tmp/library/0 (size: 10)
Updated library 0: /tmp/library/0 (size: 20)
Updated library 0: /tmp/library/0 (size: 30)
Updated library 0: /tmp/library/0 (size: 40)
Updated library 0: /tmp/library/0 (size: 50)
Updated library 0: /tmp/library/0 (size: 60)
Updated library 0: /tmp/library/0 (size: 70)
Updated library 0: /tmp/library/0 (size: 80)
Updated library 0: /tmp/library/0 (size: 90)
Updated library 0: /tmp/library/0 (size: 100)
Updated library 0: /tmp/library/0 (size: 110)
Updated library 0: /tmp/library/0 (size: 120)
Updated library 0: /tmp/library/0 (size: 130)
Updated library 0: /tmp/library/0 (size: 140)
Updated library 0: /tmp/library/0 (size: 150)
Allocated rows: 1
Valid rows: 1
db[0] = /tmp/library/0 (enabled), size = 150
@ -1367,6 +1530,7 @@ Removing file: /tmp/library/0/Artist 2/Album 0/4 - Track 4.ogg
Removing file: /tmp/library/0/Artist 2/Album 0/3 - Track 3.ogg
Removing file: /tmp/library/0/Artist 2/Album 0/2 - Track 2.ogg
Removing file: /tmp/library/0/Artist 2/Album 0/1 - Track 1.ogg
Updated library 0: /tmp/library/0 (size: 120)
Allocated rows: 1
Valid rows: 1
db[0] = /tmp/library/0 (enabled), size = 120
@ -1860,6 +2024,9 @@ Generating library: 2
Generating library: 3
Generating library: 4
Updated library 0: /tmp/library/0 (size: 130)
Updated library 0: /tmp/library/0 (size: 140)
Updated library 0: /tmp/library/0 (size: 150)
Allocated rows: 180
Valid rows: 150
db[30] = 10. Track 10 by Artist 4 from Album 2 (2013)
@ -2463,7 +2630,23 @@ db[179] = 1. Track 1 by Artist 2 from Album 0 (2011)
Play count: 0, last played 0/0/0
Artist 2/Album 0/1 - Track 1.ogg
Test 7a: PASSED
Test 7a: Added library 0: /tmp/library/2
PASSED
Updated library 0: /tmp/library/2 (size: 10)
Updated library 0: /tmp/library/2 (size: 20)
Updated library 0: /tmp/library/2 (size: 30)
Updated library 0: /tmp/library/2 (size: 40)
Updated library 0: /tmp/library/2 (size: 50)
Updated library 0: /tmp/library/2 (size: 60)
Updated library 0: /tmp/library/2 (size: 70)
Updated library 0: /tmp/library/2 (size: 80)
Updated library 0: /tmp/library/2 (size: 90)
Updated library 0: /tmp/library/2 (size: 100)
Updated library 0: /tmp/library/2 (size: 110)
Updated library 0: /tmp/library/2 (size: 120)
Updated library 0: /tmp/library/2 (size: 130)
Updated library 0: /tmp/library/2 (size: 140)
Updated library 0: /tmp/library/2 (size: 150)
Allocated rows: 1
Valid rows: 1
db[0] = /tmp/library/2 (enabled), size = 150
@ -2474,8 +2657,12 @@ Importing: /home/anna/.ocarina-test/library/1
Library already contains path: /tmp/library/2, skipping
Importing: /home/anna/.ocarina-test/library/2
Adding path: /tmp/library/3
Added library 1: /tmp/library/3
Updated library 1: /tmp/library/3 (size: 150)
Importing: /home/anna/.ocarina-test/library/3
Adding path: /tmp/library/4
Added library 2: /tmp/library/4
Updated library 2: /tmp/library/4 (size: 150)
Allocated rows: 3
Valid rows: 3
db[0] = /tmp/library/2 (enabled), size = 150