mirror of
https://github.com/QuasarApp/Heart.git
synced 2025-05-10 16:39:41 +00:00
Merge pull request #55 from QuasarApp/task_313_CheatCard
Improvements from the CheatCard's next release branch.
This commit is contained in:
commit
9a3e09bec7
CMakeLists.txtCMakeLists.txtQuasarAppLib
Heart
AbstractSpace
Diagrams
abstractnode.cppabstractnode.hasynckeysauth.cppcryptopairkeys.cppcryptopairkeys.hhcrypto
hcryptoFeatures
hostaddress.cpphostaddress.hicrypto.hiparser.cppiparser.hkeystorage.cppkeystorage.hpackages
abstractdata.cppabstractdata.hbadrequest.cppbigdatabase.cppcloseconnection.cppcloseconnection.hdatapack.hping.cpp
streambase.cppstreambase.hDataBaseSpace
basenodeinfo.cppbasenodeinfo.hdatabase.cppdatabase.hdatabasenode.cppdatabasenode.hdbpatch.cppdbpatch.h
heart.hpackages
abstractnetworkmember.cppabstractnetworkmember.hdbobject.cppdbobject.hdbobjectset.cppdbobjectset.hdbobjectsrequest.hdbobjectsrequestwithStream.hdefaultpermision.cppdefaultpermision.hdeleteobject.cppdeleteobject.hgetmaxintegerid.cppgetmaxintegerid.hgetsinglevalue.cppgetsinglevalue.hmemberpermisionobject.cppmemberpermisionobject.hnetworkmember.cppnetworkmember.hsetsinglevalue.cppsetsinglevalue.husermember.cppusermember.hwebsocket.cppwebsocketsubscriptions.cpp
singleclient.cppsqldbwriter.cppwebsocketcontroller.cppwebsocketcontroller.hHeartTests
AbstractSpace
DataBaseSpace
@ -45,7 +45,15 @@ endif()
|
||||
|
||||
# Use only for android debug builds with debugging from usb.
|
||||
option(HEART_STATIC_SSL "This option enable or disabled static link ssl libraryes" OFF)
|
||||
option(HEART_SSL "This option enable or disabled ssl functions of nodes" ON)
|
||||
option(CMAKE_SHARE "This option enable or disabled ssl functions of nodes" OFF)
|
||||
option(BUILD_SHARED_LIBS "Enable or disable shared libraryes" OFF)
|
||||
|
||||
if (WIN32)
|
||||
option(HEART_SSL "This option enable or disabled ssl functions of nodes" OFF)
|
||||
else()
|
||||
option(HEART_SSL "This option enable or disabled ssl functions of nodes" ON)
|
||||
endif()
|
||||
|
||||
|
||||
if (HEART_DB_CACHE)
|
||||
add_definitions(-DHEART_DB_CACHE)
|
||||
|
@ -1,878 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg width="218.722mm" height="114.653mm"
|
||||
viewBox="0 0 620 325"
|
||||
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.2" baseProfile="tiny">
|
||||
<title>Qt SVG Document</title>
|
||||
<desc>Generated with Qt</desc>
|
||||
<defs>
|
||||
<linearGradient gradientUnits="objectBoundingBox" x1="0" y1="0" x2="0" y2="1" id="gradient1">
|
||||
<stop offset="0" stop-color="#ebfdff" stop-opacity="1" />
|
||||
<stop offset="1" stop-color="#bfe4e8" stop-opacity="1" />
|
||||
</linearGradient>
|
||||
<linearGradient gradientUnits="objectBoundingBox" x1="0" y1="0" x2="0" y2="1" id="gradient2">
|
||||
<stop offset="0" stop-color="#ebfdff" stop-opacity="1" />
|
||||
<stop offset="1" stop-color="#bfe4e8" stop-opacity="1" />
|
||||
</linearGradient>
|
||||
<linearGradient gradientUnits="objectBoundingBox" x1="0" y1="0" x2="0" y2="1" id="gradient3">
|
||||
<stop offset="0" stop-color="#ebfdff" stop-opacity="1" />
|
||||
<stop offset="1" stop-color="#bfe4e8" stop-opacity="1" />
|
||||
</linearGradient>
|
||||
<linearGradient gradientUnits="objectBoundingBox" x1="0" y1="0" x2="0" y2="1" id="gradient4">
|
||||
<stop offset="0" stop-color="#ebfdff" stop-opacity="1" />
|
||||
<stop offset="1" stop-color="#bfe4e8" stop-opacity="1" />
|
||||
</linearGradient>
|
||||
<linearGradient gradientUnits="objectBoundingBox" x1="0" y1="0" x2="0" y2="1" id="gradient5">
|
||||
<stop offset="0" stop-color="#ebfdff" stop-opacity="1" />
|
||||
<stop offset="1" stop-color="#bfe4e8" stop-opacity="1" />
|
||||
</linearGradient>
|
||||
<linearGradient gradientUnits="objectBoundingBox" x1="0" y1="0" x2="0" y2="1" id="gradient6">
|
||||
<stop offset="0" stop-color="#ebfdff" stop-opacity="1" />
|
||||
<stop offset="1" stop-color="#bfe4e8" stop-opacity="1" />
|
||||
</linearGradient>
|
||||
<linearGradient gradientUnits="objectBoundingBox" x1="0" y1="0" x2="0" y2="1" id="gradient7">
|
||||
<stop offset="0" stop-color="#ffecd4" stop-opacity="1" />
|
||||
<stop offset="1" stop-color="#e8cdaa" stop-opacity="1" />
|
||||
</linearGradient>
|
||||
<linearGradient gradientUnits="objectBoundingBox" x1="0" y1="0" x2="0" y2="1" id="gradient8">
|
||||
<stop offset="0" stop-color="#f9eaff" stop-opacity="1" />
|
||||
<stop offset="1" stop-color="#cec1d3" stop-opacity="1" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<g fill="none" stroke="black" stroke-width="1" fill-rule="evenodd" stroke-linecap="square" stroke-linejoin="bevel" >
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(1,0,0,1,0,0)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(1,0,0,1,0,0)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(0.969231,0,0,0.969231,-53.1538,-112.277)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
</g>
|
||||
|
||||
<g fill="#ffffff" fill-opacity="1" stroke="none" transform="matrix(0.969231,0,0,0.969231,-53.1538,-112.277)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
<rect x="60" y="121" width="620" height="325"/>
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(0.969231,0,0,0.969231,-53.1538,-112.277)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(0.969231,0,0,0.969231,513.846,197.877)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(0.969231,0,0,0.969231,513.846,197.877)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(0.969231,0,0,0.969231,421.769,100.954)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
</g>
|
||||
|
||||
<g fill="url(#gradient1)" stroke="#5d979d" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(0.969231,0,0,0.969231,421.769,100.954)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
<rect x="0" y="0" width="190" height="200"/>
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(0.969231,0,0,0.969231,421.769,100.954)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(0.969231,0,0,0.969231,421.769,100.954)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(0.969231,0,0,0.969231,469.027,298.677)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(0.969231,0,0,0.969231,469.027,298.677)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(0.969231,0,0,0.969231,469.027,298.677)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
<text fill="#000000" fill-opacity="1" stroke="none" xml:space="preserve" x="4" y="15" font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>Storage Location</text>
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(0.969231,0,0,0.969231,469.027,298.677)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(1,0,0,1,0,0)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(0.969231,0,0,0.969231,469.027,298.677)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(0.969231,0,0,0.969231,469.027,298.677)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(0.969231,0,0,0.969231,469.027,298.677)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(0.969231,0,0,0.969231,460.538,144.569)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(0.969231,0,0,0.969231,460.538,144.569)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(0.969231,0,0,0.969231,441.154,115.492)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
</g>
|
||||
|
||||
<g fill="url(#gradient2)" stroke="#5d979d" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(0.969231,0,0,0.969231,441.154,115.492)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
<path vector-effect="none" fill-rule="evenodd" d="M0,0 L24,0 L40,16 L40,60 L0,60 L0,0"/>
|
||||
<polyline fill="none" vector-effect="none" points="24,0 24,16 " />
|
||||
<polyline fill="none" vector-effect="none" points="24,16 40,16 " />
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(0.969231,0,0,0.969231,441.154,115.492)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(0.969231,0,0,0.969231,441.154,115.492)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(0.969231,0,0,0.969231,436.391,177.523)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(0.969231,0,0,0.969231,436.391,177.523)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(0.969231,0,0,0.969231,436.391,177.523)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
<text fill="#000000" fill-opacity="1" stroke="none" xml:space="preserve" x="4" y="15" font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>KeyData</text>
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(0.969231,0,0,0.969231,436.391,177.523)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(1,0,0,1,0,0)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(0.969231,0,0,0.969231,436.391,177.523)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(0.969231,0,0,0.969231,436.391,177.523)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(0.969231,0,0,0.969231,436.391,177.523)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(0.969231,0,0,0.969231,562.308,144.569)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(0.969231,0,0,0.969231,562.308,144.569)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(0.969231,0,0,0.969231,542.923,115.492)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
</g>
|
||||
|
||||
<g fill="url(#gradient3)" stroke="#5d979d" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(0.969231,0,0,0.969231,542.923,115.492)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
<path vector-effect="none" fill-rule="evenodd" d="M0,0 L24,0 L40,16 L40,60 L0,60 L0,0"/>
|
||||
<polyline fill="none" vector-effect="none" points="24,0 24,16 " />
|
||||
<polyline fill="none" vector-effect="none" points="24,16 40,16 " />
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(0.969231,0,0,0.969231,542.923,115.492)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(0.969231,0,0,0.969231,542.923,115.492)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(0.969231,0,0,0.969231,535.154,177.523)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(0.969231,0,0,0.969231,535.154,177.523)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(0.969231,0,0,0.969231,535.154,177.523)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
<text fill="#000000" fill-opacity="1" stroke="none" xml:space="preserve" x="4" y="15" font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>KeyData2</text>
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(0.969231,0,0,0.969231,535.154,177.523)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(1,0,0,1,0,0)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(0.969231,0,0,0.969231,535.154,177.523)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(0.969231,0,0,0.969231,535.154,177.523)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(0.969231,0,0,0.969231,535.154,177.523)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(0.969231,0,0,0.969231,460.538,231.8)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(0.969231,0,0,0.969231,460.538,231.8)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(0.969231,0,0,0.969231,441.154,202.723)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
</g>
|
||||
|
||||
<g fill="url(#gradient4)" stroke="#5d979d" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(0.969231,0,0,0.969231,441.154,202.723)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
<path vector-effect="none" fill-rule="evenodd" d="M0,0 L24,0 L40,16 L40,60 L0,60 L0,0"/>
|
||||
<polyline fill="none" vector-effect="none" points="24,0 24,16 " />
|
||||
<polyline fill="none" vector-effect="none" points="24,16 40,16 " />
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(0.969231,0,0,0.969231,441.154,202.723)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(0.969231,0,0,0.969231,441.154,202.723)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(0.969231,0,0,0.969231,433.385,264.754)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(0.969231,0,0,0.969231,433.385,264.754)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(0.969231,0,0,0.969231,433.385,264.754)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
<text fill="#000000" fill-opacity="1" stroke="none" xml:space="preserve" x="4" y="15" font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>KeyData3</text>
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(0.969231,0,0,0.969231,433.385,264.754)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(1,0,0,1,0,0)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(0.969231,0,0,0.969231,433.385,264.754)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(0.969231,0,0,0.969231,433.385,264.754)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(0.969231,0,0,0.969231,433.385,264.754)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(0.969231,0,0,0.969231,562.308,231.8)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(0.969231,0,0,0.969231,562.308,231.8)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(0.969231,0,0,0.969231,542.923,202.723)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
</g>
|
||||
|
||||
<g fill="url(#gradient5)" stroke="#5d979d" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(0.969231,0,0,0.969231,542.923,202.723)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
<path vector-effect="none" fill-rule="evenodd" d="M0,0 L24,0 L40,16 L40,60 L0,60 L0,0"/>
|
||||
<polyline fill="none" vector-effect="none" points="24,0 24,16 " />
|
||||
<polyline fill="none" vector-effect="none" points="24,16 40,16 " />
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(0.969231,0,0,0.969231,542.923,202.723)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(0.969231,0,0,0.969231,542.923,202.723)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(0.969231,0,0,0.969231,535.154,264.754)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(0.969231,0,0,0.969231,535.154,264.754)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(0.969231,0,0,0.969231,535.154,264.754)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
<text fill="#000000" fill-opacity="1" stroke="none" xml:space="preserve" x="4" y="15" font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>KeyData3</text>
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(0.969231,0,0,0.969231,535.154,264.754)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(1,0,0,1,0,0)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(0.969231,0,0,0.969231,535.154,264.754)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(0.969231,0,0,0.969231,535.154,264.754)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(0.969231,0,0,0.969231,535.154,264.754)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(0.969231,0,0,0.969231,174.615,168.8)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(0.969231,0,0,0.969231,174.615,168.8)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(0.969231,0,0,0.969231,5,42.8)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
</g>
|
||||
|
||||
<g fill="url(#gradient6)" stroke="#5d979d" stroke-opacity="1" stroke-width="2" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(0.969231,0,0,0.969231,5,42.8)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
<path vector-effect="none" fill-rule="evenodd" d="M0,0 L52.5,-39 L402.5,-39 L402.5,221 L350,260 L0,260 L0,0"/>
|
||||
<polyline fill="none" vector-effect="none" points="0,0 350,0 " />
|
||||
<polyline fill="none" vector-effect="none" points="350,0 402.5,-39 " />
|
||||
<polyline fill="none" vector-effect="none" points="350,0 350,260 " />
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(0.969231,0,0,0.969231,5,42.8)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(0.969231,0,0,0.969231,5,42.8)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(0.969231,0,0,0.969231,115.5,46.6769)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(0.969231,0,0,0.969231,115.5,46.6769)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(0.969231,0,0,0.969231,115.5,46.6769)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
<text fill="#000000" fill-opacity="1" stroke="none" xml:space="preserve" x="19.3594" y="15" font-family="Ubuntu" font-size="11" font-weight="700" font-style="normal"
|
||||
>Node (Server or</text>
|
||||
<text fill="#000000" fill-opacity="1" stroke="none" xml:space="preserve" x="43.2656" y="28" font-family="Ubuntu" font-size="11" font-weight="700" font-style="normal"
|
||||
>Client)</text>
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(0.969231,0,0,0.969231,115.5,46.6769)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(1,0,0,1,0,0)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(0.969231,0,0,0.969231,115.5,46.6769)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(0.969231,0,0,0.969231,115.5,46.6769)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(0.969231,0,0,0.969231,115.5,46.6769)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(0.969231,0,0,0.969231,174.615,178.492)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(0.969231,0,0,0.969231,174.615,178.492)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(0.969231,0,0,0.969231,174.615,178.492)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
</g>
|
||||
|
||||
<g fill="url(#gradient7)" stroke="#ac7e42" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(0.969231,0,0,0.969231,174.615,178.492)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
<rect x="-155" y="-95" width="310" height="190"/>
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(0.969231,0,0,0.969231,174.615,178.492)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(0.969231,0,0,0.969231,174.615,132.938)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#ac7e42" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(0.969231,0,0,0.969231,174.615,132.938)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
<polyline fill="none" vector-effect="none" points="-155,4 155,4 " />
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(0.969231,0,0,0.969231,174.615,132.938)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(0.969231,0,0,0.969231,174.615,140.692)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#ac7e42" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(0.969231,0,0,0.969231,174.615,140.692)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
<polyline fill="none" vector-effect="none" points="-155,4 155,4 " />
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(0.969231,0,0,0.969231,174.615,140.692)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(0.969231,0,0,0.969231,168.149,90.2923)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(0.969231,0,0,0.969231,168.149,90.2923)"
|
||||
font-family="Ubuntu" font-size="9" font-weight="400" font-style="normal"
|
||||
>
|
||||
<text fill="#000000" fill-opacity="1" stroke="none" xml:space="preserve" x="0" y="9" font-family="Ubuntu" font-size="9" font-weight="400" font-style="normal"
|
||||
>QH</text>
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(0.969231,0,0,0.969231,168.149,90.2923)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(0.969231,0,0,0.969231,142.964,100.954)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(0.969231,0,0,0.969231,142.964,100.954)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(0.969231,0,0,0.969231,142.964,100.954)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
<text fill="#000000" fill-opacity="1" stroke="none" xml:space="preserve" x="4" y="15" font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>KeyStorage</text>
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(0.969231,0,0,0.969231,142.964,100.954)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(1,0,0,1,0,0)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(0.969231,0,0,0.969231,142.964,100.954)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(0.969231,0,0,0.969231,142.964,100.954)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(0.969231,0,0,0.969231,142.964,100.954)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(0.969231,0,0,0.969231,132.643,122.277)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(0.969231,0,0,0.969231,132.643,122.277)"
|
||||
font-family="Ubuntu" font-size="9" font-weight="400" font-style="normal"
|
||||
>
|
||||
<text fill="#000000" fill-opacity="1" stroke="none" xml:space="preserve" x="0" y="9" font-family="Ubuntu" font-size="9" font-weight="400" font-style="normal"
|
||||
>(from AbstractSpace)</text>
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(0.969231,0,0,0.969231,132.643,122.277)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(0.969231,0,0,0.969231,174.615,197.877)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(0.969231,0,0,0.969231,174.615,197.877)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(0.969231,0,0,0.969231,174.615,197.877)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
</g>
|
||||
|
||||
<g fill="url(#gradient8)" stroke="#7e6687" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(0.969231,0,0,0.969231,174.615,197.877)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
<rect x="-140" y="-50" width="280" height="100"/>
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(0.969231,0,0,0.969231,174.615,197.877)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(0.969231,0,0,0.969231,118.029,153.292)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(0.969231,0,0,0.969231,118.029,153.292)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(0.969231,0,0,0.969231,118.029,153.292)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
<text fill="#000000" fill-opacity="1" stroke="none" xml:space="preserve" x="4" y="15" font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>ReadAllData methods</text>
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(0.969231,0,0,0.969231,118.029,153.292)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(1,0,0,1,0,0)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(0.969231,0,0,0.969231,118.029,153.292)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(0.969231,0,0,0.969231,118.029,153.292)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(0.969231,0,0,0.969231,118.029,153.292)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(0.969231,0,0,0.969231,132.643,174.615)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(0.969231,0,0,0.969231,132.643,174.615)"
|
||||
font-family="Ubuntu" font-size="9" font-weight="400" font-style="normal"
|
||||
>
|
||||
<text fill="#000000" fill-opacity="1" stroke="none" xml:space="preserve" x="0" y="9" font-family="Ubuntu" font-size="9" font-weight="400" font-style="normal"
|
||||
>(from AbstractSpace)</text>
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(0.969231,0,0,0.969231,132.643,174.615)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(0.969231,0,0,0.969231,310.308,197.877)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(0.969231,0,0,0.969231,310.308,197.877)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(0.969231,0,0,0.969231,310.308,197.877)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(0.969231,0,0,0.969231,310.308,197.877)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(0.969231,0,0,0.969231,310.308,197.877)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-dasharray="4,4" stroke-dashoffset="0" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(0.969231,0,0,0.969231,310.308,197.877)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
<path vector-effect="none" fill-rule="evenodd" d="M10.3923,0 L104.608,0"/>
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(0.969231,0,0,0.969231,310.308,197.877)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(0.969231,0,0,0.969231,421.769,197.877)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(0.969231,0,0,0.969231,421.769,197.877)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(0.969231,0,0,0.969231,421.769,197.877)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
<path vector-effect="none" fill-rule="evenodd" d="M-10.3923,-6 L0,0 L-10.3923,6"/>
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(0.969231,0,0,0.969231,421.769,197.877)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(-0.969231,8.70301e-11,-8.70301e-11,-0.969231,310.308,197.877)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(-0.969231,8.70301e-11,-8.70301e-11,-0.969231,310.308,197.877)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(-0.969231,8.70301e-11,-8.70301e-11,-0.969231,310.308,197.877)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
<path vector-effect="none" fill-rule="evenodd" d="M-10.3923,-6 L0,0 L-10.3923,6"/>
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(-0.969231,8.70301e-11,-8.70301e-11,-0.969231,310.308,197.877)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(0.969231,0,0,0.969231,42.8,178.492)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(0.969231,0,0,0.969231,42.8,178.492)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(0.969231,0,0,0.969231,46.6769,182.369)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(0.969231,0,0,0.969231,46.6769,182.369)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(0.969231,0,0,0.969231,46.6769,182.369)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
<text fill="#000000" fill-opacity="1" stroke="none" xml:space="preserve" x="4" y="15" font-family="Ubuntu" font-size="11" font-weight="700" font-style="normal"
|
||||
>This method read all files from storage</text>
|
||||
<text fill="#000000" fill-opacity="1" stroke="none" xml:space="preserve" x="4" y="28" font-family="Ubuntu" font-size="11" font-weight="700" font-style="normal"
|
||||
>locations. </text>
|
||||
<text fill="#000000" fill-opacity="1" stroke="none" xml:space="preserve" x="4" y="42" font-family="Ubuntu" font-size="11" font-weight="700" font-style="normal"
|
||||
>Where a name of file it is key of DataKey.</text>
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(0.969231,0,0,0.969231,46.6769,182.369)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(1,0,0,1,0,0)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(0.969231,0,0,0.969231,46.6769,182.369)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(0.969231,0,0,0.969231,46.6769,182.369)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(0.969231,0,0,0.969231,46.6769,182.369)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(1,0,0,1,0,0)"
|
||||
font-family="Ubuntu" font-size="11" font-weight="400" font-style="normal"
|
||||
>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
Before (image error) Size: 46 KiB |
@ -1,544 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<qmt>
|
||||
<project>
|
||||
<uid>{578fb64c-d647-45d7-9413-1a54b354db2b}</uid>
|
||||
<root-package>
|
||||
<instance>
|
||||
<MPackage>
|
||||
<base-MObject>
|
||||
<MObject>
|
||||
<base-MElement>
|
||||
<MElement>
|
||||
<uid>{3cc6cd6f-0ce7-43b5-8a8c-1962b0207c79}</uid>
|
||||
</MElement>
|
||||
</base-MElement>
|
||||
<name>KeyStorageImplementation</name>
|
||||
<children>
|
||||
<handles>
|
||||
<handles>
|
||||
<qlist>
|
||||
<item>
|
||||
<handle>
|
||||
<uid>{1ee7a90d-8a76-4fbd-9bd2-ef7a78f293e9}</uid>
|
||||
<target>
|
||||
<instance type="MCanvasDiagram">
|
||||
<MCanvasDiagram>
|
||||
<base-MDiagram>
|
||||
<MDiagram>
|
||||
<base-MObject>
|
||||
<MObject>
|
||||
<base-MElement>
|
||||
<MElement>
|
||||
<uid>{1ee7a90d-8a76-4fbd-9bd2-ef7a78f293e9}</uid>
|
||||
</MElement>
|
||||
</base-MElement>
|
||||
<name>KeyStorageImplementation</name>
|
||||
</MObject>
|
||||
</base-MObject>
|
||||
<elements>
|
||||
<qlist>
|
||||
<item>
|
||||
<instance type="DItem">
|
||||
<DItem>
|
||||
<base-DObject>
|
||||
<DObject>
|
||||
<base-DElement>
|
||||
<DElement>
|
||||
<uid>{73bb3bc5-3604-4108-9eb9-6322ee2c03a6}</uid>
|
||||
</DElement>
|
||||
</base-DElement>
|
||||
<object>{5bf04cca-9103-4df5-a5a6-42ca6a7478cd}</object>
|
||||
<name>Storage Location</name>
|
||||
<pos>x:585;y:320</pos>
|
||||
<rect>x:-95;y:-100;w:190;h:200</rect>
|
||||
<auto-sized>false</auto-sized>
|
||||
<visual-role>0</visual-role>
|
||||
</DObject>
|
||||
</base-DObject>
|
||||
<variety>artifact</variety>
|
||||
<shape-editable>false</shape-editable>
|
||||
</DItem>
|
||||
</instance>
|
||||
</item>
|
||||
<item>
|
||||
<instance type="DItem">
|
||||
<DItem>
|
||||
<base-DObject>
|
||||
<DObject>
|
||||
<base-DElement>
|
||||
<DElement>
|
||||
<uid>{63906c75-b844-49ff-a2d7-003d91396628}</uid>
|
||||
</DElement>
|
||||
</base-DElement>
|
||||
<object>{54a04999-4d1f-474d-b713-b41960caad2f}</object>
|
||||
<name>KeyData</name>
|
||||
<pos>x:530;y:265</pos>
|
||||
<rect>x:-20;y:-30;w:40;h:60</rect>
|
||||
<visual-role>0</visual-role>
|
||||
</DObject>
|
||||
</base-DObject>
|
||||
<variety>document</variety>
|
||||
<shape-editable>false</shape-editable>
|
||||
</DItem>
|
||||
</instance>
|
||||
</item>
|
||||
<item>
|
||||
<instance type="DItem">
|
||||
<DItem>
|
||||
<base-DObject>
|
||||
<DObject>
|
||||
<base-DElement>
|
||||
<DElement>
|
||||
<uid>{4ba1d96e-4bb2-490f-9a2c-30f37cab8090}</uid>
|
||||
</DElement>
|
||||
</base-DElement>
|
||||
<object>{7bf70bc2-48c6-4a73-8c37-c4d74c2a471c}</object>
|
||||
<name>KeyData2</name>
|
||||
<pos>x:635;y:265</pos>
|
||||
<rect>x:-20;y:-30;w:40;h:60</rect>
|
||||
<visual-role>0</visual-role>
|
||||
</DObject>
|
||||
</base-DObject>
|
||||
<variety>document</variety>
|
||||
<shape-editable>false</shape-editable>
|
||||
</DItem>
|
||||
</instance>
|
||||
</item>
|
||||
<item>
|
||||
<instance type="DItem">
|
||||
<DItem>
|
||||
<base-DObject>
|
||||
<DObject>
|
||||
<base-DElement>
|
||||
<DElement>
|
||||
<uid>{f3c8b82c-2d10-4aab-bf2d-f0a773b1a214}</uid>
|
||||
</DElement>
|
||||
</base-DElement>
|
||||
<object>{272fa499-b8f6-4b5f-a65d-52e94fd19e75}</object>
|
||||
<name>KeyData3</name>
|
||||
<pos>x:530;y:355</pos>
|
||||
<rect>x:-20;y:-30;w:40;h:60</rect>
|
||||
<visual-role>0</visual-role>
|
||||
</DObject>
|
||||
</base-DObject>
|
||||
<variety>document</variety>
|
||||
<shape-editable>false</shape-editable>
|
||||
</DItem>
|
||||
</instance>
|
||||
</item>
|
||||
<item>
|
||||
<instance type="DItem">
|
||||
<DItem>
|
||||
<base-DObject>
|
||||
<DObject>
|
||||
<base-DElement>
|
||||
<DElement>
|
||||
<uid>{0a31881d-976f-49b4-84bc-6e829fde7524}</uid>
|
||||
</DElement>
|
||||
</base-DElement>
|
||||
<object>{41a62eef-b99a-4292-9a5e-6877f3822d74}</object>
|
||||
<name>KeyData3</name>
|
||||
<pos>x:635;y:355</pos>
|
||||
<rect>x:-20;y:-30;w:40;h:60</rect>
|
||||
<visual-role>0</visual-role>
|
||||
</DObject>
|
||||
</base-DObject>
|
||||
<variety>document</variety>
|
||||
<shape-editable>false</shape-editable>
|
||||
</DItem>
|
||||
</instance>
|
||||
</item>
|
||||
<item>
|
||||
<instance type="DItem">
|
||||
<DItem>
|
||||
<base-DObject>
|
||||
<DObject>
|
||||
<base-DElement>
|
||||
<DElement>
|
||||
<uid>{90e23bca-830b-4f04-9b79-d2b76aa7a942}</uid>
|
||||
</DElement>
|
||||
</base-DElement>
|
||||
<object>{2ccda0b5-00de-4d4c-b365-e045dc6f6f31}</object>
|
||||
<name>Node (Server or Client)</name>
|
||||
<pos>x:235;y:290</pos>
|
||||
<rect>x:-175;y:-130;w:350;h:260</rect>
|
||||
<auto-sized>false</auto-sized>
|
||||
<visual-role>0</visual-role>
|
||||
<visual-emphasized>true</visual-emphasized>
|
||||
</DObject>
|
||||
</base-DObject>
|
||||
<variety>node</variety>
|
||||
<shape-editable>false</shape-editable>
|
||||
</DItem>
|
||||
</instance>
|
||||
</item>
|
||||
<item>
|
||||
<instance type="DClass">
|
||||
<DClass>
|
||||
<base-DObject>
|
||||
<DObject>
|
||||
<base-DElement>
|
||||
<DElement>
|
||||
<uid>{32b0ae69-b40c-426c-aaa8-34d737714611}</uid>
|
||||
</DElement>
|
||||
</base-DElement>
|
||||
<object>{962cbac6-7959-42e9-acd3-f26976cbe484}</object>
|
||||
<context>AbstractSpace</context>
|
||||
<name>KeyStorage</name>
|
||||
<pos>x:235;y:300</pos>
|
||||
<rect>x:-155;y:-95;w:310;h:190</rect>
|
||||
<auto-sized>false</auto-sized>
|
||||
<visual-role>0</visual-role>
|
||||
</DObject>
|
||||
</base-DObject>
|
||||
<namespace>QH</namespace>
|
||||
</DClass>
|
||||
</instance>
|
||||
</item>
|
||||
<item>
|
||||
<instance type="DDependency">
|
||||
<DDependency>
|
||||
<base-DRelation>
|
||||
<DRelation>
|
||||
<base-DElement>
|
||||
<DElement>
|
||||
<uid>{18d07b5f-7a24-4007-811a-800f28514869}</uid>
|
||||
</DElement>
|
||||
</base-DElement>
|
||||
<object>{58bd3970-0d20-48e4-ad00-e9b89ee16e8e}</object>
|
||||
<a>{b11fad66-7c15-4a0c-90d7-fdb7c7b09d54}</a>
|
||||
<b>{73bb3bc5-3604-4108-9eb9-6322ee2c03a6}</b>
|
||||
</DRelation>
|
||||
</base-DRelation>
|
||||
<direction>2</direction>
|
||||
</DDependency>
|
||||
</instance>
|
||||
</item>
|
||||
<item>
|
||||
<instance type="DItem">
|
||||
<DItem>
|
||||
<base-DObject>
|
||||
<DObject>
|
||||
<base-DElement>
|
||||
<DElement>
|
||||
<uid>{b11fad66-7c15-4a0c-90d7-fdb7c7b09d54}</uid>
|
||||
</DElement>
|
||||
</base-DElement>
|
||||
<object>{7c08d894-d147-4b48-8829-6f3a50c45cd0}</object>
|
||||
<context>AbstractSpace</context>
|
||||
<name>ReadAllData methods</name>
|
||||
<pos>x:235;y:320</pos>
|
||||
<rect>x:-140;y:-50;w:280;h:100</rect>
|
||||
<auto-sized>false</auto-sized>
|
||||
<visual-role>0</visual-role>
|
||||
</DObject>
|
||||
</base-DObject>
|
||||
<shape-editable>false</shape-editable>
|
||||
</DItem>
|
||||
</instance>
|
||||
</item>
|
||||
<item>
|
||||
<instance type="DAnnotation">
|
||||
<DAnnotation>
|
||||
<base-DElement>
|
||||
<DElement>
|
||||
<uid>{ac8b121e-fdfc-41ae-bc0b-296e2658c1dc}</uid>
|
||||
</DElement>
|
||||
</base-DElement>
|
||||
<text>This method read all files from storage locations.
|
||||
Where a name of file it is key of DataKey.</text>
|
||||
<pos>x:99;y:300</pos>
|
||||
<rect>x:0;y:0;w:270.125;h:57</rect>
|
||||
<auto-sized>false</auto-sized>
|
||||
<visual-role>3</visual-role>
|
||||
</DAnnotation>
|
||||
</instance>
|
||||
</item>
|
||||
</qlist>
|
||||
</elements>
|
||||
<last-modified>1600928388806</last-modified>
|
||||
<toolbarid>General</toolbarid>
|
||||
</MDiagram>
|
||||
</base-MDiagram>
|
||||
</MCanvasDiagram>
|
||||
</instance>
|
||||
</target>
|
||||
</handle>
|
||||
</item>
|
||||
<item>
|
||||
<handle>
|
||||
<uid>{5bf04cca-9103-4df5-a5a6-42ca6a7478cd}</uid>
|
||||
<target>
|
||||
<instance type="MItem">
|
||||
<MItem>
|
||||
<base-MObject>
|
||||
<MObject>
|
||||
<base-MElement>
|
||||
<MElement>
|
||||
<uid>{5bf04cca-9103-4df5-a5a6-42ca6a7478cd}</uid>
|
||||
</MElement>
|
||||
</base-MElement>
|
||||
<name>Storage Location</name>
|
||||
</MObject>
|
||||
</base-MObject>
|
||||
<variety-editable>false</variety-editable>
|
||||
<variety>artifact</variety>
|
||||
</MItem>
|
||||
</instance>
|
||||
</target>
|
||||
</handle>
|
||||
</item>
|
||||
<item>
|
||||
<handle>
|
||||
<uid>{b4753b9b-bb59-4797-8201-0e7f6cc3a09f}</uid>
|
||||
<target>
|
||||
<instance type="MItem">
|
||||
<MItem>
|
||||
<base-MObject>
|
||||
<MObject>
|
||||
<base-MElement>
|
||||
<MElement>
|
||||
<uid>{b4753b9b-bb59-4797-8201-0e7f6cc3a09f}</uid>
|
||||
</MElement>
|
||||
</base-MElement>
|
||||
<name>Новый Document</name>
|
||||
</MObject>
|
||||
</base-MObject>
|
||||
<variety-editable>false</variety-editable>
|
||||
<variety>document</variety>
|
||||
</MItem>
|
||||
</instance>
|
||||
</target>
|
||||
</handle>
|
||||
</item>
|
||||
<item>
|
||||
<handle>
|
||||
<uid>{54a04999-4d1f-474d-b713-b41960caad2f}</uid>
|
||||
<target>
|
||||
<instance type="MItem">
|
||||
<MItem>
|
||||
<base-MObject>
|
||||
<MObject>
|
||||
<base-MElement>
|
||||
<MElement>
|
||||
<uid>{54a04999-4d1f-474d-b713-b41960caad2f}</uid>
|
||||
</MElement>
|
||||
</base-MElement>
|
||||
<name>KeyData</name>
|
||||
</MObject>
|
||||
</base-MObject>
|
||||
<variety-editable>false</variety-editable>
|
||||
<variety>document</variety>
|
||||
</MItem>
|
||||
</instance>
|
||||
</target>
|
||||
</handle>
|
||||
</item>
|
||||
<item>
|
||||
<handle>
|
||||
<uid>{7bf70bc2-48c6-4a73-8c37-c4d74c2a471c}</uid>
|
||||
<target>
|
||||
<instance type="MItem">
|
||||
<MItem>
|
||||
<base-MObject>
|
||||
<MObject>
|
||||
<base-MElement>
|
||||
<MElement>
|
||||
<uid>{7bf70bc2-48c6-4a73-8c37-c4d74c2a471c}</uid>
|
||||
</MElement>
|
||||
</base-MElement>
|
||||
<name>KeyData2</name>
|
||||
</MObject>
|
||||
</base-MObject>
|
||||
<variety-editable>false</variety-editable>
|
||||
<variety>document</variety>
|
||||
</MItem>
|
||||
</instance>
|
||||
</target>
|
||||
</handle>
|
||||
</item>
|
||||
<item>
|
||||
<handle>
|
||||
<uid>{272fa499-b8f6-4b5f-a65d-52e94fd19e75}</uid>
|
||||
<target>
|
||||
<instance type="MItem">
|
||||
<MItem>
|
||||
<base-MObject>
|
||||
<MObject>
|
||||
<base-MElement>
|
||||
<MElement>
|
||||
<uid>{272fa499-b8f6-4b5f-a65d-52e94fd19e75}</uid>
|
||||
</MElement>
|
||||
</base-MElement>
|
||||
<name>KeyData3</name>
|
||||
</MObject>
|
||||
</base-MObject>
|
||||
<variety-editable>false</variety-editable>
|
||||
<variety>document</variety>
|
||||
</MItem>
|
||||
</instance>
|
||||
</target>
|
||||
</handle>
|
||||
</item>
|
||||
<item>
|
||||
<handle>
|
||||
<uid>{41a62eef-b99a-4292-9a5e-6877f3822d74}</uid>
|
||||
<target>
|
||||
<instance type="MItem">
|
||||
<MItem>
|
||||
<base-MObject>
|
||||
<MObject>
|
||||
<base-MElement>
|
||||
<MElement>
|
||||
<uid>{41a62eef-b99a-4292-9a5e-6877f3822d74}</uid>
|
||||
</MElement>
|
||||
</base-MElement>
|
||||
<name>KeyData3</name>
|
||||
</MObject>
|
||||
</base-MObject>
|
||||
<variety-editable>false</variety-editable>
|
||||
<variety>document</variety>
|
||||
</MItem>
|
||||
</instance>
|
||||
</target>
|
||||
</handle>
|
||||
</item>
|
||||
<item>
|
||||
<handle>
|
||||
<uid>{2ccda0b5-00de-4d4c-b365-e045dc6f6f31}</uid>
|
||||
<target>
|
||||
<instance type="MItem">
|
||||
<MItem>
|
||||
<base-MObject>
|
||||
<MObject>
|
||||
<base-MElement>
|
||||
<MElement>
|
||||
<uid>{2ccda0b5-00de-4d4c-b365-e045dc6f6f31}</uid>
|
||||
</MElement>
|
||||
</base-MElement>
|
||||
<name>Node (Server or Client)</name>
|
||||
</MObject>
|
||||
</base-MObject>
|
||||
<variety-editable>false</variety-editable>
|
||||
<variety>node</variety>
|
||||
</MItem>
|
||||
</instance>
|
||||
</target>
|
||||
</handle>
|
||||
</item>
|
||||
<item>
|
||||
<handle>
|
||||
<uid>{d472d214-54c2-4045-b825-9a2ab109d69f}</uid>
|
||||
<target>
|
||||
<instance type="MPackage">
|
||||
<MPackage>
|
||||
<base-MObject>
|
||||
<MObject>
|
||||
<base-MElement>
|
||||
<MElement>
|
||||
<uid>{d472d214-54c2-4045-b825-9a2ab109d69f}</uid>
|
||||
<flags>1</flags>
|
||||
</MElement>
|
||||
</base-MElement>
|
||||
<name>AbstractSpace</name>
|
||||
<children>
|
||||
<handles>
|
||||
<handles>
|
||||
<qlist>
|
||||
<item>
|
||||
<handle>
|
||||
<uid>{962cbac6-7959-42e9-acd3-f26976cbe484}</uid>
|
||||
<target>
|
||||
<instance type="MClass">
|
||||
<MClass>
|
||||
<base-MObject>
|
||||
<MObject>
|
||||
<base-MElement>
|
||||
<MElement>
|
||||
<uid>{962cbac6-7959-42e9-acd3-f26976cbe484}</uid>
|
||||
<flags>1</flags>
|
||||
</MElement>
|
||||
</base-MElement>
|
||||
<name>KeyStorage</name>
|
||||
</MObject>
|
||||
</base-MObject>
|
||||
<namespace>QH</namespace>
|
||||
</MClass>
|
||||
</instance>
|
||||
</target>
|
||||
</handle>
|
||||
</item>
|
||||
<item>
|
||||
<handle>
|
||||
<uid>{7c08d894-d147-4b48-8829-6f3a50c45cd0}</uid>
|
||||
<target>
|
||||
<instance type="MItem">
|
||||
<MItem>
|
||||
<base-MObject>
|
||||
<MObject>
|
||||
<base-MElement>
|
||||
<MElement>
|
||||
<uid>{7c08d894-d147-4b48-8829-6f3a50c45cd0}</uid>
|
||||
</MElement>
|
||||
</base-MElement>
|
||||
<name>ReadAllData methods</name>
|
||||
<relations>
|
||||
<handles>
|
||||
<handles>
|
||||
<qlist>
|
||||
<item>
|
||||
<handle>
|
||||
<uid>{58bd3970-0d20-48e4-ad00-e9b89ee16e8e}</uid>
|
||||
<target>
|
||||
<instance type="MDependency">
|
||||
<MDependency>
|
||||
<base-MRelation>
|
||||
<MRelation>
|
||||
<base-MElement>
|
||||
<MElement>
|
||||
<uid>{58bd3970-0d20-48e4-ad00-e9b89ee16e8e}</uid>
|
||||
</MElement>
|
||||
</base-MElement>
|
||||
<a>{7c08d894-d147-4b48-8829-6f3a50c45cd0}</a>
|
||||
<b>{5bf04cca-9103-4df5-a5a6-42ca6a7478cd}</b>
|
||||
</MRelation>
|
||||
</base-MRelation>
|
||||
<direction>2</direction>
|
||||
</MDependency>
|
||||
</instance>
|
||||
</target>
|
||||
</handle>
|
||||
</item>
|
||||
</qlist>
|
||||
</handles>
|
||||
</handles>
|
||||
</relations>
|
||||
</MObject>
|
||||
</base-MObject>
|
||||
</MItem>
|
||||
</instance>
|
||||
</target>
|
||||
</handle>
|
||||
</item>
|
||||
</qlist>
|
||||
</handles>
|
||||
</handles>
|
||||
</children>
|
||||
</MObject>
|
||||
</base-MObject>
|
||||
</MPackage>
|
||||
</instance>
|
||||
</target>
|
||||
</handle>
|
||||
</item>
|
||||
</qlist>
|
||||
</handles>
|
||||
</handles>
|
||||
</children>
|
||||
</MObject>
|
||||
</base-MObject>
|
||||
</MPackage>
|
||||
</instance>
|
||||
</root-package>
|
||||
</project>
|
||||
</qmt>
|
@ -316,6 +316,29 @@ bool AbstractNode::generateRSAforSSL(EVP_PKEY *pkey) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
//#if OPENSSL_VERSION_MAJOR >= 3
|
||||
|
||||
// EVP_PKEY_CTX *pctx =
|
||||
// EVP_PKEY_CTX_new_from_name(NULL, "RSA", NULL);
|
||||
|
||||
// unsigned int primes = 3;
|
||||
// unsigned int bits = 4096;
|
||||
// OSSL_PARAM params[3];
|
||||
|
||||
// pkey = EVP_RSA_gen(4096);
|
||||
|
||||
// EVP_PKEY_keygen_init(pctx);
|
||||
|
||||
// params[0] = OSSL_PARAM_construct_uint("bits", &bits);
|
||||
// params[1] = OSSL_PARAM_construct_uint("primes", &primes);
|
||||
// params[2] = OSSL_PARAM_construct_end();
|
||||
// EVP_PKEY_CTX_set_params(pctx, params);
|
||||
|
||||
|
||||
// EVP_PKEY_generate(pctx, &pkey);
|
||||
// EVP_PKEY_CTX_free(pctx);
|
||||
|
||||
//#else
|
||||
BIGNUM * bn = BN_new();
|
||||
|
||||
int rc = BN_set_word(bn, RSA_F4);
|
||||
@ -334,7 +357,7 @@ bool AbstractNode::generateRSAforSSL(EVP_PKEY *pkey) const {
|
||||
q_check_ptr(rsa);
|
||||
if (EVP_PKEY_assign_RSA(pkey, rsa) <= 0)
|
||||
return false;
|
||||
|
||||
//#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -884,9 +907,7 @@ bool AbstractNode::ping(const HostAddress &address) {
|
||||
|
||||
}
|
||||
|
||||
bool AbstractNode::isBanned(QAbstractSocket *socket) const {
|
||||
auto info = getInfoPtr(HostAddress{socket->peerAddress(), socket->peerPort()});
|
||||
|
||||
bool AbstractNode::isBanned(const AbstractNodeInfo *info) const {
|
||||
if (!(info && info->isValid())) {
|
||||
return false;
|
||||
}
|
||||
@ -911,7 +932,7 @@ void AbstractNode::incomingConnection(qintptr handle) {
|
||||
|
||||
socket->setSocketDescriptor(handle);
|
||||
|
||||
if (isBanned(socket)) {
|
||||
if (isBanned(getInfoPtr(HostAddress{socket->peerAddress(), socket->peerPort()}))) {
|
||||
QuasarAppUtils::Params::log("Income connection from banned address",
|
||||
QuasarAppUtils::Error);
|
||||
|
||||
@ -1115,14 +1136,6 @@ QSharedPointer<AbstractData> AbstractNode::prepareData(const Package &pkg) const
|
||||
return value;
|
||||
}
|
||||
|
||||
QSharedPointer<AbstractData> AbstractNode::genPackage(unsigned short cmd) const {
|
||||
return QSharedPointer<AbstractData>(_registeredTypes.value(cmd, [](){return nullptr;})());
|
||||
}
|
||||
|
||||
bool AbstractNode::checkCommand(unsigned short cmd) const {
|
||||
return _registeredTypes.contains(cmd);
|
||||
}
|
||||
|
||||
QList<HostAddress> AbstractNode::connectionsList() const {
|
||||
QMutexLocker locer(&_connectionsMutex);
|
||||
|
||||
|
@ -27,8 +27,6 @@
|
||||
#include "abstractdata.h"
|
||||
#include "workstate.h"
|
||||
#include "package.h"
|
||||
#include "cryptopairkeys.h"
|
||||
#include "icrypto.h"
|
||||
#include "heart_global.h"
|
||||
#include "packagemanager.h"
|
||||
#include "abstracterrorcodes.h"
|
||||
@ -508,7 +506,7 @@ protected:
|
||||
* @param socket This is node info object for validation.
|
||||
* @return true if node is banned.
|
||||
*/
|
||||
bool isBanned(QAbstractSocket* socket) const;
|
||||
virtual bool isBanned(const AbstractNodeInfo *socket) const;
|
||||
|
||||
/**
|
||||
* @brief incomingConnection This is ovverided method of QTCPServer.
|
||||
@ -595,18 +593,6 @@ protected:
|
||||
*/
|
||||
virtual void nodeDisconnected(AbstractNodeInfo *node);
|
||||
|
||||
|
||||
template<class T>
|
||||
/**
|
||||
* @brief registerPackageType This method register package type T.
|
||||
* This is need to prepare pacakge for parsing in the parsePackage method.
|
||||
*/
|
||||
void registerPackageType() {
|
||||
_registeredTypes[T::command()] = [](){
|
||||
return new T();
|
||||
};
|
||||
};
|
||||
|
||||
void prepareForDelete() override;
|
||||
|
||||
/**
|
||||
@ -617,23 +603,6 @@ protected:
|
||||
*/
|
||||
QSharedPointer<PKG::AbstractData> prepareData(const Package& pkg) const;
|
||||
|
||||
/**
|
||||
* @brief genPackage This is factory method that generate data pacakge objects by command.
|
||||
* All object should be registered before using this method.
|
||||
* @param cmd This is command of pacakge see Header::command.
|
||||
* @return shared pointer to new data object.
|
||||
* @see AbstractNode::registerPackageType
|
||||
* @see Header::command
|
||||
*/
|
||||
QSharedPointer<PKG::AbstractData> genPackage(unsigned short cmd) const ;
|
||||
|
||||
/**
|
||||
* @brief checkCommand This method check command are if registered type or not.
|
||||
* @brief cmd This is command of a verifiable package.
|
||||
* @return True if the package is registered in a node.
|
||||
*/
|
||||
bool checkCommand(unsigned short cmd) const;
|
||||
|
||||
/**
|
||||
* @brief connectionsList This method return list of all node connections
|
||||
* @return list of node connections.
|
||||
@ -674,7 +643,7 @@ protected slots:
|
||||
* @param errorString This is string value of the error.
|
||||
* @note default implementation do nothing. Override this method if you want to handle nodes network errors.
|
||||
*/
|
||||
virtual void nodeErrorOccured(AbstractNodeInfo *nodeInfo,
|
||||
virtual void nodeErrorOccured(QH::AbstractNodeInfo *nodeInfo,
|
||||
QAbstractSocket::SocketError errorCode,
|
||||
QString errorString);
|
||||
|
||||
@ -686,12 +655,12 @@ protected slots:
|
||||
* Overrid this method for handle ssl errors on this node or server.
|
||||
* @param error This is error that occured..
|
||||
*/
|
||||
virtual void handleSslErrorOcurred(SslSocket *scket, const QSslError& error);
|
||||
virtual void handleSslErrorOcurred(QH::SslSocket *scket, const QSslError& error);
|
||||
#endif
|
||||
|
||||
private slots:
|
||||
|
||||
void avelableBytes(AbstractNodeInfo* sender);
|
||||
void avelableBytes(QH::AbstractNodeInfo* sender);
|
||||
|
||||
/**
|
||||
* @brief handleNodeStatusChanged This method invoked when status of peer node chganged.
|
||||
@ -699,7 +668,7 @@ private slots:
|
||||
* @param status This is new status of node.
|
||||
*
|
||||
*/
|
||||
void handleNodeStatusChanged(AbstractNodeInfo* node, NodeCoonectionStatus status);
|
||||
void handleNodeStatusChanged(QH::AbstractNodeInfo* node, QH::NodeCoonectionStatus status);
|
||||
|
||||
/**
|
||||
* @brief handleWorkerStoped
|
||||
@ -710,7 +679,7 @@ private slots:
|
||||
* @brief handleForceRemoveNode - force remove connection.
|
||||
* @param node
|
||||
*/
|
||||
void handleForceRemoveNode(HostAddress node);
|
||||
void handleForceRemoveNode(QH::HostAddress node);
|
||||
|
||||
/**
|
||||
* @brief handleBeginWork This method run task on new thread.
|
||||
@ -725,12 +694,12 @@ private slots:
|
||||
* Default implementation just pront error messages
|
||||
* @param errors This is errors list.
|
||||
*/
|
||||
void handleSslErrorOcurredPrivate(SslSocket *sender, const QList<QSslError> & errors);
|
||||
void handleSslErrorOcurredPrivate(QH::SslSocket *sender, const QList<QSslError> & errors);
|
||||
|
||||
/**
|
||||
* @brief handleEncrypted invoke when a ssl socket is encripted!
|
||||
*/
|
||||
void handleEncrypted(AbstractNodeInfo *node);
|
||||
void handleEncrypted(QH::AbstractNodeInfo *node);
|
||||
|
||||
#endif
|
||||
|
||||
@ -796,7 +765,6 @@ private:
|
||||
mutable QMutex _workersMutex;
|
||||
|
||||
QThreadPool *_threadPool = nullptr;
|
||||
QHash<unsigned short, std::function<PKG::AbstractData*()>> _registeredTypes;
|
||||
|
||||
friend class WebSocketController;
|
||||
friend class SocketFactory;
|
||||
|
@ -1,90 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2021-2022 QuasarApp.
|
||||
* Distributed under the lgplv3 software license, see the accompanying
|
||||
* Everyone is permitted to copy and distribute verbatim copies
|
||||
* of this license document, but changing it is not allowed.
|
||||
*/
|
||||
|
||||
#include "asynckeysauth.h"
|
||||
#include "QCryptographicHash"
|
||||
#include <QString>
|
||||
#include <time.h>
|
||||
|
||||
namespace QH {
|
||||
|
||||
AsyncKeysAuth::AsyncKeysAuth() {
|
||||
|
||||
}
|
||||
|
||||
bool AsyncKeysAuth::auth(int allowedTimeRangeSec, QString* userId) const {
|
||||
|
||||
int diff = time(0) - _unixTime;
|
||||
|
||||
if (diff < 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (diff >= allowedTimeRangeSec) {
|
||||
return false;
|
||||
}
|
||||
|
||||
QByteArray data = _publicKey;
|
||||
data.insert(0, reinterpret_cast<const char*>(&_unixTime),
|
||||
sizeof(_unixTime));
|
||||
|
||||
bool result = checkSign(data, _signature, _publicKey);
|
||||
|
||||
if (result && userId) {
|
||||
*userId = getUserId();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool AsyncKeysAuth::prepare() {
|
||||
_unixTime = time(0);
|
||||
|
||||
QByteArray data = _publicKey;
|
||||
data.insert(0, reinterpret_cast<const char*>(&_unixTime),
|
||||
sizeof(_unixTime));
|
||||
|
||||
setSignature(signMessage(data, getPrivateKey()));
|
||||
|
||||
return isValid();
|
||||
}
|
||||
|
||||
unsigned int AsyncKeysAuth::unixTime() const {
|
||||
return _unixTime;
|
||||
}
|
||||
|
||||
void AsyncKeysAuth::setUnixTime(unsigned int newUnixTime) {
|
||||
_unixTime = newUnixTime;
|
||||
}
|
||||
|
||||
const QByteArray &AsyncKeysAuth::signature() const {
|
||||
return _signature;
|
||||
}
|
||||
|
||||
const QByteArray &AsyncKeysAuth::publicKey() const {
|
||||
return _publicKey;
|
||||
}
|
||||
|
||||
void AsyncKeysAuth::setPublicKey(const QByteArray &newPublicKey) {
|
||||
_publicKey = newPublicKey;
|
||||
}
|
||||
|
||||
bool AsyncKeysAuth::isValid() const {
|
||||
return _publicKey.size() && _signature.size() && _unixTime;
|
||||
}
|
||||
|
||||
QString AsyncKeysAuth::getUserId() const {
|
||||
return QCryptographicHash::hash(_publicKey,
|
||||
QCryptographicHash::Sha256).
|
||||
toBase64(QByteArray::Base64UrlEncoding);
|
||||
}
|
||||
|
||||
void AsyncKeysAuth::setSignature(const QByteArray &newSignature) {
|
||||
_signature = newSignature;
|
||||
}
|
||||
|
||||
}
|
@ -1,81 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2018-2022 QuasarApp.
|
||||
* Distributed under the lgplv3 software license, see the accompanying
|
||||
* Everyone is permitted to copy and distribute verbatim copies
|
||||
* of this license document, but changing it is not allowed.
|
||||
*/
|
||||
|
||||
|
||||
#include "cryptopairkeys.h"
|
||||
|
||||
#include <QDataStream>
|
||||
namespace QH {
|
||||
CryptoPairKeys::CryptoPairKeys() {
|
||||
|
||||
}
|
||||
|
||||
CryptoPairKeys::CryptoPairKeys(const QByteArray &pubKey, const QByteArray &privKey) {
|
||||
setPrivKey(privKey);
|
||||
setPublicKey(pubKey);
|
||||
setBits(privKey.size() * 8);
|
||||
}
|
||||
|
||||
bool CryptoPairKeys::isValid() const {
|
||||
return _privKey.size() && _publicKey.size() && !(_bits % 8) && _bits > 1;
|
||||
}
|
||||
|
||||
QByteArray CryptoPairKeys::privKey() const {
|
||||
return _privKey;
|
||||
}
|
||||
|
||||
void CryptoPairKeys::setPrivKey(const QByteArray &privKey) {
|
||||
_privKey = privKey;
|
||||
}
|
||||
|
||||
QByteArray CryptoPairKeys::publicKey() const {
|
||||
return _publicKey;
|
||||
}
|
||||
|
||||
void CryptoPairKeys::setPublicKey(const QByteArray &publicKey) {
|
||||
_publicKey = publicKey;
|
||||
}
|
||||
|
||||
int CryptoPairKeys::bits() const {
|
||||
return _bits;
|
||||
}
|
||||
|
||||
void CryptoPairKeys::setBits(int bits) {
|
||||
_bits = bits;
|
||||
}
|
||||
|
||||
QDataStream &CryptoPairKeys::fromStream(QDataStream &stream) {
|
||||
|
||||
stream >> _publicKey;
|
||||
stream >> _privKey;
|
||||
stream >> _bits;
|
||||
|
||||
return stream;
|
||||
}
|
||||
|
||||
QDataStream &CryptoPairKeys::toStream(QDataStream &stream) const {
|
||||
stream << _publicKey;
|
||||
stream << _privKey;
|
||||
stream << _bits;
|
||||
|
||||
return stream;
|
||||
|
||||
}
|
||||
|
||||
bool operator ==(const CryptoPairKeys &left, const CryptoPairKeys &right) {
|
||||
return !(left != right);
|
||||
}
|
||||
|
||||
bool operator !=(const CryptoPairKeys &left, const CryptoPairKeys &right) {
|
||||
return left._privKey != right._privKey || left._publicKey != right._publicKey;
|
||||
}
|
||||
|
||||
uint qHash(const CryptoPairKeys &value) {
|
||||
return qHash(value.privKey());
|
||||
}
|
||||
|
||||
}
|
@ -1,90 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2018-2022 QuasarApp.
|
||||
* Distributed under the lgplv3 software license, see the accompanying
|
||||
* Everyone is permitted to copy and distribute verbatim copies
|
||||
* of this license document, but changing it is not allowed.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef CRYPTOPAIRKEYS_H
|
||||
#define CRYPTOPAIRKEYS_H
|
||||
|
||||
#include "streambase.h"
|
||||
|
||||
|
||||
namespace QH {
|
||||
|
||||
/**
|
||||
* @brief The CryptoPairKeys class contains pair keys. This is wraper for cripto graphick keys.
|
||||
*/
|
||||
class HEARTSHARED_EXPORT CryptoPairKeys: public StreamBase
|
||||
{
|
||||
public:
|
||||
CryptoPairKeys();
|
||||
CryptoPairKeys(const QByteArray& pubKey, const QByteArray& privKey);
|
||||
|
||||
/**
|
||||
* @brief isValid - This Method check an internal keys.
|
||||
* @return true if this objeсt contains a valid pair keys.
|
||||
*/
|
||||
bool isValid() const;
|
||||
|
||||
/**
|
||||
* @brief privKey This method return private key of current keys pair.
|
||||
* @return return byteArray of private key.
|
||||
*/
|
||||
QByteArray privKey() const;
|
||||
|
||||
/**
|
||||
* @brief setPrivKey This method set a private key for keys pair.
|
||||
* @param privKey new byte array of private pair keys.
|
||||
*/
|
||||
void setPrivKey(const QByteArray &privKey);
|
||||
|
||||
/**
|
||||
* @brief publicKey This method return public key of array.
|
||||
* @return publicKey of current key pair.
|
||||
*/
|
||||
QByteArray publicKey() const;
|
||||
|
||||
/**
|
||||
* @brief setPublicKey This method set new value of publickKey.
|
||||
* @param publicKey new value of publicKey.
|
||||
*/
|
||||
void setPublicKey(const QByteArray &publicKey);
|
||||
|
||||
/**
|
||||
* @brief bits This method return size pair of crypto keys in bits.
|
||||
* @return bits size of keys pair.
|
||||
*/
|
||||
int bits() const;
|
||||
|
||||
/**
|
||||
* @brief setBits This method sets new value of keys pair.
|
||||
* @param bits This is new value of size keys.
|
||||
*/
|
||||
void setBits(int bits);
|
||||
|
||||
friend bool operator != (const CryptoPairKeys& left, const CryptoPairKeys& right);
|
||||
friend bool operator == (const CryptoPairKeys& left, const CryptoPairKeys& right);
|
||||
|
||||
// StreamBase interface
|
||||
protected:
|
||||
QDataStream &fromStream(QDataStream &stream);
|
||||
QDataStream &toStream(QDataStream &stream) const;
|
||||
|
||||
private:
|
||||
QByteArray _privKey;
|
||||
QByteArray _publicKey;
|
||||
|
||||
int _bits;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief qHash This functions calc crc32 hash code of CryptoPairKeys object.
|
||||
* @param value -
|
||||
* @return crc32 hash code.
|
||||
*/
|
||||
uint qHash(const CryptoPairKeys& value);
|
||||
}
|
||||
#endif // CRYPTOPAIRKEYS_H
|
@ -6,7 +6,7 @@
|
||||
//#
|
||||
|
||||
|
||||
#include "authecdsa.h"
|
||||
#include "ecdsassl11.h"
|
||||
|
||||
#ifdef USE_HEART_SSL
|
||||
|
||||
@ -16,13 +16,14 @@
|
||||
#include <openssl/err.h>
|
||||
|
||||
#include <QCryptographicHash>
|
||||
#include <QDataStream>
|
||||
#include <QIODevice>
|
||||
#include <QVector>
|
||||
#include <quasarapp.h>
|
||||
|
||||
namespace QH {
|
||||
|
||||
AuthECDSA::AuthECDSA() {
|
||||
ECDSASSL11::ECDSASSL11() {
|
||||
|
||||
}
|
||||
|
||||
@ -79,7 +80,7 @@ QByteArray extractPublicKey(EC_KEY* key, EC_GROUP* group) {
|
||||
return data;
|
||||
}
|
||||
|
||||
bool AuthECDSA::makeKeys(QByteArray &pubKey, QByteArray &privKey) {
|
||||
bool ECDSASSL11::makeKeys(QByteArray &pubKey, QByteArray &privKey) {
|
||||
|
||||
EC_KEY *eckey= nullptr;
|
||||
EC_GROUP *ecgroup = nullptr;
|
||||
@ -101,7 +102,7 @@ bool AuthECDSA::makeKeys(QByteArray &pubKey, QByteArray &privKey) {
|
||||
return pubKey.length() && privKey.length();
|
||||
}
|
||||
|
||||
QByteArray AuthECDSA::signMessage(const QByteArray &inputData,
|
||||
QByteArray ECDSASSL11::signMessage(const QByteArray &inputData,
|
||||
const QByteArray &key) const {
|
||||
|
||||
EC_KEY *eckey= nullptr;
|
||||
@ -147,7 +148,7 @@ QByteArray AuthECDSA::signMessage(const QByteArray &inputData,
|
||||
return result;
|
||||
}
|
||||
|
||||
bool AuthECDSA::checkSign(const QByteArray &inputData,
|
||||
bool ECDSASSL11::checkSign(const QByteArray &inputData,
|
||||
const QByteArray &signature,
|
||||
const QByteArray &key) const {
|
||||
|
||||
@ -198,7 +199,15 @@ bool AuthECDSA::checkSign(const QByteArray &inputData,
|
||||
|
||||
}
|
||||
|
||||
bool AuthECDSA::prepareKeyAdnGroupObjects(EC_KEY **eckey, EC_GROUP **ecgroup) {
|
||||
QByteArray ECDSASSL11::decript(const QByteArray &message, const QByteArray &key) {
|
||||
return {};
|
||||
}
|
||||
|
||||
QByteArray ECDSASSL11::encript(const QByteArray &message, const QByteArray &key) {
|
||||
return {};
|
||||
}
|
||||
|
||||
bool ECDSASSL11::prepareKeyAdnGroupObjects(EC_KEY **eckey, EC_GROUP **ecgroup) {
|
||||
|
||||
// input data should be valid pointers to pointers of key and group objects.
|
||||
if (!(eckey && ecgroup))
|
@ -6,28 +6,27 @@
|
||||
//#
|
||||
|
||||
|
||||
#ifndef AUTHECDSA_H
|
||||
#define AUTHECDSA_H
|
||||
#ifndef QH_ECDSA_SSL_1_1_H
|
||||
#define QH_ECDSA_SSL_1_1_H
|
||||
#include "heart_global.h"
|
||||
|
||||
#ifdef USE_HEART_SSL
|
||||
|
||||
|
||||
#include "abstractdata.h"
|
||||
#include <asynckeysauth.h>
|
||||
#include "icrypto.h"
|
||||
|
||||
#include <openssl/ec.h> // for EC_GROUP_new_by_curve_name, EC_GROUP_free, EC_KEY_new, EC_KEY_set_group, EC_KEY_generate_key,EC_KEY_free
|
||||
|
||||
namespace QH {
|
||||
|
||||
/**
|
||||
* @brief The AuthECDSA class is ecdsa implementation of the Async authentication. This implementation based on Openssl library.
|
||||
* @brief The ECDSASSL11 class is ecdsa implementation of the Async authentication. This implementation based on Openssl library.
|
||||
* @note This class compatibility only with ssl 1.1 and ssl 3.0 (depricated fundtions).
|
||||
*/
|
||||
class HEARTSHARED_EXPORT AuthECDSA: public QH::AsyncKeysAuth
|
||||
class HEARTSHARED_EXPORT ECDSASSL11: public QH::ICrypto
|
||||
{
|
||||
|
||||
public:
|
||||
AuthECDSA();
|
||||
ECDSASSL11();
|
||||
|
||||
/**
|
||||
* @brief makeKeys This static method generate the public and private keys of the ECDSA.
|
||||
@ -37,19 +36,29 @@ public:
|
||||
*/
|
||||
static bool makeKeys(QByteArray &pubKey, QByteArray &privKey);
|
||||
|
||||
// AsyncKeysAuth interface
|
||||
protected:
|
||||
QByteArray signMessage(const QByteArray &inputData, const QByteArray &key) const override;
|
||||
bool checkSign(const QByteArray &inputData, const QByteArray &signature, const QByteArray &key) const override;
|
||||
|
||||
/**
|
||||
* @brief decript This method has empty implementation.
|
||||
* @return empty array.
|
||||
*/
|
||||
QByteArray decript(const QByteArray &message, const QByteArray &key) override;
|
||||
|
||||
/**
|
||||
* @brief encript This method has empty implementation.
|
||||
* @return empty array.
|
||||
*/
|
||||
QByteArray encript(const QByteArray &message, const QByteArray &key) override;
|
||||
|
||||
private:
|
||||
static bool prepareKeyAdnGroupObjects(EC_KEY **eckey, EC_GROUP **ecgroup);
|
||||
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif // AUTHECDSA_H
|
||||
#endif // QH_ECDSA_SSL_1_1_H
|
@ -11,8 +11,4 @@
|
||||
|
||||
namespace QH {
|
||||
|
||||
ICrypto::ICrypto() = default;
|
||||
|
||||
ICrypto::~ICrypto() = default;
|
||||
|
||||
}
|
65
Heart/AbstractSpace/hcrypto/icrypto.h
Normal file
65
Heart/AbstractSpace/hcrypto/icrypto.h
Normal file
@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright (C) 2021-2022 QuasarApp.
|
||||
* Distributed under the lgplv3 software license, see the accompanying
|
||||
* Everyone is permitted to copy and distribute verbatim copies
|
||||
* of this license document, but changing it is not allowed.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef I_CRYPTO_H
|
||||
#define I_CRYPTO_H
|
||||
|
||||
#include "heart_global.h"
|
||||
#include <QByteArray>
|
||||
|
||||
namespace QH {
|
||||
|
||||
/**
|
||||
* @brief The ICrypto class This is base interface that provide encription functionality.
|
||||
*/
|
||||
class HEARTSHARED_EXPORT ICrypto
|
||||
{
|
||||
|
||||
protected:
|
||||
|
||||
/**
|
||||
* @brief decript This method decript @a message using @a key.
|
||||
* @param message This is encripted message that should be decripted.
|
||||
* @param key This is key that will be used for decription for the @a message.
|
||||
* @return decripted message or empty string if method not supported or decripted failed.
|
||||
* @see IAsyncEncription::encript
|
||||
*/
|
||||
virtual QByteArray decript(const QByteArray& message, const QByteArray& key) = 0;
|
||||
/**
|
||||
* @brief decript This method encript @a message using @a key.
|
||||
* @param message This is a message that should be decripted.
|
||||
* @param key This is key that will be used for encription for the @a message.
|
||||
* @return decripted message or empty string if method not supported or decripted failed.
|
||||
* @see IAsyncEncription::encript
|
||||
*/
|
||||
virtual QByteArray encript(const QByteArray& message, const QByteArray& key) = 0;
|
||||
|
||||
/**
|
||||
* @brief signMessage This method should be sign the @a message using the @a key.
|
||||
* @param message This is input data that should be signed.
|
||||
* @param key This is a privete key for encription the @a message.
|
||||
* @return signature data array.
|
||||
* @see AsyncKeysAuth::descrupt
|
||||
*/
|
||||
virtual QByteArray signMessage(const QByteArray& message, const QByteArray& key) const = 0;
|
||||
|
||||
/**
|
||||
* @brief checkSign This method should be check signature of the @a message using the @a key.
|
||||
* @param message This is input data that should be decripted.
|
||||
* @param signature This is signature that will be checked for the @a message.
|
||||
* @param key This is a public key for encription the @a inpputData.
|
||||
* @return decripted data array.
|
||||
* @see AsyncKeysAuth::encrypt
|
||||
*/
|
||||
virtual bool checkSign(const QByteArray& message,
|
||||
const QByteArray& signature,
|
||||
const QByteArray& key) const = 0;
|
||||
};
|
||||
|
||||
}
|
||||
#endif // I_CRYPTO_H
|
@ -8,14 +8,27 @@
|
||||
#ifndef ASYNCKEYSAUTH_H
|
||||
#define ASYNCKEYSAUTH_H
|
||||
|
||||
#include <QByteArray>
|
||||
#include <QCryptographicHash>
|
||||
#include <time.h>
|
||||
#include <QString>
|
||||
|
||||
#include "heart_global.h"
|
||||
|
||||
namespace QH {
|
||||
|
||||
/**
|
||||
* @brief The AsyncKeysAuth class is base class for works with authorization of a pair of asynchronous keys
|
||||
* @brief The AsyncKeysAuth class is temaplate class for works with authorization of a pair of asynchronous keys
|
||||
* This class contains base implementation for the authentication using async encription. The base encription alhorithm defined on the template argument **CryptoImplementation**.
|
||||
* You can use any crypto alhorithm.
|
||||
*
|
||||
* ## Exampel of use:
|
||||
*
|
||||
* @code{cpp}
|
||||
* #include <hcrypto.h>
|
||||
*
|
||||
* using ECDSAAuth = AsyncKeysAuth<ECDSA>;
|
||||
*
|
||||
* @endcode
|
||||
*
|
||||
*
|
||||
* ### How to it works:
|
||||
*
|
||||
@ -46,45 +59,115 @@ namespace QH {
|
||||
* * After accept server create new user with ID = sha256(PUB) or
|
||||
* if user alredy exits make them as a logined user.
|
||||
*
|
||||
* @tparam CryptoImplementation This is internal implementaion of base encription functions.
|
||||
* @see iCrypto class.
|
||||
*
|
||||
*/
|
||||
class HEARTSHARED_EXPORT AsyncKeysAuth
|
||||
|
||||
template<class CryptoImplementation>
|
||||
class AsyncKeysAuth: public CryptoImplementation
|
||||
{
|
||||
public:
|
||||
AsyncKeysAuth();
|
||||
AsyncKeysAuth() {
|
||||
|
||||
}
|
||||
|
||||
~AsyncKeysAuth() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief auth This method make authentication and return true if the authentication finished successful else false.
|
||||
* @brief retLoginedUserId This is logined user id in Base64UrlEncoding
|
||||
* @return true if the authentication finished successful else false.
|
||||
*/
|
||||
bool auth(int allowedTimeRangeSec, QString* retLoginedUserId) const;
|
||||
bool auth(int allowedTimeRangeSec, QString* retLoginedUserId) const {
|
||||
|
||||
int diff = time(0) - _unixTime;
|
||||
|
||||
if (diff < 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (diff >= allowedTimeRangeSec) {
|
||||
return false;
|
||||
}
|
||||
|
||||
QByteArray data = _publicKey;
|
||||
data.insert(0, reinterpret_cast<const char*>(&_unixTime),
|
||||
sizeof(_unixTime));
|
||||
|
||||
bool result = checkSign(data, _signature, _publicKey);
|
||||
|
||||
if (result && retLoginedUserId) {
|
||||
*retLoginedUserId = getUserId();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief prepare This method will generate signature for autentication of client. Please inboke this method before send request to server.
|
||||
* @return true if signature generated sucessuful.
|
||||
*/
|
||||
bool prepare();
|
||||
bool prepare() {
|
||||
_unixTime = time(0);
|
||||
|
||||
QByteArray data = _publicKey;
|
||||
data.insert(0, reinterpret_cast<const char*>(&_unixTime),
|
||||
sizeof(_unixTime));
|
||||
|
||||
setSignature(signMessage(data, getPrivateKey()));
|
||||
|
||||
return isValid();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief unixTime This method return unix time that client added for authentication.
|
||||
* @return unix time that client added for authentication.
|
||||
* @see AsyncKeysAuth::setUnixTime
|
||||
*/
|
||||
unsigned int unixTime() const;
|
||||
unsigned int unixTime() const {
|
||||
return _unixTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief setUnixTime This method sets new value of the unixTime propertye.
|
||||
* @param newUnixTime This is new unix time value. Unix time sets in secunds from 1970 year
|
||||
*/
|
||||
void setUnixTime(unsigned int newUnixTime);
|
||||
void setUnixTime(unsigned int newUnixTime) {
|
||||
_unixTime = newUnixTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief signature This method return signature array.
|
||||
* @return signature array.
|
||||
* @see AsyncKeysAuth::setSignature
|
||||
*/
|
||||
const QByteArray &signature() const;
|
||||
const QByteArray &signature() const {
|
||||
return _signature;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief isValid this method check this ibject to valid.
|
||||
* @return return true if object contains valid signature else false.
|
||||
* @note Invoke the AsyncKeysAuth::prepare method before check valid of object. All object that not be preparred is invalid.
|
||||
*/
|
||||
bool isValid() const {
|
||||
return _publicKey.size() && _signature.size() && _unixTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief getUserId This method return user id that generated from the public key.
|
||||
* @note This function works slow, because this object does not contain ID of user. The user ID will be generated every invoke of this function
|
||||
* @return user ID.
|
||||
*/
|
||||
QString getUserId() const {
|
||||
return QCryptographicHash::hash(_publicKey,
|
||||
QCryptographicHash::Sha256).
|
||||
toBase64(QByteArray::Base64UrlEncoding);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief publicKey This method return public key that client added for authentication.
|
||||
@ -92,49 +175,36 @@ public:
|
||||
* @return public key that client added for authentication.
|
||||
* @see AsyncKeysAuth::setPublicKey
|
||||
*/
|
||||
const QByteArray &publicKey() const;
|
||||
const QByteArray &publicKey() const {
|
||||
return _publicKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief setPublicKey This method sets new public key for authentication.
|
||||
* @param newPublicKey Thiy is new key.
|
||||
* @see AsyncKeysAuth::publicKey
|
||||
*/
|
||||
void setPublicKey(const QByteArray &newPublicKey);
|
||||
|
||||
/**
|
||||
* @brief isValid this method check this ibject to valid.
|
||||
* @return return true if object contains valid signature else false.
|
||||
* @note Invoke the AsyncKeysAuth::prepare method before check valid of object. All object that not be preparred is invalid.
|
||||
*/
|
||||
bool isValid() const;
|
||||
|
||||
/**
|
||||
* @brief getUserId This method return user id that generated from the public key.
|
||||
* @note This function works slow, because this object does not contain ID of user. The user ID will be generated every invoke of this function
|
||||
* @return user ID.
|
||||
*/
|
||||
QString getUserId() const;
|
||||
void setPublicKey(const QByteArray &newPublicKey) {
|
||||
_publicKey = newPublicKey;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
/**
|
||||
* @brief signMessage This method should be sign the @a message using the @a key.
|
||||
* @param message This is input data that should be signed.
|
||||
* @param key This is a privete key for encription the @a message.
|
||||
* @return signature data array.
|
||||
* @see AsyncKeysAuth::descrupt
|
||||
*/
|
||||
virtual QByteArray signMessage(const QByteArray& message, const QByteArray& key) const = 0;
|
||||
QByteArray decript(const QByteArray &message, const QByteArray &key) override {
|
||||
return CryptoImplementation::decript(message, key);
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief checkSign This method should be check signature of the @a message using the @a key.
|
||||
* @param message This is input data that should be decripted.
|
||||
* @param signature This is signature that will be checked for the @a message.
|
||||
* @param key This is a public key for encription the @a inpputData.
|
||||
* @return decripted data array.
|
||||
* @see AsyncKeysAuth::encrypt
|
||||
*/
|
||||
virtual bool checkSign(const QByteArray& message, const QByteArray& signature, const QByteArray& key) const = 0;
|
||||
QByteArray encript(const QByteArray &message, const QByteArray &key) override {
|
||||
return CryptoImplementation::encript(message, key);
|
||||
};
|
||||
|
||||
QByteArray signMessage(const QByteArray &message, const QByteArray &key) const override {
|
||||
return CryptoImplementation::signMessage(message, key);
|
||||
};
|
||||
|
||||
bool checkSign(const QByteArray &message, const QByteArray &signature, const QByteArray &key) const override {
|
||||
return CryptoImplementation::checkSign(message, signature, key);
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief getPrivateKey This method should be return private key for the public key that saved in this object.
|
||||
@ -147,7 +217,9 @@ protected:
|
||||
* @param newSignature new signature value.
|
||||
* @note used in the
|
||||
*/
|
||||
void setSignature(const QByteArray &newSignature);
|
||||
void setSignature(const QByteArray &newSignature) {
|
||||
_signature = newSignature;
|
||||
}
|
||||
|
||||
unsigned int _unixTime = 0;
|
||||
QByteArray _signature;
|
31
Heart/AbstractSpace/hcryptoFeatures/authecdsa.h
Normal file
31
Heart/AbstractSpace/hcryptoFeatures/authecdsa.h
Normal file
@ -0,0 +1,31 @@
|
||||
//#
|
||||
//# Copyright (C) 2021-2022 QuasarApp.
|
||||
//# Distributed under the GPLv3 software license, see the accompanying
|
||||
//# Everyone is permitted to copy and distribute verbatim copies
|
||||
//# of this license document, but changing it is not allowed.
|
||||
//#
|
||||
|
||||
|
||||
#ifndef AUTHECDSA_H
|
||||
#define AUTHECDSA_H
|
||||
#include "heart_global.h"
|
||||
|
||||
#ifdef USE_HEART_SSL
|
||||
|
||||
|
||||
#include "hcrypto/ecdsassl11.h"
|
||||
|
||||
#include "asynckeysauth.h"
|
||||
|
||||
|
||||
namespace QH {
|
||||
|
||||
/**
|
||||
* @brief The AuthECDSA class is ecdsa implementation of the Async authentication. This implementation based on Openssl library.
|
||||
*/
|
||||
typedef AsyncKeysAuth<ECDSASSL11> AuthECDSA;
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // AUTHECDSA_H
|
22
Heart/AbstractSpace/hcryptoFeatures/ecdsasigner.h
Normal file
22
Heart/AbstractSpace/hcryptoFeatures/ecdsasigner.h
Normal file
@ -0,0 +1,22 @@
|
||||
/*
|
||||
* Copyright (C) 2021-2022 QuasarApp.
|
||||
* Distributed under the lgplv3 software license, see the accompanying
|
||||
* Everyone is permitted to copy and distribute verbatim copies
|
||||
* of this license document, but changing it is not allowed.
|
||||
*/
|
||||
|
||||
#ifndef ECDSASIGNER_H
|
||||
#define ECDSASIGNER_H
|
||||
|
||||
#include "signer.h"
|
||||
#include "hcrypto/ecdsassl11.h"
|
||||
|
||||
namespace QH {
|
||||
|
||||
/**
|
||||
* @brief The ECDSASigner class is ecdsa implementation of the Signer class. This implementation based on Openssl library.
|
||||
*/
|
||||
typedef Signer<ECDSASSL11> ECDSASigner;
|
||||
|
||||
}
|
||||
#endif // ECDSASIGNER_H
|
47
Heart/AbstractSpace/hcryptoFeatures/isignerdelegate.cpp
Normal file
47
Heart/AbstractSpace/hcryptoFeatures/isignerdelegate.cpp
Normal file
@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright (C) 2021-2022 QuasarApp.
|
||||
* Distributed under the lgplv3 software license, see the accompanying
|
||||
* Everyone is permitted to copy and distribute verbatim copies
|
||||
* of this license document, but changing it is not allowed.
|
||||
*/
|
||||
|
||||
#include "isignerdelegate.h"
|
||||
|
||||
namespace QH {
|
||||
|
||||
ISignerDelegate::ISignerDelegate() {
|
||||
|
||||
}
|
||||
|
||||
const QByteArray &ISignerDelegate::getSignature() const {
|
||||
return sign;
|
||||
}
|
||||
|
||||
void ISignerDelegate::setSignature(const QByteArray &newSignature) {
|
||||
sign = newSignature;
|
||||
}
|
||||
|
||||
const QByteArray &ISignerDelegate::getHash() const {
|
||||
return hash;
|
||||
|
||||
}
|
||||
|
||||
void ISignerDelegate::setHash(const QByteArray &newHash) {
|
||||
hash = newHash;
|
||||
|
||||
}
|
||||
|
||||
QDataStream &ISignerDelegate::fromStream(QDataStream &stream) {
|
||||
stream >> hash;
|
||||
stream >> sign;
|
||||
|
||||
return stream;
|
||||
}
|
||||
|
||||
QDataStream &ISignerDelegate::toStream(QDataStream &stream) const {
|
||||
stream << hash;
|
||||
stream << sign;
|
||||
|
||||
return stream;
|
||||
}
|
||||
}
|
83
Heart/AbstractSpace/hcryptoFeatures/isignerdelegate.h
Normal file
83
Heart/AbstractSpace/hcryptoFeatures/isignerdelegate.h
Normal file
@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Copyright (C) 2021-2022 QuasarApp.
|
||||
* Distributed under the lgplv3 software license, see the accompanying
|
||||
* Everyone is permitted to copy and distribute verbatim copies
|
||||
* of this license document, but changing it is not allowed.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef ISIGNERDELEGATE_H
|
||||
#define ISIGNERDELEGATE_H
|
||||
|
||||
#include <streambase.h>
|
||||
|
||||
|
||||
namespace QH {
|
||||
|
||||
/**
|
||||
* @brief The ISignerDelegate class This is base class of signer delegate.
|
||||
* The sisgner class will be invoke all delegate methods for control the input object that need to sign.
|
||||
* @note This class contasin sign and hash fild and override the >> and << operators for QDataStream,
|
||||
* so if you want to convert your object to bytes array don not forget invoke the ISignerDelegate::fromStream and ISignerDelegate::toStream methods.
|
||||
* @see Signer
|
||||
*/
|
||||
class ISignerDelegate: public StreamBase
|
||||
{
|
||||
public:
|
||||
ISignerDelegate();
|
||||
|
||||
/**
|
||||
* @brief getSignature This method return constant reference to the signature array.
|
||||
* @return constant reference to the signature array.
|
||||
*/
|
||||
virtual const QByteArray &getSignature() const;
|
||||
|
||||
/**
|
||||
* @brief setSignature This method sets the new signature of this object.
|
||||
* @param newSignature new signature value.
|
||||
*/
|
||||
virtual void setSignature(const QByteArray &newSignature);
|
||||
|
||||
/**
|
||||
* @brief getHash This method return constant reference to the hash array.
|
||||
* @return constant reference to the signature array.
|
||||
*/
|
||||
virtual const QByteArray &getHash() const;
|
||||
|
||||
/**
|
||||
* @brief setHash This method sets the new hash sum of this object.
|
||||
* @param newSignature new signature value.
|
||||
*/
|
||||
virtual void setHash(const QByteArray &newHash);
|
||||
|
||||
/**
|
||||
* @brief getPrivateKey This method should be return private key for the public key that saved in this object.
|
||||
* @return private key for the public key that saved in this object.
|
||||
*/
|
||||
virtual const QByteArray& getPrivateKey() const = 0;
|
||||
|
||||
/**
|
||||
* @brief getPublicKey This method should be return public key for the private key that encrypted this object.
|
||||
* @return public key for the private key that ecrypt this object.
|
||||
*/
|
||||
virtual const QByteArray& getPublicKey() const = 0;
|
||||
|
||||
/**
|
||||
* @brief getMessage This method should be return message that you want to sign.
|
||||
* @return message that you want to sign.
|
||||
*/
|
||||
virtual const QByteArray getMessage() const = 0;
|
||||
|
||||
// StreamBase interface
|
||||
protected:
|
||||
QDataStream &fromStream(QDataStream &stream) override;
|
||||
QDataStream &toStream(QDataStream &stream) const override;
|
||||
|
||||
private:
|
||||
QByteArray hash;
|
||||
QByteArray sign;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
#endif // ISIGNERDELEGATE_H
|
91
Heart/AbstractSpace/hcryptoFeatures/signer.h
Normal file
91
Heart/AbstractSpace/hcryptoFeatures/signer.h
Normal file
@ -0,0 +1,91 @@
|
||||
/*
|
||||
* Copyright (C) 2021-2022 QuasarApp.
|
||||
* Distributed under the lgplv3 software license, see the accompanying
|
||||
* Everyone is permitted to copy and distribute verbatim copies
|
||||
* of this license document, but changing it is not allowed.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef SIGNER_H
|
||||
#define SIGNER_H
|
||||
|
||||
#include <QByteArray>
|
||||
#include <QCryptographicHash>
|
||||
#include <QSharedPointer>
|
||||
#include "isignerdelegate.h"
|
||||
#include "qaservice.h"
|
||||
|
||||
namespace QH {
|
||||
|
||||
/**
|
||||
* @brief The Signer class can sign and check the signature of the any childs classes of the ISignerDelegate class.
|
||||
*
|
||||
* **Exmaple of use**
|
||||
*
|
||||
* @code{cpp}
|
||||
* #include <hcriptoFeatures/isignerdelegate.h>
|
||||
* #include <hcriptoFeatures/ecdsasigner.h>
|
||||
*
|
||||
* class MyDelegate: public ISignerDelegate {
|
||||
* // override all methods
|
||||
* };
|
||||
*
|
||||
* int main () {
|
||||
* MyDelegate delegate;
|
||||
*
|
||||
* // sign your object
|
||||
* QH::ECDSASigner::sign(&delegate);
|
||||
*
|
||||
* // check signature of the object
|
||||
* QH::ECDSASigner::check(&delegate);
|
||||
* }
|
||||
*
|
||||
*
|
||||
* @endcode
|
||||
*
|
||||
* @note the MyDelegate class should be contains a public for check signature and a private for sign object keys
|
||||
* @tparam CryptoImplementation This is internal implementaion of base encription functions.
|
||||
* @see iCrypto class.
|
||||
*/
|
||||
template<class CryptoImplementation>
|
||||
class Signer: protected QuasarAppUtils::Service<Signer<CryptoImplementation>>,
|
||||
protected CryptoImplementation
|
||||
{
|
||||
public:
|
||||
Signer() {};
|
||||
~Signer() {};
|
||||
|
||||
/**
|
||||
* @brief sign This is main method for signing of this object.
|
||||
* @return true if the object signed sucessful
|
||||
*/
|
||||
static bool sign(ISignerDelegate* obj) {
|
||||
|
||||
if (auto signer = Signer<CryptoImplementation>::autoInstance()) {
|
||||
auto sign = signer->signMessage(obj->getMessage(), obj->getPrivateKey());
|
||||
|
||||
if (sign.size()) {
|
||||
obj->setSignature(sign);
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief check This method check signature of this object.
|
||||
* @return true if the objec signed
|
||||
*/
|
||||
static bool check(const ISignerDelegate* obj) {
|
||||
if (auto signer = Signer<CryptoImplementation>::autoInstance()) {
|
||||
return signer->checkSign(obj->getMessage(), obj->signature(), obj->getPublicKey());
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
};
|
||||
}
|
||||
#endif // SIGNER_H
|
@ -30,10 +30,8 @@ HostAddress::HostAddress(const SpecialAddress &other, int port):
|
||||
setPort(port);
|
||||
}
|
||||
|
||||
HostAddress::HostAddress(const HostAddress &other):
|
||||
QHostAddress(*static_cast<const HostAddress*>(&other)) {
|
||||
|
||||
setPort(other.port());
|
||||
HostAddress::HostAddress(const HostAddress &other) {
|
||||
operator=(other);
|
||||
}
|
||||
|
||||
unsigned short HostAddress::port() const {
|
||||
@ -44,6 +42,13 @@ void HostAddress::setPort(unsigned short port) {
|
||||
_port = port;
|
||||
}
|
||||
|
||||
HostAddress &HostAddress::operator =(const HostAddress &right) {
|
||||
QHostAddress::operator=(*static_cast<const QHostAddress*>(&right));
|
||||
setPort(right.port());
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool HostAddress::isIP(const QString &address) {
|
||||
return !QHostAddress{address}.isNull();
|
||||
}
|
||||
@ -56,6 +61,22 @@ QString HostAddress::toString() const {
|
||||
return QHostAddress::toString() + ":" + QString::number(port());
|
||||
}
|
||||
|
||||
QByteArray HostAddress::toBytes() const {
|
||||
QByteArray res;
|
||||
QDataStream stream(&res, QIODevice::WriteOnly);
|
||||
operator <<(stream, *this);
|
||||
return res;
|
||||
}
|
||||
|
||||
bool HostAddress::fromBytes(const QByteArray &array) {
|
||||
if (array.isEmpty())
|
||||
return false;
|
||||
|
||||
QDataStream stream(array);
|
||||
operator >>(stream, *this);
|
||||
return true;
|
||||
}
|
||||
|
||||
QDataStream &operator >>(QDataStream &stream, HostAddress &address) {
|
||||
stream >> static_cast<QHostAddress&>(address);
|
||||
stream >> address._port;
|
||||
|
@ -47,6 +47,7 @@ public:
|
||||
friend bool& operator == (QDataStream& stream, HostAddress& address);
|
||||
friend bool& operator != (QDataStream& stream, HostAddress& address);
|
||||
|
||||
HostAddress& operator = (const HostAddress& right);;
|
||||
/**
|
||||
* @brief isIP This method return true if the @a address is valid.
|
||||
* @brief address This is tring value of the network ip address.
|
||||
@ -66,8 +67,22 @@ public:
|
||||
*/
|
||||
QString toString() const;
|
||||
|
||||
/**
|
||||
* @brief toBytes This method convert a network address to a byte array.
|
||||
* @return byte array implementation of this object.
|
||||
*/
|
||||
QByteArray toBytes() const;
|
||||
|
||||
/**
|
||||
* @brief fromBytes This method applay @a array obejct. (conver a byte array to a newtwork address object)
|
||||
* @param array this is input array.
|
||||
* @return true if array applayed successfull
|
||||
*/
|
||||
bool fromBytes(const QByteArray& array);
|
||||
|
||||
private:
|
||||
unsigned short _port = 0;
|
||||
|
||||
};
|
||||
|
||||
uint qHash(const HostAddress& address);
|
||||
|
@ -1,105 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2018-2022 QuasarApp.
|
||||
* Distributed under the lgplv3 software license, see the accompanying
|
||||
* Everyone is permitted to copy and distribute verbatim copies
|
||||
* of this license document, but changing it is not allowed.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef ICRYPTO_H
|
||||
#define ICRYPTO_H
|
||||
|
||||
#include <QList>
|
||||
#include <QThread>
|
||||
#include "heart_global.h"
|
||||
#include <QByteArray>
|
||||
#include <QHash>
|
||||
#include <QSet>
|
||||
#define RAND_KEY ""
|
||||
|
||||
class QMutex;
|
||||
|
||||
namespace QH {
|
||||
|
||||
class CryptoPairKeys;
|
||||
|
||||
/**
|
||||
* @brief The ICrypto class provide cryptographic functionality.
|
||||
* This is interface for decoration of KeyStorage classes.
|
||||
*/
|
||||
class HEARTSHARED_EXPORT ICrypto
|
||||
{
|
||||
|
||||
public:
|
||||
ICrypto();
|
||||
virtual ~ICrypto();
|
||||
|
||||
/**
|
||||
* @brief isValid check crypto object is valid.
|
||||
* @return true if the crypto object is valid.
|
||||
*/
|
||||
virtual bool isValid() const = 0;
|
||||
|
||||
|
||||
/**
|
||||
* @brief crypt This method crypt input data using public key.
|
||||
* @param data This is pointer to data array for crypting.
|
||||
* @note data as ben changed after call this method.
|
||||
* @param publicKey This is key for crypting data.
|
||||
* @return true if function finished successful.
|
||||
*/
|
||||
virtual bool crypt(QByteArray *data, const QByteArray& publicKey) = 0;
|
||||
|
||||
/**
|
||||
* @brief decrypt This method decrypt input data.
|
||||
* @param cryptedData This is pointer to data array for decrypting.
|
||||
* @note cryptedData has been changed after call this method.
|
||||
* @param privateKey This is key for decrypting data message
|
||||
* @return true if function finished successful.
|
||||
*/
|
||||
virtual bool decrypt(QByteArray *cryptedData, const QByteArray& privateKey) = 0;
|
||||
|
||||
/**
|
||||
* @brief sign This method sign a input message using privateKey.
|
||||
* @param data This is pointer to data array for signed.
|
||||
* @note data has been changed after call this method.
|
||||
* @param privateKey This is key for sign a message.
|
||||
* @return true if function finished successful.
|
||||
*/
|
||||
virtual bool sign(QByteArray* data, const QByteArray& privateKey) = 0;
|
||||
|
||||
/**
|
||||
* @brief extractSign This method extract sign from signed byteArray.
|
||||
* @param data - signed message.
|
||||
* @return return array of sign.
|
||||
*/
|
||||
virtual QByteArray extractSign(const QByteArray& data) = 0;
|
||||
|
||||
/**
|
||||
* @brief concatSign This method make a concatenation between a message data and a sign of message.
|
||||
* @param data This is message data.
|
||||
* @param sign This is sign of message.
|
||||
* @return signed message.
|
||||
*/
|
||||
virtual QByteArray concatSign(const QByteArray& data, const QByteArray& sign) = 0;
|
||||
|
||||
/**
|
||||
* @brief check This method validation signed message
|
||||
* @param signedData This is array of signed data.
|
||||
* @param publicKey This is public key for validation of message.
|
||||
* @return true if function finished successful and signedData is valid.
|
||||
*/
|
||||
virtual bool check(const QByteArray& signedData, const QByteArray& publicKey) = 0;
|
||||
|
||||
/**
|
||||
* @brief generate This method is generate a new key pair. Default implementation do nothing.
|
||||
* @note Override this method for create of new class with new keys type.
|
||||
* @param genesis This is genesis bytes Array. if is possible add support generate keys pair from genesis data.
|
||||
* @return crypto pair keys.
|
||||
*/
|
||||
virtual CryptoPairKeys generate(const QByteArray& genesis = {}) const = 0;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
#endif // CRYPTO_H
|
@ -1,5 +1,7 @@
|
||||
#include "iparser.h"
|
||||
|
||||
#include <abstractdata.h>
|
||||
|
||||
namespace QH {
|
||||
|
||||
iParser::iParser() {
|
||||
@ -19,4 +21,16 @@ QString iParser::pareseResultToString(const ParserResult &parseResult) const {
|
||||
}
|
||||
}
|
||||
|
||||
const QHash<unsigned short, std::function<PKG::AbstractData *()> > &
|
||||
iParser::registeredTypes() const {
|
||||
return _registeredTypes;
|
||||
}
|
||||
|
||||
QSharedPointer<PKG::AbstractData> iParser::genPackage(unsigned short cmd) const {
|
||||
return QSharedPointer<PKG::AbstractData>(_registeredTypes.value(cmd, [](){return nullptr;})());
|
||||
}
|
||||
|
||||
bool iParser::checkCommand(unsigned short cmd) const {
|
||||
return _registeredTypes.contains(cmd);
|
||||
}
|
||||
}
|
||||
|
@ -39,6 +39,17 @@ class HEARTSHARED_EXPORT iParser
|
||||
public:
|
||||
iParser();
|
||||
|
||||
template<class T>
|
||||
/**
|
||||
* @brief registerPackageType This method register package type T.
|
||||
* This is need to prepare pacakge for parsing in the parsePackage method.
|
||||
*/
|
||||
void registerPackageType() {
|
||||
_registeredTypes[T::command()] = [](){
|
||||
return new T();
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief parsePackage This is main method of all childs classes of an AbstractNode class.
|
||||
* This method work on own thread.
|
||||
@ -153,6 +164,34 @@ public:
|
||||
return QH::ParserResult::NotProcessed;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief registeredTypes This method return list of registered command.
|
||||
* @return list of registered command.
|
||||
* @see iParser::registerPackageType
|
||||
*/
|
||||
const QHash<unsigned short, std::function<PKG::AbstractData *()> > ®isteredTypes() const;
|
||||
|
||||
/**
|
||||
* @brief genPackage This is factory method that generate data pacakge objects by command.
|
||||
* All object should be registered before using this method.
|
||||
* @param cmd This is command of pacakge see Header::command.
|
||||
* @return shared pointer to new data object.
|
||||
* @see AbstractNode::registerPackageType
|
||||
* @see Header::command
|
||||
*/
|
||||
QSharedPointer<PKG::AbstractData> genPackage(unsigned short cmd) const ;
|
||||
|
||||
/**
|
||||
* @brief checkCommand This method check command are if registered type or not.
|
||||
* @brief cmd This is command of a verifiable package.
|
||||
* @return True if the package is registered in a node.
|
||||
*/
|
||||
bool checkCommand(unsigned short cmd) const;
|
||||
|
||||
private:
|
||||
QHash<unsigned short, std::function<PKG::AbstractData*()>> _registeredTypes;
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
@ -1,391 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2018-2022 QuasarApp.
|
||||
* Distributed under the lgplv3 software license, see the accompanying
|
||||
* Everyone is permitted to copy and distribute verbatim copies
|
||||
* of this license document, but changing it is not allowed.
|
||||
*/
|
||||
|
||||
|
||||
#include "cryptopairkeys.h"
|
||||
#include "icrypto.h"
|
||||
#include "keystorage.h"
|
||||
#include <quasarapp.h>
|
||||
|
||||
#include <QCoreApplication>
|
||||
#include <QDataStream>
|
||||
#include <QDateTime>
|
||||
#include <QDir>
|
||||
#include <QFile>
|
||||
#include <QMutex>
|
||||
#include <QStandardPaths>
|
||||
#include "config.h"
|
||||
|
||||
namespace QH {
|
||||
|
||||
#define THE_CLASS(x) QString::fromLatin1(typeid(*x).name())
|
||||
#define VERSION_FILE "version"
|
||||
|
||||
KeyStorage::KeyStorage(ICrypto * cryptoMethod) {
|
||||
_keyPoolSizeMutex = new QMutex();
|
||||
_keysMutex = new QMutex();
|
||||
_taskMutex = new QMutex();
|
||||
|
||||
_cryptoMethod = cryptoMethod;
|
||||
|
||||
assert(_cryptoMethod);
|
||||
}
|
||||
|
||||
KeyStorage::~KeyStorage() {
|
||||
|
||||
stop();
|
||||
waitForThreadFinished(WAIT_TIME);
|
||||
|
||||
if (!saveStorage()) {
|
||||
QuasarAppUtils::Params::log("save keys to storae is failed!",
|
||||
QuasarAppUtils::Error);
|
||||
}
|
||||
|
||||
delete _keyPoolSizeMutex;
|
||||
delete _keysMutex;
|
||||
delete _taskMutex;
|
||||
delete _cryptoMethod;
|
||||
}
|
||||
|
||||
CryptoPairKeys KeyStorage::getNextPair(const QString &accsessKey,
|
||||
const QByteArray& genesis,
|
||||
int timeout) {
|
||||
|
||||
if (!isInited() && genesis == RAND_KEY) {
|
||||
QuasarAppUtils::Params::log("You want get the random crypto keys pair in a not initialized crypto object.",
|
||||
QuasarAppUtils::Error);
|
||||
return CryptoPairKeys{};
|
||||
}
|
||||
|
||||
if (_keyPoolSize <= 0) {
|
||||
return CryptoPairKeys{};
|
||||
}
|
||||
|
||||
if (!genKey(accsessKey, genesis)) {
|
||||
return {};
|
||||
}
|
||||
|
||||
start();
|
||||
|
||||
if (!waitForGeneratekey(accsessKey, timeout)) {
|
||||
return CryptoPairKeys{};
|
||||
}
|
||||
|
||||
QMutexLocker locker(_keysMutex);
|
||||
|
||||
return _keys.value(accsessKey, {});
|
||||
}
|
||||
|
||||
int KeyStorage::getKeyPoolSize() const {
|
||||
return _keyPoolSize;
|
||||
}
|
||||
|
||||
void KeyStorage::setKeyPoolSize(int keyPoolSize) {
|
||||
_keyPoolSizeMutex->lock();
|
||||
_keyPoolSize = keyPoolSize;
|
||||
_keyPoolSizeMutex->unlock();
|
||||
|
||||
start();
|
||||
}
|
||||
|
||||
bool KeyStorage::isValid() const {
|
||||
return isInited();
|
||||
}
|
||||
|
||||
bool KeyStorage::isInited() const {
|
||||
return _inited;
|
||||
}
|
||||
|
||||
bool KeyStorage::crypt(QByteArray *data, const QByteArray &publicKey) {
|
||||
return _cryptoMethod->crypt(data, publicKey);
|
||||
}
|
||||
|
||||
bool KeyStorage::decrypt(QByteArray *cryptedData, const QByteArray &privateKey) {
|
||||
return _cryptoMethod->decrypt(cryptedData, privateKey);
|
||||
}
|
||||
|
||||
bool KeyStorage::sign(QByteArray *data, const QByteArray &privateKey) {
|
||||
return _cryptoMethod->sign(data, privateKey);
|
||||
}
|
||||
|
||||
QByteArray KeyStorage::extractSign(const QByteArray &data) {
|
||||
return _cryptoMethod->extractSign(data);
|
||||
}
|
||||
|
||||
QByteArray KeyStorage::concatSign(const QByteArray &data, const QByteArray &sign) {
|
||||
return _cryptoMethod->concatSign(data, sign);
|
||||
}
|
||||
|
||||
bool KeyStorage::check(const QByteArray &signedData, const QByteArray &publicKey) {
|
||||
return _cryptoMethod->check(signedData, publicKey);
|
||||
}
|
||||
|
||||
void KeyStorage::setGenesisList(const QList<QByteArray>& list) {
|
||||
_keysMutex->lock();
|
||||
for (const auto& i : list) {
|
||||
_keys.insert(i, {});
|
||||
}
|
||||
_keysMutex->unlock();
|
||||
|
||||
start();
|
||||
}
|
||||
|
||||
bool KeyStorage::toStorage(const QString &key) const {
|
||||
|
||||
if (!isValid())
|
||||
return false;
|
||||
|
||||
_keysMutex->lock();
|
||||
CryptoPairKeys value = _keys.value(key);
|
||||
_keysMutex->unlock();
|
||||
|
||||
auto filePath = storageLocation() + "/" + key;
|
||||
|
||||
QFile file(filePath);
|
||||
|
||||
if (!file.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
file.setPermissions(QFile::Permission::ReadOwner | QFile::Permission::WriteOwner);
|
||||
|
||||
QDataStream stream(&file);
|
||||
|
||||
stream << value;
|
||||
|
||||
file.close();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool KeyStorage::fromStorage(const QByteArray &key) {
|
||||
auto filePath = storageLocation() + "/" + key;
|
||||
|
||||
QFile file(filePath);
|
||||
|
||||
if (!file.open(QIODevice::ReadOnly)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
QDataStream stream(&file);
|
||||
|
||||
CryptoPairKeys value;
|
||||
stream >> value;
|
||||
|
||||
file.close();
|
||||
|
||||
_keys.insert(key, value);
|
||||
|
||||
return value.isValid();
|
||||
}
|
||||
|
||||
void KeyStorage::generateKeysByTasks() {
|
||||
_taskMutex->lock();
|
||||
auto tasks = _generateTasks;
|
||||
_taskMutex->unlock();
|
||||
|
||||
for (auto it = tasks.begin(); it != tasks.end(); ++it) {
|
||||
|
||||
if (_stopGenerator) {
|
||||
return;
|
||||
}
|
||||
|
||||
const auto& value = _keys.value(it.key());
|
||||
if (!value.isValid()) {
|
||||
|
||||
_keysMutex->lock();
|
||||
|
||||
if (it.value() == RAND_KEY && _randomKeysPool.size()) {
|
||||
_keys[it.key()] = *_randomKeysPool.begin();
|
||||
_randomKeysPool.erase(_randomKeysPool.begin());
|
||||
} else {
|
||||
_keys[it.key()] = _cryptoMethod->generate(it.value());
|
||||
}
|
||||
|
||||
_keysMutex->unlock();
|
||||
|
||||
}
|
||||
|
||||
_taskMutex->lock();
|
||||
_generateTasks.remove(it.key());
|
||||
_taskMutex->unlock();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void KeyStorage::generateRandomKeys() {
|
||||
_keyPoolSizeMutex->lock();
|
||||
int size = _keyPoolSize;
|
||||
_keyPoolSizeMutex->unlock();
|
||||
|
||||
while (size > _randomKeysPool.size()) {
|
||||
|
||||
if ((_stopGenerator))
|
||||
return;
|
||||
|
||||
auto &&keys = _cryptoMethod->generate();
|
||||
|
||||
_keysMutex->lock();
|
||||
_randomKeysPool.insert(keys);
|
||||
_keysMutex->unlock();
|
||||
}
|
||||
}
|
||||
|
||||
void KeyStorage::run() {
|
||||
|
||||
if (_stopGenerator) {
|
||||
return;
|
||||
}
|
||||
|
||||
_keyPoolSizeMutex->lock();
|
||||
int keyPoolSize = _keyPoolSize;
|
||||
_keyPoolSizeMutex->unlock();
|
||||
|
||||
while ((_generateTasks.size() || keyPoolSize > _randomKeysPool.size())
|
||||
&& !_stopGenerator) {
|
||||
|
||||
generateKeysByTasks();
|
||||
generateRandomKeys();
|
||||
|
||||
_keyPoolSizeMutex->lock();
|
||||
keyPoolSize = _keyPoolSize;
|
||||
_keyPoolSizeMutex->unlock();
|
||||
}
|
||||
}
|
||||
|
||||
void KeyStorage::stop() {
|
||||
_stopGenerator = true;
|
||||
}
|
||||
|
||||
bool KeyStorage::waitForGeneratekey(const QString& key, int timeout) const {
|
||||
return waitFor([this, &key](){return _keys.contains(key);}, timeout);
|
||||
}
|
||||
|
||||
bool KeyStorage::waitForThreadFinished(int timeout) const {
|
||||
return waitFor([this](){return !isRunning();}, timeout);
|
||||
}
|
||||
|
||||
bool KeyStorage::waitFor(const std::function<bool()> &checkFunc, int timeout) const {
|
||||
auto waitFor = timeout + QDateTime::currentMSecsSinceEpoch();
|
||||
while (!checkFunc() && waitFor > QDateTime::currentMSecsSinceEpoch()) {
|
||||
QCoreApplication::processEvents();
|
||||
}
|
||||
|
||||
return checkFunc();
|
||||
}
|
||||
|
||||
void KeyStorage::loadAllKeysFromStorage() {
|
||||
auto list = QDir(storageLocation()).entryInfoList(QDir::Files | QDir::NoDotAndDotDot);
|
||||
|
||||
for (const auto& file: list ) {
|
||||
if (file.fileName() != VERSION_FILE) {
|
||||
fromStorage(file.fileName().toLatin1());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool KeyStorage::saveStorage() const {
|
||||
|
||||
bool result = true;
|
||||
for (auto it = _keys.begin(); it != _keys.end(); ++it) {
|
||||
result = result && toStorage(it.key());
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool KeyStorage::genKey(const QString &accessKey, const QByteArray &genesis) {
|
||||
|
||||
if (accessKey.isEmpty())
|
||||
return false;
|
||||
|
||||
QMutexLocker locker(_taskMutex);
|
||||
_generateTasks.insert(accessKey, genesis);
|
||||
return true;
|
||||
}
|
||||
|
||||
QString KeyStorage::storageLocation() const {
|
||||
return _storageLocation;
|
||||
}
|
||||
|
||||
bool KeyStorage::initStorageLocation(const QString &value) {
|
||||
QFile version(value + "/" + VERSION_FILE);
|
||||
|
||||
if (!QFile::exists(value)) {
|
||||
|
||||
if (!QDir().mkpath(value)) {
|
||||
QuasarAppUtils::Params::log(" fail to create a key storagge. Into "
|
||||
+ value, QuasarAppUtils::Error);
|
||||
return false;
|
||||
}
|
||||
|
||||
QFile::setPermissions(value,
|
||||
QFile::Permission::ExeOwner |
|
||||
QFile::Permission::ReadOwner |
|
||||
QFile::Permission::WriteOwner);
|
||||
|
||||
QFile version(value + "/" + VERSION_FILE);
|
||||
|
||||
if (!version.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
QDataStream stream(&version);
|
||||
stream << THE_CLASS(_cryptoMethod);
|
||||
version.close();
|
||||
|
||||
} else {
|
||||
|
||||
if (!version.open(QIODevice::ReadOnly)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
QDataStream stream(&version);
|
||||
QString versionName;
|
||||
stream >> versionName;
|
||||
version.close();
|
||||
|
||||
if (THE_CLASS(_cryptoMethod) != versionName) {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
_storageLocation = value;
|
||||
|
||||
return _storageLocation.size();
|
||||
|
||||
}
|
||||
|
||||
bool KeyStorage::initDefaultStorageLocation(const QString &dirName) {
|
||||
auto storageLoation =
|
||||
QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) +
|
||||
"/" + dirName;
|
||||
|
||||
if (dirName.isEmpty()) {
|
||||
storageLoation += THE_CLASS(_cryptoMethod);
|
||||
}
|
||||
|
||||
storageLoation += "/crypto/";
|
||||
|
||||
if (!initStorageLocation(storageLoation)) {
|
||||
QuasarAppUtils::Params::log("CryptoStorage not inited",
|
||||
QuasarAppUtils::Error);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
loadAllKeysFromStorage();
|
||||
|
||||
return _inited = true;
|
||||
}
|
||||
|
||||
void KeyStorage::clearStorage() const {
|
||||
QDir::root().remove(storageLocation());
|
||||
}
|
||||
|
||||
}
|
@ -1,266 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2018-2022 QuasarApp.
|
||||
* Distributed under the lgplv3 software license, see the accompanying
|
||||
* Everyone is permitted to copy and distribute verbatim copies
|
||||
* of this license document, but changing it is not allowed.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef KEYSTORAGE_H
|
||||
#define KEYSTORAGE_H
|
||||
|
||||
#include <QList>
|
||||
#include <QThread>
|
||||
#include "heart_global.h"
|
||||
#include <QByteArray>
|
||||
#include <QHash>
|
||||
#include <QSet>
|
||||
#include "config.h"
|
||||
|
||||
#define RAND_KEY ""
|
||||
|
||||
class QMutex;
|
||||
|
||||
|
||||
namespace QH {
|
||||
|
||||
class CryptoPairKeys;
|
||||
class ICrypto;
|
||||
/**
|
||||
* @brief The KeyStorage class provide the functionality of control crypto keys (generate, save and write).
|
||||
* The current implementation of the key storage is collected cryptokeys like files in a key storage location.
|
||||
*
|
||||
* Work scheme:
|
||||
*\image html KeyStorage.svg width=800px
|
||||
*/
|
||||
class HEARTSHARED_EXPORT KeyStorage: public QThread
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
/**
|
||||
* @brief KeyStorage
|
||||
* @param cryptoMethod This is pointer to any class inherited from ICrypto
|
||||
*/
|
||||
KeyStorage(ICrypto* cryptoMethod);
|
||||
~KeyStorage();
|
||||
|
||||
/**
|
||||
* @brief getNextPair This method take a one pair key from the keys pool or generate a new keys pair if the keys pool is empty.
|
||||
* @warning If key pool is empty then this method frease a current thread for awaiting f neg generated pair key.
|
||||
* @note if the key is not generated within the specified period of time, an invalid copy of the key pair will be returned.
|
||||
* @param accsessKey The byte array for get a accesses to key from storage.
|
||||
* @param genesis Set this params to empty for get random key pair or set the byte array for get a key pair for genesis array.
|
||||
* @param timeout_msec This is timeout in milisecunds. default is WAIT_TIME (30000)
|
||||
* @return pair of keys.
|
||||
*/
|
||||
CryptoPairKeys getNextPair(const QString &accsessKey,
|
||||
const QByteArray &genesis = RAND_KEY,
|
||||
int timeout_msec = WAIT_TIME);
|
||||
|
||||
/**
|
||||
* @brief getKeyPoolSize - This method return size of keyPool.
|
||||
* By default it is 1.
|
||||
* @return value of keys pool size.
|
||||
*/
|
||||
int getKeyPoolSize() const;
|
||||
|
||||
/**
|
||||
* @brief setKeyPoolSize This method return the size of keys pool.
|
||||
* and start new work for generation a new keys.
|
||||
* @param keyPoolSize This is a new size of pool.
|
||||
*/
|
||||
void setKeyPoolSize(int keyPoolSize);
|
||||
|
||||
/**
|
||||
* @brief isValid This method check keysStorage to valid.
|
||||
* @return true if the crypto object is valid.
|
||||
*/
|
||||
virtual bool isValid() const;
|
||||
|
||||
/**
|
||||
* @brief isInited This method returns true if the crypto object was initialized correctly.
|
||||
* @return true if the crypto object was initialized correctly.
|
||||
*/
|
||||
virtual bool isInited() const;
|
||||
|
||||
/**
|
||||
* @brief crypt This method crypted a data message using a publicKey.
|
||||
* @param data This is pointer to data array for crypting.
|
||||
* @note data has ben changed after call this method.
|
||||
* @param publicKey This is key for crypting data.
|
||||
* @return true if function finished successful.
|
||||
*/
|
||||
bool crypt(QByteArray *data, const QByteArray& publicKey);
|
||||
|
||||
/**
|
||||
* @brief decrypt This method decrypt a data message using a privateKey.
|
||||
* @param cryptedData - Pointer to data array for decrypting.
|
||||
* @note cryptedData Has been changed after call this method.
|
||||
* @param privateKey This is private key for decrypting data.
|
||||
* @return true if function finished successful.
|
||||
*/
|
||||
bool decrypt(QByteArray *cryptedData, const QByteArray& privateKey);
|
||||
|
||||
/**
|
||||
* @brief sign This method sign a message using a privateKey.
|
||||
* @param data This is pointer to data array for signed.
|
||||
* @note data has been changed after call this method.
|
||||
* @param privateKey This is key for signing a data message.
|
||||
* @return true if function finished successful.
|
||||
*/
|
||||
bool sign(QByteArray* data, const QByteArray& privateKey);
|
||||
|
||||
/**
|
||||
* @brief extractSign This method extract sign from signed byteArray.
|
||||
* @param data This is a signed message.
|
||||
* @return return array of sign.
|
||||
*/
|
||||
QByteArray extractSign(const QByteArray& data);
|
||||
|
||||
/**
|
||||
* @brief concatSign This method concat a data of message and signs of a message.
|
||||
* @param data This is message data.
|
||||
* @param sign This is a sign of message.
|
||||
* @return signed message.
|
||||
*/
|
||||
QByteArray concatSign(const QByteArray& data, const QByteArray& sign);
|
||||
|
||||
/**
|
||||
* @brief check This method fore validation signed message.
|
||||
* @param signedData This is signed message for checking.
|
||||
* @param publicKey This is public key for validation of message.
|
||||
* @return true if function finished successful and signedData is valid.
|
||||
*/
|
||||
bool check(const QByteArray& signedData, const QByteArray& publicKey);
|
||||
|
||||
/**
|
||||
* @brief setGenesisList - set genesis list for generation key pairs.
|
||||
* After invoke this method for each all items will be generated a keys pair.
|
||||
*/
|
||||
void setGenesisList(const QList<QByteArray> &list);
|
||||
|
||||
/**
|
||||
* @brief storageLocation This method return a path of the storage location.
|
||||
* By default storageLocation is QStandardPaths::DataLocation/KeysStorage
|
||||
* @return path to storage location of crypto keys.
|
||||
*/
|
||||
QString storageLocation() const;
|
||||
|
||||
/**
|
||||
* @brief initStorageLocation This method set a new path for storage location of keys.
|
||||
* @param value This is a new path to storage location.
|
||||
*/
|
||||
bool initStorageLocation(const QString &value);
|
||||
|
||||
/**
|
||||
* @brief initDefaultStorageLocation These is some as initStorageLocation,
|
||||
* but set default path.
|
||||
* @param dirName This is name of storage location. If This parametr weel be empty then
|
||||
* storage location set default direction name. By default is name of crypto class.
|
||||
* By default path of storage is:
|
||||
* \code
|
||||
* QStandardPaths::AppDataLocation/crypto/dirName;
|
||||
* \endcode
|
||||
* @return true if the storage inited successful.
|
||||
*/
|
||||
bool initDefaultStorageLocation(const QString& dirName = "");
|
||||
|
||||
/**
|
||||
* @brief clearStorage - This method clear all storage.
|
||||
*/
|
||||
void clearStorage() const;
|
||||
|
||||
protected:
|
||||
|
||||
/**
|
||||
* @brief toStorage This method save key into local storage.
|
||||
* @param key This is key data value of keys pair.
|
||||
* @note override this method if you want to change storage location or method of save of keys.
|
||||
* @return true if key saved successful.
|
||||
*/
|
||||
virtual bool toStorage(const QString &key) const;
|
||||
|
||||
/**
|
||||
* @brief fromStorage This method load keys from local storage.
|
||||
* @param key This is key data value of keys pair.
|
||||
* @return true if key pair saved successful.
|
||||
*/
|
||||
virtual bool fromStorage(const QByteArray& key);
|
||||
|
||||
/**
|
||||
* @brief run This method start the key generator on own thread.
|
||||
*/
|
||||
void run() override;
|
||||
|
||||
/**
|
||||
* @brief stop This method stop generate keys.
|
||||
*/
|
||||
void stop();
|
||||
private:
|
||||
|
||||
/**
|
||||
* @brief waitForGeneratekey.
|
||||
* @param timeout - maximum time for generation new key. by default = WAIT_TIME (30000)
|
||||
* @return true if key generated successful.
|
||||
*/
|
||||
bool waitForGeneratekey(const QString &key, int timeout = WAIT_TIME) const;
|
||||
|
||||
/**
|
||||
* @brief waitForThreadFinished
|
||||
* @param timeout
|
||||
* @return
|
||||
*/
|
||||
bool waitForThreadFinished(int timeout = WAIT_TIME) const;
|
||||
|
||||
/**
|
||||
* @brief waitFor - Base wait function.
|
||||
* @param checkFunc - This is lambda of check event.
|
||||
* @param timeout - Maximum time line of waiting of event.
|
||||
* @return true if event is checkFunc return true.
|
||||
*/
|
||||
bool waitFor(const std::function<bool()>& checkFunc, int timeout) const;
|
||||
|
||||
/**
|
||||
* @brief loadAllKeysFromStorage
|
||||
*/
|
||||
void loadAllKeysFromStorage();
|
||||
|
||||
/**
|
||||
* @brief saveStorage This method for saved keys in storage.
|
||||
* @return true if all keys has been saved in a storage.
|
||||
*/
|
||||
bool saveStorage() const;
|
||||
|
||||
/**
|
||||
* @brief genKey - this method add a new task for generate keys pair
|
||||
* @param accessKey - the byte array for get access of the keys pair.
|
||||
* @param genesis - The byte array for generate new key.
|
||||
* @note If access key well be empty then this method return false.
|
||||
* @note For generate random key use a RAND_KEY genesis or empty value.
|
||||
* @return true if task of generation a new pair keys added successful else false.
|
||||
*/
|
||||
bool genKey(const QString &accessKey, const QByteArray& genesis = RAND_KEY);
|
||||
|
||||
QHash<QString, CryptoPairKeys> _keys;
|
||||
QSet<CryptoPairKeys> _randomKeysPool;
|
||||
|
||||
QHash<QString, QByteArray> _generateTasks;
|
||||
|
||||
int _keyPoolSize = 1;
|
||||
|
||||
QMutex *_keyPoolSizeMutex = nullptr;
|
||||
QMutex *_keysMutex = nullptr;
|
||||
QMutex *_taskMutex = nullptr;
|
||||
|
||||
QString _storageLocation;
|
||||
|
||||
bool _inited = false;
|
||||
bool _stopGenerator = false;
|
||||
|
||||
ICrypto *_cryptoMethod = nullptr;
|
||||
|
||||
void generateKeysByTasks();
|
||||
void generateRandomKeys();
|
||||
};
|
||||
}
|
||||
#endif // KEYSTORAGE_H
|
@ -9,7 +9,6 @@
|
||||
#include <QDataStream>
|
||||
#include <QMap>
|
||||
#include <typeinfo>
|
||||
#include "heart.h"
|
||||
#include <limits>
|
||||
#include <quasarapp.h>
|
||||
#include <QCryptographicHash>
|
||||
@ -44,17 +43,9 @@ bool AbstractData::toPackage(Package &package,
|
||||
return package.isValid();
|
||||
}
|
||||
|
||||
QDataStream &AbstractData::fromStream(QDataStream &stream) {
|
||||
return stream;
|
||||
}
|
||||
|
||||
QDataStream &AbstractData::toStream(QDataStream &stream) const {
|
||||
return stream;
|
||||
}
|
||||
|
||||
bool AbstractData::checkCmd() const {
|
||||
unsigned int code = typeid (*this).hash_code();
|
||||
return code == localCode(); \
|
||||
return code == localCode();
|
||||
}
|
||||
|
||||
bool AbstractData::isValid() const {
|
||||
|
@ -7,6 +7,7 @@
|
||||
|
||||
#ifndef ABSTRACTDATA_H
|
||||
#define ABSTRACTDATA_H
|
||||
#include "humanreadableobject.h"
|
||||
#include "package.h"
|
||||
#include <streambase.h>
|
||||
|
||||
@ -49,12 +50,10 @@ public:
|
||||
protected:
|
||||
// StreamBase interface override this methods for serialization your package
|
||||
QDataStream &fromStream(QDataStream &stream) {
|
||||
AbstractData::fromStream(stream);
|
||||
stream >> _data;
|
||||
return stream;
|
||||
}
|
||||
QDataStream &toStream(QDataStream &stream) const {
|
||||
AbstractData::toStream(stream);
|
||||
stream << _data;
|
||||
return stream;
|
||||
}
|
||||
@ -122,11 +121,11 @@ protected:
|
||||
* If the implementation of this method differs from the example, the data will not be copied correctly.
|
||||
* @see AbstractNode
|
||||
*/
|
||||
class HEARTSHARED_EXPORT AbstractData : public StreamBase
|
||||
class HEARTSHARED_EXPORT AbstractData : public StreamBase, public QuasarAppUtils::iHRO
|
||||
{
|
||||
public:
|
||||
|
||||
virtual ~AbstractData() override;
|
||||
~AbstractData() override;
|
||||
|
||||
/**
|
||||
* @brief cmd - This is command of this object, (for generate cmd use macross QH_PACKAGE)
|
||||
@ -184,7 +183,7 @@ public:
|
||||
* @brief toString - Return a string implementation for this object.
|
||||
* @return String of object.
|
||||
*/
|
||||
virtual QString toString() const;
|
||||
QString toString() const override;
|
||||
|
||||
/**
|
||||
* @brief create - This is factory method for create a new object.
|
||||
@ -229,9 +228,6 @@ protected:
|
||||
*/
|
||||
virtual unsigned int localCode() const = 0;
|
||||
|
||||
QDataStream& fromStream(QDataStream& stream) override;
|
||||
QDataStream& toStream(QDataStream& stream) const override;
|
||||
|
||||
private:
|
||||
/**
|
||||
* @brief checkCmd This method check QH_PACKAGE macross.
|
||||
|
@ -28,7 +28,6 @@ BadRequest::BadRequest(const Package &package):
|
||||
}
|
||||
|
||||
QDataStream &BadRequest::fromStream(QDataStream &stream) {
|
||||
AbstractData::fromStream(stream);
|
||||
|
||||
stream >> _errCode;
|
||||
stream >> _err;
|
||||
@ -37,7 +36,6 @@ QDataStream &BadRequest::fromStream(QDataStream &stream) {
|
||||
}
|
||||
|
||||
QDataStream &BadRequest::toStream(QDataStream &stream) const {
|
||||
AbstractData::toStream(stream);
|
||||
|
||||
stream << _errCode;
|
||||
stream << _err;
|
||||
|
@ -25,16 +25,12 @@ void BigDataBase::setPackageId(int newPackageId) {
|
||||
}
|
||||
|
||||
QDataStream &BigDataBase::fromStream(QDataStream &stream) {
|
||||
AbstractData::fromStream(stream);
|
||||
|
||||
stream >> _packageId;
|
||||
|
||||
return stream;
|
||||
}
|
||||
|
||||
QDataStream &BigDataBase::toStream(QDataStream &stream) const {
|
||||
AbstractData::toStream(stream);
|
||||
|
||||
stream << _packageId;
|
||||
|
||||
return stream;
|
||||
|
@ -14,5 +14,13 @@ namespace PKG {
|
||||
CloseConnection::CloseConnection() {
|
||||
|
||||
}
|
||||
|
||||
QDataStream &CloseConnection::fromStream(QDataStream &stream) {
|
||||
return stream;
|
||||
}
|
||||
|
||||
QDataStream &CloseConnection::toStream(QDataStream &stream) const {
|
||||
return stream;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -31,6 +31,11 @@ class HEARTSHARED_EXPORT CloseConnection: public AbstractData
|
||||
|
||||
public:
|
||||
CloseConnection();
|
||||
|
||||
// StreamBase interface
|
||||
protected:
|
||||
QDataStream &fromStream(QDataStream &stream) override;
|
||||
QDataStream &toStream(QDataStream &stream) const override;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -53,8 +53,23 @@ public:
|
||||
_packData.push_back(data);
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief isValid This implementation check all items of the pack to valid and packa size. The pack size should be more then 0.
|
||||
* @return true if the pack of items is valid else flase..
|
||||
*/
|
||||
bool isValid() const override {
|
||||
return AbstractData::isValid() && _packData.size();
|
||||
|
||||
if (!_packData.size()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (const auto& it: _packData) {
|
||||
if (!it->isValid()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return AbstractData::isValid();
|
||||
};
|
||||
|
||||
/**
|
||||
@ -77,7 +92,6 @@ public:
|
||||
|
||||
protected:
|
||||
QDataStream &fromStream(QDataStream &stream) override {
|
||||
AbstractData::fromStream(stream);
|
||||
|
||||
int size = 0;
|
||||
stream >> size;
|
||||
@ -95,7 +109,6 @@ protected:
|
||||
};
|
||||
|
||||
QDataStream &toStream(QDataStream &stream) const override {
|
||||
AbstractData::toStream(stream);
|
||||
stream << static_cast<int>(_packData.size());
|
||||
|
||||
for (const auto &ptr: qAsConst(_packData)) {
|
||||
|
@ -33,14 +33,12 @@ void Ping::setAnsver(bool ansver) {
|
||||
}
|
||||
|
||||
QDataStream &Ping::fromStream(QDataStream &stream) {
|
||||
AbstractData::fromStream(stream);
|
||||
stream >> _ansver;
|
||||
return stream;
|
||||
|
||||
}
|
||||
|
||||
QDataStream &Ping::toStream(QDataStream &stream) const {
|
||||
AbstractData::toStream(stream);
|
||||
stream << _ansver;
|
||||
return stream;
|
||||
}
|
||||
|
@ -5,7 +5,6 @@
|
||||
* of this license document, but changing it is not allowed.
|
||||
*/
|
||||
|
||||
#include "package.h"
|
||||
#include "streambase.h"
|
||||
|
||||
#include <QDataStream>
|
||||
@ -35,6 +34,18 @@ QByteArray StreamBase::toBytes() const {
|
||||
return res;
|
||||
}
|
||||
|
||||
bool StreamBase::fromBase64(const QString &data) {
|
||||
return fromBase64(data.toLatin1());
|
||||
}
|
||||
|
||||
bool StreamBase::fromBase64(const QByteArray &data) {
|
||||
return fromBytes(QByteArray::fromBase64(data, QByteArray::Base64UrlEncoding));
|
||||
}
|
||||
|
||||
QByteArray StreamBase::toBase64() const {
|
||||
return toBytes().toBase64(QByteArray::Base64UrlEncoding);
|
||||
}
|
||||
|
||||
unsigned int StreamBase::typeId() const {
|
||||
return typeid (*this).hash_code();
|
||||
}
|
||||
|
@ -42,6 +42,26 @@ public:
|
||||
*/
|
||||
QByteArray toBytes() const;
|
||||
|
||||
/**
|
||||
* @brief fromBase64 This method provide initialization of object from the base64 string.
|
||||
* @param data This is input base64 data.
|
||||
* @note converting from the QString is slowly instand of QByteArray, so use the StreamBase::fromBase64(const QByteArray &data) method.
|
||||
* @return true if all good else false.
|
||||
*/
|
||||
bool fromBase64(const QString &data);
|
||||
|
||||
/**
|
||||
* @brief fromBase64 This method provide initialization of object from the base64 string.
|
||||
* @param data This is input base64 data.
|
||||
* @return true if all good else false.
|
||||
*/
|
||||
bool fromBase64(const QByteArray &data);
|
||||
|
||||
/**
|
||||
* @brief toBase64 This method convert a current object to the base64 string.
|
||||
* @return base64 string of this object.
|
||||
*/
|
||||
QByteArray toBase64() const;
|
||||
|
||||
/**
|
||||
* @brief This is wrapper over toStream.
|
||||
|
@ -36,6 +36,8 @@ if (${HEART_BUILD_LVL} GREATER_EQUAL 0)
|
||||
"AbstractSpace/*.cpp" "AbstractSpace/*.h" "AbstractSpace/*.qrc"
|
||||
"AbstractSpace/packages/*.cpp" "AbstractSpace/packages/*.h" "AbstractSpace/packages/*.qrc"
|
||||
"AbstractSpace/Private/*.cpp" "AbstractSpace/Private/*.h" "AbstractSpace/Private/*.qrc"
|
||||
"AbstractSpace/hcrypto/*.cpp" "AbstractSpace/hcrypto/*.h" "AbstractSpace/hcrypto/*.qrc"
|
||||
"AbstractSpace/hcryptoFeatures/*.cpp" "AbstractSpace/hcryptoFeatures/*.h" "AbstractSpace/hcryptoFeatures/*.qrc"
|
||||
|
||||
)
|
||||
|
||||
|
@ -40,12 +40,11 @@ bool BaseNodeInfo::confirmData() const {
|
||||
return AbstractNodeInfo::confirmData();
|
||||
}
|
||||
|
||||
const QVariant& BaseNodeInfo::id() const {
|
||||
const QString& BaseNodeInfo::id() const {
|
||||
return _id;
|
||||
}
|
||||
|
||||
void BaseNodeInfo::setId(const QVariant &id)
|
||||
{
|
||||
void BaseNodeInfo::setId(const QString &id) {
|
||||
_id = id;
|
||||
}
|
||||
|
||||
|
@ -56,17 +56,17 @@ public:
|
||||
* @brief id This method return id of the connected user.
|
||||
* @return User id.
|
||||
*/
|
||||
const QVariant &id() const;
|
||||
const QString &id() const;
|
||||
|
||||
/**
|
||||
* @brief setId This method set userId for connected object.
|
||||
* @param id This is new value of user id.
|
||||
*/
|
||||
void setId(const QVariant &id);
|
||||
void setId(const QString &id);
|
||||
|
||||
protected:
|
||||
AccessToken _token;
|
||||
QVariant _id;
|
||||
QString _id;
|
||||
|
||||
};
|
||||
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include <sqldb.h>
|
||||
#include "getsinglevalue.h"
|
||||
#include "setsinglevalue.h"
|
||||
#include <qaglobalutils.h>
|
||||
|
||||
namespace QH {
|
||||
using namespace PKG;
|
||||
@ -135,7 +136,7 @@ bool DataBase::welcomeAddress(AbstractNodeInfo *) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DataBase::isBanned(const QVariant &node) const {
|
||||
bool DataBase::isBanned(const QString &node) const {
|
||||
NetworkMember member(node);
|
||||
auto objectFromDataBase = db()->getObject<AbstractNetworkMember>(member);
|
||||
|
||||
@ -163,8 +164,22 @@ void DataBase::objectChanged(const QSharedPointer<DBObject> &) {
|
||||
|
||||
}
|
||||
|
||||
DBPatchMap DataBase::dbPatches() const {
|
||||
return {};
|
||||
const DBPatchMap DataBase::dbPatches() const {
|
||||
return _dbPatches;
|
||||
}
|
||||
|
||||
void DataBase::addDBPatch(const DBPatch &patch) {
|
||||
debug_assert(patch.isValid(),
|
||||
"Failed to initialise a Data base patch!"
|
||||
" Patch object is invalid");
|
||||
|
||||
|
||||
debug_assert(!_dbPatches[patch.versionFrom].contains(patch.versionTo),
|
||||
"Failed to initialise a Data base patch!");
|
||||
|
||||
_dbPatches[patch.versionFrom][patch.versionTo] = patch;
|
||||
|
||||
_targetDBVersion = std::max(_targetDBVersion, patch.versionTo);
|
||||
}
|
||||
|
||||
void DataBase::memberSubsribed(const QVariant &, unsigned int ) {
|
||||
@ -183,7 +198,7 @@ QString DataBase::dbLocation() const {
|
||||
return "";
|
||||
}
|
||||
|
||||
bool DataBase::changeTrust(const QVariant &id, int diff) {
|
||||
bool DataBase::changeTrust(const QString &id, int diff) {
|
||||
if (!_db)
|
||||
return false;
|
||||
|
||||
@ -210,13 +225,16 @@ bool DataBase::isForbidenTable(const QString &table) {
|
||||
}
|
||||
|
||||
bool DataBase::upgradeDataBase() {
|
||||
auto patches = dbPatches();
|
||||
int actyalyVersion = patches.size();
|
||||
int currentVersion = 0;
|
||||
|
||||
if (!db())
|
||||
return false;
|
||||
|
||||
DBPatchMap patchesPack = dbPatches();
|
||||
if (!patchesPack.size()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
int currentVersion = 0;
|
||||
|
||||
bool fsupportUpgrade = db()->doQuery("SELECT COUNT(*) FROM DataBaseAttributes", true);
|
||||
|
||||
if (!fsupportUpgrade) {
|
||||
@ -232,31 +250,39 @@ bool DataBase::upgradeDataBase() {
|
||||
|
||||
if (auto responce = _db->getObject(request)) {
|
||||
currentVersion = responce->value().toInt();
|
||||
}
|
||||
}
|
||||
|
||||
bool fUpdated = false;
|
||||
while (currentVersion < actyalyVersion) {
|
||||
if (currentVersion < _targetDBVersion)
|
||||
onBeforeDBUpgrade(currentVersion, _targetDBVersion);
|
||||
|
||||
auto patch = patches.value(currentVersion, {});
|
||||
while (currentVersion < _targetDBVersion) {
|
||||
|
||||
QString message;
|
||||
message = "Upgrade data base!. to %0 versions";
|
||||
message = "Upgrade data base from %0 to %1 versions. %2";
|
||||
message = message.arg(currentVersion);
|
||||
|
||||
QuasarAppUtils::Params::log(message,
|
||||
QuasarAppUtils::Info);
|
||||
auto patches = patchesPack.value(currentVersion, {});
|
||||
|
||||
if (patch && !patch(db())) {
|
||||
QuasarAppUtils::Params::log("Failed to " + message,
|
||||
if (!patches.size()) {
|
||||
QuasarAppUtils::Params::log("Failed to " + message.arg("Unknown", "Required patch not found!"),
|
||||
QuasarAppUtils::Error);
|
||||
return false;
|
||||
}
|
||||
|
||||
currentVersion++;
|
||||
fUpdated = true;
|
||||
}
|
||||
auto patch = patches.last();
|
||||
message = message.arg(patch.versionTo);
|
||||
|
||||
QuasarAppUtils::Params::log(message.arg("(Begin)"),
|
||||
QuasarAppUtils::Info);
|
||||
|
||||
if (!patch.action(db())) {
|
||||
QuasarAppUtils::Params::log("Failed to " + message.arg("Patch finished with error code!"),
|
||||
QuasarAppUtils::Error);
|
||||
return false;
|
||||
}
|
||||
|
||||
currentVersion = patch.versionTo;
|
||||
|
||||
if (fUpdated) {
|
||||
auto updateVersionRequest = QSharedPointer<PKG::SetSingleValue>::create(
|
||||
DbAddress{"DataBaseAttributes", "version"},
|
||||
"value", currentVersion, "name");
|
||||
@ -271,6 +297,8 @@ bool DataBase::upgradeDataBase() {
|
||||
return true;
|
||||
}
|
||||
|
||||
void DataBase::onBeforeDBUpgrade(int , int ) const { }
|
||||
|
||||
const QString &DataBase::localNodeName() const {
|
||||
return _localNodeName;
|
||||
}
|
||||
@ -288,7 +316,7 @@ QVariantMap DataBase::defaultDbParams() const {
|
||||
}
|
||||
|
||||
DBOperationResult
|
||||
QH::DataBase::getObject(const QVariant &requester,
|
||||
QH::DataBase::getObject(const QString &requester,
|
||||
const QH::DBObject &templateObj,
|
||||
QSharedPointer<QH::PKG::DBObject> &result) const {
|
||||
|
||||
@ -312,7 +340,7 @@ QH::DataBase::getObject(const QVariant &requester,
|
||||
}
|
||||
|
||||
DBOperationResult
|
||||
DataBase::getObjects(const QVariant &requester,
|
||||
DataBase::getObjects(const QString &requester,
|
||||
const DBObject &templateObj,
|
||||
QList<QSharedPointer<DBObject>> &result) const {
|
||||
if (!_db) {
|
||||
@ -338,7 +366,7 @@ DataBase::getObjects(const QVariant &requester,
|
||||
}
|
||||
|
||||
DBOperationResult
|
||||
DataBase::updateObject(const QVariant &requester,
|
||||
DataBase::updateObject(const QString &requester,
|
||||
const QSharedPointer<DBObject> &saveObject) {
|
||||
|
||||
if (!_db) {
|
||||
@ -360,14 +388,14 @@ DataBase::updateObject(const QVariant &requester,
|
||||
}
|
||||
|
||||
DBOperationResult
|
||||
DataBase::createObject(const QVariant &requester,
|
||||
DataBase::createObject(const QString &requester,
|
||||
const QSharedPointer<DBObject> &obj) {
|
||||
|
||||
if (!_db) {
|
||||
return DBOperationResult::Unknown;
|
||||
}
|
||||
|
||||
if (isForbidenTable(obj->tableName())) {
|
||||
if (isForbidenTable(obj->table())) {
|
||||
return DBOperationResult::Forbidden;
|
||||
}
|
||||
|
||||
@ -387,7 +415,7 @@ DataBase::createObject(const QVariant &requester,
|
||||
}
|
||||
|
||||
DBOperationResult
|
||||
DataBase::updateIfNotExistsCreateObject(const QVariant &requester,
|
||||
DataBase::updateIfNotExistsCreateObject(const QString &requester,
|
||||
const QSharedPointer<DBObject> &obj) {
|
||||
|
||||
auto opResult = updateObject(requester, obj);
|
||||
@ -399,7 +427,7 @@ DataBase::updateIfNotExistsCreateObject(const QVariant &requester,
|
||||
}
|
||||
|
||||
DBOperationResult
|
||||
DataBase::changeObjects(const QVariant &requester,
|
||||
DataBase::changeObjects(const QString &requester,
|
||||
const DBObject &templateObj,
|
||||
const std::function<bool (const QSharedPointer<DBObject> &)> &changeAction) {
|
||||
|
||||
@ -438,11 +466,11 @@ QVariant DataBase::getSender(const AbstractNodeInfo *connectInfo,
|
||||
}
|
||||
|
||||
DBOperationResult
|
||||
DataBase::checkPermission(const QVariant &requester,
|
||||
DataBase::checkPermission(const QString &requester,
|
||||
const DbAddress &objectAddress,
|
||||
const Permission& requarimentPermision) const {
|
||||
|
||||
if (!requester.isValid())
|
||||
if (!requester.isEmpty())
|
||||
return DBOperationResult::Unknown;
|
||||
|
||||
if (!_db) {
|
||||
@ -518,7 +546,7 @@ bool DataBase::removePermission(const QVariant &member,
|
||||
}
|
||||
|
||||
DBOperationResult
|
||||
DataBase::deleteObject(const QVariant &requester,
|
||||
DataBase::deleteObject(const QString &requester,
|
||||
const QSharedPointer<DBObject> &dbObject) {
|
||||
|
||||
if (!_db) {
|
||||
|
@ -8,7 +8,7 @@
|
||||
#ifndef QH_DATABASE_H
|
||||
#define QH_DATABASE_H
|
||||
|
||||
#include "abstractnode.h"
|
||||
#include "dbpatch.h"
|
||||
#include <dbobject.h>
|
||||
#include <hostaddress.h>
|
||||
#include <permission.h>
|
||||
@ -27,20 +27,7 @@ class SqlDBWriter;
|
||||
class DbAddress;
|
||||
class NodeId;
|
||||
class iObjectProvider;
|
||||
|
||||
|
||||
/**
|
||||
* @brief DBPatch This is function that should be upgrade database.
|
||||
* @see DBPatchMap
|
||||
* @see DataBaseNode::dbPatch
|
||||
*/
|
||||
typedef std::function<bool (const QH::iObjectProvider *)> DBPatch;
|
||||
/**
|
||||
* @brief DBPatchMap This is list when index of list is version of database and value if function that should be upgrade database.
|
||||
* @see DataBaseNode::dbPatch
|
||||
* @see DBPatchMap
|
||||
*/
|
||||
typedef QList<DBPatch> DBPatchMap;
|
||||
class AbstractNodeInfo;
|
||||
|
||||
/**
|
||||
* @brief The DataBase class is DataBase base implementation.
|
||||
@ -111,7 +98,7 @@ public:
|
||||
* @return result of operation (allow, forbidden, unknown).
|
||||
* For more information about results see the DBOperationResult enum.
|
||||
*/
|
||||
DBOperationResult deleteObject(const QVariant &requester,
|
||||
DBOperationResult deleteObject(const QString &requester,
|
||||
const QSharedPointer<PKG::DBObject> &dbObject);
|
||||
|
||||
/**
|
||||
@ -123,7 +110,7 @@ public:
|
||||
* @return result of operation (allow, forbidden, unknown).
|
||||
* For more information about results see the DBOperationResult enum.
|
||||
*/
|
||||
DBOperationResult getObject(const QVariant &requester,
|
||||
DBOperationResult getObject(const QString &requester,
|
||||
const PKG::DBObject &templateObj,
|
||||
QSharedPointer<PKG::DBObject> &result) const;
|
||||
|
||||
@ -136,7 +123,7 @@ public:
|
||||
* @return result of operation (allow, forbidden, unknown).
|
||||
* For more information about results see the DBOperationResult enum.
|
||||
*/
|
||||
DBOperationResult getObjects(const QVariant &requester,
|
||||
DBOperationResult getObjects(const QString &requester,
|
||||
const PKG::DBObject &templateObj,
|
||||
QList<QSharedPointer<PKG::DBObject>> &result) const;
|
||||
|
||||
@ -148,7 +135,7 @@ public:
|
||||
* @return result of operation (allow, forbidden, unknown).
|
||||
* For more information about results see the DBOperationResult enum.
|
||||
*/
|
||||
DBOperationResult updateObject(const QVariant &requester,
|
||||
DBOperationResult updateObject(const QString &requester,
|
||||
const QSharedPointer<PKG::DBObject> &saveObject);
|
||||
|
||||
/**
|
||||
@ -159,7 +146,7 @@ public:
|
||||
* @return result of operation (allow, forbidden, unknown).
|
||||
* For more information about results see the DBOperationResult enum.
|
||||
*/
|
||||
DBOperationResult createObject(const QVariant &requester,
|
||||
DBOperationResult createObject(const QString &requester,
|
||||
const QSharedPointer<PKG::DBObject> &obj);
|
||||
|
||||
/**
|
||||
@ -172,7 +159,7 @@ public:
|
||||
* @return result of operation (allow, forbidden, unknown).
|
||||
* For more information about results see the DBOperationResult enum.
|
||||
*/
|
||||
DBOperationResult updateIfNotExistsCreateObject(const QVariant &requester,
|
||||
DBOperationResult updateIfNotExistsCreateObject(const QString &requester,
|
||||
const QSharedPointer<PKG::DBObject> &obj);
|
||||
|
||||
/**
|
||||
@ -185,7 +172,7 @@ public:
|
||||
* @return result of operation (allow, forbidden, unknown).
|
||||
* For more information about results see the DBOperationResult enum.
|
||||
*/
|
||||
DBOperationResult changeObjects(const QVariant &requester,
|
||||
DBOperationResult changeObjects(const QString &requester,
|
||||
const PKG::DBObject &templateObj,
|
||||
const std::function<bool (const QSharedPointer<QH::PKG::DBObject>&)> &changeAction);
|
||||
|
||||
@ -194,7 +181,7 @@ public:
|
||||
* @param member This is member of network (node, client or server).
|
||||
* @return true if node is banned.
|
||||
*/
|
||||
bool isBanned(const QVariant &member) const;
|
||||
bool isBanned(const QString &member) const;
|
||||
|
||||
/**
|
||||
* @brief dbLocation This method return location of nodes or clients database.
|
||||
@ -209,7 +196,7 @@ public:
|
||||
* @param diff This is difference of trust.
|
||||
* @return true if trust of user changed successful.
|
||||
*/
|
||||
bool changeTrust(const QVariant &id, int diff);
|
||||
bool changeTrust(const QString &id, int diff);
|
||||
|
||||
signals:
|
||||
|
||||
@ -296,7 +283,7 @@ protected:
|
||||
* @return DBOperationResult::Alowed if permission granted.
|
||||
* For more information about result see the DBOperationResult enum.
|
||||
*/
|
||||
virtual DBOperationResult checkPermission(const QVariant &requester,
|
||||
virtual DBOperationResult checkPermission(const QString &requester,
|
||||
const DbAddress& objectAddress,
|
||||
const Permission& requarimentPermision) const;
|
||||
|
||||
@ -402,31 +389,48 @@ protected:
|
||||
* Where the 0 version is first version of database. (genesis)
|
||||
*
|
||||
* @code{cpp}
|
||||
* QH::DBPatchMap dbPatches() const {
|
||||
QH::DBPatchMap result;
|
||||
addDBPatch({
|
||||
0, // fromVersion
|
||||
1, // toVersion
|
||||
[](const QH::iObjectProvider* database) -> bool {
|
||||
// Some code for update from 0 to 1
|
||||
} // action of patch
|
||||
});
|
||||
|
||||
result += [](const QH::iObjectProvider* database) -> bool {
|
||||
// Some code for update from 0 to 1
|
||||
};
|
||||
addDBPatch({
|
||||
1, // fromVersion
|
||||
2, // toVersion
|
||||
[](const QH::iObjectProvider* database) -> bool {
|
||||
// Some code for update from 1 to 2
|
||||
} // action of patch
|
||||
});
|
||||
|
||||
result += [](const QH::iObjectProvider* database) -> bool {
|
||||
// Some code for update from 1 to 2
|
||||
};
|
||||
|
||||
result += [](const QH::iObjectProvider* database) -> bool {
|
||||
// Some code for update from 2 to 3
|
||||
};
|
||||
|
||||
return result;
|
||||
}
|
||||
addDBPatch({
|
||||
2, // fromVersion
|
||||
3, // toVersion
|
||||
[](const QH::iObjectProvider* database) -> bool {
|
||||
// Some code for update from 2 to 3
|
||||
} // action of patch
|
||||
});
|
||||
* @endcode
|
||||
*
|
||||
* @return Map of database pactches.
|
||||
*
|
||||
* @see DBPatchMap
|
||||
* @see DBPatch
|
||||
* @see DataBase::addDBPatch
|
||||
* @see DataBase::onBeforeDBUpgrade
|
||||
*/
|
||||
virtual DBPatchMap dbPatches() const;
|
||||
virtual const DBPatchMap dbPatches() const;
|
||||
|
||||
/**
|
||||
* @brief addDBPatch This method add database patch to the data base object.
|
||||
* @param patch This is object of the database patch
|
||||
* @note This method will be crashed if patch is invalid.
|
||||
* @see DataBase::dbPatches
|
||||
* @see DataBase::onBeforeDBUpgrade
|
||||
*/
|
||||
void addDBPatch(const DBPatch& patch);
|
||||
|
||||
/**
|
||||
* @brief upgradeDataBase This method upgrade data base to actyaly database version.
|
||||
@ -435,6 +439,15 @@ protected:
|
||||
* @note if you want to disable this feature then override this method and return true.
|
||||
*/
|
||||
virtual bool upgradeDataBase();
|
||||
|
||||
/**
|
||||
* @brief onBeforeDBUpgrade This method will be invoked before upgrade database.
|
||||
* @param currentVerion This is current database version
|
||||
* @param tergetVersion This is target database version.
|
||||
* @see DataBase::dbPatches
|
||||
* @see DataBase::addDBPatch
|
||||
*/
|
||||
virtual void onBeforeDBUpgrade(int currentVerion, int tergetVersion) const;
|
||||
private:
|
||||
/**
|
||||
* @brief workWithSubscribe This method work with subscribe commnads.
|
||||
@ -450,6 +463,8 @@ private:
|
||||
bool isForbidenTable(const QString& table);
|
||||
|
||||
ISqlDBCache *_db = nullptr;
|
||||
unsigned short _targetDBVersion = 0;
|
||||
DBPatchMap _dbPatches;
|
||||
QString _localNodeName;
|
||||
friend class DataBaseNode;
|
||||
|
||||
|
@ -20,7 +20,6 @@
|
||||
#include <websocketcontroller.h>
|
||||
#include <QCoreApplication>
|
||||
#include <ping.h>
|
||||
#include <keystorage.h>
|
||||
#include <basenodeinfo.h>
|
||||
#include <abstractnetworkmember.h>
|
||||
#include <memberpermisionobject.h>
|
||||
@ -89,7 +88,7 @@ bool DataBaseNode::isSqlInited() const {
|
||||
return _db && _db->isSqlInited();
|
||||
}
|
||||
|
||||
DBOperationResult DataBaseNode::checkPermission(const QVariant &requester,
|
||||
DBOperationResult DataBaseNode::checkPermission(const QString &requester,
|
||||
const DbAddress &objectAddress,
|
||||
const Permission &requarimentPermision) const {
|
||||
if (!_db) {
|
||||
@ -126,10 +125,14 @@ bool DataBaseNode::welcomeAddress(AbstractNodeInfo *) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DataBaseNode::isBanned(const QVariant &node) const {
|
||||
bool DataBaseNode::isBanned(const QString &node) const {
|
||||
return db()->isBanned(node);
|
||||
}
|
||||
|
||||
bool DataBaseNode::isBanned(const AbstractNodeInfo *node) const {
|
||||
return AbstractNode::isBanned(node);
|
||||
}
|
||||
|
||||
bool DataBaseNode::notifyObjectChanged(const QSharedPointer<PKG::ISubscribableData> &item) {
|
||||
|
||||
if (!item.dynamicCast<PKG::AbstractData>()) {
|
||||
@ -199,13 +202,13 @@ bool DataBaseNode::changeTrust(const HostAddress &id, int diff) {
|
||||
if (!info)
|
||||
return false;
|
||||
|
||||
if (info->id().isValid())
|
||||
if (info->id().size())
|
||||
return changeTrust(info->id(), diff);
|
||||
|
||||
return AbstractNode::changeTrust(id, diff);
|
||||
}
|
||||
|
||||
bool DataBaseNode::changeTrust(const QVariant &id, int diff) {
|
||||
bool DataBaseNode::changeTrust(const QString &id, int diff) {
|
||||
if (!_db)
|
||||
return false;
|
||||
return _db->changeTrust(id, diff);
|
||||
@ -250,7 +253,7 @@ ParserResult DataBaseNode::parsePackage(const QSharedPointer<AbstractData> &pkg,
|
||||
if (WebSocket::command() == pkg->cmd()) {
|
||||
WebSocket *obj = static_cast<WebSocket*>(pkg.data());
|
||||
|
||||
QVariant requesterId = getSender(sender, obj);
|
||||
auto requesterId = getSender(sender, obj);
|
||||
if (!obj->isValid()) {
|
||||
badRequest(sender->networkAddress(), pkgHeader,
|
||||
{
|
||||
@ -289,7 +292,7 @@ DataBase *DataBaseNode::db() const {
|
||||
}
|
||||
|
||||
bool DataBaseNode::workWithSubscribe(const WebSocket &rec,
|
||||
const QVariant &clientOrNodeid,
|
||||
const QString &clientOrNodeid,
|
||||
const AbstractNodeInfo * sender) {
|
||||
|
||||
auto _db = db();
|
||||
@ -325,7 +328,7 @@ bool DataBaseNode::workWithSubscribe(const WebSocket &rec,
|
||||
}
|
||||
|
||||
DBOperationResult
|
||||
QH::DataBaseNode::getObject(const QVariant &requester,
|
||||
QH::DataBaseNode::getObject(const QString &requester,
|
||||
const QH::DBObject &templateObj,
|
||||
QSharedPointer<QH::PKG::DBObject> &result) const {
|
||||
|
||||
@ -336,7 +339,7 @@ QH::DataBaseNode::getObject(const QVariant &requester,
|
||||
}
|
||||
|
||||
DBOperationResult
|
||||
DataBaseNode::getObjects(const QVariant &requester,
|
||||
DataBaseNode::getObjects(const QString &requester,
|
||||
const DBObject &templateObj,
|
||||
QList<QSharedPointer<DBObject>> &result) const {
|
||||
|
||||
@ -347,7 +350,7 @@ DataBaseNode::getObjects(const QVariant &requester,
|
||||
}
|
||||
|
||||
DBOperationResult
|
||||
DataBaseNode::updateObject(const QVariant &requester,
|
||||
DataBaseNode::updateObject(const QString &requester,
|
||||
const QSharedPointer<DBObject> &saveObject) {
|
||||
|
||||
if (!_db) {
|
||||
@ -357,7 +360,7 @@ DataBaseNode::updateObject(const QVariant &requester,
|
||||
}
|
||||
|
||||
DBOperationResult
|
||||
DataBaseNode::createObject(const QVariant &requester,
|
||||
DataBaseNode::createObject(const QString &requester,
|
||||
const QSharedPointer<DBObject> &obj) {
|
||||
|
||||
if (!_db) {
|
||||
@ -367,7 +370,7 @@ DataBaseNode::createObject(const QVariant &requester,
|
||||
}
|
||||
|
||||
DBOperationResult
|
||||
DataBaseNode::updateIfNotExistsCreateObject(const QVariant &requester,
|
||||
DataBaseNode::updateIfNotExistsCreateObject(const QString &requester,
|
||||
const QSharedPointer<DBObject> &obj) {
|
||||
|
||||
if (!_db) {
|
||||
@ -377,7 +380,7 @@ DataBaseNode::updateIfNotExistsCreateObject(const QVariant &requester,
|
||||
}
|
||||
|
||||
DBOperationResult
|
||||
DataBaseNode::changeObjects(const QVariant &requester,
|
||||
DataBaseNode::changeObjects(const QString &requester,
|
||||
const DBObject &templateObj,
|
||||
const std::function<bool (const QSharedPointer<DBObject> &)> &changeAction) {
|
||||
|
||||
@ -387,7 +390,7 @@ DataBaseNode::changeObjects(const QVariant &requester,
|
||||
return _db->changeObjects(requester, templateObj, changeAction);
|
||||
}
|
||||
|
||||
QVariant DataBaseNode::getSender(const AbstractNodeInfo *connectInfo,
|
||||
QString DataBaseNode::getSender(const AbstractNodeInfo *connectInfo,
|
||||
const AbstractData *) const {
|
||||
|
||||
auto info = dynamic_cast<const BaseNodeInfo*>(connectInfo);
|
||||
@ -398,7 +401,7 @@ QVariant DataBaseNode::getSender(const AbstractNodeInfo *connectInfo,
|
||||
}
|
||||
|
||||
DBOperationResult
|
||||
DataBaseNode::deleteObject(const QVariant &requester,
|
||||
DataBaseNode::deleteObject(const QString &requester,
|
||||
const QSharedPointer<DBObject> &dbObject) {
|
||||
|
||||
if (!_db) {
|
||||
|
@ -86,7 +86,7 @@ public:
|
||||
* @return result of operation (allow, forbidden, unknown).
|
||||
* For more information about results see the DBOperationResult enum.
|
||||
*/
|
||||
DBOperationResult deleteObject(const QVariant &requester,
|
||||
DBOperationResult deleteObject(const QString &requester,
|
||||
const QSharedPointer<PKG::DBObject> &dbObject);
|
||||
|
||||
/**
|
||||
@ -98,7 +98,7 @@ public:
|
||||
* @return result of operation (allow, forbidden, unknown).
|
||||
* For more information about results see the DBOperationResult enum.
|
||||
*/
|
||||
DBOperationResult getObject(const QVariant &requester,
|
||||
DBOperationResult getObject(const QString &requester,
|
||||
const PKG::DBObject &templateObj,
|
||||
QSharedPointer<PKG::DBObject> &result) const;
|
||||
|
||||
@ -111,7 +111,7 @@ public:
|
||||
* @return result of operation (allow, forbidden, unknown).
|
||||
* For more information about results see the DBOperationResult enum.
|
||||
*/
|
||||
DBOperationResult getObjects(const QVariant &requester,
|
||||
DBOperationResult getObjects(const QString &requester,
|
||||
const PKG::DBObject &templateObj,
|
||||
QList<QSharedPointer<PKG::DBObject>> &result) const;
|
||||
|
||||
@ -123,7 +123,7 @@ public:
|
||||
* @return result of operation (allow, forbidden, unknown).
|
||||
* For more information about results see the DBOperationResult enum.
|
||||
*/
|
||||
DBOperationResult updateObject(const QVariant &requester,
|
||||
DBOperationResult updateObject(const QString &requester,
|
||||
const QSharedPointer<PKG::DBObject> &saveObject);
|
||||
|
||||
/**
|
||||
@ -134,7 +134,7 @@ public:
|
||||
* @return result of operation (allow, forbidden, unknown).
|
||||
* For more information about results see the DBOperationResult enum.
|
||||
*/
|
||||
DBOperationResult createObject(const QVariant &requester,
|
||||
DBOperationResult createObject(const QString &requester,
|
||||
const QSharedPointer<PKG::DBObject> &obj);
|
||||
|
||||
/**
|
||||
@ -147,7 +147,7 @@ public:
|
||||
* @return result of operation (allow, forbidden, unknown).
|
||||
* For more information about results see the DBOperationResult enum.
|
||||
*/
|
||||
DBOperationResult updateIfNotExistsCreateObject(const QVariant &requester,
|
||||
DBOperationResult updateIfNotExistsCreateObject(const QString &requester,
|
||||
const QSharedPointer<PKG::DBObject> &obj);
|
||||
|
||||
/**
|
||||
@ -160,7 +160,7 @@ public:
|
||||
* @return result of operation (allow, forbidden, unknown).
|
||||
* For more information about results see the DBOperationResult enum.
|
||||
*/
|
||||
DBOperationResult changeObjects(const QVariant &requester,
|
||||
DBOperationResult changeObjects(const QString &requester,
|
||||
const PKG::DBObject &templateObj,
|
||||
const std::function<bool (const QSharedPointer<QH::PKG::DBObject>&)> &changeAction);
|
||||
|
||||
@ -179,7 +179,7 @@ public:
|
||||
* @return DBOperationResult::Alowed if permission granted.
|
||||
* For more information about result see the DBOperationResult enum.
|
||||
*/
|
||||
DBOperationResult checkPermission(const QVariant &requester,
|
||||
DBOperationResult checkPermission(const QString &requester,
|
||||
const DbAddress& objectAddress,
|
||||
const Permission& requarimentPermision) const;
|
||||
|
||||
@ -208,7 +208,7 @@ protected:
|
||||
* @param diff This is difference of trust.
|
||||
* @return true if trust of user changed successful.
|
||||
*/
|
||||
virtual bool changeTrust(const QVariant &id, int diff);
|
||||
virtual bool changeTrust(const QString &id, int diff);
|
||||
|
||||
/**
|
||||
* @brief hashgenerator This method generate a hash from any value.
|
||||
@ -249,7 +249,7 @@ protected:
|
||||
* @param requestData This is data of request.
|
||||
* @return id of requester member.
|
||||
*/
|
||||
virtual QVariant getSender(const AbstractNodeInfo *connectInfo, const PKG::AbstractData *requestData) const;
|
||||
virtual QString getSender(const AbstractNodeInfo *connectInfo, const PKG::AbstractData *requestData) const;
|
||||
|
||||
/**
|
||||
* @brief dbLocation This method return location of nodes or clients database.
|
||||
@ -270,7 +270,9 @@ protected:
|
||||
* @param member This is member of network (node, client or server).
|
||||
* @return true if node is banned.
|
||||
*/
|
||||
bool isBanned(const QVariant &member) const;
|
||||
bool isBanned(const QString &member) const;
|
||||
|
||||
bool isBanned(const AbstractNodeInfo *member) const override;
|
||||
|
||||
/**
|
||||
* @brief notifyObjectChanged This method send all subscriptions message with this object.
|
||||
@ -312,7 +314,7 @@ private:
|
||||
* @return true if data parsed successful.
|
||||
*/
|
||||
bool workWithSubscribe(const PKG::WebSocket &rec,
|
||||
const QVariant &clientOrNodeid,
|
||||
const QString &clientOrNodeid,
|
||||
const AbstractNodeInfo *sender);
|
||||
|
||||
|
||||
|
16
Heart/DataBaseSpace/dbpatch.cpp
Normal file
16
Heart/DataBaseSpace/dbpatch.cpp
Normal file
@ -0,0 +1,16 @@
|
||||
/*
|
||||
* Copyright (C) 2018-2022 QuasarApp.
|
||||
* Distributed under the lgplv3 software license, see the accompanying
|
||||
* Everyone is permitted to copy and distribute verbatim copies
|
||||
* of this license document, but changing it is not allowed.
|
||||
*/
|
||||
|
||||
|
||||
#include "dbpatch.h"
|
||||
namespace QH {
|
||||
|
||||
bool DBPatch::isValid() const {
|
||||
return versionFrom < versionTo && action;
|
||||
}
|
||||
|
||||
}
|
51
Heart/DataBaseSpace/dbpatch.h
Normal file
51
Heart/DataBaseSpace/dbpatch.h
Normal file
@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright (C) 2018-2022 QuasarApp.
|
||||
* Distributed under the lgplv3 software license, see the accompanying
|
||||
* Everyone is permitted to copy and distribute verbatim copies
|
||||
* of this license document, but changing it is not allowed.
|
||||
*/
|
||||
|
||||
#ifndef DBPATCH_H
|
||||
#define DBPATCH_H
|
||||
|
||||
#include "iobjectprovider.h"
|
||||
|
||||
|
||||
namespace QH {
|
||||
|
||||
|
||||
/**
|
||||
* @brief DBPatch This is function that should be upgrade database.
|
||||
* @see DBPatchMap
|
||||
* @see DataBaseNode::dbPatch
|
||||
*
|
||||
* @note version is version number of the current database.
|
||||
* After execute this path version of data base will be increment.
|
||||
*/
|
||||
struct DBPatch {
|
||||
/// This is version of data base that need to up.
|
||||
/// For example - we has a data base with version 1 and we want to upgrade to version 2 then you need to set cersion field version to 1.
|
||||
unsigned short versionFrom = 0;
|
||||
|
||||
/// This is version of data base that need to up.
|
||||
/// For example - we has a data base with version 1 and we want to upgrade to version 2 then you need to set cersion field version to 1.
|
||||
unsigned short versionTo = 0;
|
||||
|
||||
/// This is lymbda function with action that will upgrade data base to new versio.
|
||||
std::function<bool (const QH::iObjectProvider *)> action;
|
||||
|
||||
/**
|
||||
* @brief isValid This method check this oject to valid.
|
||||
* @return true if object is valid else false.
|
||||
*/
|
||||
bool isValid() const;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief DBPatchMap This is 2 depch map of the DBPatch structure when the first key it is version (from) and second key is version to.
|
||||
* @see DataBaseNode::dbPatch
|
||||
* @see DBPatchMap
|
||||
*/
|
||||
typedef QMap<unsigned short, QMap<unsigned short, DBPatch>> DBPatchMap;
|
||||
}
|
||||
#endif // DBPATCH_H
|
@ -16,7 +16,7 @@
|
||||
namespace QH {
|
||||
namespace PKG {
|
||||
|
||||
AbstractNetworkMember::AbstractNetworkMember():DBObject("NetworkMembers") {
|
||||
AbstractNetworkMember::AbstractNetworkMember() {
|
||||
|
||||
}
|
||||
|
||||
@ -25,16 +25,14 @@ AbstractNetworkMember::AbstractNetworkMember(const Package &pkg):
|
||||
fromBytes(pkg.data);
|
||||
}
|
||||
|
||||
AbstractNetworkMember::AbstractNetworkMember(const QVariant &id):
|
||||
AbstractNetworkMember::AbstractNetworkMember(const QString& id):
|
||||
AbstractNetworkMember() {
|
||||
setId(id);
|
||||
}
|
||||
|
||||
bool AbstractNetworkMember::fromSqlRecord(const QSqlRecord &q) {
|
||||
if (!DBObject::fromSqlRecord(q)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
setId(q.value("id").toString());
|
||||
setAuthenticationData(q.value("authenticationData").toByteArray());
|
||||
setTrust(q.value("trust").toInt());
|
||||
|
||||
@ -52,6 +50,7 @@ void AbstractNetworkMember::setAuthenticationData(const QByteArray &publickKey)
|
||||
QDataStream &AbstractNetworkMember::fromStream(QDataStream &stream) {
|
||||
DBObject::fromStream(stream);
|
||||
|
||||
stream >> _id;
|
||||
stream >> _authenticationData;
|
||||
stream >> _trust;
|
||||
|
||||
@ -59,8 +58,7 @@ QDataStream &AbstractNetworkMember::fromStream(QDataStream &stream) {
|
||||
}
|
||||
|
||||
QDataStream &AbstractNetworkMember::toStream(QDataStream &stream) const {
|
||||
DBObject::toStream(stream);
|
||||
|
||||
stream << _id;
|
||||
stream << _authenticationData;
|
||||
stream << _trust;
|
||||
return stream;
|
||||
@ -68,17 +66,33 @@ QDataStream &AbstractNetworkMember::toStream(QDataStream &stream) const {
|
||||
|
||||
DBVariantMap AbstractNetworkMember::variantMap() const {
|
||||
|
||||
auto map = DBObject::variantMap();
|
||||
map["authenticationData"] = {_authenticationData, MemberType::InsertUpdate};
|
||||
map["trust"] = {_trust, MemberType::InsertUpdate};
|
||||
return {{"id", {_id, QH::PKG::MemberType::PrimaryKey}},
|
||||
{"authenticationData", {_authenticationData, QH::PKG::MemberType::InsertUpdate}},
|
||||
{"trust", {_trust, QH::PKG::MemberType::InsertUpdate}},
|
||||
|
||||
return map;
|
||||
};
|
||||
}
|
||||
|
||||
QString AbstractNetworkMember::primaryKey() const {
|
||||
return "id";
|
||||
}
|
||||
|
||||
QString AbstractNetworkMember::primaryValue() const {
|
||||
return _id;
|
||||
}
|
||||
|
||||
const QString &AbstractNetworkMember::getId() const {
|
||||
return _id;
|
||||
}
|
||||
|
||||
void AbstractNetworkMember::setId(const QString &newId) {
|
||||
_id = newId;
|
||||
}
|
||||
|
||||
QString AbstractNetworkMember::table() const {
|
||||
return "NetworkMembers";
|
||||
}
|
||||
|
||||
int AbstractNetworkMember::trust() const {
|
||||
return _trust;
|
||||
}
|
||||
@ -103,6 +117,7 @@ bool AbstractNetworkMember::copyFrom(const AbstractData * other) {
|
||||
if (!otherObject)
|
||||
return false;
|
||||
|
||||
this->_id = otherObject->_id;
|
||||
this->_authenticationData = otherObject->_authenticationData;
|
||||
this->_trust = otherObject->_trust;
|
||||
|
||||
|
@ -26,7 +26,7 @@ class HEARTSHARED_EXPORT AbstractNetworkMember: public DBObject
|
||||
public:
|
||||
AbstractNetworkMember();
|
||||
AbstractNetworkMember(const Package& pkg);
|
||||
AbstractNetworkMember(const QVariant &id);
|
||||
AbstractNetworkMember(const QString &id);
|
||||
|
||||
// DBObject interface
|
||||
bool fromSqlRecord(const QSqlRecord &q) override;
|
||||
@ -67,15 +67,29 @@ public:
|
||||
*/
|
||||
void setTrust(int trust);
|
||||
|
||||
/**
|
||||
* @brief getId This method return id of this object in database.
|
||||
* @return id of this object in database.
|
||||
*/
|
||||
const QString &getId() const;
|
||||
|
||||
/**
|
||||
* @brief setId This method sets new id of this object.
|
||||
* @param newId This is new value of @a id of this object.
|
||||
*/
|
||||
void setId(const QString &newId);
|
||||
|
||||
QString table() const override;
|
||||
protected:
|
||||
|
||||
// StreamBase interface
|
||||
QDataStream &fromStream(QDataStream &stream) override;
|
||||
QDataStream &toStream(QDataStream &stream) const override;
|
||||
QString primaryKey() const override;
|
||||
QString primaryValue() const override;
|
||||
|
||||
private:
|
||||
QString _id;
|
||||
QByteArray _authenticationData;
|
||||
int _trust;
|
||||
|
||||
|
@ -21,30 +21,21 @@
|
||||
namespace QH {
|
||||
namespace PKG {
|
||||
|
||||
DBObject::DBObject(const QString &tableName) {
|
||||
DBObject::DBObject() {
|
||||
DBObject::clear();
|
||||
_dbId.setTable(tableName);
|
||||
}
|
||||
|
||||
DBObject::DBObject(const DbAddress &address) {
|
||||
_dbId = address;
|
||||
}
|
||||
|
||||
DBObject::~DBObject() {
|
||||
|
||||
}
|
||||
|
||||
QString DBObject::tableName() const {
|
||||
return _dbId.table();
|
||||
}
|
||||
|
||||
PrepareResult DBObject::prepareSelectQuery(QSqlQuery &q) const {
|
||||
|
||||
auto map = variantMap().keys();
|
||||
|
||||
QString queryString = "SELECT " + map.join(",") + " FROM %0 " + getWhereBlock();
|
||||
|
||||
queryString = queryString.arg(tableName());
|
||||
queryString = queryString.arg(table());
|
||||
|
||||
if (!q.prepare(queryString)) {
|
||||
return PrepareResult::Fail;
|
||||
@ -53,17 +44,6 @@ PrepareResult DBObject::prepareSelectQuery(QSqlQuery &q) const {
|
||||
return PrepareResult::Success;
|
||||
}
|
||||
|
||||
bool DBObject::fromSqlRecord(const QSqlRecord &q) {
|
||||
|
||||
QString key = primaryKey();
|
||||
if (key.size() && q.contains(key)) {
|
||||
setId(q.value(key));
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
PrepareResult DBObject::prepareInsertQuery(QSqlQuery &q) const {
|
||||
|
||||
DBVariantMap map = variantMap();
|
||||
@ -78,7 +58,7 @@ PrepareResult DBObject::prepareInsertQuery(QSqlQuery &q) const {
|
||||
QString queryString = "INSERT INTO %0(%1) VALUES (%2) ";
|
||||
|
||||
|
||||
queryString = queryString.arg(tableName());
|
||||
queryString = queryString.arg(table());
|
||||
QString tableInsertHeader = "";
|
||||
QString tableInsertValues = "";
|
||||
|
||||
@ -129,7 +109,7 @@ PrepareResult DBObject::prepareUpdateQuery(QSqlQuery &q) const {
|
||||
|
||||
QString queryString = "UPDATE %0 SET %1 WHERE " + condition();
|
||||
|
||||
queryString = queryString.arg(tableName());
|
||||
queryString = queryString.arg(table());
|
||||
QString tableUpdateValues = "";
|
||||
|
||||
for (auto it = map.begin(); it != map.end(); ++it) {
|
||||
@ -183,7 +163,7 @@ bool DBObject::isBundle() const {
|
||||
}
|
||||
|
||||
uint DBObject::dbKey() const {
|
||||
return HASH_KEY(DbAddressKey(_dbId));
|
||||
return HASH_KEY(DbAddressKey(dbAddress()));
|
||||
}
|
||||
|
||||
QString DBObject::condition() const {
|
||||
@ -204,21 +184,9 @@ QString DBObject::condition() const {
|
||||
QString errorString = "WRONG OBJECT";
|
||||
|
||||
// if object have a primaryKey then return primary key
|
||||
auto primaryVal = getId();
|
||||
if (primaryVal.isValid()) {
|
||||
|
||||
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
|
||||
bool fWarning = primaryVal.type() == QVariant::ByteArray;
|
||||
|
||||
#else
|
||||
bool fWarning = primaryVal.metaType().id() == QMetaType::QByteArray;
|
||||
#endif
|
||||
if (fWarning) {
|
||||
byteArrayWarning();
|
||||
return errorString;
|
||||
}
|
||||
|
||||
return prepareCondition(primaryKey(), primaryVal.toString());
|
||||
auto primaryVal = primaryValue();
|
||||
if (primaryVal.size()) {
|
||||
return prepareCondition(primaryKey(), primaryVal);
|
||||
}
|
||||
|
||||
auto map = variantMap();
|
||||
@ -266,20 +234,12 @@ QString DBObject::condition() const {
|
||||
return errorString;
|
||||
}
|
||||
|
||||
const QVariant &DBObject::primaryValue() const {
|
||||
return _dbId.id();
|
||||
}
|
||||
|
||||
void DBObject::setDbAddress(const DbAddress &address) {
|
||||
_dbId = address;
|
||||
}
|
||||
|
||||
bool DBObject::isInsertPrimaryKey() const {
|
||||
return bool(variantMap().value(primaryKey()).type & MemberType::Insert);
|
||||
}
|
||||
|
||||
const DbAddress &DBObject::dbAddress() const {
|
||||
return _dbId;
|
||||
DbAddress DBObject::dbAddress() const {
|
||||
return {table(), primaryValue()};
|
||||
}
|
||||
|
||||
DBObject *DBObject::cloneRaw() const {
|
||||
@ -293,7 +253,7 @@ DBObject *DBObject::cloneRaw() const {
|
||||
|
||||
QString DBObject::toString() const {
|
||||
return AbstractData::toString() +
|
||||
QString(" %0").arg(_dbId.toString());
|
||||
QString(" %0").arg(dbAddress().toString());
|
||||
}
|
||||
|
||||
QString DBObject::getWhereBlock() const {
|
||||
@ -315,11 +275,27 @@ void DBObject::setPrintError(bool newPrintError) {
|
||||
_printError = newPrintError;
|
||||
}
|
||||
|
||||
QDataStream &DBObject::fromStream(QDataStream &stream) {
|
||||
QuasarAppUtils::Params::log("This object not support stream operator."
|
||||
" Please Override the fromStream method for this object. " + toString(),
|
||||
QuasarAppUtils::Warning);
|
||||
|
||||
return stream;
|
||||
}
|
||||
|
||||
QDataStream &DBObject::toStream(QDataStream &stream) const {
|
||||
|
||||
QuasarAppUtils::Params::log("This object not support stream operator."
|
||||
" Please Override the toStream method for this object. " + toString(),
|
||||
QuasarAppUtils::Warning);
|
||||
return stream;
|
||||
}
|
||||
|
||||
PrepareResult DBObject::prepareRemoveQuery(QSqlQuery &q) const {
|
||||
|
||||
QString queryString = "DELETE FROM %0 " + getWhereBlock();
|
||||
|
||||
queryString = queryString.arg(tableName());
|
||||
queryString = queryString.arg(table());
|
||||
|
||||
if (!q.prepare(queryString)) {
|
||||
return PrepareResult::Fail;
|
||||
@ -328,25 +304,9 @@ PrepareResult DBObject::prepareRemoveQuery(QSqlQuery &q) const {
|
||||
return PrepareResult::Success;
|
||||
}
|
||||
|
||||
QDataStream &DBObject::fromStream(QDataStream &stream) {
|
||||
AbstractData::fromStream(stream);
|
||||
|
||||
stream >> _dbId;
|
||||
|
||||
return stream;
|
||||
}
|
||||
|
||||
QDataStream &DBObject::toStream(QDataStream &stream) const {
|
||||
AbstractData::toStream(stream);
|
||||
|
||||
stream << _dbId;
|
||||
|
||||
return stream;
|
||||
}
|
||||
|
||||
DBVariantMap DBObject::variantMap() const {
|
||||
if (isHaveAPrimaryKey()) {
|
||||
return {{primaryKey(), {_dbId.id(), MemberType::PrimaryKey}}};
|
||||
return {{primaryKey(), {primaryValue(), MemberType::PrimaryKey}}};
|
||||
}
|
||||
|
||||
return {};
|
||||
@ -357,23 +317,14 @@ bool DBObject::isValid() const {
|
||||
return false;
|
||||
|
||||
if (isInsertPrimaryKey()) {
|
||||
return _dbId.isValid();
|
||||
return primaryValue().size();
|
||||
}
|
||||
|
||||
return _dbId.table().size();
|
||||
return table().size();
|
||||
}
|
||||
|
||||
bool DBObject::copyFrom(const AbstractData * other) {
|
||||
if (!AbstractData::copyFrom(other))
|
||||
return false;
|
||||
|
||||
auto otherObject = dynamic_cast<const DBObject*>(other);
|
||||
if (!otherObject)
|
||||
return false;
|
||||
|
||||
this->_dbId = otherObject->_dbId;
|
||||
|
||||
return true;
|
||||
return AbstractData::copyFrom(other);
|
||||
}
|
||||
|
||||
unsigned int DBObject::subscribeId() const {
|
||||
@ -388,17 +339,7 @@ bool DBObject::isHaveAPrimaryKey() const {
|
||||
return primaryKey().size();
|
||||
}
|
||||
|
||||
const QVariant& DBObject::getId() const {
|
||||
return dbAddress().id();
|
||||
}
|
||||
|
||||
void DBObject::setId(const QVariant& id) {
|
||||
_dbId.setId(id);
|
||||
}
|
||||
|
||||
void DBObject::clear() {
|
||||
setId({});
|
||||
}
|
||||
void DBObject::clear() {}
|
||||
|
||||
DBVariant::DBVariant() {
|
||||
|
||||
|
@ -102,12 +102,7 @@ class HEARTSHARED_EXPORT DBObject : public AbstractData, public ISubscribableDat
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* @brief DBObject This is default constructor.Before using this class you need set the table name and primary key of this object.
|
||||
* @param tableName This is table name.
|
||||
*/
|
||||
DBObject(const QString& tableName);
|
||||
DBObject(const DbAddress& address);
|
||||
DBObject();
|
||||
|
||||
~DBObject() override;
|
||||
|
||||
@ -129,30 +124,13 @@ public:
|
||||
*/
|
||||
bool isHaveAPrimaryKey() const;
|
||||
|
||||
/**
|
||||
* @brief getId This method return id of database object. The database id it is pair of an id member of table and a table name.
|
||||
* @return The id of database object.
|
||||
*/
|
||||
const QVariant &getId() const;
|
||||
|
||||
/**
|
||||
* @brief setId This method set new id for current database object.
|
||||
* @param id This is new value of id.
|
||||
*/
|
||||
void setId(const QVariant& id);
|
||||
|
||||
/**
|
||||
* @brief clear This method clear all data of database object.
|
||||
* Override This method for remove or reset your own members of class.
|
||||
* @note The Default implementation do nothing
|
||||
*/
|
||||
virtual void clear();
|
||||
|
||||
/**
|
||||
* @brief tableName This method return a table name of the database object.
|
||||
* @return string value if the table name.
|
||||
*/
|
||||
QString tableName() const;
|
||||
|
||||
/**
|
||||
* @brief createDBObject This method should be create a object with the some type as the object called this method.
|
||||
* Example of override:
|
||||
@ -190,16 +168,14 @@ public:
|
||||
* Exampel of override fromSqlRecord method:
|
||||
* \code{cpp}
|
||||
* bool ExampleObject::fromSqlRecord(const QSqlRecord &q) {
|
||||
if (!DBObject::fromSqlRecord(q)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
id = q.value("id").toInt();
|
||||
exampleMember = q.value("exampleMember").toInt();
|
||||
return isValid();
|
||||
}
|
||||
* \endcode
|
||||
*/
|
||||
virtual bool fromSqlRecord(const QSqlRecord& q);
|
||||
virtual bool fromSqlRecord(const QSqlRecord& q) = 0;
|
||||
|
||||
/**
|
||||
* @brief prepareInsertQuery This method should be prepare a query for insert object into database.
|
||||
@ -227,7 +203,7 @@ public:
|
||||
QString queryString = "INSERT INTO %0(%1) VALUES (%2) ";
|
||||
|
||||
|
||||
queryString = queryString.arg(tableName());
|
||||
queryString = queryString.arg(table());
|
||||
QString tableInsertHeader = "";
|
||||
QString tableInsertValues = "";
|
||||
|
||||
@ -281,7 +257,7 @@ public:
|
||||
|
||||
QString queryString = "UPDATE %0 SET %1 WHERE %2";
|
||||
|
||||
queryString = queryString.arg(tableName());
|
||||
queryString = queryString.arg(table());
|
||||
QString tableUpdateValues = "";
|
||||
QString tableUpdateRules = QString("%0 = :%0").
|
||||
arg(primaryKey());
|
||||
@ -368,7 +344,7 @@ public:
|
||||
* IF the object is not valid then this method return an invalid database address.
|
||||
* @return The database address of current object.
|
||||
*/
|
||||
const DbAddress& dbAddress() const;
|
||||
DbAddress dbAddress() const;
|
||||
|
||||
/**
|
||||
* @brief clone This method create a new object. The new Object is clone of current object.
|
||||
@ -426,6 +402,12 @@ public:
|
||||
*/
|
||||
virtual DBVariantMap variantMap() const;
|
||||
|
||||
/**
|
||||
* @brief table This method should be return name of the database table that should be contains objects with this type.
|
||||
* @return table name that contains object with this type.
|
||||
*/
|
||||
virtual QString table() const = 0;
|
||||
|
||||
/**
|
||||
* @brief printError This method return status of printing error messages for sql quries. by default this propertye is enabled.
|
||||
* @return true if printing error messages is enabled else false.
|
||||
@ -474,15 +456,10 @@ protected:
|
||||
/**
|
||||
* @brief primaryValue This method is wraper of DBAddress::id. If This object do not contains a id value then return invalid value.
|
||||
* @return Value of primaryKey ( database id ).
|
||||
* @note If you alredy override the condition method then You can return empty string because this method using in generate default condition only.
|
||||
* @see DBObject::condition.
|
||||
*/
|
||||
const QVariant& primaryValue() const;
|
||||
|
||||
|
||||
/**
|
||||
* @brief setDbAddress This method set the new database address.
|
||||
* @param address This is a new value of database address.
|
||||
*/
|
||||
void setDbAddress(const DbAddress &address);
|
||||
virtual QString primaryValue() const = 0;
|
||||
|
||||
/**
|
||||
* @brief isInsertPrimaryKey This method check primaryKeys type.
|
||||
@ -494,8 +471,6 @@ protected:
|
||||
private:
|
||||
QString getWhereBlock() const;
|
||||
bool _printError = true;
|
||||
DbAddress _dbId;
|
||||
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -8,9 +8,8 @@
|
||||
#include "dbobjectset.h"
|
||||
namespace QH {
|
||||
namespace PKG {
|
||||
DBObjectSet::DBObjectSet(const QString table):
|
||||
DBObject(table) {
|
||||
|
||||
DBObjectSet::DBObjectSet(const QString table) {
|
||||
_table = table;
|
||||
}
|
||||
|
||||
PrepareResult DBObjectSet::prepareInsertQuery(QSqlQuery &) const {
|
||||
@ -41,6 +40,10 @@ QString DBObjectSet::primaryKey() const {
|
||||
return "";
|
||||
}
|
||||
|
||||
QString DBObjectSet::table() const {
|
||||
return _table;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -27,8 +27,6 @@ class HEARTSHARED_EXPORT DBObjectSet: public DBObject
|
||||
public:
|
||||
DBObjectSet(const QString table);
|
||||
|
||||
// DBObject interface
|
||||
public:
|
||||
PrepareResult prepareInsertQuery(QSqlQuery &) const override final;
|
||||
PrepareResult prepareRemoveQuery(QSqlQuery &q) const override final;
|
||||
PrepareResult prepareSelectQuery(QSqlQuery &q) const override final;
|
||||
@ -37,6 +35,10 @@ public:
|
||||
bool isCached() const override final;
|
||||
bool isBundle() const override final;
|
||||
QString primaryKey() const override;
|
||||
QString table() const override;
|
||||
|
||||
private:
|
||||
QString _table;
|
||||
|
||||
};
|
||||
}
|
||||
|
@ -56,6 +56,14 @@ public:
|
||||
_conditions = conditions;
|
||||
};
|
||||
|
||||
QString primaryValue() const override {
|
||||
return "";
|
||||
}
|
||||
|
||||
QString primaryKey() const override {
|
||||
return "";
|
||||
}
|
||||
|
||||
void clear() override {
|
||||
_data.clear();
|
||||
};
|
||||
@ -73,6 +81,14 @@ public:
|
||||
return true;
|
||||
};
|
||||
|
||||
QDataStream &fromStream(QDataStream &stream) override {
|
||||
return stream;
|
||||
};
|
||||
|
||||
QDataStream &toStream(QDataStream &stream) const override {
|
||||
return stream;
|
||||
};
|
||||
|
||||
bool isValid() const override {
|
||||
return true;
|
||||
};
|
||||
@ -108,7 +124,7 @@ protected:
|
||||
}
|
||||
|
||||
DBObject *createDBObject() const override {
|
||||
return create<DBObjectsRequest<T>>(tableName(), _conditions);
|
||||
return create<DBObjectsRequest<T>>(table(), _conditions);
|
||||
};
|
||||
|
||||
QList<QSharedPointer<T>> _data;
|
||||
|
@ -49,7 +49,6 @@ protected:
|
||||
QDataStream &fromStream(QDataStream &stream) override {
|
||||
DBObjectSet::fromStream(stream);
|
||||
|
||||
clear();
|
||||
int size = 0;
|
||||
stream >> size;
|
||||
|
||||
|
@ -10,7 +10,7 @@ namespace QH {
|
||||
namespace PKG {
|
||||
|
||||
DefaultPermision::DefaultPermision():
|
||||
MemberPermisionObject("DefaultPermissions") {
|
||||
MemberPermisionObject() {
|
||||
|
||||
}
|
||||
|
||||
@ -48,5 +48,9 @@ QString DefaultPermision::condition() const {
|
||||
return result;
|
||||
}
|
||||
|
||||
QString DefaultPermision::table() const {
|
||||
return "DefaultPermissions";
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -34,6 +34,8 @@ public:
|
||||
bool fromSqlRecord(const QSqlRecord &q) override;
|
||||
DBObject *createDBObject() const override;
|
||||
QString condition() const override;
|
||||
|
||||
QString table () const override;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -8,7 +8,7 @@
|
||||
#include "deleteobject.h"
|
||||
namespace QH {
|
||||
namespace PKG {
|
||||
DeleteObject::DeleteObject(): DBObject("") {
|
||||
DeleteObject::DeleteObject() {
|
||||
|
||||
}
|
||||
|
||||
@ -32,21 +32,21 @@ void DeleteObject::setSignToken(const AccessToken &token) {
|
||||
_token = token;
|
||||
}
|
||||
|
||||
QString DeleteObject::primaryKey() const {
|
||||
return "id";
|
||||
bool DeleteObject::fromSqlRecord(const QSqlRecord &q) {
|
||||
Q_UNUSED(q);
|
||||
return true;
|
||||
}
|
||||
|
||||
QDataStream &DeleteObject::fromStream(QDataStream &stream) {
|
||||
DBObject::fromStream(stream);
|
||||
|
||||
stream >> _address;
|
||||
stream >> _token;
|
||||
|
||||
return stream;
|
||||
}
|
||||
|
||||
QDataStream &DeleteObject::toStream(QDataStream &stream) const {
|
||||
DBObject::toStream(stream);
|
||||
|
||||
stream << _address;
|
||||
stream << _token;
|
||||
|
||||
return stream;
|
||||
@ -55,5 +55,26 @@ QDataStream &DeleteObject::toStream(QDataStream &stream) const {
|
||||
bool DeleteObject::isCached() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
QString DeleteObject::table() const {
|
||||
return _address.table();
|
||||
}
|
||||
|
||||
const DbAddress &DeleteObject::address() const {
|
||||
return _address;
|
||||
}
|
||||
|
||||
void DeleteObject::setAddress(const DbAddress &newAddress) {
|
||||
_address = newAddress;
|
||||
}
|
||||
|
||||
QString DeleteObject::primaryKey() const {
|
||||
return "id";
|
||||
}
|
||||
|
||||
QString DeleteObject::primaryValue() const {
|
||||
return _address.id().toString();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -30,16 +30,34 @@ public:
|
||||
const AccessToken &getSignToken() const override;
|
||||
void setSignToken(const AccessToken &token) override;
|
||||
|
||||
bool fromSqlRecord(const QSqlRecord &q) override;
|
||||
|
||||
bool isCached() const override;
|
||||
|
||||
QString table() const override;
|
||||
|
||||
/**
|
||||
* @brief address This method return address of the object that will be deleted.
|
||||
* @return database address of the object that will be deleted.
|
||||
*/
|
||||
const DbAddress &address() const;
|
||||
|
||||
/**
|
||||
* @brief setAddress This method sets new address for object that will be deleted from database.
|
||||
* @param newAddress This is new value of the database adderess.
|
||||
*/
|
||||
void setAddress(const DbAddress &newAddress);
|
||||
|
||||
protected:
|
||||
QString primaryKey() const override;
|
||||
QString primaryValue() const override;
|
||||
|
||||
QDataStream &fromStream(QDataStream &stream) override;
|
||||
QDataStream &toStream(QDataStream &stream) const override;
|
||||
|
||||
// DBObject interface
|
||||
public:
|
||||
bool isCached() const override;
|
||||
private:
|
||||
|
||||
DbAddress _address;
|
||||
AccessToken _token;
|
||||
|
||||
};
|
||||
|
@ -8,9 +8,9 @@ namespace QH {
|
||||
namespace PKG {
|
||||
|
||||
|
||||
GetMaxIntegerId::GetMaxIntegerId(const QString& table, const QString& field):
|
||||
DBObject(table) {
|
||||
GetMaxIntegerId::GetMaxIntegerId(const QString& table, const QString& field) {
|
||||
|
||||
_table = table;
|
||||
_field = field;
|
||||
}
|
||||
|
||||
@ -19,13 +19,13 @@ int GetMaxIntegerId::value() const {
|
||||
}
|
||||
|
||||
DBObject *GetMaxIntegerId::createDBObject() const {
|
||||
return create<GetMaxIntegerId>(tableName(), _field);
|
||||
return create<GetMaxIntegerId>(table(), _field);
|
||||
}
|
||||
|
||||
PrepareResult GetMaxIntegerId::prepareSelectQuery(QSqlQuery &q) const {
|
||||
QString queryString = "SELECT max(%0) FROM %1";
|
||||
|
||||
queryString = queryString.arg(_field, tableName());
|
||||
queryString = queryString.arg(_field, table());
|
||||
|
||||
if (!q.prepare(queryString)) {
|
||||
return PrepareResult::Fail;
|
||||
@ -44,9 +44,17 @@ bool GetMaxIntegerId::isCached() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
QString GetMaxIntegerId::table() const {
|
||||
return _table;
|
||||
}
|
||||
|
||||
QString GetMaxIntegerId::primaryKey() const {
|
||||
return "";
|
||||
}
|
||||
|
||||
QString GetMaxIntegerId::primaryValue() const {
|
||||
return "";
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -39,12 +39,14 @@ public:
|
||||
PrepareResult prepareSelectQuery(QSqlQuery &q) const override;
|
||||
bool fromSqlRecord(const QSqlRecord &q) override;
|
||||
bool isCached() const override;
|
||||
|
||||
QString table() const override;
|
||||
|
||||
protected:
|
||||
QString primaryKey() const override;
|
||||
QString primaryValue() const override;
|
||||
|
||||
private:
|
||||
QString _table;
|
||||
QString _field;
|
||||
int _value;
|
||||
};
|
||||
|
@ -14,9 +14,12 @@ namespace QH {
|
||||
|
||||
namespace PKG {
|
||||
|
||||
GetSingleValue::GetSingleValue(const DbAddress& address, const QString& field, const QString& primaryKey):
|
||||
DBObject(address) {
|
||||
GetSingleValue::GetSingleValue(const DbAddress& address,
|
||||
const QString& field,
|
||||
const QString& primaryKey) {
|
||||
|
||||
_table = address.table();
|
||||
_id = address.id().toString();
|
||||
_field = field;
|
||||
_key = primaryKey;
|
||||
}
|
||||
@ -32,7 +35,7 @@ DBObject *GetSingleValue::createDBObject() const {
|
||||
PrepareResult GetSingleValue::prepareSelectQuery(QSqlQuery &q) const {
|
||||
QString queryString = "SELECT %0 FROM %1 WHERE %2='%3'";
|
||||
|
||||
queryString = queryString.arg(_field, tableName(), _key, getId().toString());
|
||||
queryString = queryString.arg(_field, table(), _key, _id);
|
||||
|
||||
if (!q.prepare(queryString)) {
|
||||
return PrepareResult::Fail;
|
||||
@ -51,8 +54,16 @@ bool GetSingleValue::isCached() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
QString GetSingleValue::table() const {
|
||||
return _table;
|
||||
}
|
||||
|
||||
QString GetSingleValue::primaryKey() const {
|
||||
return _key;
|
||||
return _id;
|
||||
}
|
||||
|
||||
QString GetSingleValue::primaryValue() const {
|
||||
return _field;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -59,13 +59,15 @@ public:
|
||||
PrepareResult prepareSelectQuery(QSqlQuery &q) const override;
|
||||
bool fromSqlRecord(const QSqlRecord &q) override;
|
||||
bool isCached() const override;
|
||||
|
||||
QString table() const override;
|
||||
|
||||
protected:
|
||||
QString primaryKey() const override;
|
||||
|
||||
QString primaryValue() const override;
|
||||
private:
|
||||
QString _id;
|
||||
QString _field;
|
||||
QString _table;
|
||||
QVariant _value;
|
||||
QString _key;
|
||||
|
||||
|
@ -14,8 +14,7 @@
|
||||
namespace QH {
|
||||
namespace PKG {
|
||||
|
||||
MemberPermisionObject::MemberPermisionObject():
|
||||
MemberPermisionObject("MemberPermisions") {
|
||||
MemberPermisionObject::MemberPermisionObject() {
|
||||
|
||||
}
|
||||
|
||||
@ -30,11 +29,6 @@ MemberPermisionObject::MemberPermisionObject(const PermisionData &id):
|
||||
setKey(id);
|
||||
}
|
||||
|
||||
MemberPermisionObject::MemberPermisionObject(const QString &tableName):
|
||||
DBObject(tableName) {
|
||||
|
||||
}
|
||||
|
||||
bool MemberPermisionObject::isValid() const {
|
||||
return _key.isValid();
|
||||
}
|
||||
@ -92,9 +86,13 @@ QDataStream &MemberPermisionObject::toStream(QDataStream &stream) const {
|
||||
}
|
||||
|
||||
DBVariantMap MemberPermisionObject::variantMap() const {
|
||||
return {{"memberId", {_key.id(), MemberType::InsertUpdate}},
|
||||
{"dbAddress", {_key.addressHash(), MemberType::InsertUpdate}},
|
||||
{"lvl", {static_cast<unsigned char>(_permision), MemberType::InsertUpdate}}};
|
||||
return {{"memberId", {_key.id(), MemberType::InsertUpdate}},
|
||||
{"dbAddress", {_key.addressHash(), MemberType::InsertUpdate}},
|
||||
{"lvl", {static_cast<unsigned char>(_permision), MemberType::InsertUpdate}}};
|
||||
}
|
||||
|
||||
QString MemberPermisionObject::table() const {
|
||||
return "MemberPermisions";
|
||||
}
|
||||
|
||||
QString MemberPermisionObject::condition() const {
|
||||
@ -117,13 +115,16 @@ QString MemberPermisionObject::primaryKey() const {
|
||||
return "";
|
||||
}
|
||||
|
||||
QString MemberPermisionObject::primaryValue() const {
|
||||
return "";
|
||||
}
|
||||
|
||||
PermisionData MemberPermisionObject::key() const {
|
||||
return _key;
|
||||
}
|
||||
|
||||
void MemberPermisionObject::setKey(const PermisionData &key) {
|
||||
_key = key;
|
||||
setId(_key.hash());
|
||||
}
|
||||
|
||||
Permission MemberPermisionObject::permisions() const {
|
||||
|
@ -40,6 +40,8 @@ public:
|
||||
bool isCached() const override;
|
||||
DBVariantMap variantMap() const override;
|
||||
|
||||
QString table() const override;
|
||||
|
||||
/**
|
||||
* @brief permisions This method return value permission of object.
|
||||
* For select object set it id using a MemberPermisionObject::setKey method.
|
||||
@ -66,17 +68,13 @@ public:
|
||||
void setKey(const PermisionData &key);
|
||||
|
||||
protected:
|
||||
/**
|
||||
* @brief MemberPermisionObject This is protected constructor for support inheritance functions.
|
||||
*/
|
||||
MemberPermisionObject(const QString& tableName);
|
||||
|
||||
|
||||
// StreamBase interface
|
||||
QDataStream &fromStream(QDataStream &stream) override;
|
||||
QDataStream &toStream(QDataStream &stream) const override;
|
||||
QString condition() const override;
|
||||
QString primaryKey() const override;
|
||||
QString primaryValue() const override;
|
||||
|
||||
private:
|
||||
Permission _permision;
|
||||
|
@ -14,7 +14,7 @@ NetworkMember::NetworkMember() {
|
||||
|
||||
}
|
||||
|
||||
NetworkMember::NetworkMember(const QVariant &id): AbstractNetworkMember(id) {
|
||||
NetworkMember::NetworkMember(const QString &id): AbstractNetworkMember(id) {
|
||||
|
||||
}
|
||||
|
||||
|
@ -24,7 +24,7 @@ class HEARTSHARED_EXPORT NetworkMember: public AbstractNetworkMember
|
||||
|
||||
public:
|
||||
NetworkMember();
|
||||
NetworkMember(const QVariant& id);
|
||||
NetworkMember(const QString& id);
|
||||
|
||||
public:
|
||||
DBObject *createDBObject() const override;
|
||||
|
@ -19,9 +19,9 @@ namespace PKG {
|
||||
SetSingleValue::SetSingleValue(const DbAddress& address,
|
||||
const QString& field,
|
||||
const QVariant& value,
|
||||
const QString &primaryKey):
|
||||
DBObject(address)
|
||||
{
|
||||
const QString &primaryKey) {
|
||||
_id = address.id().toString();
|
||||
_table = address.table();
|
||||
_field = field;
|
||||
_value = value;
|
||||
_primaryKey = primaryKey;
|
||||
@ -34,7 +34,7 @@ DBObject *SetSingleValue::createDBObject() const {
|
||||
PrepareResult SetSingleValue::prepareUpdateQuery(QSqlQuery &q) const {
|
||||
QString queryString = "UPDATE %0 SET %1=:%1 WHERE %2='%3'";
|
||||
|
||||
queryString = queryString.arg(tableName(), _field, primaryKey(), getId().toString());
|
||||
queryString = queryString.arg(table(), _field, primaryKey(), _id);
|
||||
|
||||
if (!q.prepare(queryString)) {
|
||||
|
||||
@ -51,7 +51,7 @@ PrepareResult SetSingleValue::prepareUpdateQuery(QSqlQuery &q) const {
|
||||
PrepareResult SetSingleValue::prepareInsertQuery(QSqlQuery &q) const {
|
||||
QString queryString = "INSERT INTO %0 (%1, %2) VALUES (:%1, :%2)";
|
||||
|
||||
queryString = queryString.arg(tableName(), primaryKey(), _field);
|
||||
queryString = queryString.arg(table(), primaryKey(), _field);
|
||||
|
||||
if (!q.prepare(queryString)) {
|
||||
|
||||
@ -60,7 +60,7 @@ PrepareResult SetSingleValue::prepareInsertQuery(QSqlQuery &q) const {
|
||||
return PrepareResult::Fail;
|
||||
}
|
||||
|
||||
q.bindValue(":" + primaryKey(), getId().toString());
|
||||
q.bindValue(":" + primaryKey(), primaryValue());
|
||||
q.bindValue(":" + _field, _value);
|
||||
|
||||
return PrepareResult::Success;
|
||||
@ -74,8 +74,16 @@ bool SetSingleValue::isCached() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
QString SetSingleValue::table() const {
|
||||
return _table;
|
||||
}
|
||||
|
||||
QString SetSingleValue::primaryKey() const {
|
||||
return _primaryKey;
|
||||
}
|
||||
|
||||
QString SetSingleValue::primaryValue() const {
|
||||
return _id;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -54,11 +54,16 @@ public:
|
||||
bool fromSqlRecord(const QSqlRecord &q) override;
|
||||
bool isCached() const override;
|
||||
|
||||
QString table() const override;
|
||||
|
||||
|
||||
protected:
|
||||
QString primaryKey() const override;
|
||||
QString primaryValue() const override;
|
||||
|
||||
private:
|
||||
QString _id;
|
||||
QString _table;
|
||||
QString _field;
|
||||
QString _primaryKey;
|
||||
QVariant _value;
|
||||
|
@ -13,7 +13,7 @@ UserMember::UserMember(const Package &pkg):
|
||||
fromBytes(pkg.data);
|
||||
}
|
||||
|
||||
UserMember::UserMember(const QVariant &id):
|
||||
UserMember::UserMember(const QString &id):
|
||||
UserMember() {
|
||||
setId(id);
|
||||
}
|
||||
|
@ -26,7 +26,7 @@ class HEARTSHARED_EXPORT UserMember: public AbstractNetworkMember
|
||||
public:
|
||||
UserMember();
|
||||
UserMember(const Package &pkg);
|
||||
UserMember(const QVariant &id);
|
||||
UserMember(const QString &id);
|
||||
|
||||
bool copyFrom(const AbstractData *other) override;
|
||||
bool fromSqlRecord(const QSqlRecord &q) override;
|
||||
|
@ -23,7 +23,6 @@ WebSocket::WebSocket(const Package &package):
|
||||
}
|
||||
|
||||
QDataStream &WebSocket::fromStream(QDataStream &stream) {
|
||||
AbstractData::fromStream(stream);
|
||||
stream >> _request;
|
||||
stream >> _subscribeId;
|
||||
|
||||
@ -31,7 +30,6 @@ QDataStream &WebSocket::fromStream(QDataStream &stream) {
|
||||
}
|
||||
|
||||
QDataStream &WebSocket::toStream(QDataStream &stream) const {
|
||||
AbstractData::toStream(stream);
|
||||
stream << _request;
|
||||
stream << _subscribeId;
|
||||
|
||||
|
@ -26,13 +26,11 @@ WebSocketSubscriptions::WebSocketSubscriptions(const QH::Package &package):
|
||||
}
|
||||
|
||||
QDataStream &WebSocketSubscriptions::fromStream(QDataStream &stream) {
|
||||
AbstractData::fromStream(stream);
|
||||
|
||||
return stream >> _subscribeIds;
|
||||
}
|
||||
|
||||
QDataStream &WebSocketSubscriptions::toStream(QDataStream &stream) const {
|
||||
AbstractData::toStream(stream);
|
||||
|
||||
return stream << _subscribeIds;
|
||||
}
|
||||
|
@ -155,7 +155,8 @@ bool SingleClient::removeUser() {
|
||||
|
||||
|
||||
QH::PKG::DeleteObject request;
|
||||
request.copyFrom(&getMember());
|
||||
request.setAddress(getMember().dbAddress());
|
||||
|
||||
if (!sendData(&request, realServerAddress())) {
|
||||
return false;
|
||||
};
|
||||
|
@ -51,8 +51,8 @@ bool SqlDBWriter::exec(QSqlQuery *sq, const QString& sqlFile) const {
|
||||
temp = temp.remove(0, delimiterIndex + 1);
|
||||
|
||||
if (!result) {
|
||||
QuasarAppUtils::Params::log(QString("exec database error. line:%0: %1").
|
||||
arg(lineNumber).arg(sq->lastError().text()),
|
||||
QuasarAppUtils::Params::log(QString("Exec database error. File: %0. Line:%1: %2").
|
||||
arg(sqlFile).arg(lineNumber).arg(sq->lastError().text()),
|
||||
QuasarAppUtils::Error);
|
||||
f.close();
|
||||
return false;
|
||||
@ -137,10 +137,10 @@ bool SqlDBWriter::doQueryPrivate(const QString &query, QSqlQuery* result) const
|
||||
return false;
|
||||
}
|
||||
|
||||
QSqlQuery q(query, *db());
|
||||
|
||||
if (!q.exec()) {
|
||||
QuasarAppUtils::Params::log("request error : " + q.lastError().text());
|
||||
QSqlQuery q(*db());
|
||||
if (!q.exec(query)) {
|
||||
QuasarAppUtils::Params::log("request error : " + q.lastError().text(),
|
||||
QuasarAppUtils::Error);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -391,7 +391,9 @@ bool SqlDBWriter::selectQuery(const DBObject& requestObject,
|
||||
|
||||
while (q.next()) {
|
||||
if (!newObject->fromSqlRecord(q.record())) {
|
||||
QuasarAppUtils::Params::log("Init sql object error.",
|
||||
QuasarAppUtils::Params::log("Select query finished successful but, "
|
||||
"the fromSqlRecord method return false." +
|
||||
newObject->toString(),
|
||||
QuasarAppUtils::Error);
|
||||
return false;
|
||||
}
|
||||
@ -466,11 +468,12 @@ bool SqlDBWriter::workWithQuery(QSqlQuery &q,
|
||||
if (!printErrors)
|
||||
return ;
|
||||
|
||||
QuasarAppUtils::Params::log("prepare sql error: " + q.executedQuery(),
|
||||
QuasarAppUtils::Debug);
|
||||
|
||||
QuasarAppUtils::Params::log("exec sql error: " + q.lastError().text(),
|
||||
QuasarAppUtils::Error);
|
||||
|
||||
QuasarAppUtils::Params::log("prepare sql error: " + q.executedQuery(),
|
||||
QuasarAppUtils::Error);
|
||||
};
|
||||
|
||||
|
||||
|
@ -21,7 +21,7 @@ WebSocketController::WebSocketController(DataBaseNode *node) {
|
||||
|
||||
}
|
||||
|
||||
void WebSocketController::subscribe(const QVariant &subscriber,
|
||||
void WebSocketController::subscribe(const QString &subscriber,
|
||||
unsigned int item) {
|
||||
|
||||
_subscribsMutex.lock();
|
||||
@ -33,7 +33,7 @@ void WebSocketController::subscribe(const QVariant &subscriber,
|
||||
_subscribsMutex.unlock();
|
||||
}
|
||||
|
||||
void WebSocketController::unsubscribe(const QVariant &subscriber,
|
||||
void WebSocketController::unsubscribe(const QString &subscriber,
|
||||
unsigned int item) {
|
||||
_subscribsMutex.lock();
|
||||
_itemsMutex.lock();
|
||||
@ -44,7 +44,7 @@ void WebSocketController::unsubscribe(const QVariant &subscriber,
|
||||
_subscribsMutex.unlock();
|
||||
}
|
||||
|
||||
QSet<unsigned int> WebSocketController::list(const QVariant &subscriber) {
|
||||
QSet<unsigned int> WebSocketController::list(const QString &subscriber) {
|
||||
QMutexLocker locker(&_itemsMutex);
|
||||
return _items[subscriber];
|
||||
}
|
||||
@ -56,14 +56,14 @@ void WebSocketController::handleItemChanged(const QSharedPointer<ISubscribableDa
|
||||
}
|
||||
|
||||
void WebSocketController::foreachSubscribers(const QSharedPointer<ISubscribableData> &item,
|
||||
const QSet<QVariant> &subscribersList) {
|
||||
const QSet<QString> &subscribersList) {
|
||||
|
||||
for (const auto &subscriber : subscribersList) {
|
||||
|
||||
auto abstractItem = item.dynamicCast<AbstractData>();
|
||||
|
||||
if (!abstractItem) {
|
||||
QuasarAppUtils::Params::log("All Subsribable objects must be child classes of the AbstractData." + subscriber.toString(),
|
||||
QuasarAppUtils::Params::log("All Subsribable objects must be child classes of the AbstractData." + subscriber,
|
||||
QuasarAppUtils::Error);
|
||||
unsubscribePrivate(subscriber, item->subscribeId());
|
||||
|
||||
@ -78,7 +78,7 @@ void WebSocketController::foreachSubscribers(const QSharedPointer<ISubscribableD
|
||||
}
|
||||
|
||||
if (fAllowed && !_node->sendData(abstractItem.data(), subscriber)) {
|
||||
QuasarAppUtils::Params::log("Send update failed for " + subscriber.toString(),
|
||||
QuasarAppUtils::Params::log("Send update failed for " + subscriber,
|
||||
QuasarAppUtils::Warning);
|
||||
|
||||
unsubscribePrivate(subscriber, item->subscribeId());
|
||||
@ -86,20 +86,20 @@ void WebSocketController::foreachSubscribers(const QSharedPointer<ISubscribableD
|
||||
|
||||
if (!fAllowed) {
|
||||
QuasarAppUtils::Params::log(QString("Internal Error. Member:%0 not have permission to object %1").
|
||||
arg(subscriber.toString(), abstractItem->toString()),
|
||||
arg(subscriber, abstractItem->toString()),
|
||||
QuasarAppUtils::Error);
|
||||
unsubscribePrivate(subscriber, item->subscribeId());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void WebSocketController::unsubscribePrivate(const QVariant &subscriber,
|
||||
void WebSocketController::unsubscribePrivate(const QString &subscriber,
|
||||
unsigned int item) {
|
||||
_subscribs[item].remove(subscriber);
|
||||
_items[subscriber].remove(item);
|
||||
}
|
||||
|
||||
void WebSocketController::subscribePrivate(const QVariant &subscriber,
|
||||
void WebSocketController::subscribePrivate(const QString &subscriber,
|
||||
unsigned int item) {
|
||||
|
||||
_subscribs[item].insert(subscriber);
|
||||
|
@ -38,7 +38,7 @@ public:
|
||||
* @param item This is a subscribable object id.
|
||||
* @return true if method finished successful.
|
||||
*/
|
||||
void subscribe(const QVariant &subscriber,
|
||||
void subscribe(const QString &subscriber,
|
||||
unsigned int item);
|
||||
|
||||
/**
|
||||
@ -47,7 +47,7 @@ public:
|
||||
* @param item This is a subscribable object id.
|
||||
* @return true if method finished successful.
|
||||
*/
|
||||
void unsubscribe(const QVariant &subscriber,
|
||||
void unsubscribe(const QString &subscriber,
|
||||
unsigned int item);
|
||||
|
||||
/**
|
||||
@ -55,7 +55,7 @@ public:
|
||||
* @param subscriber This is network member that want get a list of own subscription.
|
||||
* @return true if method finished successful.
|
||||
*/
|
||||
QSet<unsigned int> list(const QVariant& subscriber);
|
||||
QSet<unsigned int> list(const QString& subscriber);
|
||||
|
||||
/**
|
||||
* @brief handleItemChanged This method invoked when item on database changed.
|
||||
@ -65,17 +65,17 @@ public:
|
||||
|
||||
private:
|
||||
void foreachSubscribers(const QSharedPointer<PKG::ISubscribableData> &item,
|
||||
const QSet<QVariant> &subscribersList);
|
||||
const QSet<QString> &subscribersList);
|
||||
|
||||
void unsubscribePrivate(const QVariant &subscriber,
|
||||
void unsubscribePrivate(const QString &subscriber,
|
||||
unsigned int item);
|
||||
|
||||
void subscribePrivate(const QVariant &subscriber,
|
||||
void subscribePrivate(const QString &subscriber,
|
||||
unsigned int item);
|
||||
|
||||
/// subscribers it is nodes or clients
|
||||
QHash<unsigned int, QSet<QVariant>> _subscribs;
|
||||
QHash<QVariant, QSet<unsigned int>> _items;
|
||||
QHash<unsigned int, QSet<QString>> _subscribs;
|
||||
QHash<QString, QSet<unsigned int>> _items;
|
||||
|
||||
QMutex _subscribsMutex;
|
||||
QMutex _itemsMutex;
|
||||
|
@ -47,12 +47,10 @@ public:
|
||||
protected:
|
||||
// StreamBase interface override this methods for serialization your package
|
||||
QDataStream &fromStream(QDataStream &stream) {
|
||||
AbstractData::fromStream(stream);
|
||||
stream >> _data;
|
||||
return stream;
|
||||
}
|
||||
QDataStream &toStream(QDataStream &stream) const {
|
||||
AbstractData::toStream(stream);
|
||||
stream << _data;
|
||||
return stream;
|
||||
}
|
||||
|
@ -10,7 +10,6 @@
|
||||
#include "testutils.h"
|
||||
|
||||
#include <abstractnode.h>
|
||||
#include <keystorage.h>
|
||||
#include <ping.h>
|
||||
|
||||
#define LOCAL_TEST_PORT TEST_PORT + 1
|
||||
|
@ -22,16 +22,12 @@ public:
|
||||
// StreamBase interface
|
||||
protected:
|
||||
QDataStream &fromStream(QDataStream &stream) override{
|
||||
AbstractData::fromStream(stream);
|
||||
|
||||
stream >> data;
|
||||
|
||||
return stream;
|
||||
};
|
||||
|
||||
QDataStream &toStream(QDataStream &stream) const override{
|
||||
AbstractData::toStream(stream);
|
||||
|
||||
stream << data;
|
||||
|
||||
return stream;
|
||||
|
@ -6,9 +6,9 @@
|
||||
*/
|
||||
|
||||
#include "ecdsaauthtest.h"
|
||||
#include "authecdsa.h"
|
||||
#include <QtTest>
|
||||
#include "thread"
|
||||
#include <hcryptoFeatures/authecdsa.h>
|
||||
#include <thread>
|
||||
|
||||
#ifdef USE_HEART_SSL
|
||||
|
||||
|
@ -12,7 +12,6 @@
|
||||
|
||||
#include <databasenode.h>
|
||||
#include <hostaddress.h>
|
||||
#include <keystorage.h>
|
||||
#include <ping.h>
|
||||
|
||||
#define LOCAL_TEST_PORT TEST_PORT + 2
|
||||
|
@ -96,7 +96,7 @@ protected:
|
||||
|
||||
// create request for get all objects from database.
|
||||
QH::PKG::DBObjectsRequest<WorkType> setRequest(
|
||||
testObjec->tableName(), "");
|
||||
testObjec->table(), "");
|
||||
|
||||
auto list = BASE::db()->getObject(setRequest);
|
||||
QVERIFY(list);
|
||||
@ -181,7 +181,7 @@ protected:
|
||||
|
||||
QVERIFY(BASE::run( _dbNodeName));
|
||||
|
||||
QVERIFY(!BASE::changeTrust(QVariant{}, -10));
|
||||
QVERIFY(!BASE::changeTrust("", -10));
|
||||
|
||||
QVERIFY(BASE::changeTrust(testObjec->getId(), -10));
|
||||
|
||||
|
@ -7,6 +7,8 @@
|
||||
#include <QtTest>
|
||||
#include <isqldbcache.h>
|
||||
#include <database.h>
|
||||
#include <qaglobalutils.h>
|
||||
|
||||
#define LOCAL_TEST_PORT TEST_PORT + 5
|
||||
|
||||
class UpgradableDatabase: public QH::DataBase {
|
||||
@ -15,6 +17,10 @@ class UpgradableDatabase: public QH::DataBase {
|
||||
// DataBaseNode interface
|
||||
public:
|
||||
|
||||
UpgradableDatabase() {
|
||||
initDBPatches();
|
||||
}
|
||||
|
||||
bool checkVersion(int version) {
|
||||
QSqlQuery query;
|
||||
if (!db()->doQuery("SELECT * FROM DataBaseAttributes WHERE name='version'", true, &query)){
|
||||
@ -31,38 +37,47 @@ public:
|
||||
|
||||
protected:
|
||||
|
||||
void initDBPatches() {
|
||||
|
||||
QH::DBPatchMap dbPatches() const {
|
||||
QH::DBPatchMap result;
|
||||
addDBPatch({
|
||||
0, // from version
|
||||
1, // to version
|
||||
|
||||
result += [](const QH::iObjectProvider* database) -> bool {
|
||||
QSqlQuery query;
|
||||
if (!database->doQuery("select * from DataBaseAttributes", true, &query)){
|
||||
return false;
|
||||
};
|
||||
[](const QH::iObjectProvider* database) -> bool {
|
||||
QSqlQuery query;
|
||||
if (!database->doQuery("select * from DataBaseAttributes", true, &query)){
|
||||
return false;
|
||||
};
|
||||
|
||||
return true;
|
||||
};
|
||||
return true;
|
||||
} // action of patch
|
||||
});
|
||||
|
||||
result += [](const QH::iObjectProvider* database) -> bool {
|
||||
QSqlQuery query;
|
||||
if (!database->doQuery("select * from DataBaseAttributes", true, &query)){
|
||||
return false;
|
||||
};
|
||||
addDBPatch({
|
||||
1, // from version
|
||||
2, // to version
|
||||
[](const QH::iObjectProvider* database) -> bool {
|
||||
QSqlQuery query;
|
||||
if (!database->doQuery("select * from DataBaseAttributes", true, &query)){
|
||||
return false;
|
||||
};
|
||||
|
||||
return true;
|
||||
};
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
result += [](const QH::iObjectProvider* database) -> bool {
|
||||
QSqlQuery query;
|
||||
if (!database->doQuery("select * from DataBaseAttributes", true, &query)){
|
||||
return false;
|
||||
};
|
||||
addDBPatch({
|
||||
2, // from version
|
||||
3, // to version
|
||||
[](const QH::iObjectProvider* database) -> bool {
|
||||
QSqlQuery query;
|
||||
if (!database->doQuery("select * from DataBaseAttributes", true, &query)){
|
||||
return false;
|
||||
};
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
return result;
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit 4c596e30882931312b2beb31f8020351e719b2ce
|
||||
Subproject commit c492fa2fe8b83f93806cc31498af66ee053630ae
|
Loading…
x
Reference in New Issue
Block a user