Servidor de datos A7: gestión de datos en línea

Hola Habr!


Todas las entradas de mitap están disponibles aquí: https://youtu.be/kJS5rfCWmPI


Estamos probando publicaciones con transcripciones de informes realizados en PiterJS.
Como esta es la primera experiencia, estaremos encantados de escuchar críticas constructivas y sugerencias de mejora.


Mire videos y diapositivas , y para decodificar: bienvenido a cat.


El informe y la transcripción fueron preparados por Andrey Loginov , Director Técnico de A7 Systems.


Empecemos


Fast Big Data Server: servidor para grandes datos rápidos. Inicialmente, el A7 DS está diseñado para Digital Twin , gestionando roles y patrones de datos. Pero eso no es todo lo que puede hacer.


Que hay dentro


A ver:


  • Base de datos de objetos
  • Base de datos temporal (cronológica)
  • Máquina virtual JavaScript (para ser honesto, lenguaje similar a js)
  • Sistema de nivel de acceso
  • Servidor de aplicaciones

Además de la tipificación y la herencia, una base de datos de objetos tiene varias características:


  • soporte de árbol
  • soporte gráfico
  • montaje y enlaces
  • Espacios
  • Soporte de unión (reactividad)

Espacio


Lo más inusual aquí es el espacio.
El espacio es una instancia de un espacio de trabajo típico.

El espacio incluye:


  • datos
  • datos compartidos (datos compartidos para varios espacios. Por ejemplo, clima o tipo de cambio)
  • roles (propietario, usuarios, grupos)
    Es decir, Space está bastante aislado del servidor A7 DS y de otros espacios.

Como usar


Ahora la pregunta es: cómo usarlo. Esta es probablemente la pregunta más importante.
Creemos una pequeña aplicación móvil en ECMAScript.


Necesitaremos:


  • Mínimo conocimiento de C ++. (posiblemente como parte del currículo escolar)
  • Conocimiento de ECMAScript y QML (Qt)
  • Android NDK (solo para compilar esto)

En mi opinión, los mejores ejemplos siempre están relacionados con el dinero, así que intente crear una billetera familiar en línea)).


Crear objetos en la base de datos de objetos. Más precisamente, crearemos tipos. Es más conveniente usar un editor para describir objetos, pero no somos así y crear una descripción de objetos en JSON.


Primero, cree un objeto de dinero en el que tengamos efectivo, una tarjeta de crédito y el monto 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"} ] } 

Los campos de tarjeta y efectivo son valores simples (el valor predeterminado es 0), puede escribir un poco más corto:


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

El campo de suma es una fórmula (¡hola reactividad!), También puedes escribir un poco más corto:


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

Ahora crearemos un par de niños y niñas.


 { "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"} ] } 

Suma de campo (¡hola reactividad otra vez!), Comenzó a incluir enlaces a subobjetos:


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

Ahora, con cada cambio en cualquier cifra, recibiremos automáticamente un recálculo del saldo actual.


Pero es útil para nosotros agregar un poco de historia.


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

En una breve entrada


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

Bueno, el objeto mismo de la historia. Quién, qué y cuánto ha cambiado.


 { "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} ] } 

Agregar desencadenantes para emparejar:


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

Y el código desencadenante en sí:


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

Por analogía, agregamos desencadenantes para boyfriend.card , girlfriend.card , girlfriend.cash .


Dado que queremos que nuestra aplicación tenga un gran número de pares, creamos un espacio SpacePair típico y lo convertimos en el elemento raíz de Pair .
Agregar dos usuarios por defecto
Girl
Boy


En realidad, el generador de espacio para controlar billeteras está listo.


Agrega algunos espacios. Cuando agrega espacio, se crea automáticamente una región de datos (y los datos en sí mismos con valores predeterminados). También se crean usuarios y grupos preestablecidos (por espacio).
Cada espacio tiene sus usuarios y sus grupos.


Comenzamos a hacer el cliente:


Agregar al proyecto de 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 } } 

Arreglemos un poco el archivo 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(); } 

La parte de C ++ está terminada y podemos pasar a QML.


Primero, crea un par de componentes.


Agregue un componente para mostrar los datos.


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; } } } 

Ahora vamos a armar la ventana 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 "¿Pero qué pasa con el prometido Digital Twin y otros nishtyaki?" - preguntará el lector atento.
"La unión es buena, pero ¿dónde están las monturas y los gráficos?" - él agregará.


Estas son preguntas justas, y las respuestas a ellas se darán en los siguientes artículos;).

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


All Articles