From 3e1887914037e52a4c411b364cc4cee435a9b2bc Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E6=BD=98=E5=BB=BA=E4=B8=9C?= <617601767@qq.com>
Date: Sat, 2 Mar 2024 15:35:40 +0800
Subject: [PATCH] =?UTF-8?q?=E5=88=9D=E7=89=88=E6=8E=A5=E5=8F=A3?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.dockerignore | 30 +
.gitattributes | 63 ++
.gitignore | 363 ++++++++
.../Controllers/HadoopController.cs | 228 +++++
Hadoop/ZKLT.Hadoop.API/Dockerfile | 27 +
Hadoop/ZKLT.Hadoop.API/Program.cs | 49 ++
.../Properties/launchSettings.json | 40 +
Hadoop/ZKLT.Hadoop.API/ZKLT.Hadoop.API.csproj | 22 +
.../appsettings.Development.json | 8 +
Hadoop/ZKLT.Hadoop.API/appsettings.json | 9 +
.../ZKLT.Hadoop.Interface/IHadoopService.cs | 137 +++
Hadoop/ZKLT.Hadoop.Interface/ITableService.cs | 106 +++
.../ZKLT.Hadoop.Interface.csproj | 13 +
Hadoop/ZKLT.Hadoop.Model/HDP_Column.cs | 80 ++
.../ZKLT.Hadoop.Model/HDP_ColumnDataType.cs | 44 +
Hadoop/ZKLT.Hadoop.Model/HDP_Command.cs | 63 ++
Hadoop/ZKLT.Hadoop.Model/HDP_Page.cs | 42 +
Hadoop/ZKLT.Hadoop.Model/HDP_Source.cs | 81 ++
Hadoop/ZKLT.Hadoop.Model/HDP_Table.cs | 140 +++
Hadoop/ZKLT.Hadoop.Model/HDP_WhereType.cs | 25 +
.../ZKLT.Hadoop.Model.csproj | 13 +
Hadoop/ZKLT.Hadoop/HadoopService.cs | 589 +++++++++++++
Hadoop/ZKLT.Hadoop/TableService.cs | 828 ++++++++++++++++++
Hadoop/ZKLT.Hadoop/ZKLT.Hadoop.csproj | 23 +
ZKLT.sln | 51 ++
25 files changed, 3074 insertions(+)
create mode 100644 .dockerignore
create mode 100644 .gitattributes
create mode 100644 .gitignore
create mode 100644 Hadoop/ZKLT.Hadoop.API/Controllers/HadoopController.cs
create mode 100644 Hadoop/ZKLT.Hadoop.API/Dockerfile
create mode 100644 Hadoop/ZKLT.Hadoop.API/Program.cs
create mode 100644 Hadoop/ZKLT.Hadoop.API/Properties/launchSettings.json
create mode 100644 Hadoop/ZKLT.Hadoop.API/ZKLT.Hadoop.API.csproj
create mode 100644 Hadoop/ZKLT.Hadoop.API/appsettings.Development.json
create mode 100644 Hadoop/ZKLT.Hadoop.API/appsettings.json
create mode 100644 Hadoop/ZKLT.Hadoop.Interface/IHadoopService.cs
create mode 100644 Hadoop/ZKLT.Hadoop.Interface/ITableService.cs
create mode 100644 Hadoop/ZKLT.Hadoop.Interface/ZKLT.Hadoop.Interface.csproj
create mode 100644 Hadoop/ZKLT.Hadoop.Model/HDP_Column.cs
create mode 100644 Hadoop/ZKLT.Hadoop.Model/HDP_ColumnDataType.cs
create mode 100644 Hadoop/ZKLT.Hadoop.Model/HDP_Command.cs
create mode 100644 Hadoop/ZKLT.Hadoop.Model/HDP_Page.cs
create mode 100644 Hadoop/ZKLT.Hadoop.Model/HDP_Source.cs
create mode 100644 Hadoop/ZKLT.Hadoop.Model/HDP_Table.cs
create mode 100644 Hadoop/ZKLT.Hadoop.Model/HDP_WhereType.cs
create mode 100644 Hadoop/ZKLT.Hadoop.Model/ZKLT.Hadoop.Model.csproj
create mode 100644 Hadoop/ZKLT.Hadoop/HadoopService.cs
create mode 100644 Hadoop/ZKLT.Hadoop/TableService.cs
create mode 100644 Hadoop/ZKLT.Hadoop/ZKLT.Hadoop.csproj
create mode 100644 ZKLT.sln
diff --git a/.dockerignore b/.dockerignore
new file mode 100644
index 0000000..fe1152b
--- /dev/null
+++ b/.dockerignore
@@ -0,0 +1,30 @@
+**/.classpath
+**/.dockerignore
+**/.env
+**/.git
+**/.gitignore
+**/.project
+**/.settings
+**/.toolstarget
+**/.vs
+**/.vscode
+**/*.*proj.user
+**/*.dbmdl
+**/*.jfm
+**/azds.yaml
+**/bin
+**/charts
+**/docker-compose*
+**/Dockerfile*
+**/node_modules
+**/npm-debug.log
+**/obj
+**/secrets.dev.yaml
+**/values.dev.yaml
+LICENSE
+README.md
+!**/.gitignore
+!.git/HEAD
+!.git/config
+!.git/packed-refs
+!.git/refs/heads/**
\ No newline at end of file
diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000..1ff0c42
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1,63 @@
+###############################################################################
+# Set default behavior to automatically normalize line endings.
+###############################################################################
+* text=auto
+
+###############################################################################
+# Set default behavior for command prompt diff.
+#
+# This is need for earlier builds of msysgit that does not have it on by
+# default for csharp files.
+# Note: This is only used by command line
+###############################################################################
+#*.cs diff=csharp
+
+###############################################################################
+# Set the merge driver for project and solution files
+#
+# Merging from the command prompt will add diff markers to the files if there
+# are conflicts (Merging from VS is not affected by the settings below, in VS
+# the diff markers are never inserted). Diff markers may cause the following
+# file extensions to fail to load in VS. An alternative would be to treat
+# these files as binary and thus will always conflict and require user
+# intervention with every merge. To do so, just uncomment the entries below
+###############################################################################
+#*.sln merge=binary
+#*.csproj merge=binary
+#*.vbproj merge=binary
+#*.vcxproj merge=binary
+#*.vcproj merge=binary
+#*.dbproj merge=binary
+#*.fsproj merge=binary
+#*.lsproj merge=binary
+#*.wixproj merge=binary
+#*.modelproj merge=binary
+#*.sqlproj merge=binary
+#*.wwaproj merge=binary
+
+###############################################################################
+# behavior for image files
+#
+# image files are treated as binary by default.
+###############################################################################
+#*.jpg binary
+#*.png binary
+#*.gif binary
+
+###############################################################################
+# diff behavior for common document formats
+#
+# Convert binary document formats to text before diffing them. This feature
+# is only available from the command line. Turn it on by uncommenting the
+# entries below.
+###############################################################################
+#*.doc diff=astextplain
+#*.DOC diff=astextplain
+#*.docx diff=astextplain
+#*.DOCX diff=astextplain
+#*.dot diff=astextplain
+#*.DOT diff=astextplain
+#*.pdf diff=astextplain
+#*.PDF diff=astextplain
+#*.rtf diff=astextplain
+#*.RTF diff=astextplain
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..9491a2f
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,363 @@
+## Ignore Visual Studio temporary files, build results, and
+## files generated by popular Visual Studio add-ons.
+##
+## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
+
+# User-specific files
+*.rsuser
+*.suo
+*.user
+*.userosscache
+*.sln.docstates
+
+# User-specific files (MonoDevelop/Xamarin Studio)
+*.userprefs
+
+# Mono auto generated files
+mono_crash.*
+
+# Build results
+[Dd]ebug/
+[Dd]ebugPublic/
+[Rr]elease/
+[Rr]eleases/
+x64/
+x86/
+[Ww][Ii][Nn]32/
+[Aa][Rr][Mm]/
+[Aa][Rr][Mm]64/
+bld/
+[Bb]in/
+[Oo]bj/
+[Oo]ut/
+[Ll]og/
+[Ll]ogs/
+
+# Visual Studio 2015/2017 cache/options directory
+.vs/
+# Uncomment if you have tasks that create the project's static files in wwwroot
+#wwwroot/
+
+# Visual Studio 2017 auto generated files
+Generated\ Files/
+
+# MSTest test Results
+[Tt]est[Rr]esult*/
+[Bb]uild[Ll]og.*
+
+# NUnit
+*.VisualState.xml
+TestResult.xml
+nunit-*.xml
+
+# Build Results of an ATL Project
+[Dd]ebugPS/
+[Rr]eleasePS/
+dlldata.c
+
+# Benchmark Results
+BenchmarkDotNet.Artifacts/
+
+# .NET Core
+project.lock.json
+project.fragment.lock.json
+artifacts/
+
+# ASP.NET Scaffolding
+ScaffoldingReadMe.txt
+
+# StyleCop
+StyleCopReport.xml
+
+# Files built by Visual Studio
+*_i.c
+*_p.c
+*_h.h
+*.ilk
+*.meta
+*.obj
+*.iobj
+*.pch
+*.pdb
+*.ipdb
+*.pgc
+*.pgd
+*.rsp
+*.sbr
+*.tlb
+*.tli
+*.tlh
+*.tmp
+*.tmp_proj
+*_wpftmp.csproj
+*.log
+*.vspscc
+*.vssscc
+.builds
+*.pidb
+*.svclog
+*.scc
+
+# Chutzpah Test files
+_Chutzpah*
+
+# Visual C++ cache files
+ipch/
+*.aps
+*.ncb
+*.opendb
+*.opensdf
+*.sdf
+*.cachefile
+*.VC.db
+*.VC.VC.opendb
+
+# Visual Studio profiler
+*.psess
+*.vsp
+*.vspx
+*.sap
+
+# Visual Studio Trace Files
+*.e2e
+
+# TFS 2012 Local Workspace
+$tf/
+
+# Guidance Automation Toolkit
+*.gpState
+
+# ReSharper is a .NET coding add-in
+_ReSharper*/
+*.[Rr]e[Ss]harper
+*.DotSettings.user
+
+# TeamCity is a build add-in
+_TeamCity*
+
+# DotCover is a Code Coverage Tool
+*.dotCover
+
+# AxoCover is a Code Coverage Tool
+.axoCover/*
+!.axoCover/settings.json
+
+# Coverlet is a free, cross platform Code Coverage Tool
+coverage*.json
+coverage*.xml
+coverage*.info
+
+# Visual Studio code coverage results
+*.coverage
+*.coveragexml
+
+# NCrunch
+_NCrunch_*
+.*crunch*.local.xml
+nCrunchTemp_*
+
+# MightyMoose
+*.mm.*
+AutoTest.Net/
+
+# Web workbench (sass)
+.sass-cache/
+
+# Installshield output folder
+[Ee]xpress/
+
+# DocProject is a documentation generator add-in
+DocProject/buildhelp/
+DocProject/Help/*.HxT
+DocProject/Help/*.HxC
+DocProject/Help/*.hhc
+DocProject/Help/*.hhk
+DocProject/Help/*.hhp
+DocProject/Help/Html2
+DocProject/Help/html
+
+# Click-Once directory
+publish/
+
+# Publish Web Output
+*.[Pp]ublish.xml
+*.azurePubxml
+# Note: Comment the next line if you want to checkin your web deploy settings,
+# but database connection strings (with potential passwords) will be unencrypted
+*.pubxml
+*.publishproj
+
+# Microsoft Azure Web App publish settings. Comment the next line if you want to
+# checkin your Azure Web App publish settings, but sensitive information contained
+# in these scripts will be unencrypted
+PublishScripts/
+
+# NuGet Packages
+*.nupkg
+# NuGet Symbol Packages
+*.snupkg
+# The packages folder can be ignored because of Package Restore
+**/[Pp]ackages/*
+# except build/, which is used as an MSBuild target.
+!**/[Pp]ackages/build/
+# Uncomment if necessary however generally it will be regenerated when needed
+#!**/[Pp]ackages/repositories.config
+# NuGet v3's project.json files produces more ignorable files
+*.nuget.props
+*.nuget.targets
+
+# Microsoft Azure Build Output
+csx/
+*.build.csdef
+
+# Microsoft Azure Emulator
+ecf/
+rcf/
+
+# Windows Store app package directories and files
+AppPackages/
+BundleArtifacts/
+Package.StoreAssociation.xml
+_pkginfo.txt
+*.appx
+*.appxbundle
+*.appxupload
+
+# Visual Studio cache files
+# files ending in .cache can be ignored
+*.[Cc]ache
+# but keep track of directories ending in .cache
+!?*.[Cc]ache/
+
+# Others
+ClientBin/
+~$*
+*~
+*.dbmdl
+*.dbproj.schemaview
+*.jfm
+*.pfx
+*.publishsettings
+orleans.codegen.cs
+
+# Including strong name files can present a security risk
+# (https://github.com/github/gitignore/pull/2483#issue-259490424)
+#*.snk
+
+# Since there are multiple workflows, uncomment next line to ignore bower_components
+# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
+#bower_components/
+
+# RIA/Silverlight projects
+Generated_Code/
+
+# Backup & report files from converting an old project file
+# to a newer Visual Studio version. Backup files are not needed,
+# because we have git ;-)
+_UpgradeReport_Files/
+Backup*/
+UpgradeLog*.XML
+UpgradeLog*.htm
+ServiceFabricBackup/
+*.rptproj.bak
+
+# SQL Server files
+*.mdf
+*.ldf
+*.ndf
+
+# Business Intelligence projects
+*.rdl.data
+*.bim.layout
+*.bim_*.settings
+*.rptproj.rsuser
+*- [Bb]ackup.rdl
+*- [Bb]ackup ([0-9]).rdl
+*- [Bb]ackup ([0-9][0-9]).rdl
+
+# Microsoft Fakes
+FakesAssemblies/
+
+# GhostDoc plugin setting file
+*.GhostDoc.xml
+
+# Node.js Tools for Visual Studio
+.ntvs_analysis.dat
+node_modules/
+
+# Visual Studio 6 build log
+*.plg
+
+# Visual Studio 6 workspace options file
+*.opt
+
+# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
+*.vbw
+
+# Visual Studio LightSwitch build output
+**/*.HTMLClient/GeneratedArtifacts
+**/*.DesktopClient/GeneratedArtifacts
+**/*.DesktopClient/ModelManifest.xml
+**/*.Server/GeneratedArtifacts
+**/*.Server/ModelManifest.xml
+_Pvt_Extensions
+
+# Paket dependency manager
+.paket/paket.exe
+paket-files/
+
+# FAKE - F# Make
+.fake/
+
+# CodeRush personal settings
+.cr/personal
+
+# Python Tools for Visual Studio (PTVS)
+__pycache__/
+*.pyc
+
+# Cake - Uncomment if you are using it
+# tools/**
+# !tools/packages.config
+
+# Tabs Studio
+*.tss
+
+# Telerik's JustMock configuration file
+*.jmconfig
+
+# BizTalk build output
+*.btp.cs
+*.btm.cs
+*.odx.cs
+*.xsd.cs
+
+# OpenCover UI analysis results
+OpenCover/
+
+# Azure Stream Analytics local run output
+ASALocalRun/
+
+# MSBuild Binary and Structured Log
+*.binlog
+
+# NVidia Nsight GPU debugger configuration file
+*.nvuser
+
+# MFractors (Xamarin productivity tool) working folder
+.mfractor/
+
+# Local History for Visual Studio
+.localhistory/
+
+# BeatPulse healthcheck temp database
+healthchecksdb
+
+# Backup folder for Package Reference Convert tool in Visual Studio 2017
+MigrationBackup/
+
+# Ionide (cross platform F# VS Code tools) working folder
+.ionide/
+
+# Fody - auto-generated XML schema
+FodyWeavers.xsd
\ No newline at end of file
diff --git a/Hadoop/ZKLT.Hadoop.API/Controllers/HadoopController.cs b/Hadoop/ZKLT.Hadoop.API/Controllers/HadoopController.cs
new file mode 100644
index 0000000..e34419a
--- /dev/null
+++ b/Hadoop/ZKLT.Hadoop.API/Controllers/HadoopController.cs
@@ -0,0 +1,228 @@
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Mvc;
+using MySqlX.XDevAPI.Relational;
+using Newtonsoft.Json.Linq;
+using ZKLT.Hadoop.Interface;
+using ZKLT.Hadoop.Model;
+
+namespace ZKLT.Hadoop.API.Controllers
+{
+ ///
+ /// 云计算接口
+ ///
+ [Route("api/[controller]")]
+ [ApiController]
+ public class HadoopController : ControllerBase
+ {
+ public HadoopController(IHadoopService hadoop)
+ {
+ _HadoopService = hadoop;
+ }
+
+ private IHadoopService _HadoopService;
+
+ [HttpGet("getsource")]
+ public ActionResult GetSource([FromQuery] string sourceid)
+ {
+ try
+ {
+ return Ok(_HadoopService.GetSource(sourceid));
+ }
+ catch (Exception e)
+ {
+ return BadRequest(e.Message);
+ }
+ }
+
+ [HttpPost("insertsource")]
+ public ActionResult InsertSource(HDP_Source source)
+ {
+ try
+ {
+ return Ok(_HadoopService.InsertSource(source));
+ }
+ catch (Exception e)
+ {
+ return BadRequest(e.Message);
+ }
+ }
+
+ [HttpPost("updatesource")]
+ public ActionResult UpdateSource(HDP_Source source)
+ {
+ try
+ {
+ return Ok(_HadoopService.UpdateSource(source));
+ }
+ catch (Exception e)
+ {
+ return BadRequest(e.Message);
+ }
+ }
+
+ [HttpGet("deletesource")]
+ public ActionResult DeleteSource([FromQuery] string sourceid)
+ {
+ try
+ {
+ return Ok(_HadoopService.DeleteSource(sourceid));
+ }
+ catch (Exception e)
+ {
+ return BadRequest(e.Message);
+ }
+ }
+
+ [HttpPost("querysource")]
+ public ActionResult QuerySource(HDP_Command command)
+ {
+ try
+ {
+ return Ok(_HadoopService.QuerySource(command));
+ }
+ catch (Exception e)
+ {
+ return BadRequest(e.Message);
+ }
+ }
+
+ [HttpGet("gettable")]
+ public ActionResult GetTable([FromQuery] string tableid)
+ {
+ try
+ {
+ return Ok(_HadoopService.GetTable(tableid));
+ }
+ catch (Exception e)
+ {
+ return BadRequest(e.Message);
+ }
+ }
+
+ [HttpPost("inserttable")]
+ public ActionResult InsertTable(HDP_Table table)
+ {
+ try
+ {
+ return Ok(_HadoopService.InsertTable(table));
+ }
+ catch (Exception e)
+ {
+ return BadRequest(e.Message);
+ }
+ }
+
+ [HttpPost("updatetable")]
+ public ActionResult UpdateTable(HDP_Table table)
+ {
+ try
+ {
+ return Ok(_HadoopService.UpdateTable(table));
+ }
+ catch (Exception e)
+ {
+ return BadRequest(e.Message);
+ }
+ }
+
+ [HttpGet("deletetable")]
+ public ActionResult DeleteTable([FromQuery] string tableId) {
+ try
+ {
+ return Ok(_HadoopService.DeleteTable(tableId));
+ }
+ catch (Exception e)
+ {
+ return BadRequest(e.Message);
+ }
+ }
+
+ [HttpPost("querytable")]
+ public ActionResult QueryTable(HDP_Command command) {
+ try
+ {
+ return Ok(_HadoopService.QueryTable(command));
+ }
+ catch (Exception e)
+ {
+ return BadRequest(e.Message);
+ }
+ }
+
+ [HttpPost("insert")]
+ public ActionResult Insert(HDP_Command command) {
+ try
+ {
+ return Ok(_HadoopService.Insert(command));
+ }
+ catch (Exception e)
+ {
+ return BadRequest(e.Message);
+ }
+ }
+
+ [HttpPost("update")]
+ public ActionResult Update(HDP_Command command)
+ {
+ try
+ {
+ return Ok(_HadoopService.Update(command));
+ }
+ catch (Exception e)
+ {
+ return BadRequest(e.Message);
+ }
+ }
+
+ [HttpPost("delete")]
+ public ActionResult Delete(HDP_Command command)
+ {
+ try
+ {
+ return Ok(_HadoopService.Delete(command));
+ }
+ catch (Exception e)
+ {
+ return BadRequest(e.Message);
+ }
+ }
+
+ [HttpPost("querysingle")]
+ public ActionResult QuerySingle(HDP_Command command)
+ {
+ try
+ {
+ return Ok(_HadoopService.QuerySingle(command));
+ }
+ catch (Exception e)
+ {
+ return BadRequest(e.Message);
+ }
+ }
+
+ [HttpPost("query")]
+ public ActionResult Query(HDP_Command command)
+ {
+ try
+ {
+ return Ok(_HadoopService.Query(command));
+ }
+ catch (Exception e)
+ {
+ return BadRequest(e.Message);
+ }
+ }
+
+ [HttpPost("page")]
+ public ActionResult Page(HDP_Command command) {
+ try
+ {
+ return Ok(_HadoopService.Page(command));
+ }
+ catch (Exception e)
+ {
+ return BadRequest(e.Message);
+ }
+ }
+ }
+}
diff --git a/Hadoop/ZKLT.Hadoop.API/Dockerfile b/Hadoop/ZKLT.Hadoop.API/Dockerfile
new file mode 100644
index 0000000..a4e2d3d
--- /dev/null
+++ b/Hadoop/ZKLT.Hadoop.API/Dockerfile
@@ -0,0 +1,27 @@
+#See https://aka.ms/customizecontainer to learn how to customize your debug container and how Visual Studio uses this Dockerfile to build your images for faster debugging.
+
+FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base
+USER app
+WORKDIR /app
+EXPOSE 8080
+
+FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
+ARG BUILD_CONFIGURATION=Release
+WORKDIR /src
+COPY ["Hadoop/ZKLT.Hadoop.API/ZKLT.Hadoop.API.csproj", "Hadoop/ZKLT.Hadoop.API/"]
+COPY ["Hadoop/ZKLT.Hadoop/ZKLT.Hadoop.csproj", "Hadoop/ZKLT.Hadoop/"]
+COPY ["Hadoop/ZKLT.Hadoop.Interface/ZKLT.Hadoop.Interface.csproj", "Hadoop/ZKLT.Hadoop.Interface/"]
+COPY ["Hadoop/ZKLT.Hadoop.Model/ZKLT.Hadoop.Model.csproj", "Hadoop/ZKLT.Hadoop.Model/"]
+RUN dotnet restore "./Hadoop/ZKLT.Hadoop.API/./ZKLT.Hadoop.API.csproj"
+COPY . .
+WORKDIR "/src/Hadoop/ZKLT.Hadoop.API"
+RUN dotnet build "./ZKLT.Hadoop.API.csproj" -c $BUILD_CONFIGURATION -o /app/build
+
+FROM build AS publish
+ARG BUILD_CONFIGURATION=Release
+RUN dotnet publish "./ZKLT.Hadoop.API.csproj" -c $BUILD_CONFIGURATION -o /app/publish /p:UseAppHost=false
+
+FROM base AS final
+WORKDIR /app
+COPY --from=publish /app/publish .
+ENTRYPOINT ["dotnet", "ZKLT.Hadoop.API.dll"]
\ No newline at end of file
diff --git a/Hadoop/ZKLT.Hadoop.API/Program.cs b/Hadoop/ZKLT.Hadoop.API/Program.cs
new file mode 100644
index 0000000..1be08e0
--- /dev/null
+++ b/Hadoop/ZKLT.Hadoop.API/Program.cs
@@ -0,0 +1,49 @@
+using Newtonsoft.Json;
+using Newtonsoft.Json.Serialization;
+using ZKLT.Hadoop;
+namespace ZKLT.Hadoop.API
+{
+ public class Program
+ {
+ public static void Main(string[] args)
+ {
+ var builder = WebApplication.CreateBuilder(args);
+
+ // Add services to the container.
+
+ builder.Services.AddControllers().AddNewtonsoftJson(options =>
+ {
+ options.SerializerSettings.ContractResolver = new DefaultContractResolver();
+
+ options.SerializerSettings.NullValueHandling = NullValueHandling.Ignore;
+
+ options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
+ });
+ // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
+ builder.Services.AddEndpointsApiExplorer();
+ builder.Services.AddSwaggerGen();
+ builder.Services.AddHadoop();
+ var app = builder.Build();
+ app.UseHadoop((c) => {
+ c.Host = "127.0.0.1";
+ c.Account = "root";
+ c.PassWord = "root";
+ c.Key = "devdb";
+ c.Port = 3306;
+ });
+ // Configure the HTTP request pipeline.
+ if (app.Environment.IsDevelopment())
+ {
+ app.UseSwagger();
+ app.UseSwaggerUI();
+ }
+
+ app.UseAuthorization();
+
+
+ app.MapControllers();
+
+ app.Run();
+ }
+ }
+}
diff --git a/Hadoop/ZKLT.Hadoop.API/Properties/launchSettings.json b/Hadoop/ZKLT.Hadoop.API/Properties/launchSettings.json
new file mode 100644
index 0000000..fb9f190
--- /dev/null
+++ b/Hadoop/ZKLT.Hadoop.API/Properties/launchSettings.json
@@ -0,0 +1,40 @@
+{
+ "profiles": {
+ "http": {
+ "commandName": "Project",
+ "launchBrowser": true,
+ "launchUrl": "swagger",
+ "environmentVariables": {
+ "ASPNETCORE_ENVIRONMENT": "Development"
+ },
+ "dotnetRunMessages": true,
+ "applicationUrl": "http://localhost:5171"
+ },
+ "IIS Express": {
+ "commandName": "IISExpress",
+ "launchBrowser": true,
+ "launchUrl": "swagger",
+ "environmentVariables": {
+ "ASPNETCORE_ENVIRONMENT": "Development"
+ }
+ },
+ "Docker": {
+ "commandName": "Docker",
+ "launchBrowser": true,
+ "launchUrl": "{Scheme}://{ServiceHost}:{ServicePort}/swagger",
+ "environmentVariables": {
+ "ASPNETCORE_HTTP_PORTS": "8080"
+ },
+ "publishAllPorts": true
+ }
+ },
+ "$schema": "http://json.schemastore.org/launchsettings.json",
+ "iisSettings": {
+ "windowsAuthentication": false,
+ "anonymousAuthentication": true,
+ "iisExpress": {
+ "applicationUrl": "http://localhost:59844",
+ "sslPort": 0
+ }
+ }
+}
\ No newline at end of file
diff --git a/Hadoop/ZKLT.Hadoop.API/ZKLT.Hadoop.API.csproj b/Hadoop/ZKLT.Hadoop.API/ZKLT.Hadoop.API.csproj
new file mode 100644
index 0000000..7fb3a8b
--- /dev/null
+++ b/Hadoop/ZKLT.Hadoop.API/ZKLT.Hadoop.API.csproj
@@ -0,0 +1,22 @@
+
+
+
+ net8.0
+ enable
+ enable
+ true
+ Linux
+ ..\..
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Hadoop/ZKLT.Hadoop.API/appsettings.Development.json b/Hadoop/ZKLT.Hadoop.API/appsettings.Development.json
new file mode 100644
index 0000000..0c208ae
--- /dev/null
+++ b/Hadoop/ZKLT.Hadoop.API/appsettings.Development.json
@@ -0,0 +1,8 @@
+{
+ "Logging": {
+ "LogLevel": {
+ "Default": "Information",
+ "Microsoft.AspNetCore": "Warning"
+ }
+ }
+}
diff --git a/Hadoop/ZKLT.Hadoop.API/appsettings.json b/Hadoop/ZKLT.Hadoop.API/appsettings.json
new file mode 100644
index 0000000..10f68b8
--- /dev/null
+++ b/Hadoop/ZKLT.Hadoop.API/appsettings.json
@@ -0,0 +1,9 @@
+{
+ "Logging": {
+ "LogLevel": {
+ "Default": "Information",
+ "Microsoft.AspNetCore": "Warning"
+ }
+ },
+ "AllowedHosts": "*"
+}
diff --git a/Hadoop/ZKLT.Hadoop.Interface/IHadoopService.cs b/Hadoop/ZKLT.Hadoop.Interface/IHadoopService.cs
new file mode 100644
index 0000000..9c34355
--- /dev/null
+++ b/Hadoop/ZKLT.Hadoop.Interface/IHadoopService.cs
@@ -0,0 +1,137 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Transactions;
+using ZKLT.Hadoop.Model;
+
+namespace ZKLT.Hadoop.Interface
+{
+ ///
+ /// 云计算接口
+ ///
+ public interface IHadoopService
+ {
+ ///
+ /// 初始化云计算
+ ///
+ /// 配置
+ public void Init(Action config);
+
+ ///
+ /// 获取源
+ ///
+ /// 数据源编号
+ /// 结果
+ public HDP_Source? GetSource(string sourceid);
+
+ ///
+ /// 创建源
+ ///
+ /// 源
+ /// 是否成功
+ public bool InsertSource(HDP_Source source);
+
+ ///
+ /// 更新源
+ ///
+ /// 源
+ /// 是否成功
+ public bool UpdateSource(HDP_Source source);
+
+ ///
+ /// 删除源
+ ///
+ /// 源
+ /// 是否成功
+ public bool DeleteSource(string sourceid);
+
+ ///
+ /// 查询源
+ ///
+ /// 命令
+ /// 结果
+ public HDP_Source[] QuerySource(HDP_Command command);
+
+ ///
+ /// 获取表
+ ///
+ /// 表编号
+ /// 结果
+ public HDP_Table? GetTable(string tableid);
+
+ ///
+ /// 创建表
+ ///
+ /// 表
+ /// 是否成功
+ public bool InsertTable(HDP_Table table);
+
+ ///
+ /// 更新表
+ ///
+ ///
+ /// 是否成功
+ public bool UpdateTable(HDP_Table table);
+
+ ///
+ /// 删除表
+ ///
+ ///
+ /// 是否成功
+ public bool DeleteTable(string tableId);
+
+ ///
+ /// 查询表
+ ///
+ /// 命令
+ /// 结果
+ public HDP_Table[] QueryTable(HDP_Command command);
+
+ ///
+ /// 插入数据
+ ///
+ /// 命令
+ /// 是否成功
+ public bool Insert(HDP_Command command);
+
+ ///
+ /// 更新数据
+ ///
+ ///
+ /// 是否成功
+ public bool Update(HDP_Command command);
+
+ ///
+ /// 删除数据
+ ///
+ /// 命令
+ /// 是否成功
+ public bool Delete(HDP_Command command);
+
+ ///
+ /// 查询单条
+ ///
+ /// 返回类型
+ /// 命令
+ /// 结果
+ public T? QuerySingle(HDP_Command command);
+
+ ///
+ /// 查询列表
+ ///
+ /// 返回类型
+ /// 命令
+ /// 结果
+ public T[] Query(HDP_Command command);
+
+ ///
+ /// 分页查询
+ ///
+ /// 返回类型
+ /// 命令
+ /// 结果
+ public HDP_Page Page(HDP_Command command);
+ }
+}
diff --git a/Hadoop/ZKLT.Hadoop.Interface/ITableService.cs b/Hadoop/ZKLT.Hadoop.Interface/ITableService.cs
new file mode 100644
index 0000000..b637140
--- /dev/null
+++ b/Hadoop/ZKLT.Hadoop.Interface/ITableService.cs
@@ -0,0 +1,106 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using ZKLT.Hadoop.Model;
+
+namespace ZKLT.Hadoop.Interface
+{
+ public interface ITableService
+ {
+ ///
+ /// 同步结构
+ ///
+ /// 数据源
+ /// 数据表
+ /// 是否成功
+ public bool InitStruct(HDP_Source source, HDP_Table table);
+
+ ///
+ /// 删除结构
+ ///
+ /// 源
+ /// 表
+ /// 是否成功
+ public bool RemoveStruct(HDP_Source source, string tableKey);
+
+ ///
+ /// 插入数据
+ ///
+ /// 数据源
+ /// 数据表
+ /// 数据
+ /// 是否成功
+ public bool Insert(HDP_Source source, HDP_Table table, Dictionary row);
+
+ ///
+ /// 更新
+ ///
+ /// 数据源
+ /// 数据表
+ /// 条件
+ /// 数据
+ /// 是否成功
+ public bool Update(HDP_Source source, HDP_Table table, Dictionary where, Dictionary row);
+
+ ///
+ /// 删除
+ ///
+ /// 数据源
+ /// 数据表
+ /// 条件
+ /// 数据
+ /// 是否成功
+ public bool Delete(HDP_Source source, HDP_Table table, Dictionary where, Dictionary row);
+
+ ///
+ /// 查询单个
+ ///
+ /// 数据源
+ /// 数据表
+ /// 条件
+ /// 数据
+ /// 结果
+ public T? QuerySingle(HDP_Source source, HDP_Table table, Dictionary where, Dictionary row);
+
+ ///
+ /// 查询列表
+ ///
+ /// 返回类型
+ /// 数据源
+ /// 数据表
+ /// 条件
+ /// 数据
+ /// 结果集
+ public T[] Query(HDP_Source source, HDP_Table table, Dictionary? where = null, Dictionary? row = null, Dictionary? order = null);
+
+ ///
+ /// 查询列表
+ ///
+ /// 返回类型
+ /// 数据源
+ /// 数据表
+ /// 条件
+ /// 数据
+ /// 结果集
+ public HDP_Page QueryPage(HDP_Source source, HDP_Table table, int pageIndex, int pageSize, Dictionary? where = null, Dictionary? row = null, Dictionary? order = null);
+
+
+ ///
+ /// 判断数据源是否存在表
+ ///
+ /// 数据源
+ /// 表名
+ /// 是否存在
+ public bool DbExistTable(HDP_Source source, string tableName);
+
+ ///
+ /// 查询数据列
+ ///
+ /// 数据源
+ /// 表名
+ /// 列
+ public HDP_Column[] DbGetColumns(HDP_Source source, string tableName);
+ }
+}
diff --git a/Hadoop/ZKLT.Hadoop.Interface/ZKLT.Hadoop.Interface.csproj b/Hadoop/ZKLT.Hadoop.Interface/ZKLT.Hadoop.Interface.csproj
new file mode 100644
index 0000000..0f60bcb
--- /dev/null
+++ b/Hadoop/ZKLT.Hadoop.Interface/ZKLT.Hadoop.Interface.csproj
@@ -0,0 +1,13 @@
+
+
+
+ net8.0
+ enable
+ enable
+
+
+
+
+
+
+
diff --git a/Hadoop/ZKLT.Hadoop.Model/HDP_Column.cs b/Hadoop/ZKLT.Hadoop.Model/HDP_Column.cs
new file mode 100644
index 0000000..a1b2794
--- /dev/null
+++ b/Hadoop/ZKLT.Hadoop.Model/HDP_Column.cs
@@ -0,0 +1,80 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace ZKLT.Hadoop.Model
+{
+ ///
+ /// 数据列
+ ///
+ [AttributeUsage(AttributeTargets.Property, Inherited = true)]
+ [HDP_Table(Key = "HDP_Column", Description = "列")]
+ public class HDP_Column : Attribute
+ {
+ private string? _Id;
+
+ private string? _TableId;
+
+ private string? _Key;
+
+ private bool _IsPrimary;
+
+ private string? _Description;
+
+ private string? _DataType;
+
+ private int _Length;
+
+ private int _DecimalLength;
+
+ ///
+ /// 编号
+ ///
+ [HDP_Column(Key = "Id",Description = "编号", Length = 100, DataType = HDP_ColumnDataType.VARCHAR, IsPrimary = true)]
+ public string? Id { get => _Id; set => _Id = value; }
+
+ ///
+ /// 表编号
+ ///
+ [HDP_Column(Key = "TableId",Description = "表编号", Length = 100, DataType = HDP_ColumnDataType.VARCHAR)]
+ public string? TableId { get => _TableId; set => _TableId = value; }
+
+ ///
+ /// 列名
+ ///
+ [HDP_Column(Key = "Key", Description = "列名", Length = 100, DataType = HDP_ColumnDataType.VARCHAR)]
+ public string? Key { get => _Key; set => _Key = value; }
+
+ ///
+ /// 是否主键
+ ///
+ [HDP_Column(Key = "IsPrimary", Description = "是否主键", DataType = HDP_ColumnDataType.BOOL)]
+ public bool IsPrimary { get => _IsPrimary; set => _IsPrimary = value; }
+
+ ///
+ /// 描述
+ ///
+ [HDP_Column(Key = "Description", Description = "描述",Length = 200, DataType = HDP_ColumnDataType.VARCHAR)]
+ public string? Description { get => _Description; set => _Description = value; }
+
+ ///
+ /// 数据类型
+ ///
+ [HDP_Column(Key = "DataType", Description = "数据类型", Length = 100, DataType = HDP_ColumnDataType.VARCHAR)]
+ public string? DataType { get => _DataType; set => _DataType = value; }
+
+ ///
+ /// 长度
+ ///
+ [HDP_Column(Key = "Length", Description = "长度", DataType = HDP_ColumnDataType.INT)]
+ public int Length { get => _Length; set => _Length = value; }
+
+ ///
+ /// 小数长度
+ ///
+ [HDP_Column(Key = "DecimalLength", Description = "小数长度", DataType = HDP_ColumnDataType.INT)]
+ public int DecimalLength { get => _DecimalLength; set => _DecimalLength = value; }
+ }
+}
diff --git a/Hadoop/ZKLT.Hadoop.Model/HDP_ColumnDataType.cs b/Hadoop/ZKLT.Hadoop.Model/HDP_ColumnDataType.cs
new file mode 100644
index 0000000..f49a18f
--- /dev/null
+++ b/Hadoop/ZKLT.Hadoop.Model/HDP_ColumnDataType.cs
@@ -0,0 +1,44 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace ZKLT.Hadoop.Model
+{
+ ///
+ /// 列数据类型
+ ///
+ public class HDP_ColumnDataType
+ {
+ ///
+ /// 整数
+ ///
+ public const string INT = "INT";
+
+ ///
+ /// 大整数
+ ///
+ public const string BIGINT = "BIGINT";
+
+ ///
+ /// 浮点数
+ ///
+ public const string DECIMAL = "DECIMAL";
+
+ ///
+ /// 字符串
+ ///
+ public const string VARCHAR = "VARCHAR";
+
+ ///
+ /// 日期
+ ///
+ public const string DATETIME = "DATETIME";
+
+ ///
+ /// 布尔值
+ ///
+ public const string BOOL = "BOOL";
+ }
+}
diff --git a/Hadoop/ZKLT.Hadoop.Model/HDP_Command.cs b/Hadoop/ZKLT.Hadoop.Model/HDP_Command.cs
new file mode 100644
index 0000000..b0ab375
--- /dev/null
+++ b/Hadoop/ZKLT.Hadoop.Model/HDP_Command.cs
@@ -0,0 +1,63 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace ZKLT.Hadoop.Model
+{
+ ///
+ /// 命令
+ ///
+ public class HDP_Command
+ {
+ private string? _SourceId;
+
+ private string? _TableId;
+
+ private int? _PageIndex;
+
+ private int? _PageSize;
+
+ private Dictionary? _Where;
+
+ private Dictionary? _Data;
+
+ private Dictionary? _Order;
+
+ ///
+ /// 源
+ ///
+ public string? SourceId { get => _SourceId; set => _SourceId = value; }
+
+ ///
+ /// 表
+ ///
+ public string? TableId { get => _TableId; set => _TableId = value; }
+
+ ///
+ /// 条件
+ ///
+ public Dictionary? Where { get => _Where; set => _Where = value; }
+
+ ///
+ /// 数据
+ ///
+ public Dictionary? Data { get => _Data; set => _Data = value; }
+
+ ///
+ /// 分页下标
+ ///
+ public int? PageIndex { get => _PageIndex; set => _PageIndex = value; }
+
+ ///
+ /// 分页大小
+ ///
+ public int? PageSize { get => _PageSize; set => _PageSize = value; }
+
+ ///
+ /// 排序
+ ///
+ public Dictionary? Order { get => _Order; set => _Order = value; }
+ }
+}
diff --git a/Hadoop/ZKLT.Hadoop.Model/HDP_Page.cs b/Hadoop/ZKLT.Hadoop.Model/HDP_Page.cs
new file mode 100644
index 0000000..a3c3178
--- /dev/null
+++ b/Hadoop/ZKLT.Hadoop.Model/HDP_Page.cs
@@ -0,0 +1,42 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace ZKLT.Hadoop.Model
+{
+ ///
+ /// 分页数据
+ ///
+ public class HDP_Page
+ {
+ private int _PageIndex;
+
+ private int _PageSize;
+
+ private int _Total;
+
+ private T?[]? _Data;
+
+ ///
+ /// 分页下标
+ ///
+ public int PageIndex { get => _PageIndex; set => _PageIndex = value; }
+
+ ///
+ /// 分页大小
+ ///
+ public int PageSize { get => _PageSize; set => _PageSize = value; }
+
+ ///
+ /// 总条数
+ ///
+ public int Total { get => _Total; set => _Total = value; }
+
+ ///
+ /// 数据
+ ///
+ public T?[]? Data { get => _Data; set => _Data = value; }
+ }
+}
diff --git a/Hadoop/ZKLT.Hadoop.Model/HDP_Source.cs b/Hadoop/ZKLT.Hadoop.Model/HDP_Source.cs
new file mode 100644
index 0000000..2a8c9e6
--- /dev/null
+++ b/Hadoop/ZKLT.Hadoop.Model/HDP_Source.cs
@@ -0,0 +1,81 @@
+using System;
+using System.Collections.Generic;
+using System.Data.Common;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace ZKLT.Hadoop.Model
+{
+ ///
+ /// 源
+ ///
+ [HDP_Table(Key = "HDP_Source",Description = "源")]
+ public class HDP_Source
+ {
+ private string? _Id;
+
+ private string? _Key;
+
+ private string? _Host;
+
+ private int? _Port;
+
+ private string? _Account;
+
+ private string? _PassWord;
+
+ private string? _Description;
+
+ ///
+ /// 编号
+ ///
+ [HDP_Column(Key = "Id", Description = "编号", Length = 100, DataType = HDP_ColumnDataType.VARCHAR, IsPrimary = true)]
+ public string? Id { get => _Id; set => _Id = value; }
+
+ ///
+ /// 键
+ ///
+ [HDP_Column(Key = "Key", Description = "键", Length = 100, DataType = HDP_ColumnDataType.VARCHAR)]
+ public string? Key { get => _Key; set => _Key = value; }
+
+ ///
+ /// 主机
+ ///
+ [HDP_Column(Key = "Host", Description = "主机", Length = 200, DataType = HDP_ColumnDataType.VARCHAR)]
+ public string? Host { get => _Host; set => _Host = value; }
+
+ ///
+ /// 端口
+ ///
+ [HDP_Column(Key = "Port", Description = "端口", DataType = HDP_ColumnDataType.INT)]
+ public int? Port { get => _Port; set => _Port = value; }
+
+ ///
+ /// 用户名
+ ///
+ [HDP_Column(Key = "Account", Description = "用户名",Length = 100, DataType = HDP_ColumnDataType.VARCHAR)]
+ public string? Account { get => _Account; set => _Account = value; }
+
+ ///
+ /// 密码
+ ///
+ [HDP_Column(Key = "PassWord", Description = "密码", Length = 100, DataType = HDP_ColumnDataType.VARCHAR)]
+ public string? PassWord { get => _PassWord; set => _PassWord = value; }
+
+ ///
+ /// 描述
+ ///
+ [HDP_Column(Key = "Description", Description = "描述", Length = 200, DataType = HDP_ColumnDataType.VARCHAR)]
+ public string? Description { get => _Description; set => _Description = value; }
+
+ ///
+ /// 获取连接字符串
+ ///
+ /// 连接字符串
+ public string GetConnectString() {
+ return @$"Data Source={Host};Port={Port};Database={Key};User Id={Account};
+ Pwd={PassWord};Charset=utf8;Pooling=true;";
+ }
+ }
+}
diff --git a/Hadoop/ZKLT.Hadoop.Model/HDP_Table.cs b/Hadoop/ZKLT.Hadoop.Model/HDP_Table.cs
new file mode 100644
index 0000000..9c62ad3
--- /dev/null
+++ b/Hadoop/ZKLT.Hadoop.Model/HDP_Table.cs
@@ -0,0 +1,140 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations.Schema;
+using System.Linq;
+using System.Reflection;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace ZKLT.Hadoop.Model
+{
+ ///
+ /// 表
+ ///
+ [AttributeUsage(AttributeTargets.Class, Inherited = true)]
+ [HDP_Table(Key = "HDP_Table", Description = "表")]
+ public class HDP_Table : Attribute
+ {
+ private string? _Id;
+
+ private string? _SourceId;
+
+ private string? _Key;
+
+ private string? _Description;
+
+ private HDP_Column[]? _Columns;
+
+ ///
+ /// 编号
+ ///
+ [HDP_Column(Key = "Id", Description = "编号", Length = 100, DataType = HDP_ColumnDataType.VARCHAR, IsPrimary = true)]
+ public string? Id { get => _Id; set => _Id = value; }
+
+ ///
+ /// 源编号
+ ///
+ [HDP_Column(Key = "SourceId", Description = "源编号", Length = 100, DataType = HDP_ColumnDataType.VARCHAR)]
+ public string? SourceId { get => _SourceId; set => _SourceId = value; }
+
+ ///
+ /// 键
+ ///
+ [HDP_Column(Key = "Key", Description = "键", Length = 100, DataType = HDP_ColumnDataType.VARCHAR)]
+ public string? Key { get => _Key; set => _Key = value; }
+
+ ///
+ /// 描述
+ ///
+ [HDP_Column(Key = "Description", Description = "描述", Length = 200, DataType = HDP_ColumnDataType.VARCHAR)]
+ public string? Description { get => _Description; set => _Description = value; }
+
+ ///
+ /// 列
+ ///
+ public HDP_Column[]? Columns { get => _Columns; set => _Columns = value; }
+
+ ///
+ /// 类转换Table
+ ///
+ /// 类型
+ ///
+ public static HDP_Table Class2Table()
+ {
+ Type _type = typeof(T);
+
+ var _tableAttribute = _type.GetCustomAttribute();
+
+ if (_tableAttribute == null)
+ {
+ throw new ArgumentNullException("Table标记不存在");
+ }
+
+ if (string.IsNullOrEmpty(_tableAttribute.Key))
+ {
+ _tableAttribute.Key = _type.Name;
+ }
+
+ if (string.IsNullOrEmpty(_tableAttribute.Id))
+ {
+ _tableAttribute.Id = _tableAttribute.Key;
+ }
+
+ var _properties = _type.GetProperties();
+
+ var _columns = new List();
+
+ foreach (var _property in _properties)
+ {
+ var _column = _property.GetCustomAttribute();
+
+ if (_column == null)
+ {
+ continue;
+ }
+
+ if (string.IsNullOrEmpty(_column.TableId))
+ {
+ _column.TableId = _tableAttribute.Id;
+ }
+
+ if (string.IsNullOrEmpty(_column.Key))
+ {
+ _column.Key = _property.Name;
+ }
+
+ if (string.IsNullOrEmpty(_column.Id))
+ {
+ _column.Id = _column.Key;
+ }
+
+ _columns.Add(_column);
+ }
+
+ _tableAttribute.Columns = _columns.ToArray();
+
+ return _tableAttribute;
+ }
+
+ ///
+ /// 类
+ ///
+ /// 数据
+ /// 字典
+ public static Dictionary Class2Dictionary(object data)
+ {
+ var _result = new Dictionary();
+
+ Type _type = data.GetType();
+
+ var _properties = _type.GetProperties();
+
+ foreach (var _property in _properties)
+ {
+ _result.Add(_property.Name, _property.GetValue(data)!);
+ }
+
+ return _result;
+ }
+ }
+}
diff --git a/Hadoop/ZKLT.Hadoop.Model/HDP_WhereType.cs b/Hadoop/ZKLT.Hadoop.Model/HDP_WhereType.cs
new file mode 100644
index 0000000..96f23aa
--- /dev/null
+++ b/Hadoop/ZKLT.Hadoop.Model/HDP_WhereType.cs
@@ -0,0 +1,25 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace ZKLT.Hadoop.Model
+{
+ public class HDP_WhereType
+ {
+ public const string EQUAL = "=";
+
+ public const string NOTEQUAL = "!=";
+
+ public const string LIKE = "LIKE";
+
+ public const string MORE = ">";
+
+ public const string LESS = "<";
+
+ public const string MORETHEN = ">=";
+
+ public const string LESSTHEN = "<=";
+ }
+}
diff --git a/Hadoop/ZKLT.Hadoop.Model/ZKLT.Hadoop.Model.csproj b/Hadoop/ZKLT.Hadoop.Model/ZKLT.Hadoop.Model.csproj
new file mode 100644
index 0000000..daeed6e
--- /dev/null
+++ b/Hadoop/ZKLT.Hadoop.Model/ZKLT.Hadoop.Model.csproj
@@ -0,0 +1,13 @@
+
+
+
+ net8.0
+ enable
+ enable
+
+
+
+
+
+
+
diff --git a/Hadoop/ZKLT.Hadoop/HadoopService.cs b/Hadoop/ZKLT.Hadoop/HadoopService.cs
new file mode 100644
index 0000000..74ac972
--- /dev/null
+++ b/Hadoop/ZKLT.Hadoop/HadoopService.cs
@@ -0,0 +1,589 @@
+using Microsoft.AspNetCore.Builder;
+using Microsoft.Extensions.DependencyInjection;
+using MySqlX.XDevAPI.Relational;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Transactions;
+using ZKLT.Hadoop.Interface;
+using ZKLT.Hadoop.Model;
+
+namespace ZKLT.Hadoop
+{
+ ///
+ /// 云计算扩展
+ ///
+ public static class HadoopServiceExtend
+ {
+ ///
+ /// 注入云计算服务
+ ///
+ /// 服务集合
+ ///
+ public static IServiceCollection AddHadoop(this IServiceCollection services)
+ {
+ services.AddSingleton();
+ services.AddSingleton();
+ return services;
+ }
+
+ ///
+ /// 应用云计算
+ ///
+ /// 应用
+ /// 源配置
+ ///
+ public static IApplicationBuilder UseHadoop(this IApplicationBuilder app, Action config)
+ {
+ var _HadoopService = app.ApplicationServices.GetRequiredService();
+ _HadoopService.Init(config);
+ return app;
+ }
+ }
+
+ ///
+ /// 云计算服务
+ ///
+ public class HadoopService : IHadoopService
+ {
+ public HadoopService(ITableService tableService)
+ {
+ _TableService = tableService;
+
+ _Source = new HDP_Source();
+
+ _Tables = new List();
+ }
+
+ private ITableService _TableService;
+
+ private HDP_Source _Source;
+
+ private List _Tables;
+
+ ///
+ /// 初始化云计算
+ ///
+ /// 配置
+ public void Init(Action config)
+ {
+ if (config == null)
+ {
+ throw new ArgumentNullException("配置无效");
+ }
+ config(_Source);
+
+ //参数校验
+ if (string.IsNullOrEmpty(_Source.Host))
+ {
+ throw new ArgumentException("主机无效");
+ }
+ if (string.IsNullOrEmpty(_Source.Key))
+ {
+ throw new ArgumentException("源无效");
+ }
+ if (string.IsNullOrEmpty(_Source.Account))
+ {
+ throw new ArgumentException("用户名无效");
+ }
+ if (string.IsNullOrEmpty(_Source.PassWord))
+ {
+ throw new ArgumentException("密码无效");
+ }
+
+ //初始化
+ if (_Source.Port == null)
+ {
+ _Source.Port = 3306;
+ }
+ if (string.IsNullOrEmpty(_Source.Id))
+ {
+ _Source.Id = "";
+ }
+ if (string.IsNullOrEmpty(_Source.Description))
+ {
+ _Source.Description = "云计算系统";
+ }
+
+ var _source = HDP_Table.Class2Table();
+ _Tables.Add(_source);
+ if (!_TableService.InitStruct(_Source, _source))
+ {
+ throw new Exception("初始化数据源失败");
+ }
+
+ var _table = HDP_Table.Class2Table();
+ _Tables.Add(_table);
+ if (!_TableService.InitStruct(_Source, _table))
+ {
+ throw new Exception("初始化数据表失败");
+ }
+
+ var _column = HDP_Table.Class2Table();
+ _Tables.Add(_column);
+ if (!_TableService.InitStruct(_Source, _column))
+ {
+ throw new Exception("初始化数据列失败");
+ }
+ }
+
+ ///
+ /// 获取源
+ ///
+ /// 数据源编号
+ /// 结果
+ public HDP_Source? GetSource(string sourceid)
+ {
+ if (string.IsNullOrEmpty(sourceid) || _Source.Id == sourceid)
+ {
+ return _Source;
+ }
+ var _result = _TableService.QuerySingle(_Source, GetTable("HDP_Source")!, new Dictionary
+ {
+ { "Id","=" }
+ }, new Dictionary {
+ { "Id",sourceid}
+ });
+ return _result;
+ }
+
+ ///
+ /// 创建源
+ ///
+ /// 源
+ /// 是否成功
+ public bool InsertSource(HDP_Source source)
+ {
+ //校验
+ if (string.IsNullOrEmpty(source.Id))
+ {
+ throw new ArgumentNullException("编号无效");
+ }
+ if (string.IsNullOrEmpty(source.Host))
+ {
+ throw new ArgumentNullException("主机无效");
+ }
+ if (source.Port == null)
+ {
+ throw new ArgumentNullException("端口无效");
+ }
+ if (string.IsNullOrEmpty(source.Key))
+ {
+ throw new ArgumentNullException("数据源键无效");
+ }
+ if (string.IsNullOrEmpty(source.Account))
+ {
+ throw new ArgumentNullException("用户名无效");
+ }
+ if (string.IsNullOrEmpty(source.PassWord))
+ {
+ throw new ArgumentNullException("密码无效");
+ }
+ if (GetSource(source.Id) != null)
+ {
+ throw new ArgumentException("编号已存在");
+ }
+
+ return _TableService.Insert(_Source, GetTable("HDP_Source")!, HDP_Table.Class2Dictionary(source));
+ }
+
+ ///
+ /// 更新源
+ ///
+ /// 源
+ /// 是否成功
+ public bool UpdateSource(HDP_Source source)
+ {
+ //校验
+ if (string.IsNullOrEmpty(source.Id))
+ {
+ throw new ArgumentNullException("编号无效");
+ }
+ if (string.IsNullOrEmpty(source.Host))
+ {
+ throw new ArgumentNullException("主机无效");
+ }
+ if (source.Port == null)
+ {
+ throw new ArgumentNullException("端口无效");
+ }
+ if (string.IsNullOrEmpty(source.Key))
+ {
+ throw new ArgumentNullException("数据源键无效");
+ }
+ if (string.IsNullOrEmpty(source.Account))
+ {
+ throw new ArgumentNullException("用户名无效");
+ }
+ if (string.IsNullOrEmpty(source.PassWord))
+ {
+ throw new ArgumentNullException("密码无效");
+ }
+ if (GetSource(source.Id) == null)
+ {
+ throw new ArgumentException("编号不存在");
+ }
+
+ return _TableService.Update(_Source, GetTable("HDP_Source")!, new Dictionary {
+ {"Id","=" }
+ }, HDP_Table.Class2Dictionary(source));
+ }
+
+ ///
+ /// 删除源
+ ///
+ /// 源
+ /// 是否成功
+ public bool DeleteSource(string sourceid)
+ {
+ //校验
+ if (string.IsNullOrEmpty(sourceid))
+ {
+ throw new ArgumentNullException("编号无效");
+ }
+ if (GetSource(sourceid) == null)
+ {
+ throw new ArgumentException("编号不存在");
+ }
+
+ return _TableService.Delete(_Source, GetTable("HDP_Source")!, new Dictionary {
+ {"Id","=" }
+ }, new Dictionary {
+ {"Id",sourceid }
+ });
+ }
+
+ ///
+ /// 查询源
+ ///
+ /// 命令
+ /// 结果
+ public HDP_Source[] QuerySource(HDP_Command command)
+ {
+ return _TableService.Query(_Source, GetTable("HDP_Source")!, command.Where!, command.Data!, command.Order!);
+ }
+
+ ///
+ /// 获取表
+ ///
+ /// 表编号
+ /// 结果
+ public HDP_Table? GetTable(string tableid)
+ {
+ if (string.IsNullOrEmpty(tableid))
+ {
+ throw new ArgumentNullException("数据表编号无效");
+ }
+
+ if (_Tables.Any(x => x.Id == tableid))
+ {
+ return _Tables.First(x => x.Id == tableid);
+ }
+
+ var _result = _TableService.QuerySingle(_Source, GetTable("HDP_Table")!, new Dictionary
+ {
+ { "Id","=" }
+ }, new Dictionary {
+ { "Id",tableid}
+ });
+
+ if (_result != null)
+ {
+ _result.Columns = _TableService.Query(_Source, GetTable("HDP_Column")!, new Dictionary {
+ { "TableId","="}
+ }, new Dictionary {
+ {"TableId",_result.Id! }
+ });
+ }
+
+ return _result;
+ }
+
+ ///
+ /// 创建表
+ ///
+ /// 表
+ /// 是否成功
+ public bool InsertTable(HDP_Table table)
+ {
+ if (string.IsNullOrEmpty(table.Id))
+ {
+ throw new ArgumentNullException("表编号无效");
+ }
+ if (GetTable(table.Id) != null)
+ {
+ throw new ArgumentNullException("表编号已存在");
+ }
+ if (_TableService.InitStruct(_Source, table))
+ {
+ using (TransactionScope _scope = new TransactionScope())
+ {
+ if (!_TableService.Insert(_Source, GetTable("HDP_Table")!, HDP_Table.Class2Dictionary(table)))
+ {
+ return false;
+ }
+ for (var i = 0; i < table.Columns!.Length; i++)
+ {
+ var _column = table.Columns![i];
+ _column.TableId = table.Id;
+ if (!_TableService.Insert(_Source, GetTable("HDP_Column")!, HDP_Table.Class2Dictionary(_column)))
+ {
+ return false;
+ }
+ }
+ _scope.Complete();
+ return true;
+ }
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ ///
+ /// 更新表
+ ///
+ /// 表
+ /// 是否成功
+ public bool UpdateTable(HDP_Table table)
+ {
+ if (string.IsNullOrEmpty(table.Id))
+ {
+ throw new ArgumentNullException("表编号无效");
+ }
+ if (GetTable(table.Id) == null)
+ {
+ throw new ArgumentNullException("表编号不存在");
+ }
+ if (_TableService.InitStruct(_Source, table))
+ {
+ using (TransactionScope _scope = new TransactionScope())
+ {
+ if (!_TableService.Update(_Source, GetTable("HDP_Table")!, new Dictionary {
+ { "Id","="}
+ }, HDP_Table.Class2Dictionary(table)))
+ {
+ return false;
+ }
+
+ for (var i = 0; i < table.Columns!.Length; i++)
+ {
+ var _column = table.Columns![i];
+ _column.TableId = table.Id;
+ if (_TableService.QuerySingle(_Source, GetTable("HDP_Column")!, new Dictionary
+ {
+ {"Id","=" }
+ }, HDP_Table.Class2Dictionary(_column)) == null)
+ {
+ if (!_TableService.Insert(_Source, GetTable("HDP_Column")!, HDP_Table.Class2Dictionary(_column)))
+ {
+ return false;
+ }
+ }
+ else
+ {
+ if (!_TableService.Update(_Source, GetTable("HDP_Column")!, new Dictionary {
+ {"Id","=" }
+ }, HDP_Table.Class2Dictionary(_column)))
+ {
+ return false;
+ }
+ }
+ }
+
+ _scope.Complete();
+ return true;
+ }
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ ///
+ /// 删除表
+ ///
+ /// 表编号
+ /// 是否成功
+ public bool DeleteTable(string tableId)
+ {
+ //校验
+ if (string.IsNullOrEmpty(tableId))
+ {
+ throw new ArgumentNullException("编号无效");
+ }
+ if (GetTable(tableId) == null)
+ {
+ throw new ArgumentException("编号不存在");
+ }
+
+ using (TransactionScope _scope = new TransactionScope())
+ {
+ if (!_TableService.Delete(_Source, GetTable("HDP_Table")!, new Dictionary {
+ {"Id","=" }
+ }, new Dictionary {
+ {"Id",tableId }
+ }))
+ {
+ return false;
+ }
+ if (!_TableService.Delete(_Source, GetTable("HDP_Column")!, new Dictionary {
+ { "TableId","="}
+ }, new Dictionary {
+ {"TableId",tableId }
+ }))
+ {
+ return false;
+ }
+
+ _scope.Complete();
+ return true;
+ }
+ }
+
+ ///
+ /// 查询表
+ ///
+ /// 命令
+ /// 结果
+ public HDP_Table[] QueryTable(HDP_Command command)
+ {
+ return _TableService.Query(_Source, GetTable("HDP_Table")!, command.Where!, command.Data!, command.Order!);
+ }
+
+ ///
+ /// 插入数据
+ ///
+ /// 命令
+ /// 是否成功
+ public bool Insert(HDP_Command command)
+ {
+ if (string.IsNullOrEmpty(command.TableId))
+ {
+ throw new ArgumentNullException("表无效");
+ }
+ var _table = GetTable(command.TableId);
+ if (_table == null)
+ {
+ throw new ArgumentException("表不存在");
+ }
+ var _source = GetSource(_table.SourceId!);
+ return _TableService.Insert(_source!, _table, command.Data!);
+ }
+
+ ///
+ /// 更新数据
+ ///
+ ///
+ /// 是否成功
+ public bool Update(HDP_Command command)
+ {
+ if (string.IsNullOrEmpty(command.TableId))
+ {
+ throw new ArgumentNullException("表无效");
+ }
+ var _table = GetTable(command.TableId);
+ if (_table == null)
+ {
+ throw new ArgumentException("表不存在");
+ }
+ var _source = GetSource(_table.SourceId!);
+ return _TableService.Update(_source!, _table, command.Where!, command.Data!);
+ }
+
+ ///
+ /// 删除数据
+ ///
+ /// 命令
+ /// 是否成功
+ public bool Delete(HDP_Command command)
+ {
+ if (string.IsNullOrEmpty(command.TableId))
+ {
+ throw new ArgumentNullException("表无效");
+ }
+ var _table = GetTable(command.TableId);
+ if (_table == null)
+ {
+ throw new ArgumentException("表不存在");
+ }
+ var _source = GetSource(_table.SourceId!);
+ return _TableService.Delete(_source!, _table, command.Where!, command.Data!);
+ }
+
+ ///
+ /// 查询单条
+ ///
+ /// 返回类型
+ /// 命令
+ /// 结果
+ public T? QuerySingle(HDP_Command command)
+ {
+ if (string.IsNullOrEmpty(command.TableId))
+ {
+ throw new ArgumentNullException("表无效");
+ }
+ var _table = GetTable(command.TableId);
+ if (_table == null)
+ {
+ throw new ArgumentException("表不存在");
+ }
+ var _source = GetSource(_table.SourceId!);
+ return _TableService.QuerySingle(_source!, _table, command.Where!, command.Data!);
+ }
+
+ ///
+ /// 查询列表
+ ///
+ /// 返回类型
+ /// 命令
+ /// 结果
+ public T[] Query(HDP_Command command)
+ {
+ if (string.IsNullOrEmpty(command.TableId))
+ {
+ throw new ArgumentNullException("表无效");
+ }
+ var _table = GetTable(command.TableId);
+ if (_table == null)
+ {
+ throw new ArgumentException("表不存在");
+ }
+ var _source = GetSource(_table.SourceId!);
+ return _TableService.Query(_source!, _table, command.Where!, command.Data!, command.Order!);
+ }
+
+ ///
+ /// 分页查询
+ ///
+ /// 返回类型
+ /// 命令
+ /// 结果
+ public HDP_Page Page(HDP_Command command)
+ {
+ if (string.IsNullOrEmpty(command.TableId))
+ {
+ throw new ArgumentNullException("表无效");
+ }
+ if (command.PageIndex == null || command.PageIndex <= 0)
+ {
+ throw new ArgumentNullException("分页下标无效");
+ }
+ if (command.PageSize == null || command.PageSize <= 0)
+ {
+ throw new ArgumentNullException("分页大小无效");
+ }
+ var _table = GetTable(command.TableId);
+ if (_table == null)
+ {
+ throw new ArgumentException("表不存在");
+ }
+ var _source = GetSource(_table.SourceId!);
+ return _TableService.QueryPage(_source!, _table, (int)command.PageIndex, (int)command.PageSize, command.Where!, command.Data!, command.Order!);
+ }
+ }
+}
diff --git a/Hadoop/ZKLT.Hadoop/TableService.cs b/Hadoop/ZKLT.Hadoop/TableService.cs
new file mode 100644
index 0000000..26c4dcd
--- /dev/null
+++ b/Hadoop/ZKLT.Hadoop/TableService.cs
@@ -0,0 +1,828 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Security.Policy;
+using System.Text;
+using System.Threading.Tasks;
+using MySql.Data.MySqlClient;
+using Dapper;
+using ZKLT.Hadoop.Interface;
+using ZKLT.Hadoop.Model;
+using MySqlX.XDevAPI.Relational;
+using Mysqlx.Crud;
+
+namespace ZKLT.Hadoop
+{
+ public class TableService : ITableService
+ {
+ ///
+ /// 同步结构
+ ///
+ /// 数据源
+ /// 数据表
+ /// 是否成功
+ public bool InitStruct(HDP_Source source, HDP_Table table)
+ {
+ //数据校验
+ if (string.IsNullOrEmpty(table.Key))
+ {
+ throw new ArgumentNullException("表键无效");
+ }
+ if (table.Columns == null || table.Columns.Length == 0)
+ {
+ throw new ArgumentNullException("列无效");
+ }
+ using (MySqlConnection _connection = new MySqlConnection(source.GetConnectString()))
+ {
+ try
+ {
+ _connection.Open();
+ }
+ catch
+ {
+ throw new ArgumentException("数据源连接失败");
+ }
+
+ StringBuilder _command = new StringBuilder();
+ if (DbExistTable(source, table.Key))
+ {
+ var _dbColumns = DbGetColumns(source, table.Key);
+ _command.AppendLine($@"ALTER TABLE `{table.Key}`");
+ _command.AppendLine("DROP PRIMARY KEY,");
+
+ //加载列
+ for (var i = 0; i < table.Columns.Length; i++)
+ {
+ StringBuilder _colstr = new StringBuilder();
+ var _column = table.Columns[i];
+ if (_dbColumns.Any(x => x.Key == _column.Key))
+ {
+ _colstr.Append($@"MODIFY `{_column.Key}`");
+ }
+ else
+ {
+ _colstr.Append($@"ADD `{_column.Key}`");
+ }
+ switch (_column.DataType)
+ {
+ case HDP_ColumnDataType.VARCHAR:
+ if (_column.Length == 0)
+ {
+ throw new ArgumentNullException(@$"列{_column.Key}长度无效");
+ }
+ _colstr.Append($@" {_column.DataType}({_column.Length})");
+ break;
+ case HDP_ColumnDataType.DECIMAL:
+ if (_column.Length == 0 || _column.DecimalLength == 0)
+ {
+ throw new ArgumentNullException(@$"列{_column.Key}长度无效");
+ }
+ _colstr.Append($@" {_column.DataType}({_column.Length},{_column.DecimalLength})");
+ break;
+ default:
+ _colstr.Append(@$" {_column.DataType}");
+ break;
+ }
+ if (!string.IsNullOrEmpty(_column.Description))
+ {
+ _colstr.Append($@" COMMENT '{_column.Description}'");
+ }
+ _colstr.Append(",");
+ _command.AppendLine(_colstr.ToString());
+ }
+
+ //加载主键
+ var _primarys = table.Columns.Where(x => x.IsPrimary == true).ToArray();
+ if (_primarys.Length > 0)
+ {
+ StringBuilder _primaryStr = new StringBuilder();
+ _primaryStr.Append("ADD PRIMARY KEY (");
+ for (var i = 0; i < _primarys.Length; i++)
+ {
+ var _primary = _primarys[i];
+ _primaryStr.Append($@"`{_primary.Key}`");
+ if (i < _primarys.Length - 1)
+ {
+ _primaryStr.Append(",");
+ }
+ }
+ _primaryStr.Append(")");
+ _command.AppendLine(_primaryStr.ToString());
+ }
+ if (!string.IsNullOrEmpty(table.Description))
+ {
+ _command.AppendLine(@$"COMMENT '{table.Description}'");
+ }
+ _connection.Execute(_command.ToString());
+ return true;
+ }
+ else
+ {
+ _command.AppendLine($@"CREATE TABLE `{table.Key}` (");
+
+ //加载列
+ for (int i = 0; i < table.Columns.Length; i++)
+ {
+ StringBuilder _colstr = new StringBuilder();
+ var _column = table.Columns[i];
+ _colstr.Append($@"`{_column.Key}`");
+ switch (_column.DataType)
+ {
+ case HDP_ColumnDataType.VARCHAR:
+ if (_column.Length == 0)
+ {
+ throw new ArgumentNullException(@$"列{_column.Key}长度无效");
+ }
+ _colstr.Append($@" {_column.DataType}({_column.Length})");
+ break;
+ case HDP_ColumnDataType.DECIMAL:
+ if (_column.Length == 0 || _column.DecimalLength == 0)
+ {
+ throw new ArgumentNullException(@$"列{_column.Key}长度无效");
+ }
+ _colstr.Append($@" {_column.DataType}({_column.Length},{_column.DecimalLength})");
+ break;
+ default:
+ _colstr.Append(@$" {_column.DataType}");
+ break;
+ }
+ if (!string.IsNullOrEmpty(_column.Description))
+ {
+ _colstr.Append($@" COMMENT '{_column.Description}'");
+ }
+ if (i < table.Columns.Length - 1)
+ {
+ _colstr.Append(",");
+ }
+ _command.AppendLine(_colstr.ToString());
+ }
+
+ //加载主键
+ var _primarys = table.Columns.Where(x => x.IsPrimary == true).ToArray();
+ if (_primarys.Length > 0)
+ {
+ _command.Append(",");
+ StringBuilder _primaryStr = new StringBuilder();
+ _primaryStr.Append("PRIMARY KEY (");
+ for (var i = 0; i < _primarys.Length; i++)
+ {
+ var _primary = _primarys[i];
+ _primaryStr.Append($@"`{_primary.Key}`");
+ if (i < _primarys.Length - 1)
+ {
+ _primaryStr.Append(",");
+ }
+ }
+ _primaryStr.Append(")");
+ _command.AppendLine(_primaryStr.ToString());
+ }
+
+ _command.AppendLine(")");
+ if (!string.IsNullOrEmpty(table.Description))
+ {
+ _command.AppendLine(@$"COMMENT '{table.Description}'");
+ }
+ _connection.Execute(_command.ToString());
+ }
+ _connection.Close();
+ return true;
+ }
+ }
+
+ ///
+ /// 删除结构
+ ///
+ /// 源
+ /// 表
+ /// 是否成功
+ public bool RemoveStruct(HDP_Source source, string tableKey)
+ {
+ //数据校验
+ if (string.IsNullOrEmpty(tableKey))
+ {
+ throw new ArgumentNullException("表键无效");
+ }
+ if (!DbExistTable(source, tableKey))
+ {
+ throw new ArgumentNullException("表不存在");
+ }
+
+ using (MySqlConnection _connection = new MySqlConnection(source.GetConnectString()))
+ {
+ try
+ {
+ _connection.Open();
+ }
+ catch
+ {
+ throw new ArgumentException("数据源连接失败");
+ }
+
+ StringBuilder _command = new StringBuilder();
+ _command.AppendLine(@$"DROP TABLE {tableKey}");
+ _connection.Execute(_command.ToString());
+ _connection.Close();
+ return !DbExistTable(source, tableKey);
+ }
+ }
+
+ ///
+ /// 插入数据
+ ///
+ /// 数据源
+ /// 数据表
+ /// 数据
+ /// 是否成功
+ public bool Insert(HDP_Source source, HDP_Table table, Dictionary row)
+ {
+ //数据校验
+ if (string.IsNullOrEmpty(table.Key))
+ {
+ throw new ArgumentNullException("表键无效");
+ }
+ if (table.Columns == null || table.Columns.Length == 0)
+ {
+ throw new ArgumentNullException("列无效");
+ }
+ if (row == null || row.Count == 0)
+ {
+ throw new ArgumentNullException("数据无效");
+ }
+ using (MySqlConnection _connection = new MySqlConnection(source.GetConnectString()))
+ {
+ try
+ {
+ _connection.Open();
+ }
+ catch
+ {
+ throw new ArgumentException("数据源连接失败");
+ }
+ StringBuilder _command = new StringBuilder();
+
+ //主键检查
+ var _primarys = table.Columns.Where(x => x.IsPrimary == true).ToArray();
+ for (var i = 0; i < _primarys.Length; i++)
+ {
+ var _primary = _primarys[i];
+ if (row[_primary.Key!] == null || string.IsNullOrEmpty(row[_primary.Key!].ToString()))
+ {
+ throw new ArgumentException($@"主键{_primary.Key}值无效");
+ }
+ }
+
+ //插入命令
+ _command.AppendLine($@"INSERT INTO `{table.Key}` (");
+ StringBuilder _colstr = new StringBuilder();
+ StringBuilder _parmstr = new StringBuilder();
+ Dictionary _params = new Dictionary();
+ for (var i = 0; i < table.Columns.Length; i++)
+ {
+ var _column = table.Columns[i];
+ if (row.ContainsKey(_column.Key!))
+ {
+ _colstr.Append($@"`{_column.Key!}`,");
+ _parmstr.Append($@"@{_column.Key},");
+ _params.Add(_column.Key!, row[_column.Key!]);
+ }
+ }
+ if (_colstr[_colstr.Length - 1] == ',')
+ {
+ _colstr.Remove(_colstr.Length - 1, 1);
+ }
+ if (_parmstr[_parmstr.Length - 1] == ',')
+ {
+ _parmstr.Remove(_parmstr.Length - 1, 1);
+ }
+ _command.AppendLine(_colstr.ToString());
+ _command.AppendLine(") VALUES (");
+ _command.AppendLine(_parmstr.ToString());
+ _command.AppendLine(")");
+ var _result = _connection.Execute(_command.ToString(), _params);
+ _connection.Close();
+ if (_result > 0)
+ {
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+ }
+
+ ///
+ /// 更新
+ ///
+ /// 数据源
+ /// 数据表
+ /// 条件
+ /// 数据
+ /// 是否成功
+ public bool Update(HDP_Source source, HDP_Table table, Dictionary where, Dictionary row)
+ {
+ //数据校验
+ if (string.IsNullOrEmpty(table.Key))
+ {
+ throw new ArgumentNullException("表键无效");
+ }
+ if (table.Columns == null || table.Columns.Length == 0)
+ {
+ throw new ArgumentNullException("列无效");
+ }
+ if (where == null || where.Count == 0)
+ {
+ throw new ArgumentNullException("条件无效");
+ }
+ if (row == null || row.Count == 0)
+ {
+ throw new ArgumentNullException("数据无效");
+ }
+ using (MySqlConnection _connection = new MySqlConnection(source.GetConnectString()))
+ {
+ try
+ {
+ _connection.Open();
+ }
+ catch
+ {
+ throw new ArgumentException("数据源连接失败");
+ }
+
+ //更新命令
+ StringBuilder _command = new StringBuilder();
+ Dictionary _params = new Dictionary();
+ _command.AppendLine(@$"UPDATE `{table.Key}` SET ");
+
+ //更新列
+ StringBuilder _colstr = new StringBuilder();
+ for (var i = 0; i < table.Columns.Length; i++)
+ {
+ var _column = table.Columns[i];
+ if (row.ContainsKey(_column.Key!) && !where.ContainsKey(_column.Key!))
+ {
+ _colstr.Append($@"`{_column.Key!}`=@{_column.Key!},");
+ _params.Add(_column.Key!, row[_column.Key!]);
+ }
+ }
+ if (_colstr[_colstr.Length - 1] == ',')
+ {
+ _colstr.Remove(_colstr.Length - 1, 1);
+ }
+ _command.AppendLine(_colstr.ToString());
+
+ //执行条件
+ StringBuilder _wherestr = new StringBuilder();
+ _wherestr.Append("WHERE 1 = 1");
+ for (var i = 0; i < table.Columns.Length; i++)
+ {
+ var _column = table.Columns[i];
+ if (where.ContainsKey(_column.Key!))
+ {
+ switch (where[_column.Key!])
+ {
+ case HDP_WhereType.LIKE:
+ _wherestr.Append($@" AND `{_column.Key!}` {where[_column.Key!]} '%' + @{_column.Key!} + '%'");
+ break;
+ default:
+ _wherestr.Append($@" AND `{_column.Key!}` {where[_column.Key!]} @{_column.Key!}");
+ break;
+ }
+ _params.Add(_column.Key!, row[_column.Key!]);
+ }
+ }
+ _command.AppendLine(_wherestr.ToString());
+
+ var _result = _connection.Execute(_command.ToString(), _params);
+ _connection.Close();
+ if (_result > 0)
+ {
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+ }
+
+ ///
+ /// 删除
+ ///
+ /// 数据源
+ /// 数据表
+ /// 条件
+ /// 数据
+ /// 是否成功
+ public bool Delete(HDP_Source source, HDP_Table table, Dictionary where, Dictionary row)
+ {
+ //数据校验
+ if (string.IsNullOrEmpty(table.Key))
+ {
+ throw new ArgumentNullException("表键无效");
+ }
+ if (table.Columns == null || table.Columns.Length == 0)
+ {
+ throw new ArgumentNullException("列无效");
+ }
+ if (where == null || where.Count == 0)
+ {
+ throw new ArgumentNullException("条件无效");
+ }
+ if (row == null || row.Count == 0)
+ {
+ throw new ArgumentNullException("数据无效");
+ }
+ using (MySqlConnection _connection = new MySqlConnection(source.GetConnectString()))
+ {
+ try
+ {
+ _connection.Open();
+ }
+ catch
+ {
+ throw new ArgumentException("数据源连接失败");
+ }
+
+ //更新命令
+ StringBuilder _command = new StringBuilder();
+ Dictionary _params = new Dictionary();
+ _command.AppendLine(@$"DELETE FROM `{table.Key}`");
+
+ //执行条件
+ StringBuilder _wherestr = new StringBuilder();
+ _wherestr.Append("WHERE 1 = 1");
+ for (var i = 0; i < table.Columns.Length; i++)
+ {
+ var _column = table.Columns[i];
+ if (where.ContainsKey(_column.Key!))
+ {
+ switch (where[_column.Key!])
+ {
+ case HDP_WhereType.LIKE:
+ _wherestr.Append($@" AND `{_column.Key!}` {where[_column.Key!]} '%' + @{_column.Key!} + '%'");
+ break;
+ default:
+ _wherestr.Append($@" AND `{_column.Key!}` {where[_column.Key!]} @{_column.Key!}");
+ break;
+ }
+ _params.Add(_column.Key!, row[_column.Key!]);
+ }
+ }
+ _command.AppendLine(_wherestr.ToString());
+
+ var _result = _connection.Execute(_command.ToString(), _params);
+ _connection.Close();
+ if (_result > 0)
+ {
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+ }
+
+ ///
+ /// 查询单个
+ ///
+ /// 数据源
+ /// 数据表
+ /// 条件
+ /// 数据
+ /// 结果
+ public T? QuerySingle(HDP_Source source, HDP_Table table, Dictionary where, Dictionary row)
+ {
+ //数据校验
+ if (string.IsNullOrEmpty(table.Key))
+ {
+ throw new ArgumentNullException("表键无效");
+ }
+ if (table.Columns == null || table.Columns.Length == 0)
+ {
+ throw new ArgumentNullException("列无效");
+ }
+ if (where == null || where.Count == 0)
+ {
+ throw new ArgumentNullException("条件无效");
+ }
+ if (row == null || row.Count == 0)
+ {
+ throw new ArgumentNullException("数据无效");
+ }
+ using (MySqlConnection _connection = new MySqlConnection(source.GetConnectString()))
+ {
+ try
+ {
+ _connection.Open();
+ }
+ catch
+ {
+ throw new ArgumentException("数据源连接失败");
+ }
+
+ //查询命令
+ StringBuilder _command = new StringBuilder();
+ Dictionary _params = new Dictionary();
+ _command.AppendLine(@$"SELECT * FROM `{table.Key}`");
+
+ //执行条件
+ StringBuilder _wherestr = new StringBuilder();
+ _wherestr.Append("WHERE 1 = 1");
+ for (var i = 0; i < table.Columns.Length; i++)
+ {
+ var _column = table.Columns[i];
+ if (where.ContainsKey(_column.Key!))
+ {
+ switch (where[_column.Key!])
+ {
+ case HDP_WhereType.LIKE:
+ _wherestr.Append($@" AND `{_column.Key!}` {where[_column.Key!]} '%' + @{_column.Key!} + '%'");
+ break;
+ default:
+ _wherestr.Append($@" AND `{_column.Key!}` {where[_column.Key!]} @{_column.Key!}");
+ break;
+ }
+ _params.Add(_column.Key!, row[_column.Key!]);
+ }
+ }
+ _command.AppendLine(_wherestr.ToString());
+
+ var _result = _connection.Query(_command.ToString(), _params).ToArray();
+ _connection.Close();
+ if (_result.Length > 0)
+ {
+ return _result[0];
+ }
+ else
+ {
+ return default(T);
+ }
+ }
+ }
+
+ ///
+ /// 查询列表
+ ///
+ /// 返回类型
+ /// 数据源
+ /// 数据表
+ /// 条件
+ /// 数据
+ /// 结果集
+ public T[] Query(HDP_Source source, HDP_Table table, Dictionary? where = null, Dictionary? row = null, Dictionary? order = null)
+ {
+ //数据校验
+ if (string.IsNullOrEmpty(table.Key))
+ {
+ throw new ArgumentNullException("表键无效");
+ }
+ if (table.Columns == null || table.Columns.Length == 0)
+ {
+ throw new ArgumentNullException("列无效");
+ }
+ using (MySqlConnection _connection = new MySqlConnection(source.GetConnectString()))
+ {
+ try
+ {
+ _connection.Open();
+ }
+ catch
+ {
+ throw new ArgumentException("数据源连接失败");
+ }
+
+ //查询命令
+ StringBuilder _command = new StringBuilder();
+ Dictionary _params = new Dictionary();
+ _command.AppendLine(@$"SELECT * FROM `{table.Key}`");
+
+ //执行条件
+ StringBuilder _wherestr = new StringBuilder();
+ _wherestr.Append("WHERE 1 = 1");
+ if (where != null && where.Count > 0)
+ {
+ for (var i = 0; i < table.Columns.Length; i++)
+ {
+ var _column = table.Columns[i];
+ if (where.ContainsKey(_column.Key!))
+ {
+ switch (where[_column.Key!])
+ {
+ case HDP_WhereType.LIKE:
+ _wherestr.Append($@" AND `{_column.Key!}` {where[_column.Key!]} '%' + @{_column.Key!} + '%'");
+ break;
+ default:
+ _wherestr.Append($@" AND `{_column.Key!}` {where[_column.Key!]} @{_column.Key!}");
+ break;
+ }
+ _params.Add(_column.Key!, row[_column.Key!]);
+ }
+ }
+ _command.AppendLine(_wherestr.ToString());
+ }
+
+ //执行排序
+ StringBuilder _orderstr = new StringBuilder();
+ _orderstr.Append("ORDER BY ");
+ if (order != null && order.Count > 0)
+ {
+ for (var i = 0; i < table.Columns.Length; i++)
+ {
+ var _column = table.Columns[i];
+ if (order.ContainsKey(_column.Key!))
+ {
+ switch (order[_column.Key!])
+ {
+ case "DESC":
+ _orderstr.Append($@"`{_column.Key!}` DESC,");
+ break;
+ default:
+ _orderstr.Append($@"`{_column.Key!}` ASC,");
+ break;
+ }
+ }
+ }
+ if (_orderstr[_orderstr.Length - 1] == ',')
+ {
+ _orderstr.Remove(_orderstr.Length - 1, 1);
+ }
+ _command.AppendLine(_orderstr.ToString());
+ }
+ var _result = _connection.Query(_command.ToString(), _params);
+ _connection.Close();
+ return _result.ToArray();
+ }
+ }
+
+ ///
+ /// 查询列表
+ ///
+ /// 返回类型
+ /// 数据源
+ /// 数据表
+ /// 条件
+ /// 数据
+ /// 结果集
+ public HDP_Page QueryPage(HDP_Source source, HDP_Table table, int pageIndex, int pageSize, Dictionary? where = null, Dictionary? row = null, Dictionary? order = null)
+ {
+ //数据校验
+ if (string.IsNullOrEmpty(table.Key))
+ {
+ throw new ArgumentNullException("表键无效");
+ }
+ if (table.Columns == null || table.Columns.Length == 0)
+ {
+ throw new ArgumentNullException("列无效");
+ }
+ using (MySqlConnection _connection = new MySqlConnection(source.GetConnectString()))
+ {
+ try
+ {
+ _connection.Open();
+ }
+ catch
+ {
+ throw new ArgumentException("数据源连接失败");
+ }
+
+ //查询命令
+ StringBuilder _command = new StringBuilder();
+ Dictionary _params = new Dictionary();
+ _command.AppendLine(@$"SELECT * FROM `{table.Key}`");
+
+ //执行条件
+ StringBuilder _wherestr = new StringBuilder();
+ _wherestr.Append("WHERE 1 = 1");
+ if (where != null && where.Count > 0)
+ {
+ for (var i = 0; i < table.Columns.Length; i++)
+ {
+ var _column = table.Columns[i];
+ if (where.ContainsKey(_column.Key!))
+ {
+ switch (where[_column.Key!])
+ {
+ case HDP_WhereType.LIKE:
+ _wherestr.Append($@" AND `{_column.Key!}` {where[_column.Key!]} '%' + @{_column.Key!} + '%'");
+ break;
+ default:
+ _wherestr.Append($@" AND `{_column.Key!}` {where[_column.Key!]} @{_column.Key!}");
+ break;
+ }
+ _params.Add(_column.Key!, row[_column.Key!]);
+ }
+ }
+ _command.AppendLine(_wherestr.ToString());
+ }
+ //执行排序
+ StringBuilder _orderstr = new StringBuilder();
+ _orderstr.Append("ORDER BY ");
+ if (order != null && order.Count > 0)
+ {
+ for (var i = 0; i < table.Columns.Length; i++)
+ {
+ var _column = table.Columns[i];
+ if (order.ContainsKey(_column.Key!))
+ {
+ switch (order[_column.Key!])
+ {
+ case "DESC":
+ _orderstr.Append($@"`{_column.Key!}` DESC,");
+ break;
+ default:
+ _orderstr.Append($@"`{_column.Key!}` ASC,");
+ break;
+ }
+ }
+ }
+ if (_orderstr[_orderstr.Length - 1] == ',')
+ {
+ _orderstr.Remove(_orderstr.Length - 1, 1);
+ }
+ _command.AppendLine(_orderstr.ToString());
+ }
+ var _result = new HDP_Page();
+ _result.PageIndex = pageIndex;
+ _result.PageSize = pageSize;
+ StringBuilder _totalstr = new StringBuilder();
+ _totalstr.AppendLine($@"SELECT COUNT(0) FROM (");
+ _totalstr.AppendLine(_command.ToString());
+ _totalstr.AppendLine(") AS Temp");
+ _result.Total = _connection.QuerySingle(_totalstr.ToString(), _params);
+ StringBuilder _pagestr = new StringBuilder();
+ _pagestr.AppendLine($@"SELECT * FROM (");
+ _pagestr.AppendLine(_command.ToString());
+ _pagestr.AppendLine(") AS Temp");
+ _pagestr.AppendLine(@$"LIMIT {(_result.PageIndex - 1) * _result.PageSize},{_result.PageSize}");
+ _result.Data = _connection.Query(_pagestr.ToString(), _params).ToArray();
+ _connection.Close();
+ return _result;
+ }
+ }
+
+ ///
+ /// 判断数据源是否存在表
+ ///
+ /// 数据源
+ /// 表名
+ /// 是否存在
+ public bool DbExistTable(HDP_Source source, string tableName)
+ {
+ using (MySqlConnection _connection = new MySqlConnection(source.GetConnectString()))
+ {
+ try
+ {
+ _connection.Open();
+ }
+ catch
+ {
+ throw new ArgumentException("数据源连接失败");
+ }
+
+ StringBuilder _command = new StringBuilder();
+ _command.AppendLine($@"SELECT COUNT(0) FROM INFORMATION_SCHEMA.TABLES WHERE `TABLE_TYPE`='BASE TABLE' AND `TABLE_SCHEMA`=@SourceKey AND `TABLE_NAME` =@TableKey");
+ int _result = _connection.QuerySingle(_command.ToString(), new { SourceKey = source.Key, TableKey = tableName });
+ _connection.Close();
+ if (_result > 0)
+ {
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+ }
+
+ ///
+ /// 查询数据列
+ ///
+ /// 数据源
+ /// 表名
+ /// 列
+ public HDP_Column[] DbGetColumns(HDP_Source source, string tableName)
+ {
+ using (MySqlConnection _connection = new MySqlConnection(source.GetConnectString()))
+ {
+ var _result = new List();
+ try
+ {
+ _connection.Open();
+ }
+ catch
+ {
+ throw new ArgumentException("数据源连接失败");
+ }
+
+ StringBuilder _command = new StringBuilder();
+ _command.AppendLine($@"SELECT `COLUMN_NAME` AS `Key`,`DATA_TYPE` AS `DataType`,`COLUMN_COMMENT` AS `Description` FROM INFORMATION_SCHEMA.COLUMNS
+ WHERE `TABLE_SCHEMA`=@SourceKey AND `TABLE_NAME`=@TableKey");
+ _result.AddRange(_connection.Query(_command.ToString(), new { SourceKey = source.Key, TableKey = tableName }));
+ _connection.Close();
+ return _result.ToArray();
+ }
+ }
+ }
+}
diff --git a/Hadoop/ZKLT.Hadoop/ZKLT.Hadoop.csproj b/Hadoop/ZKLT.Hadoop/ZKLT.Hadoop.csproj
new file mode 100644
index 0000000..231ebe7
--- /dev/null
+++ b/Hadoop/ZKLT.Hadoop/ZKLT.Hadoop.csproj
@@ -0,0 +1,23 @@
+
+
+ net8.0
+ enable
+ enable
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/ZKLT.sln b/ZKLT.sln
new file mode 100644
index 0000000..ce20877
--- /dev/null
+++ b/ZKLT.sln
@@ -0,0 +1,51 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.8.34408.163
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ZKLT.Hadoop", "Hadoop\ZKLT.Hadoop\ZKLT.Hadoop.csproj", "{CD7387DB-B80A-412E-89B9-830EFD28C0F4}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Hadoop", "Hadoop", "{14EA48C3-3F3A-4789-BB0B-5485771D3840}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ZKLT.Hadoop.Model", "Hadoop\ZKLT.Hadoop.Model\ZKLT.Hadoop.Model.csproj", "{070B12FF-0B5A-4D0B-B444-70D6F91FB338}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ZKLT.Hadoop.Interface", "Hadoop\ZKLT.Hadoop.Interface\ZKLT.Hadoop.Interface.csproj", "{893FE0B2-8D14-42BB-B19E-0FD09EEA2433}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ZKLT.Hadoop.API", "Hadoop\ZKLT.Hadoop.API\ZKLT.Hadoop.API.csproj", "{398DF3E5-B94B-4B2E-9DC6-B6741D7CF4DB}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {CD7387DB-B80A-412E-89B9-830EFD28C0F4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {CD7387DB-B80A-412E-89B9-830EFD28C0F4}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {CD7387DB-B80A-412E-89B9-830EFD28C0F4}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {CD7387DB-B80A-412E-89B9-830EFD28C0F4}.Release|Any CPU.Build.0 = Release|Any CPU
+ {070B12FF-0B5A-4D0B-B444-70D6F91FB338}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {070B12FF-0B5A-4D0B-B444-70D6F91FB338}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {070B12FF-0B5A-4D0B-B444-70D6F91FB338}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {070B12FF-0B5A-4D0B-B444-70D6F91FB338}.Release|Any CPU.Build.0 = Release|Any CPU
+ {893FE0B2-8D14-42BB-B19E-0FD09EEA2433}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {893FE0B2-8D14-42BB-B19E-0FD09EEA2433}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {893FE0B2-8D14-42BB-B19E-0FD09EEA2433}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {893FE0B2-8D14-42BB-B19E-0FD09EEA2433}.Release|Any CPU.Build.0 = Release|Any CPU
+ {398DF3E5-B94B-4B2E-9DC6-B6741D7CF4DB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {398DF3E5-B94B-4B2E-9DC6-B6741D7CF4DB}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {398DF3E5-B94B-4B2E-9DC6-B6741D7CF4DB}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {398DF3E5-B94B-4B2E-9DC6-B6741D7CF4DB}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(NestedProjects) = preSolution
+ {CD7387DB-B80A-412E-89B9-830EFD28C0F4} = {14EA48C3-3F3A-4789-BB0B-5485771D3840}
+ {070B12FF-0B5A-4D0B-B444-70D6F91FB338} = {14EA48C3-3F3A-4789-BB0B-5485771D3840}
+ {893FE0B2-8D14-42BB-B19E-0FD09EEA2433} = {14EA48C3-3F3A-4789-BB0B-5485771D3840}
+ {398DF3E5-B94B-4B2E-9DC6-B6741D7CF4DB} = {14EA48C3-3F3A-4789-BB0B-5485771D3840}
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {87BED7C0-F181-4EA3-85CD-6D146DA33FF3}
+ EndGlobalSection
+EndGlobal