A7 Data Server: gerenciamento de dados online

Olá Habr!


Todas as entradas mitap estão disponíveis aqui: https://youtu.be/kJS5rfCWmPI


Estamos pilotando publicações com transcrições de relatórios feitos no PiterJS.
Como esta é a primeira experiência, teremos o maior prazer em ouvir críticas construtivas e sugestões de melhorias.


Assista a vídeos e slides e decodifique - bem-vindo ao gato.


O relatório e a transcrição foram preparados por Andrey Loginov , diretor técnico da A7 Systems.


Vamos começar


Fast Big Data Server - servidor para grandes dados rápidos. Inicialmente, o A7 DS foi projetado para o Digital Twin , gerenciando funções e padrões de dados. Mas isso não é tudo que ele pode fazer.


O que tem dentro.


Vamos ver:


  • Banco de dados de objetos
  • Banco de dados temporal (cronológico)
  • Máquina virtual JavaScript (para ser sincero, linguagem js)
  • Sistema de nível de acesso
  • Servidor de aplicativos

Além de digitar e herança, um banco de dados de objetos possui vários recursos:


  • suporte de árvore
  • suporte gráfico
  • montagem e links
  • Espaços
  • Suporte de ligação (reatividade)

Espaço


A coisa mais incomum aqui é o espaço.
O espaço é uma instância de um espaço de trabalho típico.

O espaço inclui:


  • dados
  • dados compartilhados (dados compartilhados para vários espaços. Por exemplo, clima ou taxa de câmbio)
  • funções (proprietário, usuários, grupos)
    Ou seja, o Space é bastante isolado do servidor A7 DS e de outros espaços do Spaces.

Como usar


Agora a questão é: como usá-lo. Esta é provavelmente a pergunta mais importante.
Vamos criar um pequeno aplicativo móvel no ECMAScript.


Vamos precisar de:


  • Conhecimento mínimo de C ++. (possivelmente como parte do currículo da escola)
  • Conhecimento de ECMAScript e QML (Qt)
  • Android NDK (apenas para compilar isso)

Na minha opinião, os melhores exemplos estão sempre relacionados ao dinheiro, então tente criar uma carteira familiar on-line)).


Crie objetos no banco de dados de objetos. Mais precisamente, criaremos tipos. É mais conveniente usar um editor para descrever objetos, mas não somos assim, e criar uma descrição de objetos em JSON.


Primeiro, crie um objeto monetário no qual tenhamos dinheiro, cartão de crédito e o valor total:


{ "name": "Money", "fields": [ {"name": "card","fieldtype": "value","datatype": "double", "def": 0}, {"name": "cash","fieldtype": "value","datatype": "double","def": 0}, {"name": "sum","fieldtype": "formula","datatype": "double", "def": "card+credit"} ] } 

Os campos cartão e caixa são valores simples (o padrão é 0), você pode escrever um pouco mais:


 {"name": "card","value": 0.0}, {"name": "cash","value": 0.0} 

O campo soma é uma fórmula (oi reatividade!). Você também pode escrever um pouco mais curto:


 {"name": "sum","formula":"card+credit"} 

Agora vamos criar um par de meninos e meninas.


 { "name": "Pair", "fields": [ {"name": "boyfriend","fieldtype": "value","datatype": "Money", "def": "Money"}, {"name": "girlfriend","fieldtype": "value","datatype": "Money","def": "Money"}, {"name": "sum","fieldtype": "formula","datatype": "double", "def": "boyfriend.sum+girlfriend.sum"} ] } 

Soma do campo (olá reatividade novamente!), Começou a incluir links para subobjetos:


 {"name": "sum","formula":"boyfriend.sum+girlfriend.sum"} 

Agora, com cada alteração em qualquer figura, receberemos automaticamente um recálculo do saldo atual.


Mas é útil adicionar um pouco de história.


 {"name": "history","fieldtype": "list", "list":{"datatype": "History"}} 

Em uma entrada curta


 {"name": "history", "list":{"datatype": "History"}} 

Bem, o próprio objeto da história. Quem, o quê e quanto mudou.


 { "name": "History", "fields": [ {"name": "who","fieldtype": "value","datatype": "string", "def": “”}, {"name": "which","fieldtype": "value","datatype": "string","def": “”}, {"name": "delta","fieldtype": "value","datatype": "double","def": 0} ] } 

Adicione gatilhos ao par:


 "functions": [{"functiontype": "before", "arguments": [boyfriend.cash], "code": "..." } ] 

E o próprio código de gatilho:


 { var historyItem= history.add(new History()); historyItem.who=”boyfriend”; historyItem.which=”cash”; history.delta=value-boyfriend.cash; return true; } 

Por analogia, adicionamos gatilhos para boyfriend.card , girlfriend.card , girlfriend.cash .


Como queremos tornar nosso aplicativo um grande número de pares, criamos um espaço SpacePair típico e o tornamos o elemento raiz do Pair .
Adicione dois usuários por padrão
Girl
Boy


Na verdade, o gerador de espaço para controlar carteiras está pronto.


Adicione alguns espaços. Quando você adiciona espaço, uma região de dados é criada automaticamente (e os próprios dados com valores padrão). Usuários e grupos predefinidos também são criados (para espaço).
Cada espaço tem seus usuários e seus grupos.


Começamos a fazer o cliente:


