summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGuilherme Lepsch <lepsch@expertisesolutions.com.br>2014-12-01 18:37:05 -0200
committerLarry Jr <larry.olj@gmail.com>2014-12-02 16:02:49 -0200
commit7d97fcbb15c5500fde8751be1a79a29b18bede13 (patch)
treeaafde97238d334a01fc0efc1284a306185c2043e
parent5f301e8149020230e6e4b72f4da94bc884d2f14b (diff)
* WIP: Database schema to create/validate/migrate versions.
-rw-r--r--src/Makefile.in3
-rw-r--r--src/audiolistmodel.cc41
-rw-r--r--src/audiolistmodel.hh2
-rw-r--r--src/database_schema.cc35
-rw-r--r--src/database_schema.hh76
5 files changed, 146 insertions, 11 deletions
diff --git a/src/Makefile.in b/src/Makefile.in
index 9e477d5..e224d97 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -10,7 +10,8 @@ SOURCES= \
10 mainctrl.cc \ 10 mainctrl.cc \
11 settingsmodel.cc \ 11 settingsmodel.cc \
12 emc.cc \ 12 emc.cc \
13 file_scanner.cc 13 file_scanner.cc \
14 database_schema.cc
14OBJECTS=$(SOURCES:.cc=.o) 15OBJECTS=$(SOURCES:.cc=.o)
15 16
16emc_LIBADD = @EMC_LIBS@ 17emc_LIBADD = @EMC_LIBS@
diff --git a/src/audiolistmodel.cc b/src/audiolistmodel.cc
index 4521e9a..885c948 100644
--- a/src/audiolistmodel.cc
+++ b/src/audiolistmodel.cc
@@ -7,11 +7,7 @@
7 7
8#include <eina_accessor.hh> 8#include <eina_accessor.hh>
9 9
10namespace { 10#include "database_schema.hh"
11 const std::string ARTISTS_TABLE_NAME = "artists";
12 const std::string ALBUMS_TABLE_NAME = "albums";
13 const std::string TRACKS_TABLE_NAME = "tracks";
14}
15 11
16namespace emc { 12namespace emc {
17 13
@@ -20,8 +16,10 @@ audiolistmodel::audiolistmodel()
20 artists(nullptr), 16 artists(nullptr),
21 albums(nullptr), 17 albums(nullptr),
22 tracks(nullptr), 18 tracks(nullptr),
23 init_connection(nullptr) 19 init_connection(nullptr),
20 db_table_created_connection(nullptr)
24{ 21{
22 // TODO: Configure database path to user data
25 database = esql::model("./emc.db", "", "", ""); 23 database = esql::model("./emc.db", "", "", "");
26 24
27 init_connection = database.callback_children_count_changed_add( 25 init_connection = database.callback_children_count_changed_add(
@@ -40,17 +38,40 @@ audiolistmodel::init(void * info)
40{ 38{
41 init_connection.disconnect(); 39 init_connection.disconnect();
42 40
41 // TODO: Create a service to take care of database schema creation/validation/migration
42
43 unsigned int table_count = *static_cast<unsigned int *>(info); 43 unsigned int table_count = *static_cast<unsigned int *>(info);
44 std::cout << "audioDB children count change " << table_count << std::endl; 44 std::cout << "audioDB children count change " << table_count << std::endl;
45 if (0 == table_count) 45 if (0 == table_count)
46 { 46 {
47 // TODO: This is a new database, create it 47 std::cout << "Creating database..." << std::endl;
48 db_table_created_connection = database.callback_children_count_changed_add(
49 std::bind(&audiolistmodel::db_table_created, this, std::placeholders::_3));
50 // TODO: connect the load_status_error callback
51 schema::create_database(database);
48 return false; 52 return false;
49 } 53 }
50 54
51 55
52 // TODO: Validate schema version 56 // TODO: Validate schema version
57 // if (schema::tables.size() != table_count ...)
58
59 // TODO: Migrate old schema version or error on newer than current
60 // if (version_table.value != current_version)
61
62 load_tables();
63 return false;
64}
65
66bool
67audiolistmodel::db_table_created(void * info)
68{
69 unsigned int table_count = *static_cast<unsigned int *>(info);
70 std::cout << "Database table created. Number of tables: " << table_count << std::endl;
71 if (schema::tables.size() != table_count)
72 return false;
53 73
74 db_table_created_connection.disconnect();
54 75
55 load_tables(); 76 load_tables();
56 return false; 77 return false;
@@ -72,11 +93,11 @@ audiolistmodel::load_tables()
72 93
73 std::string tablename = table.name_get(); 94 std::string tablename = table.name_get();
74 95
75 if (ARTISTS_TABLE_NAME == tablename) 96 if (schema::artists_table.name == tablename)
76 artists = table; 97 artists = table;
77 else if (ALBUMS_TABLE_NAME == tablename) 98 else if (schema::albums_table.name == tablename)
78 albums = table; 99 albums = table;
79 else if (TRACKS_TABLE_NAME == tablename) 100 else if (schema::tracks_table.name == tablename)
80 tracks = table; 101 tracks = table;
81 } 102 }
82 103
diff --git a/src/audiolistmodel.hh b/src/audiolistmodel.hh
index 7c60afe..1fcba24 100644
--- a/src/audiolistmodel.hh
+++ b/src/audiolistmodel.hh
@@ -28,8 +28,10 @@ class audiolistmodel
28 28
29 file_scanner scanner; 29 file_scanner scanner;
30 ::efl::eo::signal_connection init_connection; 30 ::efl::eo::signal_connection init_connection;
31 ::efl::eo::signal_connection db_table_created_connection;
31 32
32 bool init(void * info); 33 bool init(void * info);
34 bool db_table_created(void * info);
33 bool load_tables(); 35 bool load_tables();
34 36
35 public: 37 public:
diff --git a/src/database_schema.cc b/src/database_schema.cc
new file mode 100644
index 0000000..e951fa5
--- /dev/null
+++ b/src/database_schema.cc
@@ -0,0 +1,35 @@
1#include "database_schema.hh"
2
3#include <ostream>
4
5extern "C"
6{
7#include <Esskyuehl.h>
8#include <Esql_Model.h>
9}
10#include <Esql_Model.hh>
11
12namespace emc { namespace schema {
13
14void create_table(const schema::table &table_definition, esql::model &database)
15{
16 std::cout << "Creating table: " << table_definition.name << std::endl;
17 efl::eo::base obj = database.child_add();
18 esql::model_table table(::eo_ref(obj._eo_ptr()));
19 table.name_set(table_definition.name);
20
21 for (auto &field : table_definition.fields)
22 {
23 std::cout << "Creating field: " << table_definition.name << "." << field.name << std::endl;
24 ::efl::eina::value field_type(field.type + " " + field.constraint);
25 table.property_set(field.name, *field_type.native_handle());
26 }
27}
28
29void create_database(esql::model &database)
30{
31 for (auto &table : schema::tables)
32 create_table(*table, database);
33}
34
35}}
diff --git a/src/database_schema.hh b/src/database_schema.hh
new file mode 100644
index 0000000..5f4390b
--- /dev/null
+++ b/src/database_schema.hh
@@ -0,0 +1,76 @@
1#ifndef _DB_SCHEMA_HH
2#define _DB_SCHEMA_HH
3
4#include <string>
5#include <vector>
6
7namespace esql { struct model; }
8
9namespace emc { namespace schema {
10
11struct field
12{
13 std::string name;
14 std::string type;
15 std::string constraint;
16};
17
18struct table
19{
20 std::string name;
21 std::vector<field> fields;
22};
23
24// SQLite types
25const std::string INTEGER = "INTEGER";
26const std::string TEXT = "TEXT";
27
28// SQLite constraints
29const std::string PRIMARY_KEY = "PRIMARY KEY";
30const std::string NOT_NULL = ""; //"NOT NULL"; TODO: SQLite doesn't support adding NOT NULL columns
31const std::string DEFAULT_NULL = "DEFAULT NULL";
32const std::string DEFAULT_0 = "DEFAULT 0";
33
34inline namespace v1 {
35
36const table tracks_table = {
37 "tracks",
38 {
39 {"id", INTEGER, PRIMARY_KEY},
40 {"id_artist", INTEGER},
41 {"id_album", INTEGER},
42 {"name", TEXT, NOT_NULL},
43 {"track", INTEGER},
44 {"file", TEXT, NOT_NULL}
45 }
46};
47
48const table artists_table = {
49 "artists",
50 {
51 {"id", INTEGER, PRIMARY_KEY},
52 {"name", TEXT, NOT_NULL}
53 }
54};
55
56const table albums_table = {
57 "albums",
58 {
59 {"id", INTEGER, PRIMARY_KEY},
60 {"id_artist", INTEGER},
61 {"name", TEXT, NOT_NULL},
62 {"genre", TEXT, DEFAULT_NULL},
63 {"year", INTEGER, DEFAULT_0}
64 }
65};
66
67const std::vector<const table*> tables = {&tracks_table, &artists_table, &albums_table};
68
69} // v1
70
71
72void create_database(esql::model &database);
73
74}}
75
76#endif