Added support for raw library queries using existing C++ constructs.

This commit is contained in:
casey langen 2020-02-01 21:15:28 -08:00
parent d945268515
commit 43c23c3f34
4 changed files with 222 additions and 1 deletions

View File

@ -163,6 +163,7 @@ mcsdk_export void mcsdk_context_init(mcsdk_context** context) {
c->metadata.opaque = internal->metadata;
c->preferences.opaque = internal->preferences.get();
c->playback.opaque = internal->playback;
c->library.opaque = internal->library.get();
auto indexer = internal->library->Indexer();
auto indexer_internal = new mcsdk_svc_indexer_context_internal();

View File

@ -59,14 +59,22 @@
#include <core/sdk/IStreamingEncoder.h>
#include <core/sdk/IDevice.h>
#include <core/sdk/IOutput.h>
#include <core/library/query/local/LocalQueryBase.h>
#include <core/library/ILibrary.h>
#include <core/library/IIndexer.h>
#include <core/library/track/TrackList.h>
#include <core/audio/Stream.h>
#include <core/audio/Player.h>
#include <core/db/ScopedTransaction.h>
#include <core/db/Connection.h>
#include <core/db/Statement.h>
#include <core/support/Common.h>
#include <string>
using namespace musik;
using namespace musik::core;
using namespace musik::core::db;
using namespace musik::core::sdk;
using namespace musik::core::audio;
@ -96,6 +104,10 @@ using namespace musik::core::audio;
#define AUDIOSTREAM(x) reinterpret_cast<IStream*>(x.opaque)
#define PLAYER(x) reinterpret_cast<mcsdk_player_context_internal*>(x.opaque)
#define INDEXER(x) reinterpret_cast<mcsdk_svc_indexer_context_internal*>(x.opaque)->indexer
#define LIBRARY(x) reinterpret_cast<ILibrary*>(x.opaque)
#define DBCONNECTION(x) reinterpret_cast<Connection*>(x.opaque)
#define DBSTATEMENT(x) reinterpret_cast<Statement*>(x.opaque)
#define DBTRANSACTION(x) reinterpret_cast<ScopedTransaction*>(x.opaque)
#define RELEASE(x, type) if (mcsdk_handle_ok(x)) { type(x)->Release(); x.opaque = nullptr; }
@ -1229,4 +1241,133 @@ mcsdk_export void mcsdk_svc_indexer_remove_callbacks(mcsdk_svc_indexer in, mcsdk
if (it != internal->callbacks.end()) {
internal->callbacks.erase(it);
}
}
}
/*
* ILibrary
*/
class mcsdk_db_wrapped_query: public LocalQueryBase {
public:
mcsdk_db_wrapped_query(
mcsdk_svc_library library,
const std::string& name,
mcsdk_svc_library_run_query_callback cb)
{
this->library = library;
this->name = name;
this->cb = cb;
}
protected:
virtual bool OnRun(musik::core::db::Connection& db) {
return cb(this->library, { &db });
}
virtual std::string Name() {
return "";
}
private:
mcsdk_svc_library library;
std::string name;
mcsdk_svc_library_run_query_callback cb;
};
mcsdk_export void mcsdk_svc_library_run_query(mcsdk_svc_library l, const char* name, mcsdk_svc_library_run_query_callback cb, mcsdk_svc_library_query_flag flags) {
LIBRARY(l)->Enqueue(std::make_shared<mcsdk_db_wrapped_query>(l, name, cb));
}
mcsdk_export int mcsdk_svc_library_get_id(mcsdk_svc_library l) {
return LIBRARY(l)->Id();
}
mcsdk_export int mcsdk_svc_library_get_name(mcsdk_svc_library l, char* dst, int len) {
return CopyString(LIBRARY(l)->Name(), dst, len);
}
/*
* Statement
*/
mcsdk_export mcsdk_db_statement mcsdk_db_statement_create(mcsdk_db_connection db, const char* sql) {
return { new Statement(sql, *DBCONNECTION(db)) };
}
mcsdk_export void mcsdk_db_statement_bind_int32(mcsdk_db_statement stmt, int position, int value) {
DBSTATEMENT(stmt)->BindInt32(position, value);
}
mcsdk_export void mcsdk_db_statement_bind_int64(mcsdk_db_statement stmt, int position, int64_t value) {
DBSTATEMENT(stmt)->BindInt64(position, value);
}
mcsdk_export void mcsdk_db_statement_bind_float(mcsdk_db_statement stmt, int position, float value) {
DBSTATEMENT(stmt)->BindFloat(position, value);
}
mcsdk_export void mcsdk_db_statement_bind_text(mcsdk_db_statement stmt, int position, const char* value) {
DBSTATEMENT(stmt)->BindText(position, value);
}
mcsdk_export void mcsdk_db_statement_bind_null(mcsdk_db_statement stmt, int position) {
DBSTATEMENT(stmt)->BindNull(position);
}
mcsdk_export int mcsdk_db_statement_column_int32(mcsdk_db_statement stmt, int column) {
return DBSTATEMENT(stmt)->ColumnInt32(column);
}
mcsdk_export int64_t mcsdk_db_statement_column_int64(mcsdk_db_statement stmt, int column) {
return DBSTATEMENT(stmt)->ColumnInt64(column);
}
mcsdk_export float mcsdk_db_statement_column_float(mcsdk_db_statement stmt, int column) {
return DBSTATEMENT(stmt)->ColumnFloat(column);
}
mcsdk_export int mcsdk_db_statement_column_text(mcsdk_db_statement stmt, int column, char* dst, int len) {
return CopyString(DBSTATEMENT(stmt)->ColumnText(column), dst, len);
}
mcsdk_export mcsdk_db_result mcsdk_db_statement_step(mcsdk_db_statement stmt) {
return (mcsdk_db_result) DBSTATEMENT(stmt)->Step();
}
mcsdk_export void mcsdk_db_statement_reset(mcsdk_db_statement stmt) {
DBSTATEMENT(stmt)->Reset();
}
mcsdk_export void mcsdk_db_statement_unbind(mcsdk_db_statement stmt) {
DBSTATEMENT(stmt)->Unbind();
}
mcsdk_export void mcsdk_db_statement_reset_and_unbind(mcsdk_db_statement stmt) {
DBSTATEMENT(stmt)->ResetAndUnbind();
}
mcsdk_export void mcsdk_db_statement_release(mcsdk_db_statement stmt) {
delete DBSTATEMENT(stmt);
stmt.opaque = nullptr;
}
/*
* ScopedTransaction
*/
mcsdk_export mcsdk_db_transaction mcsdk_db_transaction_create(mcsdk_db_connection db) {
return { new ScopedTransaction(*DBCONNECTION(db)) };
}
mcsdk_export void mcsdk_db_transaction_cancel(mcsdk_db_transaction tx) {
DBTRANSACTION(tx)->Cancel();
}
mcsdk_export void mcsdk_db_transaction_commit_and_restart(mcsdk_db_transaction tx) {
DBTRANSACTION(tx)->CommitAndRestart();
}
mcsdk_export void mcsdk_db_transaction_release(mcsdk_db_transaction tx) {
delete DBCONNECTION(tx);
tx.opaque = nullptr;
}