Adicionar ao projeto da biblioteca


 android { debug{ LIBS+= ../A7DS/Libs/android/libA17EDboClientBaseBind.a LIBS+= ../A7DS/Libs/android/libA17ClientLibBind.a } release{ LIBS+= ../A7DS/Libs/android/libA17EDboClientBaseBin.a LIBS+= ../A7DS/Libs/android/libA17ClientLibBin.a } } 

Vamos corrigir um pouco o arquivo main.cpp


 #include <QApplication> #include <QQmlApplicationEngine> #include <QVariant> #include <QQmlEngine> //    *.h  #include "../A7DS/A17EBase/A17EDboClientBaseBin/a17edboclientbasebin.h" int main(int argc, char *argv[]) { QApplication app(argc, argv); QQmlApplicationEngine engine; //    A7DS A17EDboClientBaseBin*client=new A17EDboClientBaseBin(engine,&app); //    A7DS client->init(engine); //    engine.load(QUrl(QLatin1String(QString("qrc:/main.qml").toLatin1()))); return app.exec(); } 

A parte do C ++ está concluída e podemos passar para a QML.


Primeiro, crie um par de componentes.


Adicione um componente para exibir os dados.


MyLabelView.qml


 import QtQuick 2.7 import Astra.Dbo 17.0 Item {id: viewItem property alias field: field property string label: "  " width: parent.width height: 100 DboField{ id: field } Text { id: labelItem text: viewItem.label anchors.left: parent.left anchors.right: parent.horizontalCenter anchors.top: parent.top anchors.bottom: parent.bottom } Text { id: valueItem text: field.value anchors.right: parent.right anchors.left: parent.horizontalCenter anchors.top: parent.top anchors.bottom: parent.bottom } } 

MyLabelEdit.qml


 import QtQuick 2.7 import Astra.Dbo 17.0 Item {id: viewItem property alias field: field property string label: "  " width: parent.width height: 100 DboField{ id: field } Text { id: labelItem text: viewItem.label anchors.left: parent.left anchors.right: parent.horizontalCenter anchors.top: parent.top anchors.bottom: parent.bottom } TextInput { id: valueItem text: field.value anchors.right: parent.right anchors.left: parent.horizontalCenter anchors.top: parent.top anchors.bottom: parent.bottom onEditingFinished:{ field.value=text; } } } 

Agora vamos montar a janela principal
MyLabelEdit.qml


 import QtQuick 2.7 import Astra.Dbo 17.0 import QtQuick.Controls 1.5 {id:appWindow visible: true width: 640 height: 480 property var component; property var sprite; ApplicationWindow {id: viewItem property alias field: field property string label: "  " property string host: "127.0.0.1" ////  A7 DS property int port: 8989 //  A7 DS property string isBoy: (dboconnection.login=="Boy") property var myselfMoney: (isBoy)?boyfriend:girlfriend property var myfriendMoney: (!isBoy)?boyfriend:girlfriend /* ,         */ DboObject{id:boyfriend parentObject: rootData parentFieldName: "boyfriend" } DboObject{id:girlfriend parentObject: rootData parentFieldName: "girlfriend" } DboModel{id:history parentObject: rootData parentFieldName: "history" } /* ,   ,      A7 DS */ Column{ z: 10 visible: (! dboconnection.isConnect) anchors.fill: parent TextInput{id:login width: parent.width height: 100 } TextInput{id:password width: parent.width height: 100 } Button{id:btn width: parent.width height: 100 text: ”” onClicked: dboconnection.connectToDbo( login.text, password..text, viewItem.host, viewItem.port); } } SwipeView{ anchors.fill: parent currentIndex: 1 ///      Page{ ListView{ model: history delegate: Text{ text: model.who+” ”+model.which+” ”+model.delta } } } ///      Page{ Column{ anchors.fill: parent MyLabelEdit{id:myCash; label: “ ” field.name: “cash”; field.parentObject: myselfMoney } MyLabelEdit{id:myCard; label: “ ” field.name: “card”; field.parentObject: myselfMoney } MyLabelView{id:mySum; label: “  ” field.name: “sum”; field.parentObject: myselfMoney } MyLabelView{id:myfriendCash; label: “ ” field.name: “cash”; field.parentObject: myfriendMoney } MyLabelView{id:myfriendCard; label: “ ” field.name: “card”; field.parentObject: myfriendMoney } MyLabelView{id:myfriendSum; label: “  ” field.name: “sum”; field.parentObject: myfriendMoney } MyLabelView{id:mypairSum; label: “  ” field.name: “sum”; field.parentObject: mypairMoney } } } } } Text { id: labelItem text: viewItem.label anchors.left: parent.left anchors.right: parent.horizontalCenter anchors.top: parent.top anchors.bottom: parent.bottom } TextInput { id: valueItem text: field.value anchors.right: parent.right anchors.left: parent.horizontalCenter anchors.top: parent.top anchors.bottom: parent.bottom onEditingFinished:{ field.value=text; } } } 

Umm. "Mas e o prometido Digital Twin e outros nishtyaki?" - o leitor atento perguntará.
"A encadernação é boa, mas onde estão as montagens e os gráficos?" - ele adicionará.


Essas são perguntas justas e as respostas serão fornecidas nos seguintes artigos;).

Source: https://habr.com/ru/post/pt422281/


All Articles