mirror of
https://github.com/sqlitebrowser/sqlitebrowser.git
synced 2026-01-20 02:50:46 -06:00
grammar: Introduce basic View class stub
Parsing views or generating a CREATE VIEW statement isn't implemented yet. Also unify the process by which it's possible to retrieve information on the fields of a database object.
This commit is contained in:
@@ -195,15 +195,23 @@ void DbStructureModel::reloadData()
|
||||
addNode(typeToParentItem.value("browsable"), *it);
|
||||
|
||||
// Add field nodes
|
||||
sqlb::FieldVector pk = (*it).object.dynamicCast<sqlb::Table>()->primaryKey();
|
||||
for(int i=0; i < (*it).object.dynamicCast<sqlb::Table>()->fields().size(); ++i)
|
||||
QStringList pk_columns;
|
||||
if(it->gettype() == sqlb::Object::Types::Table)
|
||||
{
|
||||
sqlb::FieldVector pk = it->object.dynamicCast<sqlb::Table>()->primaryKey();
|
||||
foreach(sqlb::FieldPtr pk_col, pk)
|
||||
pk_columns.push_back(pk_col->name());
|
||||
|
||||
}
|
||||
sqlb::FieldInfoList fieldList = it->object->fieldInformation();
|
||||
foreach(const sqlb::FieldInfo& field, fieldList)
|
||||
{
|
||||
QTreeWidgetItem *fldItem = new QTreeWidgetItem(item);
|
||||
fldItem->setText(0, (*it).object.dynamicCast<sqlb::Table>()->fields().at(i)->name());
|
||||
fldItem->setText(0, field.name);
|
||||
fldItem->setText(1, "field");
|
||||
fldItem->setText(2, (*it).object.dynamicCast<sqlb::Table>()->fields().at(i)->type());
|
||||
fldItem->setText(3, (*it).object.dynamicCast<sqlb::Table>()->fields().at(i)->toString(" ", " "));
|
||||
if(pk.contains((*it).object.dynamicCast<sqlb::Table>()->fields().at(i)))
|
||||
fldItem->setText(2, field.type);
|
||||
fldItem->setText(3, field.sql);
|
||||
if(pk_columns.contains(field.name))
|
||||
fldItem->setIcon(0, QIcon(":/icons/field_key"));
|
||||
else
|
||||
fldItem->setIcon(0, QIcon(":/icons/field"));
|
||||
|
||||
@@ -367,11 +367,9 @@ void MainWindow::populateStructure()
|
||||
{
|
||||
QString objectname = it.value().getname();
|
||||
|
||||
for(int i=0; i < (*it).object.dynamicCast<sqlb::Table>()->fields().size(); ++i)
|
||||
{
|
||||
QString fieldname = (*it).object.dynamicCast<sqlb::Table>()->fields().at(i)->name();
|
||||
tablesToColumnsMap[objectname].append(fieldname);
|
||||
}
|
||||
sqlb::FieldInfoList fi = it->object->fieldInformation();
|
||||
foreach(const sqlb::FieldInfo& f, fi)
|
||||
tablesToColumnsMap[objectname].append(f.name);
|
||||
}
|
||||
SqlTextEdit::sqlLexer->setTableNames(tablesToColumnsMap);
|
||||
ui->editLogApplication->reloadKeywords();
|
||||
|
||||
@@ -1253,27 +1253,28 @@ void DBBrowserDB::updateSchema( )
|
||||
continue;
|
||||
|
||||
DBBrowserObject obj(val_name, val_sql, type, val_tblname);
|
||||
if((type == sqlb::Object::Types::Table || type == sqlb::Object::Types::Index) && !val_sql.isEmpty())
|
||||
if((type == sqlb::Object::Types::Table || type == sqlb::Object::Types::Index || type == sqlb::Object::Types::View) && !val_sql.isEmpty())
|
||||
{
|
||||
obj.object = sqlb::Object::parseSQL(type, val_sql);
|
||||
if(val_temp == "1")
|
||||
obj.object->setTemporary(true);
|
||||
|
||||
// For virtual tables query the column list using the SQLite pragma
|
||||
if(type == sqlb::Object::Types::Table && obj.object.dynamicCast<sqlb::Table>()->isVirtual())
|
||||
// For virtual tables and views query the column list using the SQLite pragma because for both we can't yet rely on our grammar parser
|
||||
if((type == sqlb::Object::Types::Table && obj.object.dynamicCast<sqlb::Table>()->isVirtual()) || type == sqlb::Object::Types::View)
|
||||
{
|
||||
sqlb::TablePtr tab = obj.object.dynamicCast<sqlb::Table>();
|
||||
auto columns = queryColumnInformation(val_name);
|
||||
foreach(const auto& column, columns)
|
||||
tab->addField(sqlb::FieldPtr(new sqlb::Field(column.first, column.second)));
|
||||
|
||||
if(type == sqlb::Object::Types::Table)
|
||||
{
|
||||
sqlb::TablePtr tab = obj.object.dynamicCast<sqlb::Table>();
|
||||
foreach(const auto& column, columns)
|
||||
tab->addField(sqlb::FieldPtr(new sqlb::Field(column.first, column.second)));
|
||||
} else {
|
||||
sqlb::ViewPtr view = obj.object.dynamicCast<sqlb::View>();
|
||||
foreach(const auto& column, columns)
|
||||
view->addField(sqlb::FieldPtr(new sqlb::Field(column.first, column.second)));
|
||||
}
|
||||
}
|
||||
} else if(type == sqlb::Object::Types::View) {
|
||||
// For views we currently can't rely on our grammar parser to get the column list. Use the pragma offered by SQLite instead
|
||||
auto columns = queryColumnInformation(val_name);
|
||||
sqlb::Table* view_dummy = new sqlb::Table("");
|
||||
foreach(const auto& column, columns)
|
||||
view_dummy->addField(sqlb::FieldPtr(new sqlb::Field(column.first, column.second)));
|
||||
obj.object = sqlb::TablePtr(view_dummy);
|
||||
}
|
||||
objMap.insert(val_type, obj);
|
||||
}
|
||||
|
||||
@@ -76,6 +76,9 @@ ObjectPtr Object::parseSQL(Object::Types type, const QString& sSQL)
|
||||
case Object::Types::Index:
|
||||
result = Index::parseSQL(sSQL);
|
||||
break;
|
||||
case Object::Types::View:
|
||||
result = View::parseSQL(sSQL);
|
||||
break;
|
||||
default:
|
||||
return ObjectPtr(nullptr);
|
||||
}
|
||||
@@ -310,6 +313,14 @@ QStringList Table::fieldNames() const
|
||||
return sl;
|
||||
}
|
||||
|
||||
FieldInfoList Table::fieldInformation() const
|
||||
{
|
||||
FieldInfoList result;
|
||||
foreach(FieldPtr f, m_fields)
|
||||
result.append({f->name(), f->type(), f->toString(" ", " ")});
|
||||
return result;
|
||||
}
|
||||
|
||||
bool Table::hasAutoIncrement() const
|
||||
{
|
||||
foreach(FieldPtr f, m_fields) {
|
||||
@@ -1132,4 +1143,52 @@ void CreateIndexWalker::parsecolumn(Index* index, antlr::RefAST c)
|
||||
index->addColumn(IndexedColumnPtr(new IndexedColumn(name, isExpression, order)));
|
||||
}
|
||||
|
||||
|
||||
|
||||
View::~View()
|
||||
{
|
||||
clear();
|
||||
}
|
||||
|
||||
ObjectPtr View::parseSQL(const QString& /*sSQL*/)
|
||||
{
|
||||
// TODO
|
||||
|
||||
return ViewPtr(new View(""));
|
||||
}
|
||||
|
||||
void View::clear()
|
||||
{
|
||||
m_fields.clear();
|
||||
}
|
||||
|
||||
void View::addField(const FieldPtr& f)
|
||||
{
|
||||
m_fields.append(FieldPtr(f));
|
||||
}
|
||||
|
||||
void View::setFields(const FieldVector& fields)
|
||||
{
|
||||
clear();
|
||||
m_fields = fields;
|
||||
}
|
||||
|
||||
QStringList View::fieldNames() const
|
||||
{
|
||||
QStringList sl;
|
||||
|
||||
foreach(FieldPtr f, m_fields)
|
||||
sl << f->name();
|
||||
|
||||
return sl;
|
||||
}
|
||||
|
||||
FieldInfoList View::fieldInformation() const
|
||||
{
|
||||
FieldInfoList result;
|
||||
foreach(FieldPtr f, m_fields)
|
||||
result.append({f->name(), f->type(), f->toString(" ", " ")});
|
||||
return result;
|
||||
}
|
||||
|
||||
} //namespace sqlb
|
||||
|
||||
@@ -15,21 +15,32 @@ QString escapeIdentifier(QString id);
|
||||
class Object;
|
||||
class Table;
|
||||
class Index;
|
||||
class View;
|
||||
class Field;
|
||||
class Constraint;
|
||||
class IndexedColumn;
|
||||
struct FieldInfo;
|
||||
typedef QSharedPointer<Object> ObjectPtr;
|
||||
typedef QSharedPointer<Table> TablePtr;
|
||||
typedef QSharedPointer<Index> IndexPtr;
|
||||
typedef QSharedPointer<View> ViewPtr;
|
||||
typedef QSharedPointer<Field> FieldPtr;
|
||||
typedef QSharedPointer<Constraint> ConstraintPtr;
|
||||
typedef QVector<FieldPtr> FieldVector;
|
||||
typedef QSharedPointer<IndexedColumn> IndexedColumnPtr;
|
||||
typedef QVector<IndexedColumnPtr> IndexedColumnVector;
|
||||
typedef QMultiHash<FieldVector, ConstraintPtr> ConstraintMap;
|
||||
typedef QList<FieldInfo> FieldInfoList;
|
||||
|
||||
QStringList fieldVectorToFieldNames(const sqlb::FieldVector& vector);
|
||||
|
||||
struct FieldInfo
|
||||
{
|
||||
QString name;
|
||||
QString type;
|
||||
QString sql;
|
||||
};
|
||||
|
||||
class Object
|
||||
{
|
||||
public:
|
||||
@@ -60,6 +71,8 @@ public:
|
||||
void setFullyParsed(bool fully_parsed) { m_fullyParsed = fully_parsed; }
|
||||
bool fullyParsed() const { return m_fullyParsed; }
|
||||
|
||||
virtual FieldInfoList fieldInformation() const { return FieldInfoList(); }
|
||||
|
||||
virtual void clear() {}
|
||||
|
||||
/**
|
||||
@@ -250,6 +263,8 @@ public:
|
||||
|
||||
void clear();
|
||||
|
||||
virtual FieldInfoList fieldInformation() const;
|
||||
|
||||
void addConstraint(FieldVector fields, ConstraintPtr constraint);
|
||||
void setConstraint(FieldVector fields, ConstraintPtr constraint);
|
||||
void removeConstraints(FieldVector fields = FieldVector(), Constraint::ConstraintTypes type = Constraint::NoType); //! Only removes the first constraint, if any
|
||||
@@ -365,6 +380,31 @@ private:
|
||||
IndexedColumnVector m_columns;
|
||||
};
|
||||
|
||||
class View : public Object
|
||||
{
|
||||
public:
|
||||
explicit View(const QString& name): Object(name) {}
|
||||
virtual ~View();
|
||||
|
||||
virtual Types type() const { return Object::View; }
|
||||
|
||||
QString sql() const { /* TODO */ return m_originalSql; }
|
||||
|
||||
static ObjectPtr parseSQL(const QString& sSQL);
|
||||
|
||||
void clear();
|
||||
|
||||
void addField(const FieldPtr& f);
|
||||
void setFields(const FieldVector& fields);
|
||||
const FieldPtr& field(int index) const { return m_fields[index]; }
|
||||
QStringList fieldNames() const;
|
||||
|
||||
virtual FieldInfoList fieldInformation() const;
|
||||
|
||||
private:
|
||||
FieldVector m_fields;
|
||||
};
|
||||
|
||||
} //namespace sqlb
|
||||
|
||||
#endif // SQLITETYPES_H
|
||||
|
||||
Reference in New Issue
Block a user