diff --git a/main.go b/main.go index 51f3452..4c5baac 100644 --- a/main.go +++ b/main.go @@ -238,6 +238,25 @@ func Bolt_ListItems(b ObjectReference, browse []string) ObjectReference { return pNC_Ref } +//export Bolt_GetItem +func Bolt_GetItem(b ObjectReference, browse []string, key string) (int64, *C.char, int) { + var ret *C.char = nil + var ret_len = 0 + + err := withBrowse_ReadOnly(b, browse, func(db *bolt.DB, tx *bolt.Tx, bucket *bolt.Bucket) error { + d := bucket.Get([]byte(key)) + ret = C.CString(string(d)) + ret_len = len(d) + return nil + }) + + if err != nil { + return ERROR_AND_STOP_CALLING, C.CString(err.Error()), len(err.Error()) + } + + return REAL_MESSAGE, ret, ret_len +} + //export GetNext func GetNext(oRef ObjectReference) (int64, *C.char, int) { pNC_Iface, ok := gms.Get(oRef) diff --git a/qbolt/boltdb.cpp b/qbolt/boltdb.cpp index 200a1a4..3d5189a 100644 --- a/qbolt/boltdb.cpp +++ b/qbolt/boltdb.cpp @@ -59,6 +59,29 @@ bool BoltDB::listKeys(QStringList bucketPath, QString& errorOut, std::function onSuccess, std::function onError) +{ + GoSliceManagedWrapper browse(&bucketPath); + GoString keyGS = Interop::toGoString_WeakRef(&key); + auto resp = ::Bolt_GetItem(this->gmsDbRef, browse.slice, keyGS); + + if (resp.r0 == ERROR_AND_STOP_CALLING) { + onError(QString::fromUtf8(resp.r1, resp.r2)); + free(resp.r1); + return false; + + } else if (resp.r0 == REAL_MESSAGE) { + onSuccess(QByteArray(resp.r1, resp.r2)); + free(resp.r1); + return true; + + } else { + // ?? unreachable + return false; + + } +} + bool BoltDB::pumpNext(GoInt64 jobRef, QString& errorOut, NameReciever cb) { errorOut.clear(); @@ -95,9 +118,8 @@ bool BoltDB::getStatsJSON(std::function onSuccess, std::functi auto statresp = Bolt_DBStats(this->gmsDbRef); if (statresp.r0 == ERROR_AND_STOP_CALLING) { - QString err = QString::fromUtf8(statresp.r1, statresp.r2); + onError(QString::fromUtf8(statresp.r1, statresp.r2)); free(statresp.r1); - onError(err); return false; } else if (statresp.r0 == REAL_MESSAGE) { diff --git a/qbolt/boltdb.h b/qbolt/boltdb.h index 1297d80..9ff39b6 100644 --- a/qbolt/boltdb.h +++ b/qbolt/boltdb.h @@ -22,6 +22,8 @@ public: bool listKeys(QStringList bucketPath, QString& errorOut, std::function cb); + bool getData(QStringList bucketPath, QByteArray key, std::function onSuccess, std::function onError); + bool getStatsJSON(std::function onSuccess, std::function onError); bool getBucketStatsJSON(QStringList bucketPath, std::function onSuccess, std::function onError); diff --git a/qbolt/itemwindow.cpp b/qbolt/itemwindow.cpp new file mode 100644 index 0000000..6ba97bf --- /dev/null +++ b/qbolt/itemwindow.cpp @@ -0,0 +1,18 @@ +#include "itemwindow.h" +#include "ui_itemwindow.h" + +ItemWindow::ItemWindow(QWidget *parent) : + QDialog(parent), + ui(new Ui::ItemWindow) +{ + ui->setupUi(this); +} + +ItemWindow::~ItemWindow() +{ + delete ui; +} + +QPlainTextEdit* ItemWindow::ContentArea() const { + return ui->contentArea; +} diff --git a/qbolt/itemwindow.h b/qbolt/itemwindow.h new file mode 100644 index 0000000..326ae52 --- /dev/null +++ b/qbolt/itemwindow.h @@ -0,0 +1,25 @@ +#ifndef ITEMWINDOW_H +#define ITEMWINDOW_H + +#include +#include + +namespace Ui { +class ItemWindow; +} + +class ItemWindow : public QDialog +{ + Q_OBJECT + +public: + explicit ItemWindow(QWidget *parent = 0); + ~ItemWindow(); + + QPlainTextEdit* ContentArea() const; + +private: + Ui::ItemWindow *ui; +}; + +#endif // ITEMWINDOW_H diff --git a/qbolt/itemwindow.ui b/qbolt/itemwindow.ui new file mode 100644 index 0000000..ab9a896 --- /dev/null +++ b/qbolt/itemwindow.ui @@ -0,0 +1,46 @@ + + + ItemWindow + + + + 0 + 0 + 370 + 353 + + + + + + + + :/rsrc/database_lightning.png:/rsrc/database_lightning.png + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + QFrame::NoFrame + + + + + + + + + + diff --git a/qbolt/mainwindow.cpp b/qbolt/mainwindow.cpp index 03ea9dd..4e4c2cf 100644 --- a/qbolt/mainwindow.cpp +++ b/qbolt/mainwindow.cpp @@ -1,6 +1,6 @@ #include "mainwindow.h" #include "ui_mainwindow.h" - +#include "itemwindow.h" #include "boltdb.h" #include @@ -58,6 +58,8 @@ void MainWindow::on_actionOpen_database_triggered() refreshBucketTree(top); ui->bucketTree->setCurrentItem(top); + + ui->bucketTree->expandItem(top); } void MainWindow::refreshBucketTree(QTreeWidgetItem* itm) @@ -225,12 +227,15 @@ void MainWindow::on_bucketTree_currentItemChanged(QTreeWidgetItem *current, QTre itm->setText(1, QString("%1").arg(dataLen)); ui->bucketData->addTopLevelItem(itm); }); + if (! ok) { QMessageBox qmb; qmb.setText(tr("Error listing bucket content: %1").arg(err)); qmb.exec(); } + ui->bucketData->resizeColumnToContents(0); + // Clean up foreign areas ui->databasePropertiesArea->clear(); } @@ -240,3 +245,49 @@ void MainWindow::on_actionClear_selection_triggered() { ui->bucketTree->setCurrentItem(nullptr); } + +void MainWindow::on_bucketData_doubleClicked(const QModelIndex &index) +{ + auto *itm = ui->bucketTree->currentItem(); + if (itm == nullptr) { + return; + } + + // Get browse path + + QTreeWidgetItem* top = itm; + QStringList browse; + while(top->parent() != nullptr) { + browse.push_front(top->text(0)); + top = top->parent(); + } + + // Get BDB + + auto *bdb = GET_BDB(top); + + // Get item key + + auto model = index.model(); + QString key = model->data(model->index(index.row(), 0), 0).toString(); + + // DB lookup + + bdb->getData( + browse, + key.toUtf8(), + [=](QByteArray content) { + auto iw = new ItemWindow(); + iw->ContentArea()->setPlainText(QString::fromUtf8(content)); + iw->setWindowTitle(key); + connect(iw, &ItemWindow::finished, iw, &ItemWindow::deleteLater); + iw->show(); + }, + [=](QString error) { + QMessageBox qmb; + qmb.setText(tr("Error loading item content: %1").arg(error)); + qmb.exec(); + } + ); + +} diff --git a/qbolt/mainwindow.h b/qbolt/mainwindow.h index b806614..552a665 100644 --- a/qbolt/mainwindow.h +++ b/qbolt/mainwindow.h @@ -36,6 +36,8 @@ private slots: void on_actionClear_selection_triggered(); + void on_bucketData_doubleClicked(const QModelIndex &index); + protected: void refreshBucketTree(QTreeWidgetItem* top); diff --git a/qbolt/qbolt.pro b/qbolt/qbolt.pro index 082d30c..30632d7 100644 --- a/qbolt/qbolt.pro +++ b/qbolt/qbolt.pro @@ -29,14 +29,17 @@ linux: { SOURCES += main.cpp\ mainwindow.cpp \ interop.cpp \ - boltdb.cpp + boltdb.cpp \ + itemwindow.cpp HEADERS += mainwindow.h \ interop.h \ boltdb.h \ - qbolt_cgo.h + qbolt_cgo.h \ + itemwindow.h -FORMS += mainwindow.ui +FORMS += mainwindow.ui \ + itemwindow.ui RESOURCES += \ resources.qrc