retrieve bucket properties
This commit is contained in:
parent
95a1bfeea5
commit
60d71104e8
49
main.go
49
main.go
@ -76,6 +76,34 @@ func withBoltDBReference(b ObjectReference, fn func(db *bolt.DB) error) error {
|
||||
return fn(ptrDB)
|
||||
}
|
||||
|
||||
func withBrowse_ReadOnly(b_ref ObjectReference, browse []string, fn func(db *bolt.DB, tx *bolt.Tx, bucket *bolt.Bucket) error) error {
|
||||
if len(browse) == 0 {
|
||||
// not a bucket
|
||||
return errors.New("No bucket selected")
|
||||
}
|
||||
|
||||
return withBoltDBReference(b_ref, func(db *bolt.DB) error {
|
||||
return db.View(func(tx *bolt.Tx) error {
|
||||
|
||||
bucket := tx.Bucket([]byte(browse[0]))
|
||||
if bucket == nil {
|
||||
return errors.New("Unknown bucket")
|
||||
}
|
||||
|
||||
for i := 1; i < len(browse); i += 1 {
|
||||
bucket = bucket.Bucket([]byte(browse[i]))
|
||||
if bucket == nil {
|
||||
return errors.New("Unknown bucket")
|
||||
}
|
||||
}
|
||||
|
||||
// Walked the bucket chain, now run the user callback
|
||||
return fn(db, tx, bucket)
|
||||
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
type CallResponse struct {
|
||||
s string
|
||||
e error
|
||||
@ -98,6 +126,27 @@ func Bolt_DBStats(b ObjectReference) (int64, *C.char, int) {
|
||||
return REAL_MESSAGE, C.CString(string(jBytes)), len(jBytes)
|
||||
}
|
||||
|
||||
//export Bolt_BucketStats
|
||||
func Bolt_BucketStats(b ObjectReference, browse []string) (int64, *C.char, int) {
|
||||
var stats bolt.BucketStats
|
||||
|
||||
err := withBrowse_ReadOnly(b, browse, func(db *bolt.DB, tx *bolt.Tx, bucket *bolt.Bucket) error {
|
||||
stats = bucket.Stats()
|
||||
return nil
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return ERROR_AND_STOP_CALLING, C.CString(err.Error()), len(err.Error())
|
||||
}
|
||||
|
||||
jBytes, err := json.Marshal(stats)
|
||||
if err != nil {
|
||||
return ERROR_AND_STOP_CALLING, C.CString(err.Error()), len(err.Error())
|
||||
}
|
||||
|
||||
return REAL_MESSAGE, C.CString(string(jBytes)), len(jBytes)
|
||||
}
|
||||
|
||||
type NextCall struct {
|
||||
content chan CallResponse
|
||||
}
|
||||
|
9
qbolt.h
9
qbolt.h
@ -76,6 +76,15 @@ struct Bolt_DBStats_return {
|
||||
|
||||
extern struct Bolt_DBStats_return Bolt_DBStats(GoInt64 p0);
|
||||
|
||||
/* Return type for Bolt_BucketStats */
|
||||
struct Bolt_BucketStats_return {
|
||||
GoInt64 r0;
|
||||
char* r1;
|
||||
GoInt r2;
|
||||
};
|
||||
|
||||
extern struct Bolt_BucketStats_return Bolt_BucketStats(GoInt64 p0, GoSlice p1);
|
||||
|
||||
extern GoInt64 Bolt_ListBuckets(GoInt64 p0, GoSlice p1);
|
||||
|
||||
/* Return type for GetNext */
|
||||
|
@ -84,6 +84,29 @@ bool BoltDB::getStatsJSON(std::function<void(QString)> onSuccess, std::function<
|
||||
}
|
||||
}
|
||||
|
||||
bool BoltDB::getBucketStatsJSON(QStringList bucketPath, std::function<void(QString)> onSuccess, std::function<void(QString)> onError)
|
||||
{
|
||||
GoSliceManagedWrapper sliceWrapper(&bucketPath);
|
||||
auto statresp = Bolt_BucketStats(this->gmsDbRef, sliceWrapper.slice);
|
||||
|
||||
if (statresp.r0 == ERROR_AND_STOP_CALLING) {
|
||||
QString err = QString::fromUtf8(statresp.r1, statresp.r2);
|
||||
free(statresp.r1);
|
||||
onError(err);
|
||||
return false;
|
||||
|
||||
} else if (statresp.r0 == REAL_MESSAGE) {
|
||||
QString json = QString::fromUtf8(statresp.r1, statresp.r2);
|
||||
free(statresp.r1);
|
||||
onSuccess(json);
|
||||
return true;
|
||||
|
||||
} else {
|
||||
// ?? shouldn't be reachable
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
BoltDB::~BoltDB()
|
||||
{
|
||||
auto err = ::Bolt_Close(this->gmsDbRef);
|
||||
|
@ -20,6 +20,8 @@ public:
|
||||
|
||||
bool getStatsJSON(std::function<void(QString)> onSuccess, std::function<void(QString)> onError);
|
||||
|
||||
bool getBucketStatsJSON(QStringList bucketPath, std::function<void(QString)> onSuccess, std::function<void(QString)> onError);
|
||||
|
||||
~BoltDB();
|
||||
};
|
||||
|
||||
|
@ -1,5 +1,7 @@
|
||||
#include "interop.h"
|
||||
|
||||
#include <QStringList>
|
||||
|
||||
Interop::Interop()
|
||||
{
|
||||
|
||||
@ -12,3 +14,20 @@ GoString Interop::toGoString_WeakRef(QByteArray *qba) {
|
||||
int64_t Interop::GetMagic() {
|
||||
return ::GetMagic();
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
GoSliceManagedWrapper::GoSliceManagedWrapper(QStringList *qsl) :
|
||||
rawStrings(),
|
||||
strings(),
|
||||
slice()
|
||||
{
|
||||
for (int i = 0; i < qsl->size(); ++i) {
|
||||
rawStrings.push_back( qsl->at(i).toUtf8() );
|
||||
strings.push_back(GoString{ rawStrings[i].data(), rawStrings[i].size() });
|
||||
}
|
||||
|
||||
slice.data = static_cast<void*>( & strings.first() );
|
||||
slice.len = strings.size(); // * sizeof(GoString);
|
||||
slice.cap = slice.len;
|
||||
}
|
||||
|
@ -3,6 +3,19 @@
|
||||
|
||||
#include "../qbolt.h"
|
||||
#include <QString>
|
||||
#include <QList>
|
||||
|
||||
class GoSliceManagedWrapper {
|
||||
Q_DISABLE_COPY(GoSliceManagedWrapper)
|
||||
|
||||
public:
|
||||
GoSliceManagedWrapper(QStringList *qsl);
|
||||
protected:
|
||||
QList<QByteArray> rawStrings;
|
||||
QList<GoString> strings;
|
||||
public:
|
||||
GoSlice slice;
|
||||
};
|
||||
|
||||
class Interop
|
||||
{
|
||||
|
@ -31,6 +31,15 @@ static const int BdbPointerRole = Qt::UserRole + 1;
|
||||
#define SET_BDB(top, bdb) top->setData(0, BdbPointerRole, QVariant::fromValue<void*>(static_cast<void*>(bdb)))
|
||||
#define GET_BDB(top) static_cast<BoltDB*>( top->data(0, BdbPointerRole).value<void*>() )
|
||||
|
||||
/*
|
||||
static BoltDB* GET_BDB(QTreeWidgetItem *top) {
|
||||
while(top->parent() != nullptr) {
|
||||
top = top->parent();
|
||||
}
|
||||
|
||||
return static_cast<BoltDB*>( top->data(0, BdbPointerRole).value<void*>() );
|
||||
}
|
||||
*/
|
||||
|
||||
void MainWindow::on_actionOpen_database_triggered()
|
||||
{
|
||||
@ -152,32 +161,58 @@ void MainWindow::on_bucketTree_currentItemChanged(QTreeWidgetItem *current, QTre
|
||||
{
|
||||
Q_UNUSED(previous);
|
||||
if (current == nullptr) {
|
||||
ui->tabWidget->setVisible(false);
|
||||
ui->stackedWidget->setVisible(false);
|
||||
return;
|
||||
}
|
||||
|
||||
ui->tabWidget->setVisible(true);
|
||||
ui->stackedWidget->setVisible(true);
|
||||
|
||||
if (current->parent() == nullptr) {
|
||||
// Selected a database
|
||||
ui->stackedWidget->setCurrentWidget(ui->databasePage);
|
||||
|
||||
auto *bdb = GET_BDB(current);
|
||||
ui->propertiesArea->clear();
|
||||
bdb->getStatsJSON([=](QString j) {
|
||||
ui->propertiesArea->setPlainText(j);
|
||||
}, [=](QString error) {
|
||||
QMessageBox qmb;
|
||||
qmb.setText(tr("Error retrieving database statistics: %1").arg(error));
|
||||
qmb.exec();
|
||||
});
|
||||
bdb->getStatsJSON(
|
||||
[=](QString j) {
|
||||
ui->databasePropertiesArea->clear();
|
||||
ui->databasePropertiesArea->setPlainText(j);
|
||||
},
|
||||
[=](QString error) {
|
||||
QMessageBox qmb;
|
||||
qmb.setText(tr("Error retrieving database statistics: %1").arg(error));
|
||||
qmb.exec();
|
||||
}
|
||||
);
|
||||
|
||||
} else {
|
||||
// Selected a bucket
|
||||
|
||||
ui->stackedWidget->setCurrentWidget(ui->bucketPage);
|
||||
|
||||
QStringList browse;
|
||||
QTreeWidgetItem *top = current;
|
||||
while (top->parent() != nullptr) {
|
||||
browse.push_front(top->text(0));
|
||||
top = top->parent();
|
||||
}
|
||||
auto *bdb = GET_BDB(top);
|
||||
|
||||
bdb->getBucketStatsJSON(
|
||||
browse,
|
||||
[=](QString j) {
|
||||
ui->bucketPropertiesArea->clear();
|
||||
ui->bucketPropertiesArea->setPlainText(j);
|
||||
},
|
||||
[=](QString error) {
|
||||
QMessageBox qmb;
|
||||
qmb.setText(tr("Error retrieving bucket statistics: %1").arg(error));
|
||||
qmb.exec();
|
||||
}
|
||||
);
|
||||
|
||||
// Load the data tab
|
||||
// TODO
|
||||
|
||||
ui->propertiesArea->clear();
|
||||
}
|
||||
// refresh properties for the currently selected tree item...
|
||||
}
|
||||
|
||||
void MainWindow::on_actionClear_selection_triggered()
|
||||
|
@ -52,81 +52,115 @@
|
||||
</property>
|
||||
</column>
|
||||
</widget>
|
||||
<widget class="QTabWidget" name="tabWidget">
|
||||
<property name="currentIndex">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="propertiesTab">
|
||||
<attribute name="title">
|
||||
<string>Properties</string>
|
||||
</attribute>
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<widget class="QStackedWidget" name="stackedWidget">
|
||||
<widget class="QWidget" name="databasePage">
|
||||
<layout class="QGridLayout" name="gridLayout_4">
|
||||
<property name="leftMargin">
|
||||
<number>3</number>
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>3</number>
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>3</number>
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>3</number>
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item row="0" column="0">
|
||||
<widget class="QPlainTextEdit" name="propertiesArea">
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::NoFrame</enum>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="plainText">
|
||||
<string>No selection</string>
|
||||
<widget class="QTabWidget" name="databaseTabWidget">
|
||||
<property name="currentIndex">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="databasePropertiesTab">
|
||||
<attribute name="title">
|
||||
<string>Database</string>
|
||||
</attribute>
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<property name="leftMargin">
|
||||
<number>3</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>3</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>3</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>3</number>
|
||||
</property>
|
||||
<item row="0" column="0">
|
||||
<widget class="QPlainTextEdit" name="databasePropertiesArea">
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::NoFrame</enum>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="plainText">
|
||||
<string>No selection</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="dataTab">
|
||||
<attribute name="title">
|
||||
<string>Data</string>
|
||||
</attribute>
|
||||
<widget class="QWidget" name="bucketPage">
|
||||
<layout class="QGridLayout" name="gridLayout_3">
|
||||
<property name="leftMargin">
|
||||
<number>3</number>
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>3</number>
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>3</number>
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>3</number>
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item row="0" column="0">
|
||||
<widget class="QTreeWidget" name="treeWidget">
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::NoFrame</enum>
|
||||
</property>
|
||||
<property name="indentation">
|
||||
<widget class="QTabWidget" name="bucketTabWidget">
|
||||
<property name="currentIndex">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rootIsDecorated">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="uniformRowHeights">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<attribute name="headerVisible">
|
||||
<bool>false</bool>
|
||||
</attribute>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string notr="true">1</string>
|
||||
</property>
|
||||
</column>
|
||||
<widget class="QWidget" name="bucketPropertiesTab">
|
||||
<attribute name="title">
|
||||
<string>Bucket</string>
|
||||
</attribute>
|
||||
<layout class="QGridLayout" name="gridLayout_5">
|
||||
<property name="leftMargin">
|
||||
<number>3</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>3</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>3</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>3</number>
|
||||
</property>
|
||||
<item row="0" column="0">
|
||||
<widget class="QPlainTextEdit" name="bucketPropertiesArea">
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::NoFrame</enum>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="bucketDataTab">
|
||||
<attribute name="title">
|
||||
<string>Data</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
|
Loading…
Reference in New Issue
Block a user