View File

@ -126,6 +126,11 @@ typedef enum mcsdk_svc_indexer_sync_type {
mcsdk_svc_indexer_sync_type_sources = 3
} mcsdk_svc_indexer_sync_type;
typedef enum mcsdk_svc_library_query_flag {
mcsdk_svc_library_query_flag_none = 0,
mcsdk_svc_library_query_flag_synchronous = 1
} mcsdk_svc_library_query_flag;
typedef enum mcsdk_replay_gain_mode {
mcsdk_replay_gain_mode_disabled = 0,
mcsdk_replay_gain_mode_track = 1,
@ -164,6 +169,12 @@ typedef enum mcsdk_audio_player_release_mode {
mcsdk_audio_player_release_mode_no_drain = 1
} mcsdk_audio_player_release_mode;
typedef enum mcsdk_db_result {
mcsdk_db_result_okay = 0,
mcsdk_db_result_row = 100,
mcsdk_db_result_done = 101,
} mcsdk_db_result;
static const size_t mcsdk_equalizer_band_count = 18;
static const size_t mcsdk_equalizer_bands[] = {
@ -229,6 +240,7 @@ mcsdk_define_handle(mcsdk_track_list_editor);
mcsdk_define_handle(mcsdk_svc_metadata);
mcsdk_define_handle(mcsdk_svc_playback);
mcsdk_define_handle(mcsdk_svc_indexer);
mcsdk_define_handle(mcsdk_svc_library);
mcsdk_define_handle(mcsdk_prefs);
mcsdk_define_handle(mcsdk_audio_buffer);
mcsdk_define_handle(mcsdk_audio_buffer_provider);
@ -242,6 +254,9 @@ mcsdk_define_handle(mcsdk_blocking_encoder);
mcsdk_define_handle(mcsdk_streaming_encoder);
mcsdk_define_handle(mcsdk_audio_stream);
mcsdk_define_handle(mcsdk_audio_player);
mcsdk_define_handle(mcsdk_db_connection);
mcsdk_define_handle(mcsdk_db_statement);
mcsdk_define_handle(mcsdk_db_transaction);
typedef struct mcsdk_audio_player_callbacks {
void (*on_prepared)(mcsdk_audio_player p);
@ -266,6 +281,8 @@ typedef struct mcsdk_audio_player_gain {
float peakValid;
} mcsdk_audio_player_gain;
typedef bool (*mcsdk_svc_library_run_query_callback)(mcsdk_svc_library l, mcsdk_db_connection db);
/*
* instance context
*/
@ -274,6 +291,7 @@ typedef struct mcsdk_context {
mcsdk_svc_metadata metadata;
mcsdk_svc_playback playback;
mcsdk_svc_indexer indexer;
mcsdk_svc_library library;
mcsdk_prefs preferences;
mcsdk_internal internal;
} mcsdk_context;
@ -632,4 +650,41 @@ mcsdk_export mcsdk_svc_indexer_state mcsdk_svc_indexer_get_state(mcsdk_svc_index
mcsdk_export void mcsdk_svc_indexer_add_callbacks(mcsdk_svc_indexer in, mcsdk_svc_indexer_callbacks* cb);
mcsdk_export void mcsdk_svc_indexer_remove_callbacks(mcsdk_svc_indexer in, mcsdk_svc_indexer_callbacks* cb);
/*
* ILibrary
*/
mcsdk_export void mcsdk_svc_library_run_query(mcsdk_svc_library l, const char* name, mcsdk_svc_library_run_query_callback cb, mcsdk_svc_library_query_flag flags);
mcsdk_export int mcsdk_svc_library_get_id(mcsdk_svc_library l);
mcsdk_export int mcsdk_svc_library_get_name(mcsdk_svc_library l, char* dst, int len);
/*
* Statement
*/
mcsdk_export mcsdk_db_statement mcsdk_db_statement_create(mcsdk_db_connection db, const char* sql);
mcsdk_export void mcsdk_db_statement_bind_int32(mcsdk_db_statement stmt, int position, int value);
mcsdk_export void mcsdk_db_statement_bind_int64(mcsdk_db_statement stmt, int position, int64_t value);
mcsdk_export void mcsdk_db_statement_bind_float(mcsdk_db_statement stmt, int position, float value);
mcsdk_export void mcsdk_db_statement_bind_text(mcsdk_db_statement stmt, int position, const char* value);
mcsdk_export void mcsdk_db_statement_bind_null(mcsdk_db_statement stmt, int position);
mcsdk_export int mcsdk_db_statement_column_int32(mcsdk_db_statement stmt, int column);
mcsdk_export int64_t mcsdk_db_statement_column_int64(mcsdk_db_statement stmt, int column);
mcsdk_export float mcsdk_db_statement_column_float(mcsdk_db_statement stmt, int column);
mcsdk_export int mcsdk_db_statement_column_text(mcsdk_db_statement stmt, int column, char* dst, int len);
mcsdk_export mcsdk_db_result mcsdk_db_statement_step(mcsdk_db_statement stmt);
mcsdk_export void mcsdk_db_statement_reset(mcsdk_db_statement stmt);
mcsdk_export void mcsdk_db_statement_unbind(mcsdk_db_statement stmt);
mcsdk_export void mcsdk_db_statement_reset_and_unbind(mcsdk_db_statement stmt);
mcsdk_export void mcsdk_db_statement_release(mcsdk_db_statement stmt);
/*
* ScopedTransaction
*/
mcsdk_export mcsdk_db_transaction mcsdk_db_transaction_create(mcsdk_db_connection db);
mcsdk_export void mcsdk_db_transaction_cancel(mcsdk_db_transaction tx);
mcsdk_export void mcsdk_db_transaction_commit_and_restart(mcsdk_db_transaction tx);
mcsdk_export void mcsdk_db_transaction_release(mcsdk_db_transaction tx);
#endif

View File

@ -52,6 +52,21 @@ static void indexer_finished_callback(mcsdk_svc_indexer in, int total_updated_co
printf("[indexer_finished_callback] %d\n", total_updated_count);
}
static bool run_test_query_callback(mcsdk_svc_library library, mcsdk_db_connection connection) {
bool result = false;
mcsdk_db_statement stmt = mcsdk_db_statement_create(connection, "SELECT COUNT(*) FROM tracks");
if (mcsdk_db_statement_step(stmt) == mcsdk_db_result_row) {
int total_tracks = mcsdk_db_statement_column_int64(stmt, 0);
printf("[run_test_query_callback] success! %d total tracks", total_tracks);
result = true;
}
else {
printf("[run_test_query_callback] failed");
}
mcsdk_db_statement_release(stmt);
return result;
}
static void test_indexer(mcsdk_context* context) {
char buffer[4096];
for (int i = 0; i < mcsdk_svc_indexer_get_paths_count(context->indexer); i++) {
@ -162,6 +177,14 @@ static void test_metadata(mcsdk_context* context) {
printf("[test_metadata] done.\n");
}
static void test_library(mcsdk_context* context) {
mcsdk_svc_library_run_query(
context->library,
"test query",
run_test_query_callback,
mcsdk_svc_library_query_flag_synchronous);
}
static void configure_environment() {
const char* suffix = "stderr.log";
char* dest_path = NULL;
@ -182,6 +205,7 @@ int main(int argc, char** argv) {
printf("[main] context initialized\n");
test_indexer(context);
test_metadata(context);
test_library(context);
test_low_level_playback();
test_high_level_playback(context);
test_decode_encode();