commit
6db74a39ff
63 changed files with 6365 additions and 0 deletions
@ -0,0 +1,2 @@ |
|||
/mvnw text eol=lf |
|||
*.cmd text eol=crlf |
|||
@ -0,0 +1,33 @@ |
|||
HELP.md |
|||
target/ |
|||
!.mvn/wrapper/maven-wrapper.jar |
|||
!**/src/main/**/target/ |
|||
!**/src/test/**/target/ |
|||
|
|||
### STS ### |
|||
.apt_generated |
|||
.classpath |
|||
.factorypath |
|||
.project |
|||
.settings |
|||
.springBeans |
|||
.sts4-cache |
|||
|
|||
### IntelliJ IDEA ### |
|||
.idea |
|||
*.iws |
|||
*.iml |
|||
*.ipr |
|||
|
|||
### NetBeans ### |
|||
/nbproject/private/ |
|||
/nbbuild/ |
|||
/dist/ |
|||
/nbdist/ |
|||
/.nb-gradle/ |
|||
build/ |
|||
!**/src/main/**/build/ |
|||
!**/src/test/**/build/ |
|||
|
|||
### VS Code ### |
|||
.vscode/ |
|||
@ -0,0 +1,19 @@ |
|||
# Licensed to the Apache Software Foundation (ASF) under one |
|||
# or more contributor license agreements. See the NOTICE file |
|||
# distributed with this work for additional information |
|||
# regarding copyright ownership. The ASF licenses this file |
|||
# to you under the Apache License, Version 2.0 (the |
|||
# "License"); you may not use this file except in compliance |
|||
# with the License. You may obtain a copy of the License at |
|||
# |
|||
# http://www.apache.org/licenses/LICENSE-2.0 |
|||
# |
|||
# Unless required by applicable law or agreed to in writing, |
|||
# software distributed under the License is distributed on an |
|||
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
|||
# KIND, either express or implied. See the License for the |
|||
# specific language governing permissions and limitations |
|||
# under the License. |
|||
wrapperVersion=3.3.2 |
|||
distributionType=only-script |
|||
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.9/apache-maven-3.9.9-bin.zip |
|||
@ -0,0 +1,259 @@ |
|||
#!/bin/sh |
|||
# ---------------------------------------------------------------------------- |
|||
# Licensed to the Apache Software Foundation (ASF) under one |
|||
# or more contributor license agreements. See the NOTICE file |
|||
# distributed with this work for additional information |
|||
# regarding copyright ownership. The ASF licenses this file |
|||
# to you under the Apache License, Version 2.0 (the |
|||
# "License"); you may not use this file except in compliance |
|||
# with the License. You may obtain a copy of the License at |
|||
# |
|||
# http://www.apache.org/licenses/LICENSE-2.0 |
|||
# |
|||
# Unless required by applicable law or agreed to in writing, |
|||
# software distributed under the License is distributed on an |
|||
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
|||
# KIND, either express or implied. See the License for the |
|||
# specific language governing permissions and limitations |
|||
# under the License. |
|||
# ---------------------------------------------------------------------------- |
|||
|
|||
# ---------------------------------------------------------------------------- |
|||
# Apache Maven Wrapper startup batch script, version 3.3.2 |
|||
# |
|||
# Optional ENV vars |
|||
# ----------------- |
|||
# JAVA_HOME - location of a JDK home dir, required when download maven via java source |
|||
# MVNW_REPOURL - repo url base for downloading maven distribution |
|||
# MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven |
|||
# MVNW_VERBOSE - true: enable verbose log; debug: trace the mvnw script; others: silence the output |
|||
# ---------------------------------------------------------------------------- |
|||
|
|||
set -euf |
|||
[ "${MVNW_VERBOSE-}" != debug ] || set -x |
|||
|
|||
# OS specific support. |
|||
native_path() { printf %s\\n "$1"; } |
|||
case "$(uname)" in |
|||
CYGWIN* | MINGW*) |
|||
[ -z "${JAVA_HOME-}" ] || JAVA_HOME="$(cygpath --unix "$JAVA_HOME")" |
|||
native_path() { cygpath --path --windows "$1"; } |
|||
;; |
|||
esac |
|||
|
|||
# set JAVACMD and JAVACCMD |
|||
set_java_home() { |
|||
# For Cygwin and MinGW, ensure paths are in Unix format before anything is touched |
|||
if [ -n "${JAVA_HOME-}" ]; then |
|||
if [ -x "$JAVA_HOME/jre/sh/java" ]; then |
|||
# IBM's JDK on AIX uses strange locations for the executables |
|||
JAVACMD="$JAVA_HOME/jre/sh/java" |
|||
JAVACCMD="$JAVA_HOME/jre/sh/javac" |
|||
else |
|||
JAVACMD="$JAVA_HOME/bin/java" |
|||
JAVACCMD="$JAVA_HOME/bin/javac" |
|||
|
|||
if [ ! -x "$JAVACMD" ] || [ ! -x "$JAVACCMD" ]; then |
|||
echo "The JAVA_HOME environment variable is not defined correctly, so mvnw cannot run." >&2 |
|||
echo "JAVA_HOME is set to \"$JAVA_HOME\", but \"\$JAVA_HOME/bin/java\" or \"\$JAVA_HOME/bin/javac\" does not exist." >&2 |
|||
return 1 |
|||
fi |
|||
fi |
|||
else |
|||
JAVACMD="$( |
|||
'set' +e |
|||
'unset' -f command 2>/dev/null |
|||
'command' -v java |
|||
)" || : |
|||
JAVACCMD="$( |
|||
'set' +e |
|||
'unset' -f command 2>/dev/null |
|||
'command' -v javac |
|||
)" || : |
|||
|
|||
if [ ! -x "${JAVACMD-}" ] || [ ! -x "${JAVACCMD-}" ]; then |
|||
echo "The java/javac command does not exist in PATH nor is JAVA_HOME set, so mvnw cannot run." >&2 |
|||
return 1 |
|||
fi |
|||
fi |
|||
} |
|||
|
|||
# hash string like Java String::hashCode |
|||
hash_string() { |
|||
str="${1:-}" h=0 |
|||
while [ -n "$str" ]; do |
|||
char="${str%"${str#?}"}" |
|||
h=$(((h * 31 + $(LC_CTYPE=C printf %d "'$char")) % 4294967296)) |
|||
str="${str#?}" |
|||
done |
|||
printf %x\\n $h |
|||
} |
|||
|
|||
verbose() { :; } |
|||
[ "${MVNW_VERBOSE-}" != true ] || verbose() { printf %s\\n "${1-}"; } |
|||
|
|||
die() { |
|||
printf %s\\n "$1" >&2 |
|||
exit 1 |
|||
} |
|||
|
|||
trim() { |
|||
# MWRAPPER-139: |
|||
# Trims trailing and leading whitespace, carriage returns, tabs, and linefeeds. |
|||
# Needed for removing poorly interpreted newline sequences when running in more |
|||
# exotic environments such as mingw bash on Windows. |
|||
printf "%s" "${1}" | tr -d '[:space:]' |
|||
} |
|||
|
|||
# parse distributionUrl and optional distributionSha256Sum, requires .mvn/wrapper/maven-wrapper.properties |
|||
while IFS="=" read -r key value; do |
|||
case "${key-}" in |
|||
distributionUrl) distributionUrl=$(trim "${value-}") ;; |
|||
distributionSha256Sum) distributionSha256Sum=$(trim "${value-}") ;; |
|||
esac |
|||
done <"${0%/*}/.mvn/wrapper/maven-wrapper.properties" |
|||
[ -n "${distributionUrl-}" ] || die "cannot read distributionUrl property in ${0%/*}/.mvn/wrapper/maven-wrapper.properties" |
|||
|
|||
case "${distributionUrl##*/}" in |
|||
maven-mvnd-*bin.*) |
|||
MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/ |
|||
case "${PROCESSOR_ARCHITECTURE-}${PROCESSOR_ARCHITEW6432-}:$(uname -a)" in |
|||
*AMD64:CYGWIN* | *AMD64:MINGW*) distributionPlatform=windows-amd64 ;; |
|||
:Darwin*x86_64) distributionPlatform=darwin-amd64 ;; |
|||
:Darwin*arm64) distributionPlatform=darwin-aarch64 ;; |
|||
:Linux*x86_64*) distributionPlatform=linux-amd64 ;; |
|||
*) |
|||
echo "Cannot detect native platform for mvnd on $(uname)-$(uname -m), use pure java version" >&2 |
|||
distributionPlatform=linux-amd64 |
|||
;; |
|||
esac |
|||
distributionUrl="${distributionUrl%-bin.*}-$distributionPlatform.zip" |
|||
;; |
|||
maven-mvnd-*) MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/ ;; |
|||
*) MVN_CMD="mvn${0##*/mvnw}" _MVNW_REPO_PATTERN=/org/apache/maven/ ;; |
|||
esac |
|||
|
|||
# apply MVNW_REPOURL and calculate MAVEN_HOME |
|||
# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-<version>,maven-mvnd-<version>-<platform>}/<hash> |
|||
[ -z "${MVNW_REPOURL-}" ] || distributionUrl="$MVNW_REPOURL$_MVNW_REPO_PATTERN${distributionUrl#*"$_MVNW_REPO_PATTERN"}" |
|||
distributionUrlName="${distributionUrl##*/}" |
|||
distributionUrlNameMain="${distributionUrlName%.*}" |
|||
distributionUrlNameMain="${distributionUrlNameMain%-bin}" |
|||
MAVEN_USER_HOME="${MAVEN_USER_HOME:-${HOME}/.m2}" |
|||
MAVEN_HOME="${MAVEN_USER_HOME}/wrapper/dists/${distributionUrlNameMain-}/$(hash_string "$distributionUrl")" |
|||
|
|||
exec_maven() { |
|||
unset MVNW_VERBOSE MVNW_USERNAME MVNW_PASSWORD MVNW_REPOURL || : |
|||
exec "$MAVEN_HOME/bin/$MVN_CMD" "$@" || die "cannot exec $MAVEN_HOME/bin/$MVN_CMD" |
|||
} |
|||
|
|||
if [ -d "$MAVEN_HOME" ]; then |
|||
verbose "found existing MAVEN_HOME at $MAVEN_HOME" |
|||
exec_maven "$@" |
|||
fi |
|||
|
|||
case "${distributionUrl-}" in |
|||
*?-bin.zip | *?maven-mvnd-?*-?*.zip) ;; |
|||
*) die "distributionUrl is not valid, must match *-bin.zip or maven-mvnd-*.zip, but found '${distributionUrl-}'" ;; |
|||
esac |
|||
|
|||
# prepare tmp dir |
|||
if TMP_DOWNLOAD_DIR="$(mktemp -d)" && [ -d "$TMP_DOWNLOAD_DIR" ]; then |
|||
clean() { rm -rf -- "$TMP_DOWNLOAD_DIR"; } |
|||
trap clean HUP INT TERM EXIT |
|||
else |
|||
die "cannot create temp dir" |
|||
fi |
|||
|
|||
mkdir -p -- "${MAVEN_HOME%/*}" |
|||
|
|||
# Download and Install Apache Maven |
|||
verbose "Couldn't find MAVEN_HOME, downloading and installing it ..." |
|||
verbose "Downloading from: $distributionUrl" |
|||
verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName" |
|||
|
|||
# select .zip or .tar.gz |
|||
if ! command -v unzip >/dev/null; then |
|||
distributionUrl="${distributionUrl%.zip}.tar.gz" |
|||
distributionUrlName="${distributionUrl##*/}" |
|||
fi |
|||
|
|||
# verbose opt |
|||
__MVNW_QUIET_WGET=--quiet __MVNW_QUIET_CURL=--silent __MVNW_QUIET_UNZIP=-q __MVNW_QUIET_TAR='' |
|||
[ "${MVNW_VERBOSE-}" != true ] || __MVNW_QUIET_WGET='' __MVNW_QUIET_CURL='' __MVNW_QUIET_UNZIP='' __MVNW_QUIET_TAR=v |
|||
|
|||
# normalize http auth |
|||
case "${MVNW_PASSWORD:+has-password}" in |
|||
'') MVNW_USERNAME='' MVNW_PASSWORD='' ;; |
|||
has-password) [ -n "${MVNW_USERNAME-}" ] || MVNW_USERNAME='' MVNW_PASSWORD='' ;; |
|||
esac |
|||
|
|||
if [ -z "${MVNW_USERNAME-}" ] && command -v wget >/dev/null; then |
|||
verbose "Found wget ... using wget" |
|||
wget ${__MVNW_QUIET_WGET:+"$__MVNW_QUIET_WGET"} "$distributionUrl" -O "$TMP_DOWNLOAD_DIR/$distributionUrlName" || die "wget: Failed to fetch $distributionUrl" |
|||
elif [ -z "${MVNW_USERNAME-}" ] && command -v curl >/dev/null; then |
|||
verbose "Found curl ... using curl" |
|||
curl ${__MVNW_QUIET_CURL:+"$__MVNW_QUIET_CURL"} -f -L -o "$TMP_DOWNLOAD_DIR/$distributionUrlName" "$distributionUrl" || die "curl: Failed to fetch $distributionUrl" |
|||
elif set_java_home; then |
|||
verbose "Falling back to use Java to download" |
|||
javaSource="$TMP_DOWNLOAD_DIR/Downloader.java" |
|||
targetZip="$TMP_DOWNLOAD_DIR/$distributionUrlName" |
|||
cat >"$javaSource" <<-END |
|||
public class Downloader extends java.net.Authenticator |
|||
{ |
|||
protected java.net.PasswordAuthentication getPasswordAuthentication() |
|||
{ |
|||
return new java.net.PasswordAuthentication( System.getenv( "MVNW_USERNAME" ), System.getenv( "MVNW_PASSWORD" ).toCharArray() ); |
|||
} |
|||
public static void main( String[] args ) throws Exception |
|||
{ |
|||
setDefault( new Downloader() ); |
|||
java.nio.file.Files.copy( java.net.URI.create( args[0] ).toURL().openStream(), java.nio.file.Paths.get( args[1] ).toAbsolutePath().normalize() ); |
|||
} |
|||
} |
|||
END |
|||
# For Cygwin/MinGW, switch paths to Windows format before running javac and java |
|||
verbose " - Compiling Downloader.java ..." |
|||
"$(native_path "$JAVACCMD")" "$(native_path "$javaSource")" || die "Failed to compile Downloader.java" |
|||
verbose " - Running Downloader.java ..." |
|||
"$(native_path "$JAVACMD")" -cp "$(native_path "$TMP_DOWNLOAD_DIR")" Downloader "$distributionUrl" "$(native_path "$targetZip")" |
|||
fi |
|||
|
|||
# If specified, validate the SHA-256 sum of the Maven distribution zip file |
|||
if [ -n "${distributionSha256Sum-}" ]; then |
|||
distributionSha256Result=false |
|||
if [ "$MVN_CMD" = mvnd.sh ]; then |
|||
echo "Checksum validation is not supported for maven-mvnd." >&2 |
|||
echo "Please disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2 |
|||
exit 1 |
|||
elif command -v sha256sum >/dev/null; then |
|||
if echo "$distributionSha256Sum $TMP_DOWNLOAD_DIR/$distributionUrlName" | sha256sum -c >/dev/null 2>&1; then |
|||
distributionSha256Result=true |
|||
fi |
|||
elif command -v shasum >/dev/null; then |
|||
if echo "$distributionSha256Sum $TMP_DOWNLOAD_DIR/$distributionUrlName" | shasum -a 256 -c >/dev/null 2>&1; then |
|||
distributionSha256Result=true |
|||
fi |
|||
else |
|||
echo "Checksum validation was requested but neither 'sha256sum' or 'shasum' are available." >&2 |
|||
echo "Please install either command, or disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2 |
|||
exit 1 |
|||
fi |
|||
if [ $distributionSha256Result = false ]; then |
|||
echo "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised." >&2 |
|||
echo "If you updated your Maven version, you need to update the specified distributionSha256Sum property." >&2 |
|||
exit 1 |
|||
fi |
|||
fi |
|||
|
|||
# unzip and move |
|||
if command -v unzip >/dev/null; then |
|||
unzip ${__MVNW_QUIET_UNZIP:+"$__MVNW_QUIET_UNZIP"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -d "$TMP_DOWNLOAD_DIR" || die "failed to unzip" |
|||
else |
|||
tar xzf${__MVNW_QUIET_TAR:+"$__MVNW_QUIET_TAR"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -C "$TMP_DOWNLOAD_DIR" || die "failed to untar" |
|||
fi |
|||
printf %s\\n "$distributionUrl" >"$TMP_DOWNLOAD_DIR/$distributionUrlNameMain/mvnw.url" |
|||
mv -- "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain" "$MAVEN_HOME" || [ -d "$MAVEN_HOME" ] || die "fail to move MAVEN_HOME" |
|||
|
|||
clean || : |
|||
exec_maven "$@" |
|||
@ -0,0 +1,149 @@ |
|||
<# : batch portion |
|||
@REM ---------------------------------------------------------------------------- |
|||
@REM Licensed to the Apache Software Foundation (ASF) under one |
|||
@REM or more contributor license agreements. See the NOTICE file |
|||
@REM distributed with this work for additional information |
|||
@REM regarding copyright ownership. The ASF licenses this file |
|||
@REM to you under the Apache License, Version 2.0 (the |
|||
@REM "License"); you may not use this file except in compliance |
|||
@REM with the License. You may obtain a copy of the License at |
|||
@REM |
|||
@REM http://www.apache.org/licenses/LICENSE-2.0 |
|||
@REM |
|||
@REM Unless required by applicable law or agreed to in writing, |
|||
@REM software distributed under the License is distributed on an |
|||
@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
|||
@REM KIND, either express or implied. See the License for the |
|||
@REM specific language governing permissions and limitations |
|||
@REM under the License. |
|||
@REM ---------------------------------------------------------------------------- |
|||
|
|||
@REM ---------------------------------------------------------------------------- |
|||
@REM Apache Maven Wrapper startup batch script, version 3.3.2 |
|||
@REM |
|||
@REM Optional ENV vars |
|||
@REM MVNW_REPOURL - repo url base for downloading maven distribution |
|||
@REM MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven |
|||
@REM MVNW_VERBOSE - true: enable verbose log; others: silence the output |
|||
@REM ---------------------------------------------------------------------------- |
|||
|
|||
@IF "%__MVNW_ARG0_NAME__%"=="" (SET __MVNW_ARG0_NAME__=%~nx0) |
|||
@SET __MVNW_CMD__= |
|||
@SET __MVNW_ERROR__= |
|||
@SET __MVNW_PSMODULEP_SAVE=%PSModulePath% |
|||
@SET PSModulePath= |
|||
@FOR /F "usebackq tokens=1* delims==" %%A IN (`powershell -noprofile "& {$scriptDir='%~dp0'; $script='%__MVNW_ARG0_NAME__%'; icm -ScriptBlock ([Scriptblock]::Create((Get-Content -Raw '%~f0'))) -NoNewScope}"`) DO @( |
|||
IF "%%A"=="MVN_CMD" (set __MVNW_CMD__=%%B) ELSE IF "%%B"=="" (echo %%A) ELSE (echo %%A=%%B) |
|||
) |
|||
@SET PSModulePath=%__MVNW_PSMODULEP_SAVE% |
|||
@SET __MVNW_PSMODULEP_SAVE= |
|||
@SET __MVNW_ARG0_NAME__= |
|||
@SET MVNW_USERNAME= |
|||
@SET MVNW_PASSWORD= |
|||
@IF NOT "%__MVNW_CMD__%"=="" (%__MVNW_CMD__% %*) |
|||
@echo Cannot start maven from wrapper >&2 && exit /b 1 |
|||
@GOTO :EOF |
|||
: end batch / begin powershell #> |
|||
|
|||
$ErrorActionPreference = "Stop" |
|||
if ($env:MVNW_VERBOSE -eq "true") { |
|||
$VerbosePreference = "Continue" |
|||
} |
|||
|
|||
# calculate distributionUrl, requires .mvn/wrapper/maven-wrapper.properties |
|||
$distributionUrl = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionUrl |
|||
if (!$distributionUrl) { |
|||
Write-Error "cannot read distributionUrl property in $scriptDir/.mvn/wrapper/maven-wrapper.properties" |
|||
} |
|||
|
|||
switch -wildcard -casesensitive ( $($distributionUrl -replace '^.*/','') ) { |
|||
"maven-mvnd-*" { |
|||
$USE_MVND = $true |
|||
$distributionUrl = $distributionUrl -replace '-bin\.[^.]*$',"-windows-amd64.zip" |
|||
$MVN_CMD = "mvnd.cmd" |
|||
break |
|||
} |
|||
default { |
|||
$USE_MVND = $false |
|||
$MVN_CMD = $script -replace '^mvnw','mvn' |
|||
break |
|||
} |
|||
} |
|||
|
|||
# apply MVNW_REPOURL and calculate MAVEN_HOME |
|||
# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-<version>,maven-mvnd-<version>-<platform>}/<hash> |
|||
if ($env:MVNW_REPOURL) { |
|||
$MVNW_REPO_PATTERN = if ($USE_MVND) { "/org/apache/maven/" } else { "/maven/mvnd/" } |
|||
$distributionUrl = "$env:MVNW_REPOURL$MVNW_REPO_PATTERN$($distributionUrl -replace '^.*'+$MVNW_REPO_PATTERN,'')" |
|||
} |
|||
$distributionUrlName = $distributionUrl -replace '^.*/','' |
|||
$distributionUrlNameMain = $distributionUrlName -replace '\.[^.]*$','' -replace '-bin$','' |
|||
$MAVEN_HOME_PARENT = "$HOME/.m2/wrapper/dists/$distributionUrlNameMain" |
|||
if ($env:MAVEN_USER_HOME) { |
|||
$MAVEN_HOME_PARENT = "$env:MAVEN_USER_HOME/wrapper/dists/$distributionUrlNameMain" |
|||
} |
|||
$MAVEN_HOME_NAME = ([System.Security.Cryptography.MD5]::Create().ComputeHash([byte[]][char[]]$distributionUrl) | ForEach-Object {$_.ToString("x2")}) -join '' |
|||
$MAVEN_HOME = "$MAVEN_HOME_PARENT/$MAVEN_HOME_NAME" |
|||
|
|||
if (Test-Path -Path "$MAVEN_HOME" -PathType Container) { |
|||
Write-Verbose "found existing MAVEN_HOME at $MAVEN_HOME" |
|||
Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD" |
|||
exit $? |
|||
} |
|||
|
|||
if (! $distributionUrlNameMain -or ($distributionUrlName -eq $distributionUrlNameMain)) { |
|||
Write-Error "distributionUrl is not valid, must end with *-bin.zip, but found $distributionUrl" |
|||
} |
|||
|
|||
# prepare tmp dir |
|||
$TMP_DOWNLOAD_DIR_HOLDER = New-TemporaryFile |
|||
$TMP_DOWNLOAD_DIR = New-Item -Itemtype Directory -Path "$TMP_DOWNLOAD_DIR_HOLDER.dir" |
|||
$TMP_DOWNLOAD_DIR_HOLDER.Delete() | Out-Null |
|||
trap { |
|||
if ($TMP_DOWNLOAD_DIR.Exists) { |
|||
try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null } |
|||
catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" } |
|||
} |
|||
} |
|||
|
|||
New-Item -Itemtype Directory -Path "$MAVEN_HOME_PARENT" -Force | Out-Null |
|||
|
|||
# Download and Install Apache Maven |
|||
Write-Verbose "Couldn't find MAVEN_HOME, downloading and installing it ..." |
|||
Write-Verbose "Downloading from: $distributionUrl" |
|||
Write-Verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName" |
|||
|
|||
$webclient = New-Object System.Net.WebClient |
|||
if ($env:MVNW_USERNAME -and $env:MVNW_PASSWORD) { |
|||
$webclient.Credentials = New-Object System.Net.NetworkCredential($env:MVNW_USERNAME, $env:MVNW_PASSWORD) |
|||
} |
|||
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 |
|||
$webclient.DownloadFile($distributionUrl, "$TMP_DOWNLOAD_DIR/$distributionUrlName") | Out-Null |
|||
|
|||
# If specified, validate the SHA-256 sum of the Maven distribution zip file |
|||
$distributionSha256Sum = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionSha256Sum |
|||
if ($distributionSha256Sum) { |
|||
if ($USE_MVND) { |
|||
Write-Error "Checksum validation is not supported for maven-mvnd. `nPlease disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." |
|||
} |
|||
Import-Module $PSHOME\Modules\Microsoft.PowerShell.Utility -Function Get-FileHash |
|||
if ((Get-FileHash "$TMP_DOWNLOAD_DIR/$distributionUrlName" -Algorithm SHA256).Hash.ToLower() -ne $distributionSha256Sum) { |
|||
Write-Error "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised. If you updated your Maven version, you need to update the specified distributionSha256Sum property." |
|||
} |
|||
} |
|||
|
|||
# unzip and move |
|||
Expand-Archive "$TMP_DOWNLOAD_DIR/$distributionUrlName" -DestinationPath "$TMP_DOWNLOAD_DIR" | Out-Null |
|||
Rename-Item -Path "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain" -NewName $MAVEN_HOME_NAME | Out-Null |
|||
try { |
|||
Move-Item -Path "$TMP_DOWNLOAD_DIR/$MAVEN_HOME_NAME" -Destination $MAVEN_HOME_PARENT | Out-Null |
|||
} catch { |
|||
if (! (Test-Path -Path "$MAVEN_HOME" -PathType Container)) { |
|||
Write-Error "fail to move MAVEN_HOME" |
|||
} |
|||
} finally { |
|||
try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null } |
|||
catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" } |
|||
} |
|||
|
|||
Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD" |
|||
@ -0,0 +1,206 @@ |
|||
<?xml version="1.0" encoding="UTF-8"?> |
|||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
|||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> |
|||
<modelVersion>4.0.0</modelVersion> |
|||
<parent> |
|||
<groupId>org.springframework.boot</groupId> |
|||
<artifactId>spring-boot-starter-parent</artifactId> |
|||
<version>2.7.8</version> |
|||
<relativePath/> <!-- lookup parent from repository --> |
|||
</parent> |
|||
<groupId>com.guozhi</groupId> |
|||
<artifactId>blood-analysis</artifactId> |
|||
<version>0.0.1</version> |
|||
<name>blood-analysis</name> |
|||
<description>blood-analysis</description> |
|||
<url/> |
|||
<licenses> |
|||
<license/> |
|||
</licenses> |
|||
<developers> |
|||
<developer/> |
|||
</developers> |
|||
<scm> |
|||
<connection/> |
|||
<developerConnection/> |
|||
<tag/> |
|||
<url/> |
|||
</scm> |
|||
<properties> |
|||
<java.version>1.8</java.version> |
|||
</properties> |
|||
<dependencies> |
|||
<dependency> |
|||
<groupId>io.springfox</groupId> |
|||
<artifactId>springfox-swagger2</artifactId> |
|||
<version>2.9.2</version> |
|||
</dependency> |
|||
|
|||
<dependency> |
|||
<groupId>io.springfox</groupId> |
|||
<artifactId>springfox-swagger-ui</artifactId> |
|||
<version>2.9.2</version> |
|||
</dependency> |
|||
<!-- MyBatis --> |
|||
<dependency> |
|||
<groupId>org.mybatis.spring.boot</groupId> |
|||
<artifactId>mybatis-spring-boot-starter</artifactId> |
|||
<exclusions> |
|||
<exclusion> |
|||
<groupId>org.springframework.boot</groupId> |
|||
<artifactId>spring-boot-starter-logging</artifactId> |
|||
</exclusion> |
|||
<exclusion> |
|||
<groupId>org.apache.logging.log4j</groupId> |
|||
<artifactId>log4j-core</artifactId> |
|||
</exclusion> |
|||
<exclusion> |
|||
<groupId>org.apache.logging.log4j</groupId> |
|||
<artifactId>log4j-api</artifactId> |
|||
</exclusion> |
|||
<exclusion> |
|||
<groupId>org.apache.logging.log4j</groupId> |
|||
<artifactId>log4j-slf4j-impl</artifactId> |
|||
</exclusion> |
|||
</exclusions> |
|||
<version>3.0.0</version> |
|||
</dependency> |
|||
<dependency> |
|||
<groupId>com.github.pagehelper</groupId> |
|||
<artifactId>pagehelper-spring-boot-starter</artifactId> |
|||
<version>2.1.0</version> |
|||
</dependency> |
|||
<dependency> |
|||
<groupId>mysql</groupId> |
|||
<artifactId>mysql-connector-java</artifactId> |
|||
<version>8.0.25</version> |
|||
</dependency> |
|||
<dependency> |
|||
<groupId>com.alibaba</groupId> |
|||
<artifactId>druid-spring-boot-starter</artifactId> |
|||
<version>1.1.20</version> |
|||
</dependency> |
|||
<dependency> |
|||
<groupId>org.springframework.boot</groupId> |
|||
<artifactId>spring-boot-starter-data-redis</artifactId> |
|||
</dependency> |
|||
<dependency> |
|||
<groupId>org.springframework.boot</groupId> |
|||
<artifactId>spring-boot-starter-aop</artifactId> |
|||
</dependency> |
|||
<dependency> |
|||
<groupId>org.apache.httpcomponents</groupId> |
|||
<artifactId>httpclient</artifactId> |
|||
</dependency> |
|||
<!-- <dependency>--> |
|||
<!-- <groupId>org.springframework.boot</groupId>--> |
|||
<!-- <artifactId>spring-boot-starter-security</artifactId>--> |
|||
<!-- </dependency>--> |
|||
<dependency> |
|||
<groupId>org.springframework.boot</groupId> |
|||
<artifactId>spring-boot-starter-web</artifactId> |
|||
<exclusions> |
|||
<exclusion> |
|||
<groupId>org.springframework.boot</groupId> |
|||
<artifactId>spring-boot-starter-logging</artifactId> |
|||
</exclusion> |
|||
<exclusion> |
|||
<groupId>org.apache.logging.log4j</groupId> |
|||
<artifactId>log4j-core</artifactId> |
|||
</exclusion> |
|||
<exclusion> |
|||
<groupId>org.apache.logging.log4j</groupId> |
|||
<artifactId>log4j-api</artifactId> |
|||
</exclusion> |
|||
<exclusion> |
|||
<groupId>org.apache.logging.log4j</groupId> |
|||
<artifactId>log4j-slf4j-impl</artifactId> |
|||
</exclusion> |
|||
</exclusions> |
|||
</dependency> |
|||
<dependency> |
|||
<groupId>jakarta.validation</groupId> |
|||
<artifactId>jakarta.validation-api</artifactId> |
|||
</dependency> |
|||
<dependency> |
|||
<groupId>org.projectlombok</groupId> |
|||
<artifactId>lombok</artifactId> |
|||
<optional>true</optional> |
|||
</dependency> |
|||
<dependency> |
|||
<groupId>io.nats</groupId> |
|||
<artifactId>jnats</artifactId> |
|||
<version>2.6.5</version> |
|||
</dependency> |
|||
<dependency> |
|||
<groupId>com.alibaba</groupId> |
|||
<artifactId>fastjson</artifactId> |
|||
<version>2.0.21</version> |
|||
</dependency> |
|||
<dependency> |
|||
<groupId>org.apache.commons</groupId> |
|||
<artifactId>commons-lang3</artifactId> |
|||
<version>3.12.0</version> |
|||
</dependency> |
|||
<dependency> |
|||
<groupId>org.springframework.boot</groupId> |
|||
<artifactId>spring-boot-starter-test</artifactId> |
|||
<scope>test</scope> |
|||
</dependency> |
|||
<dependency> |
|||
<groupId>org.junit.jupiter</groupId> |
|||
<artifactId>junit-jupiter</artifactId> |
|||
<scope>test</scope> |
|||
</dependency> |
|||
<dependency> |
|||
<groupId>org.apache.logging.log4j</groupId> |
|||
<artifactId>log4j-api</artifactId> |
|||
<version>2.17.0</version> |
|||
</dependency> |
|||
<dependency> |
|||
<groupId>org.apache.logging.log4j</groupId> |
|||
<artifactId>log4j-core</artifactId> |
|||
<version>2.17.0</version> |
|||
</dependency> |
|||
<dependency> |
|||
<groupId>org.apache.logging.log4j</groupId> |
|||
<artifactId>log4j-slf4j-impl</artifactId> |
|||
<version>2.17.0</version> |
|||
</dependency> |
|||
<dependency> |
|||
<groupId>com.guozhi</groupId> |
|||
<artifactId>sqlparser</artifactId> |
|||
<version>1.0</version> |
|||
</dependency> |
|||
<dependency> |
|||
<groupId>org.apache.poi</groupId> |
|||
<artifactId>poi</artifactId> |
|||
<version>4.1.2</version> |
|||
</dependency> |
|||
<dependency> |
|||
<groupId>org.apache.poi</groupId> |
|||
<artifactId>poi-ooxml</artifactId> |
|||
<version>4.1.2</version> |
|||
</dependency> |
|||
</dependencies> |
|||
<build> |
|||
<plugins> |
|||
<plugin> |
|||
<groupId>org.springframework.boot</groupId> |
|||
<artifactId>spring-boot-maven-plugin</artifactId> |
|||
<configuration> |
|||
<mainClass>com.guozhi.bloodanalysis.BloodAnalysisApplication</mainClass> |
|||
<!-- <skip>true</skip> --> |
|||
<excludes> |
|||
<exclude> |
|||
<groupId>org.projectlombok</groupId> |
|||
<artifactId>lombok</artifactId> |
|||
</exclude> |
|||
</excludes> |
|||
</configuration> |
|||
</plugin> |
|||
</plugins> |
|||
|
|||
</build> |
|||
|
|||
</project> |
|||
@ -0,0 +1,15 @@ |
|||
package com.guozhi.bloodanalysis; |
|||
|
|||
import org.springframework.boot.SpringApplication; |
|||
import org.springframework.boot.autoconfigure.SpringBootApplication; |
|||
import org.springframework.scheduling.annotation.EnableAsync; |
|||
|
|||
@SpringBootApplication |
|||
@EnableAsync |
|||
public class BloodAnalysisApplication { |
|||
|
|||
public static void main(String[] args) { |
|||
SpringApplication.run(BloodAnalysisApplication.class, args); |
|||
} |
|||
|
|||
} |
|||
@ -0,0 +1,106 @@ |
|||
//package com.guozhi.bloodanalysis.config;
|
|||
//
|
|||
//import com.guozhi.bloodanalysis.utils.RedisUtils;
|
|||
//import lombok.extern.slf4j.Slf4j;
|
|||
//import org.aspectj.lang.JoinPoint;
|
|||
//import org.aspectj.lang.ProceedingJoinPoint;
|
|||
//import org.aspectj.lang.annotation.AfterReturning;
|
|||
//import org.aspectj.lang.annotation.Around;
|
|||
//import org.aspectj.lang.annotation.Aspect;
|
|||
//import org.aspectj.lang.annotation.Pointcut;
|
|||
//import org.springframework.beans.factory.annotation.Autowired;
|
|||
//import org.springframework.stereotype.Component;
|
|||
//
|
|||
//import javax.servlet.http.HttpServletRequest;
|
|||
//
|
|||
///**
|
|||
// * 切面处理层:使用@Pointcut定义你针对某些函数(一般来说是接口函数)的切点
|
|||
// * 使用@Around处理你定义的切点对应的处理逻辑、实例中给出了两种处理逻辑
|
|||
// * signFeild:前后台的验签逻辑、为了保证调用者的合法性和数据一致性
|
|||
// * oauthFeild: 获取用户信息的逻辑、优先从网关的头部参数中获取,如果没有取到,
|
|||
// * 应用将会请求oauth,用请求参数或头部参数中的refresh_token获取用户信息,同时进行接口权限的判断。
|
|||
// */
|
|||
//@Slf4j
|
|||
//@Component
|
|||
//@Aspect
|
|||
//public class BusinessAspect {
|
|||
//
|
|||
// @Autowired
|
|||
// HttpServletRequest request;
|
|||
//
|
|||
// @Autowired
|
|||
// private RedisUtils redisUtils;
|
|||
//
|
|||
//// @Autowired
|
|||
//// UserRoleMapper userRoleMapper;
|
|||
////
|
|||
//// @Autowired
|
|||
//// PermissionMapper permissionMapper;
|
|||
////
|
|||
//// @Autowired
|
|||
//// MenuFunctionMapper menuFunctionMapper;
|
|||
//
|
|||
//
|
|||
//// @Pointcut("execution(* com.guozhi.bloodanalysis.controller.SystemController.*(..))")
|
|||
//// public void ApiController() {}
|
|||
//
|
|||
//
|
|||
//// @Pointcut("within(@org.springframework.web.bind.annotation.RestController *) &&"+
|
|||
//// "!ApiController()")
|
|||
//// public void OauthAround() {}
|
|||
//
|
|||
//// @Around("OauthAround()")
|
|||
//// public Object OauthAround(ProceedingJoinPoint point) throws Throwable {
|
|||
//// log.info("--------ApiController PointCut Start--------");
|
|||
//// Object[] objects = point.getArgs();
|
|||
//// String token = request.getHeader("token");
|
|||
//// if (StringUtils.isEmpty(token)){
|
|||
//// throw new BusinessException("tokenError","登录信息已过期,请重新登录");
|
|||
//// }
|
|||
//// User user = (User)redisUtils.get(token);
|
|||
//// if (user == null || StringUtils.isEmpty(user.getUserName())){
|
|||
//// throw new BusinessException("tokenError","登录信息已过期,请重新登录");
|
|||
//// }
|
|||
//// redisUtils.expire(token,1800);
|
|||
//// if (!user.isAdmin()){
|
|||
//// //todo 权限验证
|
|||
//// List<UserRole> userRoleList = userRoleMapper.getUserRoleByUserName(user.getUserName());
|
|||
//// if (CollectionUtils.isEmpty(userRoleList)){
|
|||
//// throw new BusinessException("hasNoAuth","无此功能权限,联系管理员");
|
|||
//// }
|
|||
//// List<String> roleCodes = userRoleList.stream().map(UserRole::getRoleCode).collect(Collectors.toList());
|
|||
//// List<Permission> permissions = permissionMapper.getFunctionPermissionByRoleCodeList(roleCodes);
|
|||
//// if (CollectionUtils.isEmpty(permissions)){
|
|||
//// throw new BusinessException("hasNoAuth","无此功能权限,联系管理员");
|
|||
//// }
|
|||
//// boolean hasPermission = false;
|
|||
//// List<String> functionList = permissions.stream().map(Permission::getPermissionCode).collect(Collectors.toList());
|
|||
//// List<MenuFunction> menuFunctionList = menuFunctionMapper.getMenuFunctionByCodeList(functionList);
|
|||
//// if (CollectionUtils.isEmpty(menuFunctionList)){
|
|||
//// throw new BusinessException("hasNoAuth","无此功能权限,联系管理员");
|
|||
//// }
|
|||
//// for (MenuFunction menuFunction : menuFunctionList) {
|
|||
//// if (new AntPathRequestMatcher(menuFunction.getUrl()).matches(request)){
|
|||
//// hasPermission = true;
|
|||
//// break;
|
|||
//// }
|
|||
//// }
|
|||
//// if (hasPermission){
|
|||
//// return point.proceed(objects);
|
|||
//// }else{
|
|||
//// throw new BusinessException("hasNoAuth","无此功能权限,联系管理员");
|
|||
//// }
|
|||
//// }
|
|||
//// return point.proceed(objects);
|
|||
//// }
|
|||
//
|
|||
// @AfterReturning(returning = "rvt", pointcut = "within(@org.springframework.web.bind.annotation.RestController *)"+
|
|||
// " || " +
|
|||
// "within(@org.springframework.stereotype.Controller *) " +
|
|||
// "execution(* *(..))")
|
|||
// public Object afterExec(JoinPoint joinPoint, Object rvt) {
|
|||
//// log.info("--------AfterReturningResult:"+ JSON.toJSONString(rvt));
|
|||
// return rvt;
|
|||
// }
|
|||
//
|
|||
//}
|
|||
@ -0,0 +1,36 @@ |
|||
package com.guozhi.bloodanalysis.config; |
|||
|
|||
import org.springframework.context.annotation.Bean; |
|||
import org.springframework.context.annotation.Configuration; |
|||
import org.springframework.web.cors.CorsConfiguration; |
|||
import org.springframework.web.cors.UrlBasedCorsConfigurationSource; |
|||
import org.springframework.web.filter.CorsFilter; |
|||
|
|||
@Configuration // 一定不要忽略此注解
|
|||
//public class CorsConfig implements WebMvcConfigurer {
|
|||
public class CorsConfig{ |
|||
private CorsConfiguration buildConfig() { |
|||
CorsConfiguration corsConfiguration = new CorsConfiguration(); |
|||
corsConfiguration.addAllowedOrigin("*"); // 1允许任何域名使用
|
|||
corsConfiguration.addAllowedHeader("*"); // 2允许任何头
|
|||
corsConfiguration.addAllowedMethod("*"); // 3允许任何方法(post、get等)
|
|||
corsConfiguration.setAllowCredentials(false);// 允许跨域带上cookies
|
|||
return corsConfiguration; |
|||
} |
|||
|
|||
@Bean |
|||
public CorsFilter corsFilter() { |
|||
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); |
|||
source.registerCorsConfiguration("/**", buildConfig()); // 4
|
|||
return new CorsFilter(source); |
|||
} |
|||
// @Override
|
|||
// public void addCorsMappings(CorsRegistry registry) {
|
|||
// registry.addMapping("/**") // 所有接口
|
|||
// .allowCredentials(true) // 是否发送 Cookie
|
|||
// .allowedOriginPatterns("*") // 支持域
|
|||
// .allowedMethods("GET", "POST", "PUT", "DELETE") // 支持方法
|
|||
// .allowedHeaders("*")
|
|||
// .exposedHeaders("*");
|
|||
// }
|
|||
} |
|||
@ -0,0 +1,40 @@ |
|||
package com.guozhi.bloodanalysis.config; |
|||
|
|||
import com.alibaba.druid.pool.DruidDataSource; |
|||
import com.alibaba.druid.support.http.StatViewServlet; |
|||
import com.alibaba.druid.support.http.WebStatFilter; |
|||
import org.springframework.boot.context.properties.ConfigurationProperties; |
|||
import org.springframework.boot.web.servlet.FilterRegistrationBean; |
|||
import org.springframework.boot.web.servlet.ServletRegistrationBean; |
|||
import org.springframework.context.annotation.Bean; |
|||
import org.springframework.context.annotation.Configuration; |
|||
|
|||
import javax.sql.DataSource; |
|||
|
|||
@Configuration |
|||
public class DataSourceConfig { |
|||
@Bean |
|||
public ServletRegistrationBean druidServlet() {// 主要实现web监控的配置处理
|
|||
ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(new StatViewServlet(), "/druid/*");//表示进行druid监控的配置处理操作
|
|||
// servletRegistrationBean.addInitParameter("allow", "127.0.0.1,129.168.1.11");//白名单
|
|||
// servletRegistrationBean.addInitParameter("deny", "129.168.1.12");//黑名单
|
|||
servletRegistrationBean.addInitParameter("loginUsername", "admin");//用户名
|
|||
servletRegistrationBean.addInitParameter("loginPassword", "123456");//密码
|
|||
servletRegistrationBean.addInitParameter("resetEnable", "false");//是否可以重置数据源
|
|||
return servletRegistrationBean; |
|||
|
|||
} |
|||
@Bean //监控
|
|||
public FilterRegistrationBean filterRegistrationBean(){ |
|||
FilterRegistrationBean filterRegistrationBean=new FilterRegistrationBean(); |
|||
filterRegistrationBean.setFilter(new WebStatFilter()); |
|||
filterRegistrationBean.addUrlPatterns("/*");//所有请求进行监控处理
|
|||
filterRegistrationBean.addInitParameter("exclusions", "*.js,*.gif,*.jpg,*.css,/druid/*");//排除
|
|||
return filterRegistrationBean; |
|||
} |
|||
@Bean |
|||
@ConfigurationProperties(prefix = "spring.datasource.druid") |
|||
public DataSource druidDataSource() { |
|||
return new DruidDataSource(); |
|||
} |
|||
} |
|||
@ -0,0 +1,40 @@ |
|||
package com.guozhi.bloodanalysis.config; |
|||
|
|||
import org.springframework.context.annotation.Bean; |
|||
import org.springframework.context.annotation.Configuration; |
|||
import org.springframework.scheduling.annotation.AsyncConfigurer; |
|||
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; |
|||
|
|||
import java.util.concurrent.Executor; |
|||
|
|||
@Configuration |
|||
public class ExecutorConfig implements AsyncConfigurer { |
|||
|
|||
// ThredPoolTaskExcutor的处理流程
|
|||
// 当池子大小小于corePoolSize,就新建线程,并处理请求
|
|||
// 当池子大小等于corePoolSize,把请求放入workQueue中,池子里的空闲线程就去workQueue中取任务并处理
|
|||
// 当workQueue放不下任务时,就新建线程入池,并处理请求,
|
|||
// 如果池子大小撑到了maximumPoolSize,就用RejectedExecutionHandler来做拒绝处理
|
|||
// 当池子的线程数大于corePoolSize时,多余的线程会等待keepAliveTime长时间,如果无请求可处理就自行销毁
|
|||
//getAsyncExecutor:自定义线程池,若不重写会使用默认的线程池。
|
|||
@Override |
|||
@Bean |
|||
public Executor getAsyncExecutor() { |
|||
ThreadPoolTaskExecutor threadPool = new ThreadPoolTaskExecutor(); |
|||
//设置核心线程数
|
|||
threadPool.setCorePoolSize(5); |
|||
//设置最大线程数
|
|||
threadPool.setMaxPoolSize(10); |
|||
//线程池所使用的缓冲队列
|
|||
threadPool.setQueueCapacity(10); |
|||
//等待任务在关机时完成--表明等待所有线程执行完
|
|||
threadPool.setWaitForTasksToCompleteOnShutdown(true); |
|||
// 等待时间 (默认为0,此时立即停止),并没等待xx秒后强制停止
|
|||
threadPool.setAwaitTerminationSeconds(60); |
|||
// 线程名称前缀
|
|||
threadPool.setThreadNamePrefix("ThreadPoolTaskExecutor-"); |
|||
// 初始化线程
|
|||
threadPool.initialize(); |
|||
return threadPool; |
|||
} |
|||
} |
|||
@ -0,0 +1,33 @@ |
|||
package com.guozhi.bloodanalysis.config; |
|||
|
|||
import com.guozhi.bloodanalysis.exception.BusinessException; |
|||
import com.guozhi.bloodanalysis.utils.ApiResult; |
|||
import lombok.extern.slf4j.Slf4j; |
|||
import org.springframework.stereotype.Controller; |
|||
import org.springframework.web.bind.annotation.ControllerAdvice; |
|||
import org.springframework.web.bind.annotation.ExceptionHandler; |
|||
import org.springframework.web.bind.annotation.ResponseBody; |
|||
import org.springframework.web.bind.annotation.RestController; |
|||
|
|||
/** |
|||
* 全局的异常处理类 |
|||
*/ |
|||
@ControllerAdvice(annotations = {RestController.class , Controller.class}) |
|||
@ResponseBody |
|||
@Slf4j |
|||
public class GlobalRestExceptionHandler { |
|||
|
|||
@ExceptionHandler(value = com.guozhi.bloodanalysis.exception.BusinessException.class) |
|||
public ApiResult easiBaseSysExceptionHandler(Exception e) { |
|||
log.error(((BusinessException) e).getCode(),e.getMessage()); |
|||
ApiResult result = ApiResult.error( 999 , e.getMessage()); |
|||
return result; |
|||
} |
|||
|
|||
@ExceptionHandler(value = Exception.class) |
|||
public ApiResult exceptionHandler(Exception e) { |
|||
e.printStackTrace(); |
|||
ApiResult result = ApiResult.error(999, e.getMessage()); |
|||
return result; |
|||
} |
|||
} |
|||
@ -0,0 +1,159 @@ |
|||
package com.guozhi.bloodanalysis.config; |
|||
|
|||
import com.alibaba.druid.pool.DruidDataSource; |
|||
import com.github.pagehelper.PageInterceptor; |
|||
import org.apache.ibatis.plugin.Interceptor; |
|||
import org.apache.ibatis.session.SqlSessionFactory; |
|||
import org.mybatis.spring.SqlSessionFactoryBean; |
|||
import org.mybatis.spring.annotation.MapperScan; |
|||
import org.springframework.beans.factory.annotation.Qualifier; |
|||
import org.springframework.beans.factory.annotation.Value; |
|||
import org.springframework.context.annotation.Bean; |
|||
import org.springframework.context.annotation.Configuration; |
|||
import org.springframework.context.annotation.Primary; |
|||
import org.springframework.core.io.support.PathMatchingResourcePatternResolver; |
|||
import org.springframework.jdbc.datasource.DataSourceTransactionManager; |
|||
|
|||
import javax.sql.DataSource; |
|||
import java.sql.SQLException; |
|||
import java.util.Properties; |
|||
|
|||
@Configuration |
|||
@MapperScan(basePackages = MasterDataSourceConfig.PACKAGE, sqlSessionFactoryRef = "masterSqlSessionFactory") |
|||
public class MasterDataSourceConfig { |
|||
/** |
|||
* 配置多数据源 关键就在这里 这里配置了不同的mapper对应不同的数据源 |
|||
*/ |
|||
static final String PACKAGE = "com.guozhi.bloodanalysis.mapper"; |
|||
static final String MAPPER_LOCATION = "classpath:mapper/*.xml"; |
|||
|
|||
/** |
|||
* 连接数据库信息 这个其实更好的是用配置中心完成 |
|||
*/ |
|||
@Value("${master.datasource.url}") |
|||
private String url; |
|||
|
|||
@Value("${master.datasource.username}") |
|||
private String username; |
|||
|
|||
@Value("${master.datasource.password}") |
|||
private String password; |
|||
|
|||
@Value("${master.datasource.driverClassName}") |
|||
private String driverClassName; |
|||
|
|||
|
|||
/** |
|||
* 下面的配置信息可以读取配置文件,其实可以直接写死 如果是多数据源的话 还是考虑读取配置文件 |
|||
*/ |
|||
@Value("${spring.datasource.initialSize}") |
|||
private int initialSize; |
|||
|
|||
@Value("${spring.datasource.minIdle}") |
|||
private int minIdle; |
|||
|
|||
@Value("${spring.datasource.maxActive}") |
|||
private int maxActive; |
|||
|
|||
@Value("${spring.datasource.maxWait}") |
|||
private int maxWait; |
|||
|
|||
@Value("${spring.datasource.timeBetweenEvictionRunsMillis}") |
|||
private int timeBetweenEvictionRunsMillis; |
|||
|
|||
@Value("${spring.datasource.minEvictableIdleTimeMillis}") |
|||
private int minEvictableIdleTimeMillis; |
|||
|
|||
@Value("${spring.datasource.validationQuery}") |
|||
private String validationQuery; |
|||
|
|||
@Value("${spring.datasource.testWhileIdle}") |
|||
private boolean testWhileIdle; |
|||
|
|||
@Value("${spring.datasource.testOnBorrow}") |
|||
private boolean testOnBorrow; |
|||
|
|||
@Value("${spring.datasource.testOnReturn}") |
|||
private boolean testOnReturn; |
|||
|
|||
@Value("${spring.datasource.poolPreparedStatements}") |
|||
private boolean poolPreparedStatements; |
|||
|
|||
@Value("${spring.datasource.maxPoolPreparedStatementPerConnectionSize}") |
|||
private int maxPoolPreparedStatementPerConnectionSize; |
|||
|
|||
@Value("${spring.datasource.filters}") |
|||
private String filters; |
|||
|
|||
@Value("{spring.datasource.connectionProperties}") |
|||
private String connectionProperties; |
|||
|
|||
|
|||
@Bean(name = "masterDataSource") |
|||
@Primary //标志这个 Bean 如果在多个同类 Bean 候选时,该 Bean 优先被考虑。
|
|||
public DataSource masterDataSource() { |
|||
DruidDataSource dataSource = new DruidDataSource(); |
|||
dataSource.setUrl(url); |
|||
dataSource.setUsername(username); |
|||
dataSource.setPassword(password); |
|||
dataSource.setDriverClassName(driverClassName); |
|||
|
|||
//具体配置
|
|||
dataSource.setInitialSize(initialSize); |
|||
dataSource.setMinIdle(minIdle); |
|||
dataSource.setMaxActive(maxActive); |
|||
dataSource.setMaxWait(maxWait); |
|||
dataSource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis); |
|||
dataSource.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis); |
|||
dataSource.setValidationQuery(validationQuery); |
|||
dataSource.setTestWhileIdle(testWhileIdle); |
|||
dataSource.setTestOnBorrow(testOnBorrow); |
|||
dataSource.setTestOnReturn(testOnReturn); |
|||
dataSource.setPoolPreparedStatements(poolPreparedStatements); |
|||
dataSource.setMaxPoolPreparedStatementPerConnectionSize(maxPoolPreparedStatementPerConnectionSize); |
|||
|
|||
/** |
|||
* 这个是用来配置 druid 监控sql语句的 非常有用 如果你有两个数据源 这个配置哪个数据源就坚实哪个数据源的sql 同时配置那就都监控 |
|||
*/ |
|||
try { |
|||
dataSource.setFilters(filters); |
|||
} catch (SQLException e) { |
|||
e.printStackTrace(); |
|||
} |
|||
dataSource.setConnectionProperties(connectionProperties); |
|||
return dataSource; |
|||
} |
|||
|
|||
@Bean(name = "masterTransactionManager") |
|||
@Primary |
|||
public DataSourceTransactionManager masterTransactionManager() { |
|||
return new DataSourceTransactionManager(masterDataSource()); |
|||
} |
|||
|
|||
@Bean(name = "masterSqlSessionFactory") |
|||
@Primary |
|||
public SqlSessionFactory masterSqlSessionFactory(@Qualifier("masterDataSource") DataSource masterDataSource) |
|||
throws Exception { |
|||
final SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean(); |
|||
sessionFactory.setDataSource(masterDataSource); |
|||
sessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver().getResources(MasterDataSourceConfig.MAPPER_LOCATION)); |
|||
|
|||
//分页插件
|
|||
Interceptor interceptor = new PageInterceptor(); |
|||
Properties properties = new Properties(); |
|||
//数据库
|
|||
properties.setProperty("helperDialect", "mysql"); |
|||
// properties.setProperty("dialect", "mysql");
|
|||
//是否将参数offset作为PageNum使用
|
|||
properties.setProperty("offsetAsPageNum", "true"); |
|||
//是否进行count查询
|
|||
properties.setProperty("rowBoundsWithCount", "true"); |
|||
//是否分页合理化
|
|||
properties.setProperty("reasonable", "false"); |
|||
interceptor.setProperties(properties); |
|||
sessionFactory.setPlugins(new Interceptor[] {interceptor}); |
|||
|
|||
|
|||
return sessionFactory.getObject(); |
|||
} |
|||
} |
|||
@ -0,0 +1,43 @@ |
|||
package com.guozhi.bloodanalysis.config; |
|||
|
|||
import org.springframework.context.annotation.Bean; |
|||
import org.springframework.context.annotation.Configuration; |
|||
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; |
|||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport; |
|||
import springfox.documentation.builders.ApiInfoBuilder; |
|||
import springfox.documentation.service.ApiInfo; |
|||
import springfox.documentation.service.Contact; |
|||
import springfox.documentation.spi.DocumentationType; |
|||
import springfox.documentation.spring.web.plugins.Docket; |
|||
import springfox.documentation.swagger2.annotations.EnableSwagger2; |
|||
|
|||
@Configuration |
|||
@EnableSwagger2// 开启Swagger2的自动配置
|
|||
public class SwaggerConfig extends WebMvcConfigurationSupport { |
|||
/** |
|||
* 解决高版本springboot无法访问http://localhost:8001/swagger-ui.html
|
|||
* @param registry void |
|||
*/ |
|||
@Override |
|||
protected void addResourceHandlers(ResourceHandlerRegistry registry) { |
|||
// 解决静态资源无法访问
|
|||
registry.addResourceHandler("/**").addResourceLocations("classpath:/static/"); |
|||
// 解决swagger无法访问
|
|||
registry.addResourceHandler("/swagger-ui.html").addResourceLocations("classpath:/META-INF/resources/"); |
|||
// 解决swagger的js文件无法访问
|
|||
registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/"); |
|||
} |
|||
//配置文档信息
|
|||
private ApiInfo apiInfo() { |
|||
return new ApiInfoBuilder() |
|||
.title("接口文档") // 标题
|
|||
.description("各个controller以及接口,参数等展示页") //描述
|
|||
.version("v1.0") // 版本
|
|||
.contact(new Contact("薛寅飞", "http://192.168.8.138:8082/dispatch/swagger-ui.html", "qc_xueyinfei@xcmg.com")) |
|||
.build(); |
|||
} |
|||
@Bean |
|||
public Docket docket() { |
|||
return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo()); |
|||
} |
|||
} |
|||
@ -0,0 +1,36 @@ |
|||
package com.guozhi.bloodanalysis.controller; |
|||
|
|||
import com.guozhi.bloodanalysis.parser.SqlParser; |
|||
import com.guozhi.bloodanalysis.service.BloodAnalysisService; |
|||
import com.guozhi.bloodanalysis.utils.ApiResult; |
|||
import com.guozhi.bloodanalysis.utils.RedisUtils; |
|||
import org.springframework.beans.factory.annotation.Autowired; |
|||
import org.springframework.web.bind.annotation.GetMapping; |
|||
import org.springframework.web.bind.annotation.PostMapping; |
|||
import org.springframework.web.bind.annotation.RestController; |
|||
|
|||
import javax.servlet.http.HttpServletRequest; |
|||
import java.io.FileNotFoundException; |
|||
|
|||
@RestController |
|||
public class BloodAnalysisController { |
|||
|
|||
@Autowired |
|||
BloodAnalysisService bloodAnalysisService; |
|||
|
|||
@Autowired |
|||
RedisUtils redisUtils; |
|||
|
|||
@PostMapping("/bloodAnalysis") |
|||
public ApiResult<String> BloodAnalysis(HttpServletRequest request) { |
|||
String dashUserName = request.getHeader("dashUserName"); |
|||
String dashPassword = request.getHeader("dashPassword"); |
|||
Boolean startBloodAnalysis = (Boolean)redisUtils.get("startBloodAnalysis"); |
|||
if (startBloodAnalysis != null && startBloodAnalysis){ |
|||
return ApiResult.success("正在执行血缘解析任务,无需重复执行"); |
|||
}else { |
|||
bloodAnalysisService.analysis(dashUserName,dashPassword); |
|||
return ApiResult.success("启动任务成功,请稍后查看"); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,17 @@ |
|||
package com.guozhi.bloodanalysis.entity; |
|||
|
|||
import lombok.AllArgsConstructor; |
|||
import lombok.Data; |
|||
import lombok.NoArgsConstructor; |
|||
|
|||
@Data |
|||
@AllArgsConstructor |
|||
@NoArgsConstructor |
|||
public class DataLineageInfo { |
|||
private Integer onum; |
|||
private String ssysCd; |
|||
private String mdlName; |
|||
private String procName; |
|||
private String procLine; |
|||
private String procText; |
|||
} |
|||
@ -0,0 +1,28 @@ |
|||
package com.guozhi.bloodanalysis.entity; |
|||
|
|||
import lombok.AllArgsConstructor; |
|||
import lombok.Data; |
|||
import lombok.NoArgsConstructor; |
|||
|
|||
@Data |
|||
@AllArgsConstructor |
|||
@NoArgsConstructor |
|||
public class MetaBloodAnalysis { |
|||
private String id; |
|||
private Integer proId; |
|||
private String proName; |
|||
private String targetSysCd; |
|||
private String targetMdlName; |
|||
private String targetTableName; |
|||
private String targetTableCnName; |
|||
private String targetColName; |
|||
private String targetColCnName; |
|||
private String targetColType; |
|||
private String sourceSysCd; |
|||
private String sourceMdlName; |
|||
private String sourceTableName; |
|||
private String sourceTableCnName; |
|||
private String sourceColName; |
|||
private String sourceColCnName; |
|||
private String sourceColType; |
|||
} |
|||
@ -0,0 +1,18 @@ |
|||
package com.guozhi.bloodanalysis.entity; |
|||
|
|||
import lombok.AllArgsConstructor; |
|||
import lombok.Data; |
|||
import lombok.NoArgsConstructor; |
|||
|
|||
@Data |
|||
@AllArgsConstructor |
|||
@NoArgsConstructor |
|||
public class MetaColumn { |
|||
private int onum; |
|||
private String ssysCd; |
|||
private String mdlName; |
|||
private String tableEngName; |
|||
private String tableCnName; |
|||
private String fldEngName; |
|||
private String fldCnName; |
|||
} |
|||
@ -0,0 +1,19 @@ |
|||
package com.guozhi.bloodanalysis.exception; |
|||
|
|||
import lombok.Data; |
|||
import lombok.EqualsAndHashCode; |
|||
|
|||
@EqualsAndHashCode(callSuper = false) |
|||
@Data |
|||
public class BusinessException extends RuntimeException{ |
|||
private String code; |
|||
private String message; |
|||
public BusinessException(String message) { |
|||
super(message); |
|||
} |
|||
public BusinessException(String code, String message) { |
|||
super(message); |
|||
this.code = code; |
|||
this.message = message; |
|||
} |
|||
} |
|||
@ -0,0 +1,11 @@ |
|||
package com.guozhi.bloodanalysis.mapper; |
|||
|
|||
import com.guozhi.bloodanalysis.entity.DataLineageInfo; |
|||
import org.apache.ibatis.annotations.Mapper; |
|||
|
|||
import java.util.List; |
|||
|
|||
@Mapper |
|||
public interface DataLineageInfoMapper { |
|||
List<DataLineageInfo> search(); |
|||
} |
|||
@ -0,0 +1,25 @@ |
|||
package com.guozhi.bloodanalysis.mapper; |
|||
|
|||
import com.guozhi.bloodanalysis.entity.MetaBloodAnalysis; |
|||
import com.guozhi.bloodanalysis.entity.MetaColumn; |
|||
import org.apache.ibatis.annotations.Mapper; |
|||
import org.apache.ibatis.annotations.Param; |
|||
|
|||
import java.util.List; |
|||
import java.util.Map; |
|||
|
|||
@Mapper |
|||
public interface MetaBloodAnalysisMapper { |
|||
|
|||
void insert(@Param("blood") MetaBloodAnalysis metaBloodAnalysis); |
|||
|
|||
MetaColumn isColExis(@Param("db") String db, @Param("schema") String schema, @Param("tableCode") String tableCode, @Param("columnName") String columnName); |
|||
|
|||
List<Map<String, String>> getColumnsByTabId(@Param("tableId") String tabId,@Param("colCode") String colCode); |
|||
|
|||
List<Map<String, Object>> getSystem(@Param("schema") String schema, @Param("tableCode") String tableCode); |
|||
|
|||
List<Map<String, String>> getColumnsByTable(@Param("tableName") String tableName, @Param("ssysCd") String defaultDb, @Param("mdlName") String defaultSchema); |
|||
|
|||
void deleteAllBloodData(); |
|||
} |
|||
@ -0,0 +1,302 @@ |
|||
package com.guozhi.bloodanalysis.parser; |
|||
|
|||
import com.guozhi.bloodanalysis.entity.DataLineageInfo; |
|||
import com.guozhi.bloodanalysis.exception.BusinessException; |
|||
import com.guozhi.bloodanalysis.parser.clean.GenericLogNormalizer; |
|||
import com.guozhi.bloodanalysis.parser.common.*; |
|||
import com.guozhi.bloodanalysis.parser.utils.ExportParseResultUtil; |
|||
import com.guozhi.bloodanalysis.parser.vo.KColumn; |
|||
import gudusoft.gsqlparser.EDbVendor; |
|||
import gudusoft.gsqlparser.TCustomSqlStatement; |
|||
import gudusoft.gsqlparser.TGSqlParser; |
|||
import gudusoft.gsqlparser.TStatementList; |
|||
import gudusoft.gsqlparser.stmt.TAlterTableStatement; |
|||
import gudusoft.gsqlparser.stmt.TCreateTableSqlStatement; |
|||
import gudusoft.gsqlparser.stmt.TDeleteSqlStatement; |
|||
import gudusoft.gsqlparser.stmt.TInsertSqlStatement; |
|||
import gudusoft.gsqlparser.stmt.TSelectSqlStatement; |
|||
import gudusoft.gsqlparser.stmt.TUpdateSqlStatement; |
|||
import lombok.Data; |
|||
import lombok.NoArgsConstructor; |
|||
import lombok.extern.slf4j.Slf4j; |
|||
import org.apache.commons.lang3.StringUtils; |
|||
import org.springframework.beans.factory.annotation.Autowired; |
|||
import org.springframework.context.ApplicationContext; |
|||
import org.springframework.context.annotation.Scope; |
|||
import org.springframework.stereotype.Component; |
|||
|
|||
import java.util.*; |
|||
import java.util.regex.Matcher; |
|||
import java.util.regex.Pattern; |
|||
|
|||
import static com.guozhi.bloodanalysis.parser.utils.DatabaseType.Oracle; |
|||
|
|||
|
|||
@Slf4j |
|||
@Component |
|||
@Data |
|||
@NoArgsConstructor |
|||
@Scope("prototype") |
|||
public class SqlParser { |
|||
//解析器对象
|
|||
private TGSqlParser sqlParser = null; |
|||
//sql解析器上下文
|
|||
private ParserContext parserContext = new ParserContext(); |
|||
|
|||
@Autowired |
|||
ExportParseResultUtil exportParseResultUtil; |
|||
|
|||
@Autowired |
|||
ApplicationContext applicationContext; |
|||
|
|||
public void parse(DataLineageInfo dataLineageInfo, List<Map<String, String>> databaseList) throws Exception { |
|||
String sqlText = ""; |
|||
try { |
|||
List<String> targetSqlList = new ArrayList<>(); |
|||
String dbType = "MYSQL"; |
|||
if (databaseList !=null && databaseList.size()>0){ |
|||
for (Map<String, String> map : databaseList) { |
|||
String type = map.get(dataLineageInfo.getSsysCd()); |
|||
if (type != null) { |
|||
dbType = type; |
|||
} |
|||
} |
|||
} |
|||
String sql = new GenericLogNormalizer().normalizer(dataLineageInfo.getProcText(),dbType); |
|||
sql = optDeclare(sql,dataLineageInfo.getProcName()); |
|||
sql = optDeclare2(sql); |
|||
if(sql.trim().equals("")){ |
|||
throw new BusinessException("errorSQLparse:"+dataLineageInfo.getProcName()); |
|||
} |
|||
targetSqlList.add(sql); |
|||
String defaultSchema = dataLineageInfo.getMdlName(); |
|||
String defaultSystem = dataLineageInfo.getSsysCd(); |
|||
this.parserContext.setDefaultDb(defaultSystem); |
|||
this.parserContext.setDefaultSchema(defaultSchema); |
|||
int length = targetSqlList.size(); |
|||
for (String s : targetSqlList) { |
|||
sqlText = s; |
|||
if ("ORACLE".equals(dbType)) { |
|||
if (Objects.equals(dbType, Oracle.toString())) { |
|||
if (sqlText != null) { |
|||
sqlText = sqlText.toUpperCase(); |
|||
} |
|||
} |
|||
sqlParser = new TGSqlParser(EDbVendor.dbvoracle); |
|||
} |
|||
if ("MYSQL".equals(dbType)) { |
|||
sqlParser = new TGSqlParser(EDbVendor.dbvmysql); |
|||
} |
|||
if ("SQLSERVER".equals(dbType)) { |
|||
sqlParser = new TGSqlParser(EDbVendor.dbvmssql); |
|||
} |
|||
if ("TERADATA".equals(dbType)) { |
|||
sqlParser = new TGSqlParser(EDbVendor.dbvteradata); |
|||
} |
|||
if ("POSTGRESQL".equals(dbType)) { |
|||
sqlParser = new TGSqlParser(EDbVendor.dbvpostgresql); |
|||
} |
|||
if ("DB2".equals(dbType)) { |
|||
sqlParser = new TGSqlParser(EDbVendor.dbvdb2); |
|||
} |
|||
sqlParser.sqltext = sqlText; |
|||
int ret = sqlParser.parse(); |
|||
List<KColumn> result = new ArrayList<>(); |
|||
if (ret == 0) { |
|||
TStatementList statementList = sqlParser.getSqlstatements(); |
|||
while (statementList.hasNext()) { |
|||
TCustomSqlStatement stmt = statementList.next(); |
|||
parserContext.getTableInCurrentStatement().clear(); |
|||
switch (stmt.sqlstatementtype) { |
|||
case sstselect: |
|||
result = parseSelect(stmt); |
|||
break; |
|||
case sstdelete: |
|||
result = parseDelete(stmt); |
|||
break; |
|||
case sstupdate: |
|||
result = parseUpdate(stmt); |
|||
break; |
|||
case sstinsert: |
|||
result = parseInsert(stmt); |
|||
break; |
|||
case sstcreatetable: |
|||
result = parseCreateTable(stmt); |
|||
break; |
|||
case sstcreateview: |
|||
break; |
|||
case sstoraclealtertablespace: |
|||
// parseAlterTable(stmt);
|
|||
break; |
|||
case sstdroptable: |
|||
// parseDropTable(stmt);
|
|||
break; |
|||
case sstmerge: |
|||
log.error("sstmerge[" |
|||
+ stmt.sqlstatementtype |
|||
+ "][unknow sql type]sqltext:" |
|||
); |
|||
default: |
|||
log.error("[" + stmt.sqlstatementtype |
|||
+ "][unknow sql type]sqltext:" |
|||
); |
|||
break; |
|||
} |
|||
} |
|||
} else { |
|||
log.error(sqlParser.sqltext + sqlParser.getErrormessage()); |
|||
} |
|||
if (result.size() > 0) { |
|||
exportParseResultUtil.expResult(result, dataLineageInfo); |
|||
} |
|||
} |
|||
} catch (Exception e) { |
|||
e.printStackTrace(); |
|||
} |
|||
} |
|||
|
|||
private String optDeclare(String sql,String procName) { |
|||
String returnSql=sql; |
|||
if(StringUtils.isNotEmpty(sql)){ |
|||
//储存过程名称
|
|||
String[] sqls = sql.split(";"); |
|||
for(String sql2:sqls){ |
|||
sql2 = sql2.trim(); |
|||
//去掉set和 truncate和delete语句 还有引用其他存储过程的语句
|
|||
if(sql2.startsWith("SET")||sql2.startsWith("TRUNCATE")||sql2.startsWith("DELETE")||sql2.startsWith("PERFORM")){ |
|||
sql = sql.replace(sql2+";", ""); |
|||
} |
|||
|
|||
// String dd = sql2.replaceAll(" ", "");
|
|||
// int startIndex = dd.toUpperCase().lastIndexOf("PROCEDURE");
|
|||
// if(startIndex >= 0){
|
|||
// startIndex += "PROCEDURE".length();
|
|||
// int endIndex = dd.indexOf("(");
|
|||
// if(endIndex >= 0){
|
|||
// procName = dd.substring(startIndex, endIndex);
|
|||
// }
|
|||
// }
|
|||
/* |
|||
Pattern pat = Pattern.compile("(DECLARE)(\\s*)"); |
|||
Matcher mat = pat.matcher(sql2); |
|||
if (mat.find()) { |
|||
sql2 = mat.replaceAll(""); |
|||
String sub = sql2.substring(0,sql2.indexOf(" ")).trim(); |
|||
if(sql.contains(sub)){ |
|||
sql = sql.replaceAll(sub, "'88888888'"); |
|||
} |
|||
}*/ |
|||
} |
|||
Pattern pat = Pattern.compile("(DECLARE)(\\s).*"); |
|||
Matcher mat = pat.matcher(sql); |
|||
while (mat.find()) { |
|||
sql = mat.replaceAll(""); |
|||
} |
|||
|
|||
//找出脚本结束的位置
|
|||
Pattern lastPattern = Pattern.compile("(END)(\\s)+"+("".equals(procName)?";":procName)); |
|||
Matcher lastMatcher = lastPattern.matcher(sql); |
|||
if(lastMatcher.find()){ |
|||
int lastIndex = lastMatcher.start(); |
|||
if(sql.contains("BEGIN")){ |
|||
returnSql = sql.substring(sql.indexOf("BEGIN")+5, lastIndex); |
|||
}else{ |
|||
returnSql = sql.substring(0, lastIndex); |
|||
} |
|||
}else{ |
|||
Pattern tempPattern = Pattern.compile("(END)(\\s)*;"); |
|||
Matcher tempMatcher = tempPattern.matcher(sql); |
|||
Pattern tempPatternBegin = Pattern.compile("(\\s)(BEGIN)(\\s)"); |
|||
Matcher tempMatcherBegin = tempPatternBegin.matcher(sql); |
|||
|
|||
if(tempMatcher.find()){ |
|||
int tempIndex = tempMatcher.start(); |
|||
int tempIndexBegin = 0; |
|||
if(tempMatcherBegin.find()){ |
|||
tempIndexBegin = tempMatcherBegin.start(); |
|||
} |
|||
returnSql = sql.substring(tempIndexBegin+6, tempIndex); |
|||
} |
|||
} |
|||
|
|||
} |
|||
return returnSql; |
|||
} |
|||
|
|||
private String optDeclare2(String sql) { |
|||
StringBuilder returnVal = new StringBuilder(); |
|||
if(StringUtils.isNotEmpty(sql)){ |
|||
|
|||
String[] sqls = sql.split(";"); |
|||
for(String sql2:sqls){ |
|||
sql2 = sql2.trim(); |
|||
//去掉set和 truncate和delete语句 还有引用其他存储过程的语句
|
|||
if(sql2.toUpperCase().trim().startsWith("INSERT")){ |
|||
returnVal.append(sql2.substring(sql2.toUpperCase().indexOf("INSERT"))).append(";\r\n"); |
|||
|
|||
}else if(sql2.toUpperCase().trim().startsWith("UPDATE")){ |
|||
returnVal.append(sql2.substring(sql2.toUpperCase().indexOf("UPDATE"))).append(";\r\n"); |
|||
|
|||
}else if(sql2.toUpperCase().trim().startsWith("MERGE")){ |
|||
//TODO wxl merge语句的解析暂时不支持,导致报错
|
|||
// returnVal.append(sql2.substring(sql2.toUpperCase().indexOf("MERGE"))+";\r\n");
|
|||
|
|||
}else if(sql2.toUpperCase().trim().startsWith("CREATE")){ |
|||
returnVal.append(sql2.substring(sql2.toUpperCase().indexOf("CREATE"))).append(";\r\n"); |
|||
|
|||
} |
|||
} |
|||
} |
|||
return returnVal.toString(); |
|||
} |
|||
|
|||
|
|||
private List<KColumn> parseAlterTable(TCustomSqlStatement stmt) { |
|||
TAlterTableStatement alterTableStatement=(TAlterTableStatement)stmt; |
|||
AlterParser parser=new AlterParser(alterTableStatement,parserContext); |
|||
parser.parse(); |
|||
return parser.getParseResult(); |
|||
} |
|||
|
|||
private List<KColumn> parseUpdate(TCustomSqlStatement stmt) { |
|||
TUpdateSqlStatement dStmt=(TUpdateSqlStatement)stmt; |
|||
UpdateParser parser=new UpdateParser(dStmt,parserContext); |
|||
parser.parse(); |
|||
return parser.getParseResult(); |
|||
} |
|||
|
|||
private List<KColumn> parseDelete(TCustomSqlStatement stmt) { |
|||
TDeleteSqlStatement dStmt=(TDeleteSqlStatement)stmt; |
|||
DeleteParser parser=new DeleteParser(dStmt,parserContext); |
|||
parser.parse(); |
|||
return parser.getParseResult(); |
|||
} |
|||
|
|||
private List<KColumn> parseInsert(TCustomSqlStatement stmt) { |
|||
InsertParser parser = applicationContext.getBean(InsertParser.class); |
|||
parser.setMInsertSql((TInsertSqlStatement)stmt); |
|||
parser.setMParserContext(this.parserContext); |
|||
parser.parse(); |
|||
return parser.getParseResult(); |
|||
} |
|||
|
|||
// private void parseDropTable(TCustomSqlStatement stmt) {
|
|||
// DropParser dp=new DropParser(stmt,parserContext);
|
|||
// dp.parse();
|
|||
// }
|
|||
|
|||
public List<KColumn> parseCreateTable(TCustomSqlStatement stmt) { |
|||
TCreateTableSqlStatement ctSql=(TCreateTableSqlStatement)stmt; |
|||
CreateParser parser=new CreateParser(ctSql,parserContext); |
|||
parser.parse(); |
|||
return parser.getParseResult(); |
|||
} |
|||
|
|||
public List<KColumn> parseSelect(TCustomSqlStatement stmt) { |
|||
TSelectSqlStatement selectSqlStatement = (TSelectSqlStatement) stmt; |
|||
SelectParser parser=new SelectParser(selectSqlStatement,parserContext); |
|||
parser.parse(); |
|||
return parser.getParseResult(); |
|||
} |
|||
|
|||
} |
|||
@ -0,0 +1,145 @@ |
|||
package com.guozhi.bloodanalysis.parser.clean; |
|||
|
|||
import lombok.extern.slf4j.Slf4j; |
|||
|
|||
import java.util.regex.Matcher; |
|||
import java.util.regex.Pattern; |
|||
|
|||
@Slf4j |
|||
public class GenericLogNormalizer{ |
|||
|
|||
public String normalizer(String logstr,String dbType) { |
|||
String retVal=logstr.toUpperCase(); |
|||
if(retVal.length()>0){//说明存在有效内容
|
|||
// retVal = this.replaceYinhao(retVal);
|
|||
retVal = this.replaceFenhao(retVal); |
|||
retVal = this.replaceUnuseful(retVal); |
|||
retVal = this.dropUnuseful(retVal); |
|||
retVal = this.dropTableFix(retVal); |
|||
//替换出现在非查询结束状态中的升降序关键字ROW_NUMBER()OVER(PARTITION BY WORKDATE,AGENTSERIALNO DESC) AS NUM;
|
|||
retVal = this.replaceASC(retVal); |
|||
retVal = this.changeAlter(retVal); |
|||
if("GreenPlum".equals(dbType)){ |
|||
//GP类数据库清洗器
|
|||
retVal = new GenericLogNormalizerGP(retVal).parser(); |
|||
}else if("Oracle".equals(dbType)){ |
|||
//oracle类数据库清洗器
|
|||
retVal = new GenericLogNormalizerOra(retVal).parser(); |
|||
}else if("Teradata".equals(dbType)){ |
|||
//teradata类数据库清洗器
|
|||
retVal = new GenericLogNormalizerTrd(retVal).parser(); |
|||
}else if("DB2".equals(dbType)){ |
|||
//DB2类数据库清洗器
|
|||
//TODO 未实现
|
|||
retVal = new GenericLogNormalizerGP(retVal).parser(); |
|||
} |
|||
} |
|||
return retVal.trim(); |
|||
} |
|||
|
|||
private String replaceUnuseful(String retVal) { |
|||
|
|||
Pattern pat = Pattern.compile("--'\\s*\\|\\|"); |
|||
Matcher mat = pat.matcher(retVal); |
|||
while (mat.find()) { |
|||
String s = mat.group(); |
|||
String _s = s.replaceAll("--", ""); |
|||
retVal = retVal.replace(s, _s); |
|||
} |
|||
|
|||
pat = Pattern.compile("FORMAT\\s*'--.*?'"); |
|||
mat = pat.matcher(retVal); |
|||
while (mat.find()) { |
|||
String s = mat.group(); |
|||
String _s = s.replaceAll("--", ""); |
|||
retVal = retVal.replace(s, _s); |
|||
} |
|||
return retVal; |
|||
} |
|||
|
|||
private String replaceFenhao(String str) { |
|||
Pattern pat = Pattern.compile("'(\\s|\\d|;|\\||%)*(;)+(\\s|\\d|;|\\||%)*'"); |
|||
Matcher mat = pat.matcher(str); |
|||
while (mat.find()) { |
|||
str = mat.replaceAll("\\'fenhao\\'"); |
|||
} |
|||
return str ; |
|||
} |
|||
|
|||
private String dropUnuseful(String retVal) { |
|||
Pattern p = Pattern.compile("(?ms)(--.*?$)|(/\\*.*?\\*/)"); |
|||
retVal = p.matcher(retVal).replaceAll(""); //去掉/*...*/的多行注释,和以 -- 开始的单行注释
|
|||
log.info("去除/*...*/和以 -- 开始的单行注释,取出BEGIN,END等多余字符 , 成功"); |
|||
return retVal; |
|||
} |
|||
|
|||
private String dropTableFix(String str) { |
|||
Pattern pat = Pattern.compile("(((_1_PRT_P)|(_1_PRT_SDB))_PARTITION_(\\$)(\\w)*(\\s))"); |
|||
Matcher mat = pat.matcher(str); |
|||
while (mat.find()) { |
|||
str = mat.replaceAll(" "); |
|||
} |
|||
pat = Pattern.compile("(((_1_PRT_P)|(_1_PRT_SDB))_PARTITION_(\\$\\{)(\\s)*(\\w)*(\\s)*(\\})(\\s))"); |
|||
mat = pat.matcher(str); |
|||
while (mat.find()) { |
|||
str = mat.replaceAll(" "); |
|||
} |
|||
pat = Pattern.compile("(((_1_PRT_P)|(_1_PRT_SDB))_PARTITION_(\\d)+(\\s))"); |
|||
mat = pat.matcher(str); |
|||
while (mat.find()) { |
|||
str = mat.replaceAll(" "); |
|||
} |
|||
|
|||
return str; |
|||
} |
|||
|
|||
private String replaceASC(String str) { |
|||
Pattern pat = Pattern.compile("(\\bASC\\b)|(\\bDESC\\b)"); |
|||
Matcher mat = pat.matcher(str); |
|||
while (mat.find()) { |
|||
str = mat.replaceAll(""); |
|||
} |
|||
return str; |
|||
} |
|||
|
|||
private String changeAlter(String str){ |
|||
//String str_change =str;
|
|||
Pattern pat = Pattern.compile("(?ms)(ALTER)(\\s)+(TABLE)(\\s)+(\\w)+(\\.)*(\\w)*(\\s)*" + |
|||
"(EXCHANGE)(\\s)*(PARTITION)(\\s)+(\\w)+(\\s)+(WITH)(\\s)+" + |
|||
"(TABLE)(\\s)+(\\w)+(\\.)*(\\w)*(\\s)*;"); |
|||
Matcher mat = pat.matcher(str); |
|||
String dest_table =""; |
|||
String source_table =""; |
|||
while(mat.find()){ |
|||
String sen = mat.group(); |
|||
dest_table = sen.substring(sen.indexOf("ALTER")+"ALTER".length(),sen.indexOf("EXCHANGE")).trim(); |
|||
dest_table = dest_table.substring("table".length()).trim(); |
|||
source_table = sen.substring(sen.indexOf("WITH")+"WITH".length(),sen.indexOf(";")).trim(); |
|||
source_table = source_table.substring("table".length()).trim(); |
|||
str=str.replace(sen,"ALTER TABLE "+source_table+" RENAME TO "+ dest_table+" ;"); |
|||
} |
|||
return str; |
|||
} |
|||
|
|||
public static void main(String[] args) { |
|||
//------------------------------------------------TRIM(COALESCE(t2.brch_no),'')
|
|||
// String sql = "COALESCE(TRIM(A.COD_ACCT_NO_BENEF)||TRIM(CAST(A.CTR_SWP_INST_NO AS INTEGER)),'')";
|
|||
String sql = "TRIM(COALESCE(t2.brch_no),'')"; |
|||
Pattern p = Pattern.compile("(\\s*)(TRIM)(\\s*)\\((\\w+)\\(((\\w|\\.)+)\\)(\\s*)(,(\\s*)'')(\\s*)\\)"); |
|||
// sql = p.matcher(sql).replaceAll(" ");
|
|||
// System.out.println(sql.trim());
|
|||
Matcher mat = p.matcher(sql); |
|||
while(mat.find()){ |
|||
System.out.println(mat.group()); |
|||
System.out.println("1="+mat.group(1)); |
|||
System.out.println("2="+mat.group(2)); |
|||
System.out.println("3="+mat.group(3)); |
|||
System.out.println("4="+mat.group(4)); |
|||
System.out.println("5="+mat.group(5)); |
|||
System.out.println("6="+mat.group(6)); |
|||
System.out.println("7="+mat.group(7)); |
|||
System.out.println("8="+mat.group(8)); |
|||
System.out.println("9="+mat.group(9)); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,95 @@ |
|||
package com.guozhi.bloodanalysis.parser.clean; |
|||
|
|||
import java.util.regex.Matcher; |
|||
import java.util.regex.Pattern; |
|||
|
|||
public class GenericLogNormalizerGP { |
|||
private String retVal; |
|||
|
|||
public GenericLogNormalizerGP (String retVal){ |
|||
this.retVal = retVal; |
|||
} |
|||
|
|||
public String parser(){ |
|||
dropgangt(); |
|||
dropInvSql(); |
|||
replaceSpecial(); |
|||
setSpecialFun();//替换 DATE '';
|
|||
return retVal; |
|||
} |
|||
|
|||
|
|||
private void dropInvSql(){ |
|||
/** |
|||
* 去除DISTRIBUTED 原来: (GROUP|DISTRIBUTED)(\\s)+(BY)*(.*?)\\) |
|||
*/ |
|||
Pattern pat = Pattern.compile("(?ms)(GROUP|DISTRIBUTED)(\\s)+(BY)(\\s)*\\((.*?)\\)"); |
|||
retVal = pat.matcher(retVal.toUpperCase()).replaceAll(""); |
|||
pat = Pattern.compile("\\bROW\\b"); |
|||
Matcher mat = pat.matcher(retVal); |
|||
while (mat.find()) { |
|||
retVal = mat.replaceAll("ROW_SYMBOLYANG1111"); |
|||
} |
|||
} |
|||
|
|||
private void dropgangt() { |
|||
Pattern pat = Pattern.compile("(?ms)\\\\\\\\[a-zA-Z]+([a-zA-Z]|\\s|\\\\\\\\)*?$"); |
|||
Matcher mat = pat.matcher(retVal); |
|||
while(mat.find()){ |
|||
retVal = mat.replaceAll("\n"); |
|||
} |
|||
} |
|||
|
|||
|
|||
private void replaceSpecial() { |
|||
/** |
|||
* 将剩下的 ${}替换掉 |
|||
*/ |
|||
Pattern pat = Pattern.compile("\\$\\{[\\w]*\\}"); |
|||
|
|||
Matcher mat = pat.matcher(retVal); |
|||
|
|||
while(mat.find()){ |
|||
retVal = retVal.replace(mat.group(),"defaultMODEL_"+mat.group().substring(2,mat.group().length() - 1 )); |
|||
} |
|||
/** |
|||
* 将剩下的 $替换掉 |
|||
*/ |
|||
retVal = retVal.replace("$", "defaultMODEL_"); |
|||
/** |
|||
* 去除%等特殊符号 |
|||
*/ |
|||
retVal=retVal.replace("%", "/"); |
|||
retVal=retVal.replace("?", " "); |
|||
} |
|||
|
|||
private void setSpecialFun(){ |
|||
//(date(... --- (date( ...
|
|||
retVal = retVal.replaceAll("(\\()(\\s)*(d|D)(a|A)(t|T)(e|E)(\\s)*\\(", "(datetime("); |
|||
//(date'...' ---(date '...'
|
|||
retVal = retVal.replaceAll("(\\()(\\s)*(d|D)(a|A)(t|T)(e|E)(\\s)*'", "(datetime'"); |
|||
/** |
|||
* 运算符号要包括 |
|||
*/ |
|||
//,date(... --- ,(date (...
|
|||
retVal = retVal.replaceAll(",(\\s)*(d|D)(a|A)(t|T)(e|E)(\\s)*\\(", ",datetime("); |
|||
//,date'... --- ,date '...
|
|||
retVal = retVal.replaceAll(",(\\s)*(d|D)(a|A)(t|T)(e|E)(\\s)*'", ",datetime'"); |
|||
|
|||
retVal = retVal.replaceAll("=(\\s)*(d|D)(a|A)(t|T)(e|E)(\\s)*\\(", "=datetime("); |
|||
retVal = retVal.replaceAll("=(\\s)*(d|D)(a|A)(t|T)(e|E)(\\s)*'", "=datetime'"); |
|||
|
|||
retVal = retVal.replaceAll("-(\\s)*(d|D)(a|A)(t|T)(e|E)(\\s)*\\(", "-datetime("); |
|||
retVal = retVal.replaceAll("-(\\s)*(d|D)(a|A)(t|T)(e|E)(\\s)*'", "-datetime'"); |
|||
|
|||
retVal = retVal.replaceAll("(>|<|>=|<=)(\\s)*(d|D)(a|A)(t|T)(e|E)(\\s)*\\(", ">datetime("); |
|||
retVal = retVal.replaceAll("(>|<|>=|<=)(\\s)*(d|D)(a|A)(t|T)(e|E)(\\s)*'", ">datetime'"); |
|||
|
|||
// date ... ---
|
|||
//retVal = retVal.replaceAll("(\\s)+(d|D)(a|A)(t|T)(e|E)(\\s)+", " datetime ");
|
|||
// date'... --- date '...
|
|||
retVal = retVal.replaceAll("(\\s)+(d|D)(a|A)(t|T)(e|E)(\\s)*'", " datetime'"); |
|||
// date(... --- date (...
|
|||
retVal = retVal.replaceAll("(\\s)+(d|D)(a|A)(t|T)(e|E)(\\s)*\\(", " datetime("); |
|||
} |
|||
} |
|||
@ -0,0 +1,74 @@ |
|||
package com.guozhi.bloodanalysis.parser.clean; |
|||
|
|||
import java.util.regex.Matcher; |
|||
import java.util.regex.Pattern; |
|||
|
|||
public class GenericLogNormalizerOra { |
|||
private String retVal; |
|||
|
|||
public GenericLogNormalizerOra (String retVal){ |
|||
this.retVal = retVal; |
|||
} |
|||
|
|||
public String parser(){ |
|||
dropInvSql(); |
|||
replaceSpecial(); |
|||
return retVal; |
|||
} |
|||
|
|||
private void replaceSpecial() { |
|||
/** |
|||
* 将剩下的 ${}替换掉 |
|||
*/ |
|||
Pattern pat = Pattern.compile("\\$\\{[\\w]*\\}"); |
|||
|
|||
Matcher mat = pat.matcher(retVal); |
|||
|
|||
while(mat.find()){ |
|||
retVal = retVal.replace(mat.group(),"defaultMODEL_"+mat.group().substring(2,mat.group().length() - 1 )); |
|||
} |
|||
/** |
|||
* 将剩下的 $替换掉 |
|||
*/ |
|||
retVal=retVal.replace("$", "defaultMODEL_"); |
|||
/** |
|||
* 去除%等特殊符号 |
|||
*/ |
|||
retVal=retVal.replace("%", "/"); |
|||
} |
|||
|
|||
|
|||
private void dropInvSql(){ |
|||
/* |
|||
Pattern p = Pattern.compile("((\\s)+(SET).*(\\s)+)"); |
|||
retVal = p.matcher(retVal).replaceAll(""); |
|||
*/ |
|||
/** |
|||
* 去除DISTRIBUTED |
|||
*/ |
|||
Pattern p = Pattern.compile("(?ms)(GROUP|DISTRIBUTED)(\\s)+(BY)(\\s)*\\((.*?)\\)"); |
|||
retVal = p.matcher(retVal.toUpperCase()).replaceAll(""); |
|||
|
|||
p = Pattern.compile("((WHENEVER(\\s*)SQLERROR)(\\s)*.*)"); |
|||
retVal = p.matcher(retVal).replaceAll(""); |
|||
|
|||
p = Pattern.compile("((SPOOL)(\\s)*.*)"); |
|||
retVal = p.matcher(retVal).replaceAll(""); |
|||
|
|||
p = Pattern.compile("((COMMIT)(\\s)*;)"); |
|||
retVal = p.matcher(retVal).replaceAll(""); |
|||
|
|||
p = Pattern.compile("CALL(\\s)+(.*?)\\);"); |
|||
retVal = p.matcher(retVal.toUpperCase()).replaceAll(""); |
|||
|
|||
p = Pattern.compile("((EXIT)(\\s)*;)"); |
|||
retVal = p.matcher(retVal.toUpperCase()).replaceAll(" "); |
|||
|
|||
p = Pattern.compile("(\\s*)(CONNECT)(\\s*)(.*?)(/|\\\\)(.*?)(/|\\\\)(@)(.*?);"); |
|||
retVal = p.matcher(retVal.toUpperCase()).replaceAll(" "); |
|||
|
|||
if(retVal.lastIndexOf("EOF")!=-1){ |
|||
retVal = retVal.substring(0,retVal.lastIndexOf("EOF")).trim(); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,115 @@ |
|||
package com.guozhi.bloodanalysis.parser.clean; |
|||
|
|||
import java.util.regex.Matcher; |
|||
import java.util.regex.Pattern; |
|||
|
|||
public class GenericLogNormalizerTrd { |
|||
private String retVal; |
|||
|
|||
public GenericLogNormalizerTrd (String retVal){ |
|||
this.retVal = retVal; |
|||
} |
|||
|
|||
public String parser(){ |
|||
dropgangt(); |
|||
replaceSpecial(); |
|||
dropNoStdSql(); |
|||
return retVal; |
|||
} |
|||
|
|||
|
|||
private void dropgangt() { |
|||
Pattern pat = Pattern.compile("(?ms)\\\\\\\\[a-zA-Z]+([a-zA-Z]|\\s|\\\\\\\\)*?$"); |
|||
Matcher mat = pat.matcher(retVal); |
|||
while(mat.find()){ |
|||
retVal = mat.replaceAll("\n"); |
|||
} |
|||
} |
|||
|
|||
|
|||
private void replaceSpecial() { |
|||
/** |
|||
* 将剩下的'${}'替换掉 |
|||
*/ |
|||
Pattern pat = Pattern.compile("\\$\\{[\\w]*\\}\\s*(>|=|<|LIKE|>=|=>|<=|=<|<>)\\s*\\$\\{[\\w]*\\}"); |
|||
|
|||
Matcher mat = pat.matcher(retVal); |
|||
|
|||
while(mat.find()){ |
|||
retVal = retVal.replace(mat.group(), "'1' = '1'"); |
|||
} |
|||
|
|||
/** |
|||
* 先替换一次带有''${}的特殊变量 |
|||
*/ |
|||
pat = Pattern.compile("(>|=|<|LIKE|>=|=>|<=|=<|<>)\\s*\\$\\{[\\w]*\\}"); |
|||
mat = pat.matcher(retVal); |
|||
|
|||
while(mat.find()){ |
|||
retVal = retVal.replace(mat.group()," = '1'"); |
|||
} |
|||
|
|||
/** |
|||
* 将剩下的${}替换掉 |
|||
*/ |
|||
pat = Pattern.compile("\\$\\{[\\w]*\\}"); |
|||
|
|||
mat = pat.matcher(retVal); |
|||
|
|||
while(mat.find()){ |
|||
retVal = retVal.replace(mat.group(),""); |
|||
} |
|||
|
|||
/** |
|||
* 将剩下的';'替换掉 |
|||
*/ |
|||
pat = Pattern.compile("'(.*?);(.*?)'"); |
|||
mat = pat.matcher(retVal); |
|||
while (mat.find()) { |
|||
String s = mat.group(); |
|||
String _s = s.replace(";", ";"); |
|||
retVal = retVal.replace(s, _s); |
|||
} |
|||
|
|||
/** |
|||
* 去除%等特殊符号 |
|||
*/ |
|||
retVal=retVal.replace("%", "/"); |
|||
retVal=retVal.replace("?", " "); |
|||
} |
|||
|
|||
private void dropNoStdSql(){ |
|||
String pattern = "^CREATE.*|^SELECT.*|^INSERT.*|^ALTER.*"; |
|||
Pattern pat = Pattern.compile(pattern); |
|||
String retVals [] = retVal.split(";"); |
|||
retVal = ""; |
|||
for (String _retVal : retVals) { |
|||
_retVal = _retVal.toUpperCase().trim(); |
|||
_retVal = dorpLockingSql(_retVal); |
|||
Matcher mat = pat.matcher(_retVal); |
|||
while(mat.find()){ |
|||
retVal +=_retVal+";"; |
|||
} |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* 广农商的存在这个句型20170216 |
|||
* 去除LOCKING TABLE 。。。FOR ACCESS句型 |
|||
* @param val |
|||
*/ |
|||
private String dorpLockingSql(String val){ |
|||
String res = null; |
|||
String startPattern = "^(LOCKING)\\s*(TABLE)\\s.*(FOR\\s*ACCESS)\\s+[\\s\\S]*"; |
|||
if(val.matches(startPattern)) { |
|||
String keyPat = "FOR\\s*ACCESS?"; |
|||
Matcher m = Pattern.compile(keyPat).matcher(val); |
|||
int keyEnd = 0; |
|||
if(m.find()) { |
|||
keyEnd=m.end(); |
|||
res = val.substring(keyEnd); |
|||
} |
|||
} |
|||
return res == null ? val : res.trim(); |
|||
} |
|||
} |
|||
@ -0,0 +1,62 @@ |
|||
package com.guozhi.bloodanalysis.parser.common; |
|||
|
|||
import java.util.List; |
|||
|
|||
import com.guozhi.bloodanalysis.parser.vo.KColumn; |
|||
import com.guozhi.bloodanalysis.parser.vo.VTable; |
|||
import gudusoft.gsqlparser.nodes.TAlterTableOptionList; |
|||
import gudusoft.gsqlparser.nodes.TObjectName; |
|||
import gudusoft.gsqlparser.stmt.TAlterTableStatement; |
|||
import org.springframework.context.annotation.Bean; |
|||
import org.springframework.stereotype.Component; |
|||
|
|||
/** |
|||
* Created by Walk.Lai on 2015/8/29. |
|||
*/ |
|||
public class AlterParser { |
|||
private TAlterTableStatement mStmt;//table, view
|
|||
private List<KColumn> mColumns; |
|||
|
|||
private VTable mTable; |
|||
private ParserContext mParserContext; |
|||
|
|||
public AlterParser(TAlterTableStatement alterSql,ParserContext context){ |
|||
mStmt =alterSql; |
|||
this.mParserContext=context; |
|||
} |
|||
|
|||
public void parse() { |
|||
//alter table exchange partition with table
|
|||
// --将新数据以交换分区方式插入目标表
|
|||
// ALTER TABLE IML_DB.EV_EVENT_PROD_RELA EXCHANGE SUBPARTITION P_1008_1111 WITH TABLE IML_DB.VT_NEW_1008;
|
|||
/* |
|||
例如 ALTER TABLE $PDM_SCH.PD_BCC_3F_TRAN_INFO RENAME TO PD_BCC_3F_TRAN_INFO_EXCHANGE2; |
|||
ALTER TABLE $PDM_SCH.PD_BCC_3F_TRAN_INFO_EXCHANGE RENAME TO PD_BCC_3F_TRAN_INFO; |
|||
tempTable -- $PDM_SCH.PD_BCC_3F_TRAN_INFO_EXCHANGE |
|||
targetTable -- PD_BCC_3F_TRAN_INFO |
|||
*/ |
|||
String tempTableName = null; |
|||
String targetTableName = null; |
|||
TObjectName obj = mStmt.getTableName(); |
|||
if (obj!=null) { |
|||
tempTableName = obj.toString(); |
|||
} |
|||
TAlterTableOptionList oplist = mStmt.getAlterTableOptionList(); |
|||
if (oplist!=null) { |
|||
for (int i = 0; i < oplist.size(); i++) { |
|||
String option = oplist.getAlterTableOption(i).toString(); |
|||
if (option.contains("RENAME")&&option.contains(" TO ")) { |
|||
targetTableName = option.substring(option.indexOf(" TO ")+" TO ".length()).trim(); |
|||
targetTableName = targetTableName.replace("SYMBOLALTERPOINT", "."); |
|||
// targetTableName = this.addAlterSchema(tempTableName,targetTableName);
|
|||
break; |
|||
} |
|||
} |
|||
} |
|||
|
|||
} |
|||
public List<KColumn> getParseResult() { |
|||
return null; |
|||
} |
|||
|
|||
} |
|||
@ -0,0 +1,128 @@ |
|||
/* |
|||
Copyright 2015 Dell Inc. |
|||
ALL RIGHTS RESERVED. |
|||
*/ |
|||
/* |
|||
Copyright 2015 Dell Inc. |
|||
ALL RIGHTS RESERVED. |
|||
*/ |
|||
package com.guozhi.bloodanalysis.parser.common; |
|||
import com.guozhi.bloodanalysis.parser.utils.KColumnProvider; |
|||
import com.guozhi.bloodanalysis.parser.utils.KDatabaseProvider; |
|||
import com.guozhi.bloodanalysis.parser.utils.SpUtils; |
|||
import com.guozhi.bloodanalysis.parser.vo.KColumn; |
|||
import com.guozhi.bloodanalysis.parser.vo.VTable; |
|||
import gudusoft.gsqlparser.nodes.TTable; |
|||
import gudusoft.gsqlparser.stmt.TSelectSqlStatement; |
|||
import lombok.NoArgsConstructor; |
|||
import org.apache.commons.lang3.StringUtils; |
|||
import org.springframework.beans.factory.annotation.Autowired; |
|||
import org.springframework.context.ApplicationContext; |
|||
import org.springframework.stereotype.Component; |
|||
|
|||
import java.util.ArrayList; |
|||
import java.util.List; |
|||
|
|||
@Component |
|||
@NoArgsConstructor |
|||
public class AsTableParser extends BaseParser{ |
|||
private TTable tTable; |
|||
private boolean mKeepConstant=false;//是否保留常量值
|
|||
private ParserContext mParserContext; |
|||
private VTable vTable;//将整个查询语句当成一个表进行处理
|
|||
|
|||
@Autowired |
|||
ApplicationContext applicationContext; |
|||
|
|||
@Autowired |
|||
KDatabaseProvider kDatabaseProvider; |
|||
|
|||
public AsTableParser(TTable tTable,ParserContext context) { |
|||
this.tTable = tTable; |
|||
vTable = new VTable(SpUtils.generateId(tTable.toString(),"")); |
|||
this.mParserContext=context; |
|||
} |
|||
|
|||
public void parse() { |
|||
//TODO 将CTE转化为表关系
|
|||
mParserContext.setCurrentTable(vTable); |
|||
VTable sVTable = analyseTable(tTable); |
|||
sVTable.addColumns(new KColumnProvider().getColumns(sVTable, null, mParserContext)); |
|||
vTable.addTable(sVTable); |
|||
mParserContext.setCurrentTable(vTable); |
|||
vTable.addColumns(sVTable.getColumns()); |
|||
mParserContext.addVTable( vTable); |
|||
} |
|||
|
|||
|
|||
private VTable analyseTable(TTable table){ |
|||
String fullName=table.getFullName(); |
|||
String tableAlias=table.getAliasName(); |
|||
VTable vTable=null; |
|||
if(StringUtils.isBlank(fullName)){//子查询,fullName为空
|
|||
vTable=new VTable(SpUtils.generateId(table.toString(),tableAlias)); |
|||
}else{//普通表名//StringUtils.isNotBlank(fullName)
|
|||
String[] nameInfo=SpUtils.analyseTableName(fullName); |
|||
vTable=new VTable(nameInfo[2],nameInfo[2]); |
|||
vTable.db=mParserContext.getDefaultDb(); |
|||
vTable.schema=mParserContext.getDefaultSchema(); |
|||
} |
|||
if(StringUtils.isNotBlank(tableAlias)){ |
|||
vTable.setAlias(tableAlias); |
|||
} |
|||
|
|||
//已知的表
|
|||
VTable createdTable = mParserContext.findExistedTable(vTable.getFullName(),true); |
|||
if(createdTable!=null) { |
|||
createdTable.setAlias(vTable.alias); |
|||
return createdTable; |
|||
} |
|||
|
|||
switch (table.getTableType()) { |
|||
case objectname: |
|||
//真实数据库中的表,查找表对应系统,可能存在多个情况
|
|||
kDatabaseProvider.getDatabase(vTable, mParserContext); |
|||
break; |
|||
case subquery: |
|||
TSelectSqlStatement subQuery = table.getSubquery(); |
|||
// VTable currentTable=mParserContext.getCurrentTable();
|
|||
SelectParser sp = applicationContext.getBean(SelectParser.class); |
|||
sp.initWithTable(subQuery,mParserContext,vTable,mKeepConstant); |
|||
sp.parse(); |
|||
// mParserContext.setCurrentTable(vTable);
|
|||
//创建依赖关系 重复了。。。。。。。。。。
|
|||
// vTable.addColumns(sp.getParseResult());
|
|||
// vTable.getFromTables().addAll(sp.vTable.getFromTables());
|
|||
break; //subquery
|
|||
|
|||
case function: |
|||
// table.getFuncCall();
|
|||
break; |
|||
case tableExpr:break; |
|||
case rowList:break; |
|||
//SQL Server only
|
|||
case containsTable:break; |
|||
case freetextTable:break; |
|||
|
|||
default:break; |
|||
} |
|||
mParserContext.addVTable(vTable); |
|||
return vTable; |
|||
} |
|||
|
|||
public List<KColumn> getParseResult() { |
|||
List<KColumn> ret=new ArrayList<>(); |
|||
for(KColumn column: vTable.getColumns()){ |
|||
if(column==null){ |
|||
ret.add(column); |
|||
}else { |
|||
if (column.isStar) { |
|||
ret.addAll(column.getRefColumns()); |
|||
} else { |
|||
ret.add(column); |
|||
} |
|||
} |
|||
} |
|||
return ret; |
|||
} |
|||
} |
|||
@ -0,0 +1,202 @@ |
|||
package com.guozhi.bloodanalysis.parser.common; |
|||
|
|||
import com.guozhi.bloodanalysis.parser.vo.KColumn; |
|||
import com.guozhi.bloodanalysis.parser.vo.VTable; |
|||
|
|||
import java.util.ArrayList; |
|||
import java.util.HashMap; |
|||
import java.util.List; |
|||
import java.util.Map; |
|||
import java.util.regex.Matcher; |
|||
import java.util.regex.Pattern; |
|||
|
|||
|
|||
public class BaseParser { |
|||
|
|||
public void getResultParser(ParserContext mParserContext, VTable tTable, List<KColumn> mColumns){ |
|||
VTable currTable = mParserContext.getCurrentTable(); |
|||
if(currTable==null){ |
|||
return; |
|||
} |
|||
Map<String,VTable> tables = new HashMap<String, VTable>(); |
|||
if(mColumns!=null){ |
|||
//先清理一遍空表字段对象,并从目标找到最终源字段
|
|||
cleanNullTabCol(mParserContext, tTable, mColumns); |
|||
//开始验证当前SQL中的源表是否都存在结果对象中,如果不存在则需要创建一个默认字段,做到目标-源表的关系
|
|||
List<VTable> sTables = currTable.getFromTables(); |
|||
for (VTable sTable : sTables) { |
|||
childTable(mParserContext, tTable, sTable, mColumns, tables); |
|||
} |
|||
} |
|||
} |
|||
|
|||
|
|||
/*** |
|||
* 清空目标表,并从找到源字段 |
|||
* @param mParserContext |
|||
* @param tTable |
|||
* @param mColumns |
|||
*/ |
|||
private void cleanNullTabCol(ParserContext mParserContext,VTable tTable,List<KColumn> mColumns){ |
|||
//记录需要删除的目标列对象
|
|||
List<KColumn> delTCols = new ArrayList<KColumn>(); |
|||
for (int i = 0; i < mColumns.size(); i++) { |
|||
KColumn tCol = mColumns.get(i); |
|||
List<KColumn> sCols = tCol.getRefColumns(); |
|||
//删除对象集合
|
|||
List<KColumn> delSCols = new ArrayList<KColumn>(); |
|||
//调整级别的对象
|
|||
List<KColumn> addSCols = new ArrayList<KColumn>(); |
|||
Map<String,KColumn> sMap = new HashMap<String, KColumn>(); |
|||
//开始迭代子级判断获得最终的列对象
|
|||
childColumn(sCols, delSCols,addSCols,sMap,false); |
|||
//有调整列级别的
|
|||
if(addSCols.size()>0){ |
|||
for (KColumn kColumn : addSCols) { |
|||
sCols.add(kColumn); |
|||
} |
|||
} |
|||
//删除空白记录
|
|||
for (int j = 0; j < delSCols.size(); j++) { |
|||
sCols.remove(delSCols.get(j)); |
|||
} |
|||
|
|||
if(sCols.size()<=0){ |
|||
delTCols.add(tCol); |
|||
} |
|||
} |
|||
//删除没有源的目标记录
|
|||
if(delTCols.size()>0){ |
|||
for (int i = 0; i < delTCols.size(); i++) { |
|||
mColumns.remove(delTCols.get(i)); |
|||
} |
|||
} |
|||
} |
|||
|
|||
private void childColumn(List<KColumn> sCols,List<KColumn> delSCols,List<KColumn> addSCols,Map<String,KColumn> sMap,boolean isChild){ |
|||
for (KColumn sCol : sCols) { |
|||
//有表别名,但没有表名称,是一个子查询(select t.col from (select col from table) t )
|
|||
List<KColumn> _sCols = sCol.getRefColumns(); |
|||
//还有来源,继续往下走,一直走到最后一层级获取源头字段是谁
|
|||
if(_sCols.size()>0){ |
|||
isChild = true; |
|||
delSCols.add(sCol); |
|||
childColumn(sCol.getRefColumns(), delSCols, addSCols,sMap,isChild); |
|||
}else{ |
|||
if(sCol.tableName!=null){ |
|||
if(isChild){ |
|||
String colKey = sCol.db+"."+sCol.schema+"."+sCol.tableName+"."+sCol.columnName; |
|||
if(sMap.containsKey(colKey)){ |
|||
delSCols.add(sCol); |
|||
}else{ |
|||
String pattern = "(^'.*'$)|(^\\d+$)"; |
|||
Pattern pat = Pattern.compile(pattern); |
|||
Matcher mat = pat.matcher(sCol.columnName.toUpperCase().trim()); |
|||
if(mat.find()){ |
|||
delSCols.add(sCol); |
|||
}else{ |
|||
sMap.put(colKey, sCol); |
|||
addSCols.add(sCol); |
|||
} |
|||
} |
|||
} |
|||
}else{ |
|||
delSCols.add(sCol); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
private void childTable(ParserContext mParserContext,VTable tTable,VTable sTable,List<KColumn> mColumns,Map<String,VTable> tables){ |
|||
if(sTable.isRealTable()){ |
|||
//判断源表是否存在
|
|||
isSourceTableExis(tables, sTable, tTable, mParserContext, mColumns); |
|||
}else{ |
|||
List<VTable> sTbles = sTable.getFromTables(); |
|||
for (VTable sCTable : sTbles) { |
|||
//判断源表是否都存在
|
|||
childTable(mParserContext, tTable, sCTable, mColumns, tables); |
|||
} |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* 源表是否存在 |
|||
* @param tables 源表Map集合 |
|||
* @param sTable 源表 |
|||
* @param tTable 目标表 |
|||
* @param mParserContext sql上下文 |
|||
* @param mColumns 目标表字段 |
|||
*/ |
|||
private void isSourceTableExis(Map<String,VTable> tables,VTable sTable,VTable tTable,ParserContext mParserContext,List<KColumn> mColumns){ |
|||
//源表主键KEY
|
|||
String tabKey = sTable.db+"."+sTable.schema+"."+sTable.name; |
|||
boolean isTableExis = false; |
|||
//如果已经进行过验证,则退出
|
|||
if(tables.containsKey(tabKey)){ |
|||
return; |
|||
} |
|||
//开始迭代判断当前源表是否已经写入结果
|
|||
for (int i = 0; i < mColumns.size(); i++) { |
|||
KColumn tCol = mColumns.get(i); |
|||
List<KColumn> sCols = tCol.getRefColumns(); |
|||
//开始迭代查找
|
|||
isTableExis = childColumn(sCols, tabKey); |
|||
if(isTableExis){ |
|||
break; |
|||
} |
|||
} |
|||
if(sTable.isCreated()){ |
|||
//判断源表是否都存在,如果不存在,则建立源表与目标表的关系,字段建立一个默认字段
|
|||
if(!isTableExis){ |
|||
//目标
|
|||
KColumn tCol = new KColumn(); |
|||
//TODO wxl 对列名进行分析?解析不到字段级别,最终结果需要保留到表级
|
|||
tCol.columnName = "default_col"; |
|||
tCol.alias = "默认字段"; |
|||
|
|||
tCol.columnPrefix = tTable.getName(); |
|||
tCol.db=tTable.db; |
|||
tCol.schema=tTable.schema; |
|||
//表的状态是临时表还是实体表
|
|||
tCol.isEvTable = tTable.isCreated(); |
|||
tCol.tableName=tTable.getName(); |
|||
tCol.export=true; |
|||
|
|||
//源
|
|||
KColumn sCol = new KColumn(); |
|||
//TODO wxl 对列名进行分析?解析不到字段级别,最终结果需要保留到表级
|
|||
sCol.columnName = "default_col"; |
|||
sCol.alias = "默认字段"; |
|||
|
|||
sCol.columnPrefix = sTable.getName(); |
|||
sCol.db=sTable.db; |
|||
sCol.schema=sTable.schema; |
|||
sCol.tableName=sTable.getName(); |
|||
sCol.export=true; |
|||
//表的状态是临时表还是实体表
|
|||
sCol.isEvTable = sTable.isCreated(); |
|||
tCol.addRefColumn(sCol); |
|||
mColumns.add(tCol); |
|||
tables.put(tabKey, sTable); |
|||
} |
|||
} |
|||
} |
|||
|
|||
private boolean childColumn(List<KColumn> sCols,String tabKey){ |
|||
for (KColumn sCol : sCols) { |
|||
//源字段表主键KEY
|
|||
String tabColKey = sCol.db+"."+sCol.schema+"."+sCol.tableName; |
|||
if(tabColKey.toUpperCase().equals(tabKey.toUpperCase())){ |
|||
return true; |
|||
}else{ |
|||
//如果当前表不存在此层级,判断是否还有下一级继续找
|
|||
if(sCol.getRefColumns().size()>0){ |
|||
childColumn(sCol.getRefColumns() ,tabKey); |
|||
} |
|||
} |
|||
|
|||
} |
|||
return false; |
|||
} |
|||
} |
|||
@ -0,0 +1,194 @@ |
|||
/* |
|||
Copyright 2015 Dell Inc. |
|||
ALL RIGHTS RESERVED. |
|||
*/ |
|||
package com.guozhi.bloodanalysis.parser.common; |
|||
|
|||
import java.util.ArrayList; |
|||
import java.util.HashMap; |
|||
import java.util.List; |
|||
import java.util.Map; |
|||
import java.util.regex.Matcher; |
|||
import java.util.regex.Pattern; |
|||
|
|||
import com.guozhi.bloodanalysis.parser.utils.SpUtils; |
|||
import com.guozhi.bloodanalysis.parser.vo.KColumn; |
|||
import com.guozhi.bloodanalysis.parser.vo.VTable; |
|||
import gudusoft.gsqlparser.TCustomSqlStatement; |
|||
import gudusoft.gsqlparser.nodes.TColumnDefinition; |
|||
import gudusoft.gsqlparser.nodes.TColumnDefinitionList; |
|||
import gudusoft.gsqlparser.nodes.TTable; |
|||
import gudusoft.gsqlparser.stmt.TCreateTableSqlStatement; |
|||
import gudusoft.gsqlparser.stmt.TCreateViewSqlStatement; |
|||
import gudusoft.gsqlparser.stmt.TSelectSqlStatement; |
|||
|
|||
public class CreateParser extends BaseParser { |
|||
private TCustomSqlStatement mCreateSql;//table, view
|
|||
private List<KColumn> mColumns; |
|||
|
|||
/**当前目标表*/ |
|||
private VTable mTable; |
|||
private ParserContext mParserContext; |
|||
public CreateParser(TCustomSqlStatement createSql,ParserContext context){ |
|||
mCreateSql=createSql; |
|||
this.mParserContext=context; |
|||
} |
|||
|
|||
public void parse() { |
|||
if(mCreateSql instanceof TCreateTableSqlStatement){ |
|||
TCreateTableSqlStatement ctSql=(TCreateTableSqlStatement)mCreateSql; |
|||
String tableName=ctSql.getTableName().toString(); |
|||
//分析表名,如:db.schema.table或schema.table
|
|||
String[] nameInfo= SpUtils.analyseTableName(tableName); |
|||
//用表名和别名初始化一个表
|
|||
mTable=new VTable(nameInfo[2],nameInfo[2]); |
|||
mTable.db=mParserContext.getDefaultDb(); |
|||
mTable.schema=mParserContext.getDefaultSchema(); |
|||
//设置并判断是否临时表,如:CREATE MULTISET|VOLATILE的为临时表
|
|||
mTable.setCreated(isEvTable(mCreateSql.toString())); |
|||
TColumnDefinitionList cdList = ctSql.getColumnList(); |
|||
List<KColumn> definedColumns=new ArrayList<KColumn>();//定义的列
|
|||
for(int i=0;i<cdList.size();i++){ |
|||
TColumnDefinition colDef=cdList.getColumn(i); |
|||
KColumn col=new KColumn(); |
|||
col.columnName=colDef.getColumnName().getColumnNameOnly(); |
|||
col.columnPrefix =tableName; |
|||
col.alias=col.columnName; |
|||
col.db=mTable.db; |
|||
col.schema=mTable.schema; |
|||
col.tableName=mTable.getName(); |
|||
//表的状态是临时表还是实体表
|
|||
col.isEvTable = mTable.isCreated(); |
|||
definedColumns.add(col); |
|||
} |
|||
TSelectSqlStatement subQuery=ctSql.getSubQuery(); |
|||
List<KColumn> selectColumns=null;//subQuery中的结果列
|
|||
if(subQuery!=null){ |
|||
SelectParser sp=new SelectParser(subQuery,mParserContext); |
|||
sp.parse(); |
|||
selectColumns=sp.getParseResult(); |
|||
}else{ |
|||
TTable tTable = ctSql.getAsTable(); |
|||
if(tTable!=null){ |
|||
System.out.println("此处可能为AsTable,暂未考虑如何获取:"+ctSql.getAsTable()); |
|||
// System.out.println("sql:"+ctSql);
|
|||
AsTableParser asTable = new AsTableParser( tTable, mParserContext); |
|||
//设置上下文当前表,解析源表和目标表
|
|||
asTable.parse(); |
|||
selectColumns = asTable.getParseResult(); |
|||
} |
|||
} |
|||
if(selectColumns!=null&&selectColumns.size()>0) { |
|||
List<KColumn> sourceColumns=new ArrayList<KColumn>(); |
|||
for(KColumn c: selectColumns){ |
|||
if(c!=null&&c.isStar&&c.getRefColumns().size()>0){ |
|||
sourceColumns.addAll(c.getRefColumns()); |
|||
}else{ |
|||
sourceColumns.add(c); |
|||
} |
|||
} |
|||
if(definedColumns.size()>0) { |
|||
if(definedColumns.size()!=sourceColumns.size()){ |
|||
//列个数不对称,SQL出错
|
|||
}else{ |
|||
for(int i=0;i<definedColumns.size();i++){ |
|||
KColumn dc=definedColumns.get(i); |
|||
KColumn sc=sourceColumns.get(i); |
|||
if(sc!=null&&sc.vColumn&&sc.getRefColumns().size()>0){ |
|||
dc.addRefColumnList(sc.getRefColumns()); |
|||
}else { |
|||
dc.addRefColumn(sc); |
|||
} |
|||
} |
|||
} |
|||
}else{ |
|||
//类似这样的语句没有列名定义时:create table t as select a,b from c;
|
|||
for (KColumn refCol : sourceColumns) { |
|||
if(refCol==null){ |
|||
definedColumns.add(null); |
|||
continue; |
|||
} |
|||
|
|||
// String tcName = refCol.columnName;
|
|||
// if (refCol.alias != null)
|
|||
// tcName = refCol.alias;
|
|||
Map<String,String> map = getColNameAndAlias(refCol); |
|||
|
|||
KColumn col = new KColumn(); |
|||
//TODO 对列名进行分析?
|
|||
// col.columnName = "default_col";
|
|||
// col.alias = "默认字段";
|
|||
col.columnName=map.get("colName"); |
|||
col.alias=map.get("alias"); |
|||
col.columnPrefix = tableName; |
|||
col.db=mTable.db; |
|||
col.schema=mTable.schema; |
|||
col.tableName=mTable.getName(); |
|||
//表的状态是临时表还是实体表
|
|||
col.isEvTable = mTable.isCreated(); |
|||
col.addRefColumn(refCol); |
|||
definedColumns.add(col); |
|||
} |
|||
} |
|||
}else{ |
|||
//TODO 没有列的数据,出错了
|
|||
} |
|||
mColumns=definedColumns; |
|||
// mTable.addColumns(definedColumns);
|
|||
mTable.setRealTable(false); |
|||
//把字段存在创建的表里面
|
|||
mTable.addColumns(getParseResult()); |
|||
mParserContext.addCreatedTable(mTable.getFullName(), mTable); |
|||
}else if(mCreateSql instanceof TCreateViewSqlStatement){ |
|||
//视图
|
|||
} |
|||
} |
|||
|
|||
private Map<String,String> getColNameAndAlias(KColumn refCol){ |
|||
Map<String,String> map = new HashMap<String, String>(); |
|||
if(refCol.vColumn){ |
|||
if(refCol.columnName!=refCol.alias&&refCol.alias!=null&&refCol.columnName!=null){ |
|||
map.put("colName", refCol.alias); |
|||
map.put("alias", refCol.alias); |
|||
}else{ |
|||
if(refCol.getRefColumns().size()>1){ |
|||
map.put("colName", "default_col"); |
|||
map.put("alias", "默认字段"); |
|||
}else{ |
|||
KColumn c = new KColumn(); |
|||
if(refCol.getRefColumns().size()>0){ |
|||
c = refCol.getRefColumns().get(0); |
|||
} |
|||
map.put("colName", c.columnName == null ? "default_col" : c.columnName); |
|||
map.put("alias", c.alias == null ? "默认字段" : c.alias); |
|||
} |
|||
} |
|||
}else{ |
|||
map.put("colName", refCol.columnName == null ? "default_col" : refCol.columnName); |
|||
map.put("alias", refCol.alias == null ? "默认字段" : refCol.alias); |
|||
} |
|||
return map; |
|||
} |
|||
|
|||
/** |
|||
* 验证是否为实体表 |
|||
* @param retVal |
|||
* @return |
|||
*/ |
|||
private boolean isEvTable(String retVal){ |
|||
boolean isEvTable = true; |
|||
String pattern = "^\\s*CREATE\\s*(VOLATILE|MULTISET)\\s*(VOLATILE|MULTISET)"; |
|||
Pattern pat = Pattern.compile(pattern); |
|||
Matcher mat = pat.matcher(retVal.toUpperCase().trim()); |
|||
while(mat.find()){ |
|||
isEvTable = false; |
|||
break; |
|||
} |
|||
return isEvTable; |
|||
} |
|||
|
|||
public List<KColumn> getParseResult() { |
|||
super.getResultParser(mParserContext, mTable, mColumns); |
|||
return mColumns; |
|||
} |
|||
} |
|||
@ -0,0 +1,41 @@ |
|||
/* |
|||
Copyright 2015 Dell Inc. |
|||
ALL RIGHTS RESERVED. |
|||
*/ |
|||
package com.guozhi.bloodanalysis.parser.common; |
|||
|
|||
import java.util.ArrayList; |
|||
import java.util.List; |
|||
|
|||
import com.guozhi.bloodanalysis.parser.utils.ExprToColumn; |
|||
import com.guozhi.bloodanalysis.parser.vo.KColumn; |
|||
import gudusoft.gsqlparser.nodes.TExpression; |
|||
import gudusoft.gsqlparser.nodes.TWhereClause; |
|||
import gudusoft.gsqlparser.stmt.TDeleteSqlStatement; |
|||
|
|||
public class DeleteParser{ |
|||
private TDeleteSqlStatement mDeleteStmt; |
|||
private List<KColumn> mColumns; |
|||
private ParserContext mParserContext; |
|||
|
|||
public DeleteParser(TDeleteSqlStatement deleteSqlStatement,ParserContext context){ |
|||
mDeleteStmt=deleteSqlStatement; |
|||
mColumns=new ArrayList<KColumn>(); |
|||
this.mParserContext=context; |
|||
} |
|||
|
|||
public void parse() { |
|||
String tableName=mDeleteStmt.getTargetTable().toString(); |
|||
TWhereClause whereClause=mDeleteStmt.getWhereClause(); |
|||
if(whereClause!=null) { |
|||
TExpression expr = whereClause.getCondition(); |
|||
new ExprToColumn(mDeleteStmt, mParserContext, false).exprVisit(expr); |
|||
} |
|||
|
|||
//TODO
|
|||
} |
|||
public List<KColumn> getParseResult() { |
|||
return mColumns; |
|||
} |
|||
|
|||
} |
|||
@ -0,0 +1,50 @@ |
|||
/* |
|||
Copyright 2015 Dell Inc. |
|||
ALL RIGHTS RESERVED. |
|||
*/ |
|||
package com.guozhi.bloodanalysis.parser.common; |
|||
|
|||
import java.util.List; |
|||
|
|||
import com.guozhi.bloodanalysis.parser.utils.SpUtils; |
|||
import com.guozhi.bloodanalysis.parser.vo.KColumn; |
|||
import com.guozhi.bloodanalysis.parser.vo.VTable; |
|||
import lombok.extern.slf4j.Slf4j; |
|||
import gudusoft.gsqlparser.TCustomSqlStatement; |
|||
import gudusoft.gsqlparser.stmt.TDropTableSqlStatement; |
|||
import gudusoft.gsqlparser.stmt.TDropViewSqlStatement; |
|||
|
|||
@Slf4j |
|||
public class DropParser{ |
|||
private TCustomSqlStatement mDropStmt; |
|||
private ParserContext mParserContext; |
|||
|
|||
public DropParser(TCustomSqlStatement stmt,ParserContext context){ |
|||
this.mDropStmt=stmt; |
|||
this.mParserContext=context; |
|||
} |
|||
|
|||
public void parse() { |
|||
if(mDropStmt instanceof TDropTableSqlStatement){ |
|||
TDropTableSqlStatement dropTableStmt=(TDropTableSqlStatement)mDropStmt; |
|||
|
|||
String fullname=dropTableStmt.getTableName().toString(); |
|||
String tableName= SpUtils.removeQuote(fullname); |
|||
|
|||
VTable t=mParserContext.findExistedTable(tableName,true); |
|||
if(t==null){ |
|||
|
|||
} |
|||
mParserContext.dropExistTable(tableName); |
|||
//TODO 应该不用理这个表了,
|
|||
|
|||
}else if( mDropStmt instanceof TDropViewSqlStatement){ |
|||
|
|||
} |
|||
} |
|||
public List<KColumn> getParseResult() { |
|||
return null; |
|||
} |
|||
|
|||
|
|||
} |
|||
@ -0,0 +1,211 @@ |
|||
/* |
|||
Copyright 2015 Dell Inc. |
|||
ALL RIGHTS RESERVED. |
|||
*/ |
|||
package com.guozhi.bloodanalysis.parser.common; |
|||
|
|||
import java.util.ArrayList; |
|||
import java.util.List; |
|||
|
|||
import com.guozhi.bloodanalysis.parser.utils.ExprToColumn; |
|||
import com.guozhi.bloodanalysis.parser.utils.KColumnProvider; |
|||
import com.guozhi.bloodanalysis.parser.utils.SpUtils; |
|||
import com.guozhi.bloodanalysis.parser.vo.KColumn; |
|||
import com.guozhi.bloodanalysis.parser.vo.VTable; |
|||
import lombok.Data; |
|||
import lombok.EqualsAndHashCode; |
|||
import lombok.NoArgsConstructor; |
|||
import lombok.extern.slf4j.Slf4j; |
|||
import gudusoft.gsqlparser.nodes.TExpression; |
|||
import gudusoft.gsqlparser.nodes.TMultiTarget; |
|||
import gudusoft.gsqlparser.nodes.TMultiTargetList; |
|||
import gudusoft.gsqlparser.nodes.TObjectNameList; |
|||
import gudusoft.gsqlparser.nodes.TResultColumn; |
|||
import gudusoft.gsqlparser.nodes.TResultColumnList; |
|||
import gudusoft.gsqlparser.stmt.TInsertSqlStatement; |
|||
import gudusoft.gsqlparser.stmt.TSelectSqlStatement; |
|||
import org.springframework.beans.factory.annotation.Autowired; |
|||
import org.springframework.context.ApplicationContext; |
|||
import org.springframework.stereotype.Component; |
|||
|
|||
@EqualsAndHashCode(callSuper = true) |
|||
@Slf4j |
|||
@Component |
|||
@NoArgsConstructor |
|||
@Data |
|||
public class InsertParser extends BaseParser{ |
|||
private List<KColumn> mColumns; |
|||
private TInsertSqlStatement mInsertSql; |
|||
private ParserContext mParserContext; |
|||
private VTable tTable = null; |
|||
|
|||
@Autowired |
|||
private ApplicationContext applicationContext; |
|||
|
|||
public InsertParser(TInsertSqlStatement insertSqlStatement,ParserContext context) { |
|||
mInsertSql = insertSqlStatement; |
|||
this.mParserContext=context; |
|||
} |
|||
|
|||
|
|||
|
|||
public void parse() { |
|||
//INSERT INTO 表名称 VALUES (值1, 值2,....)
|
|||
//INSERT INTO table_name (列1, 列2,...) VALUES (值1, 值2,....)
|
|||
//insert into table_name select from....
|
|||
//
|
|||
String targetTableName = mInsertSql.getTargetTable().getFullName(); |
|||
// System.out.println(mInsertSql.toString());
|
|||
String[] nameInfo= SpUtils.analyseTableName(targetTableName); |
|||
tTable=new VTable(nameInfo[2],nameInfo[2]); |
|||
tTable.db=mParserContext.getDefaultDb(); |
|||
tTable.schema=mParserContext.getDefaultSchema(); |
|||
boolean exportColumn=false; |
|||
VTable createdTable=mParserContext.findExistedTable(tTable.getFullName(),false); |
|||
//在解析的时候前面已经创建了临时表,这里再次使用就直接使用临时表
|
|||
//,但是一开始解析的临时表是没有字段的,这次解析insert语句是有字段的,如果直接使用导致临时表字段缺失
|
|||
if(createdTable==null){ |
|||
exportColumn=true; |
|||
}else{ |
|||
tTable = createdTable; |
|||
} |
|||
|
|||
//目标表字段
|
|||
TObjectNameList objectNameList = mInsertSql.getColumnList(); |
|||
|
|||
mColumns=new ArrayList<KColumn>(); |
|||
if (objectNameList != null) { |
|||
for (int i = 0; i < objectNameList.size(); i++) { |
|||
KColumn col = new KColumn(); |
|||
//TODO 对列名进行分析?
|
|||
col.columnName = objectNameList.getObjectName(i).toString(); |
|||
col.alias = col.columnName; |
|||
col.columnPrefix = targetTableName; |
|||
col.db=tTable.db; |
|||
col.schema=tTable.schema; |
|||
col.tableName=tTable.getName(); |
|||
col.isEvTable = exportColumn ? true : createdTable.isCreated();//是否真实表
|
|||
col.export=exportColumn; |
|||
//grc 记录级标记
|
|||
col.etlFlag="12"; |
|||
mColumns.add(col); |
|||
} |
|||
}else{ |
|||
//这种形式只会按列顺序来计算,不会按列的名称匹配,所以列的顺序很重要
|
|||
KColumnProvider kColumnProvider = applicationContext.getBean(KColumnProvider.class); |
|||
List<KColumn> columns=kColumnProvider.getColumns(null,targetTableName, mParserContext); |
|||
if(columns!=null) { |
|||
mColumns.addAll(columns); |
|||
} |
|||
} |
|||
|
|||
List<KColumn> sourceColumns=new ArrayList<KColumn>(); |
|||
switch (mInsertSql.getValueType()) { |
|||
case 1: |
|||
TMultiTargetList valueList = mInsertSql.getValues(); |
|||
for (int i = 0; i < valueList.size(); i++) { |
|||
TMultiTarget value = valueList.getMultiTarget(i); |
|||
//TODO 对不同类型进行不同的处理
|
|||
TResultColumnList resultColumnList=value.getColumnList(); |
|||
for (int j = 0; j < resultColumnList.size(); j++) { |
|||
TResultColumn column = resultColumnList.getResultColumn(j); |
|||
TExpression expr = column.getExpr(); |
|||
//TODO currentTable可能会有些影响?
|
|||
sourceColumns.add(new ExprToColumn(mInsertSql, mParserContext, false).exprVisit(expr)); |
|||
} |
|||
} |
|||
break; |
|||
case 2://SubQuery
|
|||
TSelectSqlStatement subQuery = mInsertSql.getSubQuery(); |
|||
SelectParser sp = applicationContext.getBean(SelectParser.class); |
|||
sp.init(subQuery,mParserContext,true); |
|||
//这里解析表依赖关系》????当源表和目标表??
|
|||
sp.parse(); |
|||
//源字段,解析出的字段为null.null.null.AGMT_ID as AGMT_ID???
|
|||
List<KColumn> subQueryColumns = sp.getParseResult(); |
|||
|
|||
for(KColumn c: subQueryColumns){ |
|||
if(c!=null&&c.isStar&&c.getRefColumns().size()>0){ |
|||
sourceColumns.addAll(c.getRefColumns()); |
|||
}else{ |
|||
sourceColumns.add(c); |
|||
} |
|||
} |
|||
break; //case 2: subQuery
|
|||
case 3:break; |
|||
case 4:break; |
|||
case 6:break; |
|||
case 5: |
|||
mInsertSql.getFunctionCall(); |
|||
break; |
|||
case 7: |
|||
mInsertSql.getSetColumnValues(); |
|||
break; |
|||
case 8: |
|||
mInsertSql.getRecordName(); |
|||
default: |
|||
break; |
|||
} |
|||
|
|||
if(mColumns.size()>sourceColumns.size()){ |
|||
System.out.println(mColumns.size()+"--"+sourceColumns.size()); |
|||
log.error("目标列与源列数量不一致"); |
|||
return; |
|||
} |
|||
|
|||
if(mColumns.size()==0){ |
|||
log.info("目标表:"+targetTableName+",没有定义字段,设置默认字段,总数:"+sourceColumns.size()); |
|||
//如果没有指定字段,则默认一个字段,如有其他必须要字段,可以通过元数据管理系统获取,但需要重新开发。
|
|||
for (int i = 0; i < sourceColumns.size(); i++) { |
|||
KColumn col = new KColumn(); |
|||
//TODO 对列名进行分析?
|
|||
col.columnName = "default_col"; |
|||
col.alias = "默认字段"; |
|||
col.columnPrefix = targetTableName; |
|||
col.db=tTable.db; |
|||
col.schema=tTable.schema; |
|||
col.tableName=tTable.getName(); |
|||
col.isEvTable = exportColumn || createdTable.isCreated(); |
|||
col.export=exportColumn; |
|||
mColumns.add(col); |
|||
} |
|||
} |
|||
|
|||
|
|||
//假设列之间关系完全是可以上的
|
|||
int length=mColumns.size(); |
|||
//从源字段中获取到etlSrcTabName====
|
|||
if(mParserContext.getEtlSrcTabName() == null) { |
|||
for(int i = 0;i < length;i++){ |
|||
KColumn column=mColumns.get(i); |
|||
KColumn refCol=sourceColumns.get(i); |
|||
if(column.columnName.equals(KColumn.etlSrcTabName)) { |
|||
String etlSrcColName = refCol.columnName; |
|||
etlSrcColName = etlSrcColName.replaceAll("'", ""); |
|||
mParserContext.setEtlSrcTabName(etlSrcColName); |
|||
break; |
|||
} |
|||
} |
|||
} |
|||
for (int i=0;i<length;i++) { |
|||
KColumn column=mColumns.get(i); |
|||
KColumn refCol=sourceColumns.get(i); |
|||
column.setEtlFlag(mParserContext.getEtlSrcTabName()); |
|||
if(refCol!=null) { |
|||
refCol.setEtlFlag(mParserContext.getEtlSrcTabName()); |
|||
if(refCol.vColumn&&refCol.getRefColumns().size()>0){ |
|||
column.getRefColumns().addAll(refCol.getRefColumns()); |
|||
}else { |
|||
column.addRefColumn(refCol); |
|||
} |
|||
} |
|||
} |
|||
tTable.addColumns(mColumns); |
|||
} |
|||
|
|||
public List<KColumn> getParseResult() { |
|||
//在父类中先清理一次结果
|
|||
super.getResultParser(mParserContext, tTable, mColumns); |
|||
return mColumns; |
|||
} |
|||
} |
|||
@ -0,0 +1,141 @@ |
|||
package com.guozhi.bloodanalysis.parser.common; |
|||
|
|||
import com.guozhi.bloodanalysis.parser.vo.KColumn; |
|||
import com.guozhi.bloodanalysis.parser.vo.VTable; |
|||
|
|||
import java.util.ArrayList; |
|||
import java.util.HashMap; |
|||
import java.util.List; |
|||
import java.util.Map; |
|||
|
|||
|
|||
/** |
|||
* Created by Walk.Lai on 2015/8/1. |
|||
*/ |
|||
public class ParserContext { |
|||
// 使用create语句创建的表
|
|||
private Map<String, VTable> mCreatedTables = new HashMap<String, VTable>(); |
|||
/** 只保存当前语句中出现的表,包括虚表 */ |
|||
private List<VTable> mTableInCurrentStatement = new ArrayList<VTable>(); |
|||
// 当前语句所构成的虚表
|
|||
private VTable mCurrentTable; |
|||
|
|||
//wxl TODO 对于存储过程可以知道归属库和schema,但对于perl、python、shell、sql脚本,就获取不到了。
|
|||
private String mDefaultDb;//TODO db or sys?
|
|||
private String mDefaultSchema; |
|||
|
|||
/** |
|||
* grc etl源表名称 |
|||
*/ |
|||
private String etlSrcTabName; |
|||
|
|||
public VTable findExistedTable(String tableName, boolean isCopy) { |
|||
if (isCopy) { |
|||
return copyTable(mCreatedTables.get(tableName)); |
|||
} else { |
|||
return mCreatedTables.get(tableName); |
|||
} |
|||
} |
|||
|
|||
private VTable copyTable(VTable s) { |
|||
if (s == null) { |
|||
return null; |
|||
} |
|||
VTable t = new VTable(s.getName()); |
|||
t.alias = s.alias; |
|||
t.db = s.db; |
|||
t.name = s.name; |
|||
t.schema = s.schema; |
|||
t.setCreated(s.isCreated()); |
|||
t.setRealTable(s.isRealTable()); |
|||
for (int i = 0; i < s.getColumns().size(); i++) { |
|||
KColumn _col = s.getColumns().get(i); |
|||
KColumn col = new KColumn(); |
|||
// TODO 对列名进行分析?
|
|||
col.columnName = _col.columnName; |
|||
col.alias = _col.alias; |
|||
col.columnPrefix = _col.columnPrefix; |
|||
col.db = _col.db; |
|||
col.schema = _col.schema; |
|||
col.tableName = _col.tableName; |
|||
col.isEvTable = _col.isEvTable; |
|||
col.export = _col.export; |
|||
t.addColumn(col); |
|||
} |
|||
return t; |
|||
} |
|||
|
|||
public void dropExistTable(String tableName) { |
|||
mCreatedTables.remove(tableName); |
|||
} |
|||
|
|||
public void addVTable(VTable table) { |
|||
this.mTableInCurrentStatement.add(table); |
|||
} |
|||
|
|||
/** |
|||
* 当前解析语句中保存的表 |
|||
* |
|||
* @return |
|||
*/ |
|||
public List<VTable> getTableInCurrentStatement() { |
|||
return mTableInCurrentStatement; |
|||
} |
|||
|
|||
public VTable getCurrentTable() { |
|||
return mCurrentTable; |
|||
} |
|||
|
|||
public void setCurrentTable(VTable currentTable) { |
|||
this.mCurrentTable = currentTable; |
|||
} |
|||
|
|||
public String getDefaultDb() { |
|||
return mDefaultDb; |
|||
} |
|||
|
|||
public void setDefaultDb(String defaultDb) { |
|||
this.mDefaultDb = defaultDb; |
|||
} |
|||
|
|||
public String getDefaultSchema() { |
|||
return mDefaultSchema; |
|||
} |
|||
|
|||
public void setDefaultSchema(String defaultSchema) { |
|||
this.mDefaultSchema = defaultSchema; |
|||
} |
|||
|
|||
public Map<String, VTable> getCreatedTables() { |
|||
return mCreatedTables; |
|||
} |
|||
|
|||
|
|||
public VTable findTableInCurrentStatement(String tableName) { |
|||
for (VTable t : mTableInCurrentStatement) { |
|||
if (t.getName().equals(tableName)) |
|||
return t; |
|||
if (t.getAlias() != null) { |
|||
if (t.getAlias().equals(tableName)) |
|||
return t; |
|||
} |
|||
} |
|||
return null; |
|||
} |
|||
|
|||
public boolean addCreatedTable(String tableName, VTable table) { |
|||
if (mCreatedTables.get(tableName) == null) { |
|||
mCreatedTables.put(tableName, table); |
|||
} |
|||
return false; |
|||
} |
|||
|
|||
public String getEtlSrcTabName() { |
|||
return etlSrcTabName; |
|||
} |
|||
|
|||
public void setEtlSrcTabName(String etlSrcTabName) { |
|||
this.etlSrcTabName = etlSrcTabName; |
|||
} |
|||
|
|||
} |
|||
@ -0,0 +1,294 @@ |
|||
/* |
|||
Copyright 2015 Dell Inc. |
|||
ALL RIGHTS RESERVED. |
|||
*/ |
|||
/* |
|||
Copyright 2015 Dell Inc. |
|||
ALL RIGHTS RESERVED. |
|||
*/ |
|||
package com.guozhi.bloodanalysis.parser.common; |
|||
|
|||
import java.util.ArrayList; |
|||
import java.util.List; |
|||
|
|||
import com.guozhi.bloodanalysis.parser.utils.ExprToColumn; |
|||
import com.guozhi.bloodanalysis.parser.utils.KDatabaseProvider; |
|||
import com.guozhi.bloodanalysis.parser.utils.SpUtils; |
|||
import com.guozhi.bloodanalysis.parser.vo.KColumn; |
|||
import com.guozhi.bloodanalysis.parser.vo.VTable; |
|||
import gudusoft.gsqlparser.nodes.TExpression; |
|||
import gudusoft.gsqlparser.nodes.TExpressionList; |
|||
import gudusoft.gsqlparser.nodes.TIntoClause; |
|||
import gudusoft.gsqlparser.nodes.TJoin; |
|||
import gudusoft.gsqlparser.nodes.TJoinItem; |
|||
import gudusoft.gsqlparser.nodes.TJoinItemList; |
|||
import gudusoft.gsqlparser.nodes.TJoinList; |
|||
import gudusoft.gsqlparser.nodes.TResultColumn; |
|||
import gudusoft.gsqlparser.nodes.TResultColumnList; |
|||
import gudusoft.gsqlparser.nodes.TTable; |
|||
import gudusoft.gsqlparser.nodes.TWhereClause; |
|||
import gudusoft.gsqlparser.stmt.TSelectSqlStatement; |
|||
import lombok.Data; |
|||
import lombok.EqualsAndHashCode; |
|||
import lombok.NoArgsConstructor; |
|||
import lombok.extern.slf4j.Slf4j; |
|||
import org.apache.commons.lang3.StringUtils; |
|||
import org.springframework.beans.factory.annotation.Autowired; |
|||
import org.springframework.context.ApplicationContext; |
|||
import org.springframework.context.annotation.Scope; |
|||
import org.springframework.stereotype.Component; |
|||
|
|||
@EqualsAndHashCode(callSuper = true) |
|||
@Slf4j |
|||
@Component |
|||
@NoArgsConstructor |
|||
@Scope("prototype") |
|||
@Data |
|||
public class SelectParser extends BaseParser { |
|||
private List<KColumn> mSourceColumn = new ArrayList<KColumn>(); |
|||
private TSelectSqlStatement mSelect; |
|||
private boolean mKeepConstant=false;//是否保留常量值
|
|||
private ParserContext mParserContext; |
|||
private VTable vTable;//将整个查询语句当成一个表进行处理
|
|||
|
|||
@Autowired |
|||
ApplicationContext applicationContext; |
|||
|
|||
|
|||
public SelectParser(TSelectSqlStatement statement,ParserContext context) { |
|||
mSelect = statement; |
|||
vTable=new VTable(SpUtils.generateId(statement.toString(),"")); |
|||
this.mParserContext=context; |
|||
} |
|||
public SelectParser(TSelectSqlStatement statement,ParserContext context,boolean keepConstant) { |
|||
mSelect = statement; |
|||
mKeepConstant=keepConstant; |
|||
vTable=new VTable(SpUtils.generateId(statement.toString(),"")); |
|||
this.mParserContext=context; |
|||
} |
|||
|
|||
public void init(TSelectSqlStatement statement, ParserContext context, boolean keepConstant) { |
|||
mSelect = statement; |
|||
mKeepConstant=keepConstant; |
|||
vTable=new VTable(SpUtils.generateId(statement.toString(),"")); |
|||
this.mParserContext=context; |
|||
} |
|||
|
|||
public void initWithTable(TSelectSqlStatement statement,ParserContext context,VTable vTable,boolean keepConstant) { |
|||
mSelect = statement; |
|||
mKeepConstant=keepConstant; |
|||
this.vTable=vTable; |
|||
this.mParserContext=context; |
|||
} |
|||
|
|||
// public SelectParser(TSelectSqlStatement statement,ParserContext context,VTable vTable,boolean keepConstant) {
|
|||
// mSelect = statement;
|
|||
// mKeepConstant=keepConstant;
|
|||
// this.vTable=vTable;
|
|||
// this.mParserContext=context;
|
|||
// }
|
|||
public void parse() { |
|||
//当前表的关系已存在,则直接取消解析
|
|||
if(isTableExisted(vTable)){ |
|||
return ; |
|||
} |
|||
|
|||
//where 部分
|
|||
TWhereClause where = mSelect.getWhereClause(); |
|||
if(where != null) { |
|||
// System.out.println(where);
|
|||
} |
|||
//TODO 将CTE转化为表关系
|
|||
|
|||
mParserContext.setCurrentTable(vTable); |
|||
//Join items from后边部分都属于join
|
|||
TJoinList joinList = mSelect.joins; |
|||
if (joinList != null) { |
|||
for (int i = 0; i < joinList.size(); i++) { |
|||
TJoin join = joinList.getJoin(i); |
|||
TTable table=join.getTable(); |
|||
|
|||
vTable.addTable(analyseTable(table)); |
|||
|
|||
TJoinItemList joinItemList = join.getJoinItems(); |
|||
if (joinItemList != null) { |
|||
for (int j = 0; j < joinItemList.size(); j++) { |
|||
TJoinItem joinItem = joinItemList.getJoinItem(j); |
|||
TTable joinTable = joinItem.getTable(); |
|||
vTable.addTable(analyseTable(joinTable)); |
|||
//TExpression expr = joinItem.getOnCondition();
|
|||
//TODO 对On的列进行分析,如果不是这个表的列,则是会影响这个列的
|
|||
} |
|||
} |
|||
|
|||
} |
|||
} else { |
|||
log.error("找不到From对应的表"); |
|||
return; |
|||
} |
|||
mParserContext.setCurrentTable(vTable); |
|||
// mSelect.getSetOperatorType()
|
|||
//对 union, unionall, except等进行处理
|
|||
if(mSelect.getSetOperator()!=TSelectSqlStatement.setOperator_none){ |
|||
|
|||
VTable currentTable = mParserContext.getCurrentTable();//暂存
|
|||
|
|||
SelectParser sp1 = new SelectParser(mSelect.getLeftStmt(), mParserContext); |
|||
sp1.parse(); |
|||
|
|||
SelectParser sp2 = new SelectParser(mSelect.getRightStmt(), mParserContext); |
|||
sp2.parse(); |
|||
currentTable.addTable(sp1.vTable); |
|||
currentTable.addTable(sp2.vTable); |
|||
mParserContext.setCurrentTable(currentTable);//还原
|
|||
currentTable.addColumns(sp1.getParseResult()); |
|||
currentTable.addColumns(sp2.getParseResult()); |
|||
}else { |
|||
TResultColumnList resultColumnList = mSelect.getResultColumnList(); |
|||
for (int i = 0; i < resultColumnList.size(); i++) { |
|||
TResultColumn column = resultColumnList.getResultColumn(i); |
|||
TExpression expr = column.getExpr(); |
|||
ExprToColumn etc = applicationContext.getBean(ExprToColumn.class); |
|||
etc.setMStmt(mSelect); |
|||
etc.setMParserContext(mParserContext); |
|||
KColumn rc = etc.exprVisit(expr); |
|||
// KColumn rc = new ExprToColumn(mSelect, mParserContext, mKeepConstant).exprVisit(expr);
|
|||
///$$$$$$$$$$$$$$$$$$$$$$$grc 记录级标志
|
|||
// rc.setEtlFlag("12");
|
|||
mSourceColumn.add(rc); |
|||
} |
|||
|
|||
} |
|||
|
|||
//into table, 对应表的字段依赖于结果字段中的别名,根据上边结果创建依赖关系
|
|||
/* |
|||
SELECT * |
|||
INTO new_table_name [IN externaldatabase] |
|||
FROM old_tablename |
|||
*/ |
|||
//TODO select into相当于创建一个新表
|
|||
TIntoClause intoClause = mSelect.getIntoClause(); |
|||
if (intoClause != null) { |
|||
|
|||
TExpressionList exprList = intoClause.getExprList(); |
|||
List<KColumn> newColumns = new ArrayList<KColumn>(mSourceColumn.size()); |
|||
for (int i = 0; i < exprList.size(); i++) { |
|||
TExpression expr = exprList.getExpression(i); |
|||
String tableName = null; |
|||
switch (expr.getExpressionType()) { |
|||
case in_t: |
|||
tableName = SpUtils.removeQuote(expr.getLeftOperand().toString()); |
|||
//对表名进行处理,可能含有数据库
|
|||
break; |
|||
case simple_object_name_t: |
|||
//select语句的关联关系
|
|||
List<VTable> fromTables=vTable.getFromTables(); |
|||
String[] nameInfo= SpUtils.analyseTableName(expr.toString()); |
|||
vTable=new VTable(nameInfo[2],nameInfo[2]); |
|||
vTable.db=mParserContext.getDefaultDb(); |
|||
vTable.schema=mParserContext.getDefaultSchema(); |
|||
vTable.getFromTables().addAll(fromTables); |
|||
break; |
|||
} |
|||
|
|||
for (KColumn col : mSourceColumn) { |
|||
if(col==null)continue; |
|||
KColumn nc = new KColumn(); |
|||
nc.columnPrefix = tableName; |
|||
nc.columnName = col.alias == null ? col.columnName : col.alias; |
|||
nc.alias = null; |
|||
if(col.vColumn){ |
|||
nc.getRefColumns().addAll(col.getRefColumns()); |
|||
}else { |
|||
nc.addRefColumn(col); |
|||
} |
|||
newColumns.add(nc); |
|||
} |
|||
|
|||
} |
|||
//TODO 返回结果转化为该表的,暂时这样处理,是不是这样处理得再考虑考虑
|
|||
this.mSourceColumn=newColumns; |
|||
} |
|||
vTable.addColumns(mSourceColumn); |
|||
mParserContext.addVTable( vTable); |
|||
} |
|||
|
|||
private boolean isTableExisted(VTable vTable) { |
|||
return false; |
|||
} |
|||
|
|||
private VTable analyseTable(TTable table){ |
|||
String fullName=table.getFullName(); |
|||
String tableAlias=table.getAliasName(); |
|||
VTable vTable=null; |
|||
if(StringUtils.isBlank(fullName)){//子查询,fullName为空
|
|||
vTable=new VTable(SpUtils.generateId(table.toString(),tableAlias)); |
|||
}else{//普通表名//StringUtils.isNotBlank(fullName)
|
|||
String[] nameInfo=SpUtils.analyseTableName(fullName); |
|||
vTable=new VTable(nameInfo[2],nameInfo[2]); |
|||
vTable.db=mParserContext.getDefaultDb(); |
|||
vTable.schema=mParserContext.getDefaultSchema(); |
|||
} |
|||
|
|||
if(StringUtils.isNotBlank(tableAlias)){ |
|||
vTable.setAlias(tableAlias); |
|||
} |
|||
|
|||
//已知的表
|
|||
VTable createdTable = mParserContext.findExistedTable(vTable.getFullName(),true); |
|||
if(createdTable!=null) { |
|||
createdTable.setAlias(vTable.alias); |
|||
return createdTable; |
|||
} |
|||
|
|||
switch (table.getTableType()) { |
|||
case objectname: |
|||
//真实数据库中的表,查找表对应系统,可能存在多个情况
|
|||
KDatabaseProvider kDatabaseProvider = applicationContext.getBean(KDatabaseProvider.class); |
|||
kDatabaseProvider.getDatabase(vTable, mParserContext); |
|||
break; |
|||
case subquery: |
|||
TSelectSqlStatement subQuery = table.getSubquery(); |
|||
// VTable currentTable=mParserContext.getCurrentTable();
|
|||
SelectParser sp = applicationContext.getBean(SelectParser.class); |
|||
sp.initWithTable(subQuery,mParserContext,vTable,mKeepConstant); |
|||
sp.parse(); |
|||
// mParserContext.setCurrentTable(vTable);
|
|||
//创建依赖关系 重复了。。。。。。。。。。
|
|||
// vTable.addColumns(sp.getParseResult());
|
|||
// vTable.getFromTables().addAll(sp.vTable.getFromTables());
|
|||
break; //subquery
|
|||
|
|||
case function: |
|||
// table.getFuncCall();
|
|||
break; |
|||
case tableExpr:break; |
|||
case rowList:break; |
|||
//SQL Server only
|
|||
case containsTable:break; |
|||
case freetextTable:break; |
|||
|
|||
default:break; |
|||
} |
|||
mParserContext.addVTable(vTable); |
|||
return vTable; |
|||
} |
|||
|
|||
public List<KColumn> getParseResult() { |
|||
List<KColumn> ret=new ArrayList<KColumn>(); |
|||
for(KColumn column: vTable.getColumns()){ |
|||
if(column==null){ |
|||
ret.add(column); |
|||
}else { |
|||
if (column.isStar) { |
|||
ret.addAll(column.getRefColumns()); |
|||
} else { |
|||
ret.add(column); |
|||
} |
|||
} |
|||
} |
|||
return ret; |
|||
} |
|||
|
|||
|
|||
} |
|||
@ -0,0 +1,179 @@ |
|||
/* |
|||
Copyright 2015 Dell Inc. |
|||
ALL RIGHTS RESERVED. |
|||
*/ |
|||
package com.guozhi.bloodanalysis.parser.common; |
|||
|
|||
import java.util.ArrayList; |
|||
import java.util.List; |
|||
|
|||
import com.guozhi.bloodanalysis.parser.utils.ExprToColumn; |
|||
import com.guozhi.bloodanalysis.parser.utils.KColumnProvider; |
|||
import com.guozhi.bloodanalysis.parser.utils.SpUtils; |
|||
import com.guozhi.bloodanalysis.parser.vo.KColumn; |
|||
import com.guozhi.bloodanalysis.parser.vo.VTable; |
|||
import gudusoft.gsqlparser.nodes.TExpression; |
|||
import gudusoft.gsqlparser.nodes.TJoinList; |
|||
import gudusoft.gsqlparser.nodes.TResultColumn; |
|||
import gudusoft.gsqlparser.nodes.TResultColumnList; |
|||
import gudusoft.gsqlparser.nodes.TTable; |
|||
import gudusoft.gsqlparser.nodes.TTableList; |
|||
import gudusoft.gsqlparser.nodes.TWhereClause; |
|||
import gudusoft.gsqlparser.stmt.TSelectSqlStatement; |
|||
import gudusoft.gsqlparser.stmt.TUpdateSqlStatement; |
|||
import lombok.NoArgsConstructor; |
|||
import org.apache.commons.lang3.StringUtils; |
|||
import org.springframework.beans.factory.annotation.Autowired; |
|||
import org.springframework.context.ApplicationContext; |
|||
import org.springframework.stereotype.Component; |
|||
|
|||
@Component |
|||
@NoArgsConstructor |
|||
public class UpdateParser{ |
|||
private TUpdateSqlStatement mUpdateStmt; |
|||
private List<KColumn> mColumns; |
|||
private ParserContext mParserContext; |
|||
|
|||
@Autowired |
|||
ApplicationContext applicationContext; |
|||
|
|||
public UpdateParser(TUpdateSqlStatement stmt, ParserContext context) { |
|||
mUpdateStmt = stmt; |
|||
mColumns = new ArrayList<KColumn>(); |
|||
this.mParserContext = context; |
|||
} |
|||
|
|||
public void parse() { |
|||
TTable targetTable = mUpdateStmt.getTargetTable(); |
|||
VTable updateTable = new VTable(targetTable.getName(), targetTable.getName()); |
|||
updateTable.db = mParserContext.getDefaultDb(); |
|||
updateTable.schema = mParserContext.getDefaultSchema(); |
|||
boolean exportColumn = false; |
|||
VTable createdTable = mParserContext.findExistedTable(updateTable.getFullName(),true); |
|||
if (createdTable == null) { |
|||
exportColumn = true; |
|||
} |
|||
|
|||
mParserContext.setCurrentTable(updateTable); |
|||
TTableList tableList = mUpdateStmt.tables; |
|||
if (tableList != null) { |
|||
for (int i = 0; i < tableList.size(); i++) { |
|||
TTable fromTable = tableList.getTable(i); |
|||
VTable table=analyseTable(fromTable); |
|||
if(table.getFullName().equals(updateTable.getFullName()))continue; |
|||
|
|||
mParserContext.getTableInCurrentStatement().add(table); |
|||
|
|||
|
|||
} |
|||
} |
|||
TJoinList joinList=mUpdateStmt.getReferenceJoins(); |
|||
if(joinList!=null){ |
|||
for(int i=0;i<joinList.size();i++){ |
|||
System.out.println(joinList.getJoin(i)); |
|||
} |
|||
} |
|||
|
|||
TWhereClause whereClause = mUpdateStmt.getWhereClause(); |
|||
if(whereClause!=null) { |
|||
TExpression conditionExpr = whereClause.getCondition(); |
|||
} |
|||
// List<KColumn> conditionColumns = new ArrayList<KColumn>();
|
|||
// conditionColumns.add(new ExprToColumn(mUpdateStmt, mParserContext, false).exprVisit(conditionExpr));
|
|||
TResultColumnList rcList = mUpdateStmt.getResultColumnList(); |
|||
|
|||
|
|||
for (int i = 0; i < rcList.size(); i++) { |
|||
TResultColumn rc = rcList.getResultColumn(i); |
|||
TExpression expr = rc.getExpr(); |
|||
KColumn dest= new KColumn(); |
|||
dest.db=updateTable.db; |
|||
dest.schema=updateTable.schema; |
|||
dest.tableName=updateTable.getName(); |
|||
dest.columnName=expr.getLeftOperand().toString(); |
|||
//表的状态是临时表还是实体表
|
|||
dest.isEvTable = updateTable.isCreated(); |
|||
dest.export=exportColumn; |
|||
KColumn src= new ExprToColumn(mUpdateStmt, mParserContext, false).exprVisit(expr.getRightOperand()) ; |
|||
dest.addRefColumn(src); |
|||
mColumns.add(dest); |
|||
} |
|||
//依赖关系只计算不同表之间的
|
|||
/* for (KColumn column : conditionColumns) { |
|||
//TODO 列所属表是否相同的判断需要加强
|
|||
System.out.println(column.tableName); |
|||
if (column != null && !column.tableName.equals(targetTable.getName())) { |
|||
for (KColumn mColumn : mColumns) { |
|||
|
|||
mColumn.addRefColumn(column); |
|||
|
|||
} |
|||
} |
|||
|
|||
}*/ |
|||
|
|||
} |
|||
|
|||
public List<KColumn> getParseResult() { |
|||
return mColumns; |
|||
} |
|||
|
|||
private VTable analyseTable(TTable table) { |
|||
String fullName = table.getFullName(); |
|||
String tableAlias = table.getAliasName(); |
|||
VTable vTable = null; |
|||
if (StringUtils.isBlank(fullName)) {//子查询
|
|||
vTable = new VTable(SpUtils.generateId(table.toString(), tableAlias)); |
|||
} else if (StringUtils.isNotBlank(fullName)) {//普通表名
|
|||
String[] nameInfo = SpUtils.analyseTableName(fullName); |
|||
vTable = new VTable(nameInfo[2], nameInfo[2]); |
|||
vTable.db = mParserContext.getDefaultDb(); |
|||
vTable.schema = mParserContext.getDefaultSchema(); |
|||
} |
|||
|
|||
if (StringUtils.isNotBlank(tableAlias)) { |
|||
vTable.setAlias(tableAlias); |
|||
} |
|||
//已知的表
|
|||
VTable createdTable = mParserContext.findExistedTable(vTable.getFullName(),true); |
|||
if (createdTable != null) { |
|||
createdTable.setAlias(vTable.alias); |
|||
return createdTable; |
|||
} |
|||
switch (table.getTableType()) { |
|||
case objectname: |
|||
vTable.setRealTable(true); |
|||
//真实数据库中的表,查找表对应关系
|
|||
vTable.addColumns(new KColumnProvider().getColumns(null,table.getFullName(), mParserContext)); |
|||
break; |
|||
case subquery: |
|||
TSelectSqlStatement subQuery = table.getSubquery(); |
|||
VTable currentTable = mParserContext.getCurrentTable(); |
|||
SelectParser sp = applicationContext.getBean(SelectParser.class); |
|||
sp.initWithTable(subQuery, mParserContext, vTable, true); |
|||
sp.parse(); |
|||
mParserContext.setCurrentTable(currentTable); |
|||
//创建依赖关系
|
|||
vTable.addColumns(sp.getParseResult()); |
|||
break; //subquery
|
|||
|
|||
case function: |
|||
//table.getFuncCall();
|
|||
break; |
|||
case tableExpr: |
|||
break; |
|||
case rowList: |
|||
break; |
|||
//SQL Server only
|
|||
case containsTable: |
|||
break; |
|||
case freetextTable: |
|||
break; |
|||
|
|||
default: |
|||
break; |
|||
} |
|||
mParserContext.addVTable(vTable); |
|||
return vTable; |
|||
} |
|||
} |
|||
@ -0,0 +1,189 @@ |
|||
package com.guozhi.bloodanalysis.parser.utils; |
|||
|
|||
import com.guozhi.bloodanalysis.entity.MetaColumn; |
|||
import com.guozhi.bloodanalysis.mapper.MetaBloodAnalysisMapper; |
|||
import com.guozhi.bloodanalysis.parser.common.ParserContext; |
|||
import com.guozhi.bloodanalysis.parser.vo.KColumn; |
|||
import com.guozhi.bloodanalysis.parser.vo.VTable; |
|||
import lombok.extern.slf4j.Slf4j; |
|||
import org.springframework.beans.factory.annotation.Autowired; |
|||
import org.springframework.context.annotation.Scope; |
|||
import org.springframework.stereotype.Component; |
|||
|
|||
import java.util.List; |
|||
|
|||
/** |
|||
* Created by Walk.Lai on 2015/8/8. |
|||
*/ |
|||
@Slf4j |
|||
@Component |
|||
@Scope("prototype") |
|||
public class ColumnRefFinder { |
|||
|
|||
@Autowired |
|||
MetaBloodAnalysisMapper metaBloodAnalysisMapper; |
|||
|
|||
public void find(KColumn column, ParserContext parserContext) { |
|||
|
|||
VTable currentTable = parserContext.getCurrentTable(); |
|||
if(currentTable==null){ |
|||
return; |
|||
} |
|||
List<VTable> fromTables = currentTable.getFromTables(); |
|||
|
|||
VTable foundTable = findRelatedTable(column, fromTables,parserContext); |
|||
|
|||
if (foundTable == null) {// 实在找不到
|
|||
foundTable = findRelatedTable(column,parserContext.getTableInCurrentStatement(),parserContext); |
|||
if (foundTable == null) { |
|||
log.error("找不到列对应的表:" + column.toString()); |
|||
return; |
|||
} |
|||
} |
|||
|
|||
if (foundTable.isRealTable()) { |
|||
column.db = foundTable.db; |
|||
column.schema = foundTable.schema; |
|||
column.tableName = foundTable.getName(); |
|||
column.columnPrefix = foundTable.getFullName(); |
|||
// 找到这个表,看是不是创建的临时表
|
|||
VTable table = parserContext.getCreatedTables().get(foundTable.getFullName()); |
|||
if (table == null) { |
|||
column.export = true; |
|||
// 已经是实表了,直接关联上表就行了
|
|||
if (column.isStar) { |
|||
// TODO 通过接口查找数据库获得表对应的列信息
|
|||
if (foundTable.getColumns().size() > 0) { |
|||
column.addRefColumnList(foundTable.getColumns()); |
|||
} else { |
|||
column.addRefColumnList(new KColumnProvider().getColumns(foundTable,null,parserContext)); |
|||
} |
|||
|
|||
} |
|||
} else { |
|||
column.columnPrefix = foundTable.getFullName(); |
|||
if (column.isStar) { |
|||
column.addRefColumnList(table.getColumns()); |
|||
} else { |
|||
for (KColumn c : foundTable.getColumns()) { |
|||
if (c == null) { |
|||
continue; |
|||
} |
|||
String name = (c.alias == null ? c.columnName : c.alias); |
|||
if (name.equals(column.columnName)) { |
|||
column = c; |
|||
break; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
return; |
|||
} |
|||
if (column.isStar) { |
|||
if (foundTable.getColumns().size() > 0) { |
|||
column.addRefColumnList(foundTable.getColumns()); |
|||
} else { |
|||
// TODO 找到表的定义和对应列数据
|
|||
List<KColumn> columns = new KColumnProvider().getColumns(null,column.columnPrefix, parserContext); |
|||
column.addRefColumnList(columns); |
|||
} |
|||
} else { |
|||
for (KColumn s : foundTable.getColumns()) { |
|||
if (s == null) { |
|||
continue; |
|||
} |
|||
String name = s.alias == null ? s.columnName : s.alias; |
|||
if (name != null && name.equals(column.columnName)) { |
|||
addRefCol(s, column); |
|||
} |
|||
} |
|||
// iterFromTableColumn(column, foundTable);
|
|||
} |
|||
} |
|||
|
|||
private void addRefCol(KColumn s, KColumn column) { |
|||
KColumn t = new KColumn(); |
|||
if (s.vColumn) { |
|||
List<KColumn> list = s.getRefColumns(); |
|||
for (KColumn _s : list) { |
|||
addRefCol(_s, column); |
|||
} |
|||
} else { |
|||
if (s.db == null || s.tableName == null || s.schema == null) { |
|||
List<KColumn> list = s.getRefColumns(); |
|||
for (KColumn _s : list) { |
|||
addRefCol(_s, column); |
|||
} |
|||
} else { |
|||
t.alias = s.alias; |
|||
t.columnName = s.columnName; |
|||
t.columnPrefix = s.columnPrefix; |
|||
t.db = s.db; |
|||
t.export = s.export; |
|||
t.isEvTable = s.isEvTable; |
|||
t.isStar = s.isStar; |
|||
t.schema = s.schema; |
|||
t.tableName = s.tableName; |
|||
t.vColumn = s.vColumn; |
|||
|
|||
// 在Union等情况下,一个列会关联多个表的同名列
|
|||
column.addRefColumn(t); |
|||
} |
|||
} |
|||
} |
|||
|
|||
private VTable findRelatedTable(KColumn column, List<VTable> fromTables, ParserContext parserContext) { |
|||
if (fromTables.size() == 1) { |
|||
return fromTables.get(0); |
|||
} |
|||
|
|||
if (column.columnPrefix != null) {// 明确知道属于哪个表,必须找到这个表
|
|||
// TODO 如何判断列的前缀是哪个表?
|
|||
for (VTable t : fromTables) { |
|||
// 一般列名的前缀也就是表名或别名,不会包含数据库等
|
|||
if (column.columnPrefix.equals(t.getAlias()) |
|||
|| column.columnPrefix.equals(t.getName()) |
|||
|| column.columnPrefix.equals(t.getFullName())) { |
|||
return t; |
|||
} |
|||
} |
|||
} else { |
|||
VTable t = new VTable("V" + System.currentTimeMillis()); |
|||
// 没有前缀,无法确认是哪个表的字段,需要查找数据确认字段
|
|||
for (VTable vt : fromTables) { |
|||
if(vt.isRealTable()){ |
|||
MetaColumn col = metaBloodAnalysisMapper.isColExis(vt.db,vt.schema, vt.name, column.columnName); |
|||
if(col != null){ |
|||
t = vt; |
|||
break; |
|||
} |
|||
}else{ |
|||
if(getRealTable(vt, column.columnName)){ |
|||
t = vt; |
|||
break; |
|||
} |
|||
} |
|||
} |
|||
return t; |
|||
} |
|||
return null; |
|||
} |
|||
|
|||
private boolean getRealTable(VTable t,String colName){ |
|||
boolean isExis = false; |
|||
List<VTable> list = t.getFromTables(); |
|||
for (VTable vt : list) { |
|||
if(vt.isRealTable()){ |
|||
MetaColumn metaColumn = metaBloodAnalysisMapper.isColExis(vt.db,vt.schema, vt.name, colName); |
|||
if (metaColumn != null) { |
|||
isExis = true; |
|||
break; |
|||
} |
|||
}else{ |
|||
getRealTable(vt,colName); |
|||
} |
|||
} |
|||
return isExis; |
|||
} |
|||
|
|||
} |
|||
@ -0,0 +1,29 @@ |
|||
package com.guozhi.bloodanalysis.parser.utils; |
|||
|
|||
public class Constants { |
|||
public static String kvsImplClass = "com.pactera.edg.am.etlmapping.perlparser.perlclean.common.GenericKeyVarSimulator"; |
|||
public static String sfpImplClass = "com.pactera.edg.am.etlmapping.perlparser.perlclean.common.GenericSqlFragmentParser"; |
|||
public static String lgsImplClass = "com.pactera.edg.am.etlmapping.perlparser.perlclean.common.GenericLogGenSimulator"; |
|||
public static String lnImplClass = "com.pactera.edg.am.etlmapping.perlparser.perlclean.common.GenericLogNormalizer"; |
|||
public static String dcfppImplClass = "com.pactera.edg.am.etlmapping.perlparser.perlclean.common.GenericDbCfgFilePathParser"; |
|||
/** |
|||
* GP类脚本执行体常量定义 |
|||
*/ |
|||
public static String GP_RUN_COMMAND_STR = "SUB RUN_PSQL_COMMAND"; |
|||
/** |
|||
* ORACLE类脚本执行体常量定义 |
|||
*/ |
|||
public static String ORA_RUN_COMMAND_STR = "SUB RUN_SQLPLUS_COMMAND"; |
|||
/** |
|||
* TD类脚本执行体常量定义 |
|||
*/ |
|||
public static String TRD_RUN_COMMAND_STR = "SUB RUN_BTEQ_COMMAND"; |
|||
|
|||
// 定义需解析文件类型
|
|||
public final static String FILE_SUFFIX = ".SQL";//PL
|
|||
|
|||
//脚本状态枚举,有效、不标准、故障、不是perl脚本,无效
|
|||
public static enum fileSts { |
|||
VALID,NOTSTANDARD,FAULT,NOTPERL,INVALID |
|||
} |
|||
} |
|||
@ -0,0 +1,133 @@ |
|||
package com.guozhi.bloodanalysis.parser.utils; |
|||
|
|||
import java.io.ByteArrayOutputStream; |
|||
import java.security.InvalidKeyException; |
|||
import java.security.Key; |
|||
import java.security.NoSuchAlgorithmException; |
|||
import java.security.spec.InvalidKeySpecException; |
|||
|
|||
import javax.crypto.Cipher; |
|||
import javax.crypto.SecretKey; |
|||
import javax.crypto.SecretKeyFactory; |
|||
import javax.crypto.spec.DESKeySpec; |
|||
|
|||
import sun.misc.BASE64Decoder; |
|||
import sun.misc.BASE64Encoder; |
|||
|
|||
public class CryptUtils { |
|||
|
|||
/** |
|||
* @param args |
|||
*/ |
|||
public static void main(String[] args) { |
|||
String value = "hello12315677中国"; |
|||
String ss = getInstance().encrypt(value); |
|||
String end = getInstance().decrypt(ss); |
|||
System.out.println("加密后:" + ss); |
|||
System.out.println("解密后:" + end); |
|||
} |
|||
|
|||
private final static BASE64Encoder base64encoder = new BASE64Encoder(); |
|||
private final static BASE64Decoder base64decoder = new BASE64Decoder(); |
|||
private final static String encoding = "UTF-8"; |
|||
static byte[] keyData = { 1, 9, 8, 2, 0, 8, 2, 1 }; |
|||
|
|||
static CryptUtils utils = null; |
|||
public static CryptUtils getInstance(){ |
|||
if(utils == null){ |
|||
utils = new CryptUtils(); |
|||
} |
|||
return utils; |
|||
} |
|||
|
|||
/** |
|||
* 加密 |
|||
*/ |
|||
public String encrypt(String str) { |
|||
String result = str; |
|||
if (str != null && str.length() > 0) { |
|||
try { |
|||
byte[] encodeByte = symmetricEncrypto(str.getBytes(encoding)); |
|||
result = base64encoder.encode(encodeByte); |
|||
} catch (Exception e) { |
|||
e.printStackTrace(); |
|||
} |
|||
} |
|||
return result; |
|||
} |
|||
|
|||
/** |
|||
* 解密 |
|||
*/ |
|||
public String decrypt(String str) { |
|||
String result = str; |
|||
if (str != null && str.length() > 0) { |
|||
try { |
|||
byte[] encodeByte = base64decoder.decodeBuffer(str); |
|||
byte[] decoder = symmetricDecrypto(encodeByte); |
|||
result = new String(decoder, encoding); |
|||
} catch (Exception e) { |
|||
return str; |
|||
// e.printStackTrace();
|
|||
} |
|||
} |
|||
return result; |
|||
} |
|||
|
|||
/** |
|||
* 对称加密方法 |
|||
* |
|||
* @param byteSource |
|||
* 需要加密的数据 |
|||
* @return 经过加密的数据 |
|||
* @throws Exception |
|||
*/ |
|||
private byte[] symmetricEncrypto(byte[] byteSource) throws Exception { |
|||
ByteArrayOutputStream baos = new ByteArrayOutputStream(); |
|||
try { |
|||
int mode = Cipher.ENCRYPT_MODE; |
|||
Key key = createDESSecretKey(); |
|||
Cipher cipher = Cipher.getInstance("DES"); |
|||
cipher.init(mode, key); |
|||
byte[] result = cipher.doFinal(byteSource); |
|||
return result; |
|||
} catch (Exception e) { |
|||
throw e; |
|||
} finally { |
|||
baos.close(); |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* 对称解密方法 |
|||
* |
|||
* @param byteSource |
|||
* 需要解密的数据 |
|||
* @return 经过解密的数据 |
|||
* @throws Exception |
|||
*/ |
|||
private byte[] symmetricDecrypto(byte[] byteSource) throws Exception { |
|||
ByteArrayOutputStream baos = new ByteArrayOutputStream(); |
|||
try { |
|||
int mode = Cipher.DECRYPT_MODE; |
|||
Key key = createDESSecretKey(); |
|||
Cipher cipher = Cipher.getInstance("DES"); |
|||
cipher.init(mode, key); |
|||
byte[] result = cipher.doFinal(byteSource); |
|||
return result; |
|||
} catch (Exception e) { |
|||
throw e; |
|||
} finally { |
|||
baos.close(); |
|||
} |
|||
} |
|||
|
|||
SecretKey createDESSecretKey() |
|||
throws NoSuchAlgorithmException, InvalidKeyException, |
|||
InvalidKeySpecException { |
|||
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES"); |
|||
DESKeySpec keySpec = new DESKeySpec(keyData); |
|||
SecretKey key = keyFactory.generateSecret(keySpec); |
|||
return key; |
|||
} |
|||
} |
|||
@ -0,0 +1,5 @@ |
|||
package com.guozhi.bloodanalysis.parser.utils; |
|||
|
|||
public enum DatabaseType { |
|||
Oracle, Mysql, Teradata, SqlServer, GreenPlum, DB2, TDH, HIVE |
|||
} |
|||
@ -0,0 +1,14 @@ |
|||
/* |
|||
Copyright 2015 Dell Inc. |
|||
ALL RIGHTS RESERVED. |
|||
*/ |
|||
package com.guozhi.bloodanalysis.parser.utils; |
|||
|
|||
import lombok.extern.slf4j.Slf4j; |
|||
@Slf4j |
|||
public class ErrorRecorder { |
|||
|
|||
public static void logError(String error){ |
|||
log.error(error); |
|||
} |
|||
} |
|||
@ -0,0 +1,125 @@ |
|||
package com.guozhi.bloodanalysis.parser.utils; |
|||
|
|||
import java.util.*; |
|||
|
|||
import com.guozhi.bloodanalysis.entity.DataLineageInfo; |
|||
import com.guozhi.bloodanalysis.entity.MetaBloodAnalysis; |
|||
import com.guozhi.bloodanalysis.mapper.MetaBloodAnalysisMapper; |
|||
import com.guozhi.bloodanalysis.parser.vo.KColumn; |
|||
import lombok.extern.slf4j.Slf4j; |
|||
import org.apache.commons.lang3.StringUtils; |
|||
import org.springframework.beans.factory.annotation.Autowired; |
|||
import org.springframework.stereotype.Component; |
|||
|
|||
@Slf4j |
|||
@Component |
|||
public class ExportParseResultUtil { |
|||
@Autowired |
|||
private MetaBloodAnalysisMapper metaBloodAnalysisMapper; |
|||
|
|||
/** |
|||
* 从内存对象中导出数据 |
|||
* @throws Exception |
|||
*/ |
|||
public void expResult(List<KColumn> kColumns, DataLineageInfo dataLineageInfo) throws Exception{ |
|||
log.info("正在导出解析结果"); |
|||
List<String> result = new ArrayList<>(); |
|||
for (KColumn tCol : kColumns) { |
|||
getOutList(kColumns, tCol, tCol.getRefColumns(), result); |
|||
} |
|||
outTable(result,dataLineageInfo); |
|||
log.info("解析结果导出完成"); |
|||
} |
|||
|
|||
private void outTable(List<String> result, DataLineageInfo dataLineageInfo){ |
|||
for (String line : result) { |
|||
String lines [] = line.split(","); |
|||
MetaBloodAnalysis metaBloodAnalysis = new MetaBloodAnalysis(); |
|||
metaBloodAnalysis.setId(UUID.randomUUID().toString().replace("-","")); |
|||
metaBloodAnalysis.setProId(dataLineageInfo.getOnum()); |
|||
metaBloodAnalysis.setProName(dataLineageInfo.getProcName()); |
|||
metaBloodAnalysis.setSourceSysCd(lines[0]); |
|||
metaBloodAnalysis.setSourceMdlName(lines[1]); |
|||
metaBloodAnalysis.setSourceTableName(lines[2]); |
|||
metaBloodAnalysis.setSourceColName(lines[3]); |
|||
metaBloodAnalysis.setTargetSysCd(lines[4]); |
|||
metaBloodAnalysis.setTargetMdlName(lines[5]); |
|||
String[] arr = lines[6].split("\\."); |
|||
String targetTableName = arr[arr.length-1]; |
|||
metaBloodAnalysis.setTargetTableName(targetTableName); |
|||
metaBloodAnalysis.setTargetColName(lines[7]); |
|||
metaBloodAnalysisMapper.insert(metaBloodAnalysis); |
|||
} |
|||
} |
|||
|
|||
private void getOutList(List<KColumn> kColumns,KColumn tCol,List<KColumn> sCols,List<String> list){ |
|||
if(tCol.vColumn){ |
|||
for (KColumn sCol : sCols) { |
|||
getOutList(kColumns, sCol, sCol.getRefColumns(),list); |
|||
} |
|||
}else{ |
|||
for (KColumn sCol : sCols) { |
|||
if(sCol.vColumn){ |
|||
getOutList(kColumns,tCol, sCol.getRefColumns(),list); |
|||
continue; |
|||
} |
|||
//只取源表是实体表 字段信息
|
|||
if(sCol.isEvTable){ |
|||
//目标表为实体表
|
|||
if(tCol.isEvTable){ |
|||
addLineStr(tCol, sCol, list); |
|||
}else{ |
|||
String tKey = tCol.db+"."+tCol.schema+"."+tCol.tableName+"."+tCol.columnName+"."+tCol.isEvTable; |
|||
findTargetTab(kColumns, tKey, sCol, list); |
|||
} |
|||
} |
|||
|
|||
if(sCol.getRefColumns()!=null&&sCol.getRefColumns().size()>0){ |
|||
getOutList(kColumns,sCol,sCol.getRefColumns(), list); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
private void findTargetTab(List<KColumn> kColumns,String tKey,KColumn sCol,List<String> list){ |
|||
for (KColumn tCol : kColumns) { |
|||
List<KColumn> sCols = tCol.getRefColumns(); |
|||
for (KColumn t_sCol : sCols) { |
|||
String sKey = t_sCol.db+"."+t_sCol.schema+"."+t_sCol.tableName+"."+t_sCol.columnName+"."+t_sCol.isEvTable; |
|||
//如果在源中找到则看当前目标是否为真实表
|
|||
if(tKey.equals(sKey)){ |
|||
if(tCol.isEvTable){ |
|||
addLineStr(tCol, sCol, list); |
|||
}else{ |
|||
String t_tKey = tCol.db+"."+tCol.schema+"."+tCol.tableName+"."+tCol.columnName+"."+tCol.isEvTable; |
|||
if(!t_tKey.equals(tKey)){ |
|||
findTargetTab(kColumns, t_tKey, sCol, list); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
private void addLineStr(KColumn tCol,KColumn sCol,List<String> list){ |
|||
StringBuffer sb = new StringBuffer(); |
|||
sb.append(StringUtils.defaultString(sCol.db,"")); |
|||
sb.append(","); |
|||
sb.append(StringUtils.defaultString(sCol.schema,"")); |
|||
sb.append(","); |
|||
sb.append(StringUtils.defaultString(sCol.tableName,"")); |
|||
sb.append(","); |
|||
sb.append(StringUtils.defaultString(sCol.columnName,"")); |
|||
sb.append(","); |
|||
sb.append(StringUtils.defaultString(tCol.db,"")); |
|||
sb.append(","); |
|||
sb.append(StringUtils.defaultString(tCol.schema,"")); |
|||
sb.append(","); |
|||
sb.append(StringUtils.defaultString(tCol.tableName,"")); |
|||
sb.append(","); |
|||
sb.append(StringUtils.defaultString(tCol.columnName,"")); |
|||
// sb.append(System.getProperty("line.separator"));//jdk1.7以下
|
|||
// sb.append(System.lineSeparator());
|
|||
list.add(sb.toString()); |
|||
} |
|||
} |
|||
@ -0,0 +1,421 @@ |
|||
package com.guozhi.bloodanalysis.parser.utils; |
|||
|
|||
import java.awt.Point; |
|||
|
|||
import com.guozhi.bloodanalysis.parser.common.ParserContext; |
|||
import com.guozhi.bloodanalysis.parser.common.SelectParser; |
|||
import com.guozhi.bloodanalysis.parser.vo.KColumn; |
|||
import com.guozhi.bloodanalysis.parser.vo.VTable; |
|||
import gudusoft.gsqlparser.TCustomSqlStatement; |
|||
import gudusoft.gsqlparser.nodes.TAnalyticFunction; |
|||
import gudusoft.gsqlparser.nodes.TCaseExpression; |
|||
import gudusoft.gsqlparser.nodes.TExpression; |
|||
import gudusoft.gsqlparser.nodes.TExpressionList; |
|||
import gudusoft.gsqlparser.nodes.TFunctionCall; |
|||
import gudusoft.gsqlparser.nodes.TOrderByItem; |
|||
import gudusoft.gsqlparser.nodes.TOrderByItemList; |
|||
import gudusoft.gsqlparser.nodes.TParseTreeNode; |
|||
import gudusoft.gsqlparser.nodes.TParseTreeNodeList; |
|||
import gudusoft.gsqlparser.nodes.TResultColumn; |
|||
import gudusoft.gsqlparser.nodes.TWhenClauseItem; |
|||
import gudusoft.gsqlparser.nodes.TWhenClauseItemList; |
|||
import lombok.Data; |
|||
import lombok.NoArgsConstructor; |
|||
import lombok.extern.slf4j.Slf4j; |
|||
import org.springframework.beans.factory.annotation.Autowired; |
|||
import org.springframework.context.ApplicationContext; |
|||
import org.springframework.stereotype.Component; |
|||
|
|||
/** |
|||
* Created by Walk.Lai on 2015/7/25. |
|||
*/ |
|||
@Slf4j |
|||
@Component |
|||
@NoArgsConstructor |
|||
@Data |
|||
public class ExprToColumn { |
|||
|
|||
|
|||
private TCustomSqlStatement mStmt; |
|||
private ParserContext mParserContext; |
|||
|
|||
@Autowired |
|||
ApplicationContext applicationContext; |
|||
|
|||
|
|||
public ExprToColumn(TCustomSqlStatement stmt, ParserContext context, boolean keepConst) { |
|||
mStmt = stmt; |
|||
mParserContext = context; |
|||
} |
|||
|
|||
/** |
|||
* 取得列的别名 |
|||
* @param attr |
|||
* @return |
|||
*/ |
|||
private String getColumnAlias(TExpression attr){ |
|||
TParseTreeNodeList tokens = attr.getStartToken() |
|||
.getNodesStartFromThisToken(); |
|||
if (tokens != null) { |
|||
for (int i = 0; i < tokens.size(); i++) { |
|||
TParseTreeNode node = tokens.getElement(i); |
|||
if (node instanceof TResultColumn) { |
|||
TResultColumn field = (TResultColumn) node; |
|||
if (field.getAliasClause() != null) { |
|||
return field.getAliasClause().toString(); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
return null; |
|||
} |
|||
/** |
|||
* 把表达式转换成列信息 |
|||
* 一般来说一个表达式只能生成一列,但如果是*的话,就可能对应多列 |
|||
* |
|||
* @param attr |
|||
* @param stmt |
|||
* @return |
|||
*/ |
|||
private KColumn attrToColumn(TExpression attr, TCustomSqlStatement stmt ) { |
|||
|
|||
KColumn column = new KColumn(); |
|||
//getEndToken()取出来就是没带前缀的表名 t.a as aa =a, t.b bb =b
|
|||
column.columnName = SpUtils.removeQuote(attr.getEndToken().toString()); |
|||
if(column.columnName.indexOf("*")!=-1){ |
|||
column.vColumn=true; |
|||
column.isStar=true; |
|||
} |
|||
//TODO 这一段为什么这样处理
|
|||
//getExprAlias取出来的不是别名,别名要像下边这样取
|
|||
String alias=getColumnAlias(attr); |
|||
if(alias!=null){ |
|||
column.alias=alias; |
|||
}else{ |
|||
column.alias=column.columnName; |
|||
} |
|||
|
|||
if (attr.toString().indexOf(".") > 0) { //有前缀
|
|||
column.columnPrefix = SpUtils.removeQuote(attr.toString().substring(0, |
|||
attr.toString().lastIndexOf("."))); |
|||
}else{ |
|||
|
|||
} |
|||
new ColumnRefFinder().find(column,mParserContext); |
|||
|
|||
return column; |
|||
} |
|||
public KColumn exprVisit(TParseTreeNode pNode){ |
|||
return exprVisit(pNode,true); |
|||
} |
|||
public KColumn exprVisit(TParseTreeNode pNode,boolean keepConstant) { |
|||
if(pNode==null){ |
|||
return null; |
|||
} |
|||
TExpression expr = (TExpression) pNode; |
|||
KColumn toColumn=new KColumn(); |
|||
switch (expr.getExpressionType()) { |
|||
case simple_object_name_t: //select * 也算这一种情况
|
|||
return attrToColumn(expr, mStmt); |
|||
case simple_constant_t: |
|||
//TODO 根据配置判断常量值是否要当作一列
|
|||
toColumn.columnName=expr.toString(); |
|||
toColumn.vColumn=true; |
|||
toColumn.export=keepConstant; |
|||
ColumnRefFinder columnRefFinder = applicationContext.getBean(ColumnRefFinder.class); |
|||
columnRefFinder.find(toColumn,mParserContext); |
|||
return toColumn; |
|||
case subquery_t: |
|||
VTable currentTable=mParserContext.getCurrentTable();//暂存
|
|||
SelectParser sp = applicationContext.getBean(SelectParser.class); |
|||
sp.setMSelect(expr.getSubQuery()); |
|||
sp.setVTable(new VTable(SpUtils.generateId(expr.getSubQuery().toString(),""))); |
|||
sp.setMParserContext(mParserContext); |
|||
sp.parse(); |
|||
mParserContext.setCurrentTable(currentTable);//还原
|
|||
//TODO 别名?
|
|||
String alias=getColumnAlias(expr); |
|||
if(alias!=null){ |
|||
toColumn.alias=alias; |
|||
toColumn.columnName=toColumn.alias; |
|||
}else{ |
|||
Point location = new Point((int) expr.getEndToken().lineNo, |
|||
(int) expr.getEndToken().columnNo); |
|||
String columnName=SpUtils.generateId(mStmt.toString(), location.toString()); |
|||
toColumn.alias=columnName; |
|||
toColumn.columnName=toColumn.alias; |
|||
} |
|||
toColumn.addRefColumnList(sp.getParseResult()); |
|||
return toColumn; |
|||
case case_t: |
|||
return caseSide(expr); |
|||
case logical_and_t: |
|||
return analyseBothSide(expr); |
|||
case logical_or_t: |
|||
return analyseBothSide(expr); |
|||
case concatenate_t: //a||b
|
|||
return analyseBothSide(expr); |
|||
case logical_not_t: |
|||
return analyseLogical_not_tSide(expr); |
|||
case null_t: |
|||
return analyseNull_TSide(expr); |
|||
case simple_comparison_t: // where a=1 中的 a=1;
|
|||
return analyseBothSide(expr); |
|||
case in_t: |
|||
return analyseBothSide(expr); |
|||
case arithmetic_plus_t: |
|||
return analyseBothSide(expr); |
|||
case arithmetic_minus_t: |
|||
return analyseBothSide(expr); |
|||
case arithmetic_times_t: |
|||
return analyseBothSide(expr); |
|||
case arithmetic_divide_t: |
|||
return analyseBothSide(expr); |
|||
case typecast_t: |
|||
break; |
|||
case unknown_t: |
|||
break; |
|||
case pattern_matching_t: |
|||
break; |
|||
case unary_minus_t: |
|||
break; |
|||
case parenthesis_t: |
|||
return analyseNull_TSide(expr); |
|||
case function_t: |
|||
return functionAnalyse(expr); |
|||
case assignment_t://set a=1 中的 a=1
|
|||
return analyseBothSide(expr); |
|||
case simple_source_token_t: // select null
|
|||
return null; |
|||
case arithmetic_modulo_t: |
|||
return modSide(expr); |
|||
case list_t: |
|||
return listSide(expr); |
|||
case between_t: |
|||
return betweenSide(expr); |
|||
default: |
|||
log.info("##【留】【意】--没有检测到当前类型 : "+expr.getExpressionType()); |
|||
return null; |
|||
} |
|||
return null; |
|||
} |
|||
|
|||
private KColumn betweenSide(TExpression expr){ |
|||
KColumn column = new KColumn(); |
|||
String alias = getColumnAlias(expr); |
|||
column.vColumn = true; |
|||
column.columnName = SpUtils.generateId(expr.toString(),""); |
|||
if (alias!= null) { |
|||
column.alias = alias; |
|||
}else{ |
|||
column.alias = column.columnName; |
|||
} |
|||
column.addRefColumn(exprVisit(expr.getLeftOperand())); |
|||
column.addRefColumn(exprVisit(expr.getRightOperand())); |
|||
return column; |
|||
} |
|||
|
|||
private KColumn listSide(TExpression expr){ |
|||
KColumn column = new KColumn(); |
|||
String alias = getColumnAlias(expr); |
|||
column.vColumn = true; |
|||
column.columnName = SpUtils.generateId(expr.toString(),""); |
|||
if (alias!= null) { |
|||
column.alias = alias; |
|||
}else{ |
|||
column.alias = column.columnName; |
|||
} |
|||
TExpressionList expList = expr.getExprList(); |
|||
for (int i = 0; i < expList.size(); i++) { |
|||
TExpression exp = expList.getExpression(i); |
|||
column.addRefColumn(this.exprVisit(exp)); |
|||
} |
|||
return column; |
|||
} |
|||
|
|||
private KColumn modSide(TExpression expr){ |
|||
KColumn column = new KColumn(); |
|||
String alias = getColumnAlias(expr); |
|||
column.vColumn = true; |
|||
column.columnName = SpUtils.generateId(expr.toString(),""); |
|||
if (alias!= null) { |
|||
column.alias = alias; |
|||
}else{ |
|||
column.alias = column.columnName; |
|||
} |
|||
column.addRefColumn(analyseLeft(expr)); |
|||
return column; |
|||
} |
|||
|
|||
private KColumn caseSide(TExpression expr){ |
|||
KColumn column = new KColumn(); |
|||
column.vColumn = true; |
|||
column.columnName = SpUtils.generateId(expr.toString(),""); |
|||
String alias=getColumnAlias(expr); |
|||
if (alias!= null) { |
|||
column.alias = alias; |
|||
} |
|||
TCaseExpression caseExp = expr.getCaseExpression(); |
|||
// column.columnName = caseExp.toString().replaceAll("\r\n", "");
|
|||
//情况太复杂了,暂时不考虑case when的具体取值,如需要后期优化
|
|||
TWhenClauseItemList whenList = caseExp.getWhenClauseItemList(); |
|||
for (int i = 0; i < whenList.size(); i++) { |
|||
TWhenClauseItem item = whenList.getWhenClauseItem(i); |
|||
TExpression tExpr = item.getReturn_expr(); |
|||
TExpression sExpr = item.getComparison_expr(); |
|||
KColumn tCol = this.exprVisit(tExpr); |
|||
column.addRefColumn(tCol); |
|||
column.addRefColumn(analyseRight(sExpr)); |
|||
column.addRefColumn(analyseLeft(sExpr)); |
|||
} |
|||
column.addRefColumn(exprVisit(caseExp.getElse_expr())); |
|||
ColumnRefFinder crf = applicationContext.getBean(ColumnRefFinder.class); |
|||
crf.find(column,mParserContext); |
|||
return column; |
|||
} |
|||
|
|||
private KColumn analyseNull_TSide(TExpression expr) { |
|||
KColumn column = new KColumn(); |
|||
column.vColumn = true; |
|||
Point location = new Point((int) expr.getEndToken().lineNo, |
|||
(int) expr.getEndToken().columnNo); |
|||
column.columnName = SpUtils.generateId(mStmt.toString(), location.toString()); |
|||
|
|||
String alias=getColumnAlias(expr); |
|||
if (alias!= null) { |
|||
column.alias = alias; |
|||
}else{ |
|||
column.alias=column.columnName; |
|||
} |
|||
column.addRefColumn(exprVisit(expr.getLeftOperand())); |
|||
return column; |
|||
} |
|||
|
|||
private KColumn analyseLogical_not_tSide(TExpression expr) { |
|||
KColumn column = new KColumn(); |
|||
column.vColumn = true; |
|||
Point location = new Point((int) expr.getEndToken().lineNo, |
|||
(int) expr.getEndToken().columnNo); |
|||
column.columnName = SpUtils.generateId(mStmt.toString(), location.toString()); |
|||
|
|||
String alias=getColumnAlias(expr); |
|||
if (alias!= null) { |
|||
column.alias = alias; |
|||
}else{ |
|||
column.alias=column.columnName; |
|||
} |
|||
column.addRefColumn(exprVisit(expr.getRightOperand())); |
|||
return column; |
|||
} |
|||
|
|||
private KColumn analyseBothSide(TExpression expr) { |
|||
KColumn column = new KColumn(); |
|||
column.vColumn = true; |
|||
Point location = new Point((int) expr.getEndToken().lineNo, |
|||
(int) expr.getEndToken().columnNo); |
|||
column.columnName = SpUtils.generateId(mStmt.toString(), location.toString()); |
|||
|
|||
String alias=getColumnAlias(expr); |
|||
if (alias!= null) { |
|||
column.alias = alias; |
|||
}else{ |
|||
column.alias=column.columnName; |
|||
} |
|||
|
|||
column.addRefColumn(exprVisit(expr.getLeftOperand())); |
|||
column.addRefColumn(exprVisit(expr.getRightOperand())); |
|||
|
|||
return column; |
|||
} |
|||
|
|||
private KColumn analyseRight(TExpression expr) { |
|||
return exprVisit(expr.getRightOperand()); |
|||
} |
|||
|
|||
|
|||
private KColumn analyseLeft(TExpression expr) { |
|||
return exprVisit(expr.getLeftOperand()); |
|||
} |
|||
|
|||
|
|||
private KColumn functionAnalyse(TExpression expr){ |
|||
KColumn column=new KColumn(); |
|||
column.vColumn=true; |
|||
Point location = new Point((int) expr.getEndToken().lineNo, |
|||
(int) expr.getEndToken().columnNo); |
|||
String columnName=SpUtils.generateId(mStmt.toString(), location.toString()); |
|||
column.columnName=columnName; |
|||
String alias=getColumnAlias(expr); |
|||
if(alias!=null){ |
|||
column.alias=alias; |
|||
}else { |
|||
column.alias = columnName; |
|||
} |
|||
TFunctionCall func = expr.getFunctionCall(); |
|||
//System.out.println(func.getFunctionName());
|
|||
switch ((func.getFunctionType())){ |
|||
case extract_t: |
|||
case cast_t: |
|||
column.addRefColumn(this.exprVisit(func.getExpr1())); |
|||
break; |
|||
case trim_t: |
|||
column.addRefColumn(this.exprVisit(func.getTrimArgument().getStringExpression())); |
|||
break; |
|||
case unknown_t: |
|||
if (func.getArgs() != null){ |
|||
for ( int k = 0; k < func.getArgs( ).size( ); k++ ){ |
|||
TExpression argExpr=func.getArgs( ).getExpression(k); |
|||
column.addRefColumn(this.exprVisit(argExpr,false)); |
|||
} |
|||
}else if("DENSE_RANK".equals(func.getFunctionName()+"")||"ROW_NUMBER".equals(func.getFunctionName()+"")){ |
|||
TAnalyticFunction afun = func.getAnalyticFunction(); |
|||
//TODO wxl PARTITION BY.. 语句报错
|
|||
// TExpressionList expressionList = afun.getPartitionBy_ExprList();
|
|||
// if(expressionList!=null){
|
|||
// for ( int k = 0; k < expressionList.size( ); k++ ){
|
|||
// TExpression exp = expressionList.getExpression(k);
|
|||
// column.addRefColumn(this.exprVisit(exp,false));
|
|||
column.addRefColumn(null); |
|||
// }
|
|||
// }
|
|||
} |
|||
break; |
|||
case rank_t: |
|||
TAnalyticFunction analy = func.getAnalyticFunction(); |
|||
if(analy!=null){ |
|||
TExpressionList expList = analy.getPartitionBy_ExprList(); |
|||
if(expList!=null){ |
|||
for (int i = 0; i < expList.size(); i++) { |
|||
TExpression exp = expList.getExpression(i); |
|||
column.addRefColumn(this.exprVisit(exp,false)); |
|||
} |
|||
} |
|||
}else{ |
|||
TOrderByItemList odrList = func.getOrderByList(); |
|||
if(odrList!=null){ |
|||
for (int i = 0; i < odrList.size(); i++) { |
|||
TOrderByItem item = odrList.getOrderByItem(i); |
|||
column.addRefColumn(this.exprVisit(item.getSortKey(),false)); |
|||
} |
|||
} |
|||
} |
|||
break; |
|||
case csum_t: |
|||
TOrderByItemList odrList = func.getOrderByList(); |
|||
if(odrList!=null){ |
|||
for (int i = 0; i < odrList.size(); i++) { |
|||
TOrderByItem item = odrList.getOrderByItem(i); |
|||
column.addRefColumn(this.exprVisit(item.getSortKey(),false)); |
|||
} |
|||
} |
|||
break; |
|||
case substring_t: |
|||
column.addRefColumn(this.exprVisit(func.getExpr1())); |
|||
break; |
|||
default: |
|||
log.info("##【留】【意】--没有检测到当前函数类型 : "+func); |
|||
break; |
|||
} |
|||
return column; |
|||
} |
|||
} |
|||
@ -0,0 +1,76 @@ |
|||
package com.guozhi.bloodanalysis.parser.utils; |
|||
|
|||
import com.guozhi.bloodanalysis.mapper.MetaBloodAnalysisMapper; |
|||
import com.guozhi.bloodanalysis.parser.common.ParserContext; |
|||
import com.guozhi.bloodanalysis.parser.vo.KColumn; |
|||
import com.guozhi.bloodanalysis.parser.vo.VTable; |
|||
import org.springframework.beans.factory.annotation.Autowired; |
|||
import org.springframework.context.annotation.Scope; |
|||
import org.springframework.stereotype.Component; |
|||
|
|||
import java.util.ArrayList; |
|||
import java.util.List; |
|||
import java.util.Map; |
|||
|
|||
/** |
|||
* User: Administrator |
|||
* Date: 2015/7/28 |
|||
* Time: 22:11 |
|||
*/ |
|||
@Component |
|||
@Scope("prototype") |
|||
public class KColumnProvider { |
|||
|
|||
@Autowired |
|||
MetaBloodAnalysisMapper metaBloodAnalysisMapper; |
|||
|
|||
public List<KColumn> getColumns(VTable vt , String tableName, ParserContext context) { |
|||
if (context != null&&tableName!=null) { |
|||
VTable table = context.findTableInCurrentStatement(tableName); |
|||
if (table == null) { |
|||
table = context.findExistedTable(tableName,false); |
|||
} |
|||
if (table != null && table.getColumns().size() > 0) { |
|||
return table.getColumns(); |
|||
}else { |
|||
String[] arr = tableName.split("\\."); |
|||
List<Map<String,String>> colList = metaBloodAnalysisMapper.getColumnsByTable(arr[arr.length-1], context.getDefaultDb(),context.getDefaultSchema()); |
|||
if(colList.size()>0){ |
|||
List<KColumn> cols = new ArrayList<KColumn>(); |
|||
for (Map<String, String> colMap : colList) { |
|||
KColumn col = new KColumn(); |
|||
// col.columnPrefix = vt.alias;
|
|||
col.columnName = colMap.get("colCode"); |
|||
col.alias = col.columnName; |
|||
col.db = context.getDefaultDb(); |
|||
col.schema = context.getDefaultSchema(); |
|||
col.tableName = tableName; |
|||
col.isEvTable = true; |
|||
cols.add(col); |
|||
} |
|||
return cols; |
|||
} |
|||
} |
|||
} |
|||
if(vt!=null&&vt.tabId!=null){ |
|||
List<Map<String,String>> colList = metaBloodAnalysisMapper.getColumnsByTabId(vt.tabId, null); |
|||
if(colList.size()>0){ |
|||
List<KColumn> cols = new ArrayList<KColumn>(); |
|||
for (Map<String, String> colMap : colList) { |
|||
KColumn col = new KColumn(); |
|||
col.columnPrefix = vt.alias; |
|||
col.columnName = colMap.get("colCode"); |
|||
col.alias = col.columnName; |
|||
col.db = vt.db; |
|||
col.schema = vt.schema; |
|||
col.tableName = vt.name; |
|||
col.isEvTable = true; |
|||
cols.add(col); |
|||
} |
|||
return cols; |
|||
} |
|||
} |
|||
return null; |
|||
} |
|||
|
|||
} |
|||
@ -0,0 +1,81 @@ |
|||
package com.guozhi.bloodanalysis.parser.utils; |
|||
|
|||
import com.guozhi.bloodanalysis.mapper.MetaBloodAnalysisMapper; |
|||
import com.guozhi.bloodanalysis.parser.common.ParserContext; |
|||
import com.guozhi.bloodanalysis.parser.vo.VTable; |
|||
import lombok.Data; |
|||
import lombok.NoArgsConstructor; |
|||
import org.springframework.beans.factory.annotation.Autowired; |
|||
import org.springframework.context.ApplicationContext; |
|||
import org.springframework.context.annotation.Scope; |
|||
import org.springframework.stereotype.Component; |
|||
|
|||
import java.util.ArrayList; |
|||
import java.util.List; |
|||
import java.util.Map; |
|||
|
|||
|
|||
/** |
|||
* User: Administrator |
|||
* Date: 2015/7/28 |
|||
* Time: 22:11 |
|||
*/ |
|||
@Component |
|||
@Scope("prototype") |
|||
public class KDatabaseProvider { |
|||
|
|||
@Autowired |
|||
MetaBloodAnalysisMapper bloodAnalysisMapper; |
|||
|
|||
@Autowired |
|||
ApplicationContext applicationContext; |
|||
|
|||
public void getDatabase(VTable vTable, ParserContext context) { |
|||
boolean realTable = true; |
|||
List<String> schemas = new ArrayList<>(); |
|||
schemas.add(vTable.schema); |
|||
if(schemas.size()>1){ |
|||
for (String schema : schemas) { |
|||
List<Map<String, Object>> sysList = bloodAnalysisMapper.getSystem(schema, vTable.name); |
|||
if(sysList.size()>0){ |
|||
addRealTables(vTable, sysList, schema, context); |
|||
realTable = false; |
|||
} |
|||
} |
|||
}else{ |
|||
List<Map<String, Object>> sysList = bloodAnalysisMapper.getSystem(schemas.get(0), vTable.name); |
|||
if(sysList.size()>1){ |
|||
addRealTables(vTable, sysList, schemas.get(0), context); |
|||
}else if(sysList.size()>0){ |
|||
Map<String,Object> sysMap = sysList.get(0); |
|||
vTable.db = (String) sysMap.get("SYS_CODE"); |
|||
vTable.tabId = (String) sysMap.get("TAB_ID"); |
|||
KColumnProvider kColumnProvider = applicationContext.getBean(KColumnProvider.class); |
|||
vTable.addColumns(kColumnProvider.getColumns(vTable, null, context)); |
|||
} |
|||
} |
|||
//如果是多个,无法准确的明确出来
|
|||
vTable.setRealTable(realTable); |
|||
} |
|||
|
|||
private void addRealTables(VTable vTable , List<Map<String, Object>> sysList,String schema, ParserContext context){ |
|||
int i = 1; |
|||
for (Map<String, Object> map : sysList) { |
|||
String sysCode = (String)map.get("SYS_CODE"); |
|||
String schCode = (String)map.get("SCH_CODE"); |
|||
String tabCode = (String)map.get("TAB_CODE"); |
|||
VTable vt = new VTable(tabCode); |
|||
vt.db = sysCode; |
|||
vt.schema = schCode; |
|||
vt.alias = "T_"+schema+"_"+(i++); |
|||
Integer tabId = (Integer) map.get("TAB_ID"); |
|||
vt.tabId = String.valueOf(tabId); |
|||
vt.setRealTable(true); |
|||
KColumnProvider kColumnProvider = applicationContext.getBean(KColumnProvider.class); |
|||
vt.addColumns(kColumnProvider.getColumns(vt, null, context)); |
|||
vTable.addTable(vt); |
|||
vTable.addColumns(vt.getColumns()); |
|||
} |
|||
} |
|||
|
|||
} |
|||
@ -0,0 +1,49 @@ |
|||
package com.guozhi.bloodanalysis.parser.utils; |
|||
|
|||
import java.sql.CallableStatement; |
|||
import java.sql.Connection; |
|||
import java.sql.SQLException; |
|||
import java.util.Map; |
|||
|
|||
import org.apache.commons.logging.Log; |
|||
import org.apache.commons.logging.LogFactory; |
|||
|
|||
public class PartitionTool { |
|||
|
|||
private static Log logger = LogFactory.getLog(PartitionTool.class); |
|||
|
|||
public void truncatePartitionIfExistOrAddPartition(Connection con,Map<String,String> param){ |
|||
truncatePartitionIfExist(con,param); |
|||
addPartitionIfNoExist(con,param); |
|||
} |
|||
|
|||
public boolean truncatePartitionIfExist(Connection con,Map<String,String> map) { |
|||
String produceSql = "{call droppartition(?,?,?) }"; |
|||
boolean bool = execute(con,produceSql,map); |
|||
return bool; |
|||
} |
|||
|
|||
public boolean addPartitionIfNoExist(Connection con,Map<String,String> map) { |
|||
String produceSql = "{call addpartition(?,?,?) }"; |
|||
boolean bool = execute(con,produceSql,map); |
|||
return bool; |
|||
} |
|||
|
|||
private boolean execute(Connection con,String produceSql,Map<String,String> map){ |
|||
|
|||
String scheName = map.get("scheName"); |
|||
String tableName = map.get("tarTable"); |
|||
String partitionName = map.get("partitionName"); |
|||
logger.info("调用"+partitionName+"存储过程,参数为"+"["+scheName+","+tableName+","+partitionName+"]"); |
|||
try { |
|||
CallableStatement call = con.prepareCall(produceSql); |
|||
call.setString(1, scheName); |
|||
call.setString(2, tableName); |
|||
call.setString(3, partitionName); |
|||
return call.execute(); |
|||
} catch (SQLException e) { |
|||
logger.error("调用"+partitionName+"存储过程失败,参数为"+"["+scheName+","+tableName+","+partitionName+"]",e); |
|||
throw new RuntimeException(e); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,123 @@ |
|||
/* |
|||
Copyright 2015 Dell Inc. |
|||
ALL RIGHTS RESERVED. |
|||
*/ |
|||
package com.guozhi.bloodanalysis.parser.utils; |
|||
|
|||
import java.io.File; |
|||
import java.io.UnsupportedEncodingException; |
|||
import java.security.MessageDigest; |
|||
import java.security.NoSuchAlgorithmException; |
|||
import java.text.SimpleDateFormat; |
|||
|
|||
import lombok.extern.slf4j.Slf4j; |
|||
|
|||
import sun.misc.BASE64Encoder; |
|||
|
|||
@Slf4j |
|||
public class SpUtils { |
|||
|
|||
public static String removeQuote(String string) { |
|||
if (string != null && string.indexOf('.') != -1) { |
|||
String[] splits = string.split("\\."); |
|||
StringBuffer result = new StringBuffer(); |
|||
for (int i = 0; i < splits.length; i++) { |
|||
result.append(removeQuote(splits[i])); |
|||
if (i < splits.length - 1) { |
|||
result.append("."); |
|||
} |
|||
} |
|||
return result.toString(); |
|||
} |
|||
if (string != null && string.startsWith("\"") && string.endsWith("\"")) |
|||
return string.substring(1, string.length() - 1); |
|||
return string; |
|||
} |
|||
|
|||
public static String generateId(String wholeSQL, String idStr) { |
|||
//确定计算方法
|
|||
StringBuilder sb = new StringBuilder(wholeSQL).append(idStr); |
|||
try { |
|||
MessageDigest md5 = MessageDigest.getInstance("MD5"); |
|||
BASE64Encoder base64en = new BASE64Encoder(); |
|||
|
|||
//加密后的字符串
|
|||
|
|||
return base64en.encode(md5.digest(sb.toString().getBytes("utf-8"))); |
|||
}catch ( NoSuchAlgorithmException e){ |
|||
log.error(e.getMessage()); |
|||
}catch (UnsupportedEncodingException e){ |
|||
log.error(e.getMessage()); |
|||
} |
|||
return sb.toString(); |
|||
} |
|||
|
|||
public static String[] analyseTableName(String name){ |
|||
name=removeQuote(name); |
|||
String[] arr=name.split("\\.",3); |
|||
String[] ret=new String[]{null,null,null,null}; //db.schema.table.column
|
|||
|
|||
if(arr.length==1){ //只有表名
|
|||
ret[2]=arr[0]; |
|||
}else if(arr.length==2){//schema.table
|
|||
ret[0]=arr[0]; |
|||
ret[1]=arr[0]; |
|||
ret[2]=arr[1]; |
|||
}else if(arr.length==3) {//db.schema.table
|
|||
ret[0]=arr[0]; |
|||
ret[1]=arr[1]; |
|||
ret[2]=arr[2]; |
|||
} |
|||
return ret; |
|||
|
|||
} |
|||
|
|||
public static void deleteDir(String filePath){ |
|||
/*try { |
|||
// 创建多层目录
|
|||
if(file.isDirectory()){ |
|||
String[] children = file.list(); |
|||
//递归删除目录中的子目录下
|
|||
for (int i=0; i<children.length; i++) { |
|||
deleteDir(new File(file, children[i])); |
|||
} |
|||
} |
|||
file.delete(); |
|||
|
|||
} catch (IOException e) { |
|||
throw new Exception("目标文件未找到", e); |
|||
}*/ |
|||
java.util.Date currentTime = new java.util.Date(); |
|||
SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMdd"); |
|||
String currDateStr = formatter.format(currentTime); |
|||
File file = new File(filePath); |
|||
String[] tempList = file.list(); |
|||
File temp = null; |
|||
if(tempList!=null){ |
|||
for (int i = 0; i < tempList.length; i++) { |
|||
if(!currDateStr.equals(tempList[i])){ |
|||
if (filePath.endsWith(File.separator)) { |
|||
temp = new File(filePath + tempList[i]); |
|||
} else { |
|||
temp = new File(filePath + File.separator + tempList[i]); |
|||
} |
|||
if (temp.isFile()) { |
|||
temp.delete(); |
|||
} |
|||
if (temp.isDirectory()) { |
|||
deleteDir(filePath + "/" + tempList[i]);// 先删除文件夹里面的文件
|
|||
temp.delete(); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
public static String getNowDate(String format){ |
|||
java.util.Date currentTime = new java.util.Date(); |
|||
SimpleDateFormat formatter = new SimpleDateFormat(format); |
|||
String currDateStr = formatter.format(currentTime); |
|||
return currDateStr; |
|||
} |
|||
|
|||
} |
|||
@ -0,0 +1,9 @@ |
|||
/* |
|||
Copyright 2015 Dell Inc. |
|||
ALL RIGHTS RESERVED. |
|||
*/ |
|||
package com.guozhi.bloodanalysis.parser.vo; |
|||
|
|||
public enum ClauseType { |
|||
connectby, groupby, join, orderby, select, startwith, undefine, insert, delete, update, where |
|||
} |
|||
@ -0,0 +1,124 @@ |
|||
package com.guozhi.bloodanalysis.parser.vo; |
|||
|
|||
/** |
|||
* excel单元格封装类 |
|||
* @author HeChangZhi |
|||
* |
|||
*/ |
|||
public class ExcelCell { |
|||
|
|||
private String value;//单元格值
|
|||
|
|||
private Integer firstRow;//起始行
|
|||
|
|||
private Integer lastRow;//结束行
|
|||
|
|||
private Integer firstCol;//起始列
|
|||
|
|||
private Integer lastCol;//结束列
|
|||
|
|||
private String type; |
|||
|
|||
private String mergeDown = "0"; |
|||
|
|||
private String mergeAcross = "0"; |
|||
|
|||
private String index = ""; |
|||
|
|||
private String style = ""; |
|||
|
|||
public ExcelCell(String value) { |
|||
super(); |
|||
this.value = value; |
|||
} |
|||
|
|||
public ExcelCell(String value, Integer firstRow, Integer lastRow, Integer firstCol, Integer lastCol) { |
|||
super(); |
|||
this.value = value; |
|||
this.firstRow = firstRow; |
|||
this.lastRow = lastRow; |
|||
this.firstCol = firstCol; |
|||
this.lastCol = lastCol; |
|||
} |
|||
|
|||
public String getValue() { |
|||
return value; |
|||
} |
|||
|
|||
public void setValue(String value) { |
|||
this.value = value; |
|||
} |
|||
|
|||
public Integer getFirstRow() { |
|||
return firstRow; |
|||
} |
|||
|
|||
public void setFirstRow(Integer firstRow) { |
|||
this.firstRow = firstRow; |
|||
} |
|||
|
|||
public Integer getLastRow() { |
|||
return lastRow; |
|||
} |
|||
|
|||
public void setLastRow(Integer lastRow) { |
|||
this.lastRow = lastRow; |
|||
} |
|||
|
|||
public Integer getFirstCol() { |
|||
return firstCol; |
|||
} |
|||
|
|||
public void setFirstCol(Integer firstCol) { |
|||
this.firstCol = firstCol; |
|||
} |
|||
|
|||
public Integer getLastCol() { |
|||
return lastCol; |
|||
} |
|||
|
|||
public void setLastCol(Integer lastCol) { |
|||
this.lastCol = lastCol; |
|||
} |
|||
|
|||
public String getMergeDown() { |
|||
return mergeDown; |
|||
} |
|||
|
|||
public void setMergeDown(String mergeDown) { |
|||
this.mergeDown = mergeDown; |
|||
} |
|||
|
|||
public String getMergeAcross() { |
|||
return mergeAcross; |
|||
} |
|||
|
|||
public void setMergeAcross(String mergeAcross) { |
|||
this.mergeAcross = mergeAcross; |
|||
} |
|||
|
|||
public String getType() { |
|||
return type; |
|||
} |
|||
|
|||
public void setType(String type) { |
|||
this.type = type; |
|||
} |
|||
|
|||
public String getIndex() { |
|||
return index; |
|||
} |
|||
|
|||
public void setIndex(String index) { |
|||
this.index = index; |
|||
} |
|||
|
|||
public String getStyle() { |
|||
return style; |
|||
} |
|||
|
|||
public void setStyle(String style) { |
|||
this.style = style; |
|||
} |
|||
|
|||
} |
|||
@ -0,0 +1,72 @@ |
|||
package com.guozhi.bloodanalysis.parser.vo; |
|||
|
|||
import java.util.List; |
|||
import java.util.Map; |
|||
|
|||
/** |
|||
* excel sheet封装类 |
|||
* @author HeChangZhi |
|||
* |
|||
*/ |
|||
public class ExcelSheet { |
|||
/* |
|||
* sheet名称 |
|||
*/ |
|||
private String sheetName; |
|||
/* |
|||
* 表头是否合并单元格 |
|||
*/ |
|||
private boolean merged; |
|||
/* |
|||
* 表头 |
|||
* key为对象属性名 |
|||
* value为表头名称 |
|||
*/ |
|||
private Map<String, ExcelCell> titles; |
|||
/* |
|||
* excel数据 |
|||
*/ |
|||
//private List<?> datas;
|
|||
private List<Map<String, Object>> datas; |
|||
|
|||
public ExcelSheet(String sheetName, boolean merged, Map<String, ExcelCell> titles, List<Map<String, Object>> datas) { |
|||
super(); |
|||
this.sheetName = sheetName; |
|||
this.merged = merged; |
|||
this.titles = titles; |
|||
this.datas = datas; |
|||
} |
|||
|
|||
public String getSheetName() { |
|||
return sheetName; |
|||
} |
|||
|
|||
public void setSheetName(String sheetName) { |
|||
this.sheetName = sheetName; |
|||
} |
|||
|
|||
public boolean isMerged() { |
|||
return merged; |
|||
} |
|||
|
|||
public void setMerged(boolean merged) { |
|||
this.merged = merged; |
|||
} |
|||
|
|||
public Map<String, ExcelCell> getTitles() { |
|||
return titles; |
|||
} |
|||
|
|||
public void setTitles(Map<String, ExcelCell> titles) { |
|||
this.titles = titles; |
|||
} |
|||
|
|||
public List<Map<String, Object>> getDatas() { |
|||
return datas; |
|||
} |
|||
|
|||
public void setDatas(List<Map<String, Object>> datas) { |
|||
this.datas = datas; |
|||
} |
|||
|
|||
} |
|||
@ -0,0 +1,146 @@ |
|||
/* |
|||
Copyright 2015 Dell Inc. |
|||
ALL RIGHTS RESERVED. |
|||
*/ |
|||
package com.guozhi.bloodanalysis.parser.vo; |
|||
|
|||
import org.apache.commons.lang3.StringUtils; |
|||
|
|||
import java.util.ArrayList; |
|||
import java.util.Collection; |
|||
import java.util.HashSet; |
|||
import java.util.List; |
|||
import java.util.Set; |
|||
|
|||
public class KColumn { |
|||
/** |
|||
* 数据库标识 |
|||
*/ |
|||
public String db; |
|||
/** |
|||
* 模式Schema |
|||
*/ |
|||
public String schema; |
|||
/** |
|||
* 表名称 |
|||
*/ |
|||
public String tableName; |
|||
/** |
|||
* 字段前缀 |
|||
*/ |
|||
public String columnPrefix; |
|||
/** |
|||
* 字段名称--业务主键 |
|||
*/ |
|||
public String columnName; |
|||
/** |
|||
* 字段别名 |
|||
*/ |
|||
public String alias;//只在同一个语句中起作用,上下文中该字段没意义
|
|||
|
|||
public boolean isEvTable = true; |
|||
|
|||
public boolean vColumn = false; |
|||
public boolean isStar=false; |
|||
public boolean export=false; |
|||
|
|||
private List<KColumn> refColumns = new ArrayList<KColumn>(); //必须使用列表以确保顺序
|
|||
private Set<KColumn> whereColumns=new HashSet<KColumn>(); |
|||
|
|||
/** |
|||
* etl标志。记录源标志。 |
|||
*/ |
|||
public String etlFlag; |
|||
|
|||
/** |
|||
* grc etl标志字段名称 |
|||
*/ |
|||
public final static String etlSrcTabName="ETL_SRC_TBL_NAME"; |
|||
public KColumn() { |
|||
|
|||
} |
|||
|
|||
public void addRefColumn(KColumn column) { |
|||
if(column!=null){ |
|||
for(KColumn col: refColumns){ |
|||
if(StringUtils.equals(col.db,column.db)&&StringUtils.equals(col.schema,column.schema) |
|||
&&StringUtils.equals(col.tableName,column.tableName) |
|||
&&StringUtils.equals(col.columnName,column.columnName) |
|||
&& StringUtils.equals(col.columnPrefix,column.columnPrefix)){ |
|||
//已存在,不再次加入
|
|||
return; |
|||
} |
|||
} |
|||
this.refColumns.add(column); |
|||
} |
|||
} |
|||
|
|||
public void addRefColumnList(Collection<KColumn> columns) { |
|||
if(columns!=null) |
|||
this.refColumns.addAll(columns); |
|||
} |
|||
|
|||
public void setRefColumnList(List<KColumn> columns) { |
|||
if(columns!=null) |
|||
this.refColumns = columns; |
|||
} |
|||
|
|||
@Override |
|||
public String toString() { |
|||
|
|||
StringBuilder sb = new StringBuilder(db+"."+schema+"."+tableName + "." + columnName ); |
|||
if(alias!=null){ |
|||
sb.append(" as "+alias); |
|||
} |
|||
if (refColumns.size() > 0) { |
|||
sb.append(" <-- "+ refColumns.toString()); |
|||
} |
|||
return sb.toString(); |
|||
} |
|||
|
|||
public String toCypherString(){ |
|||
StringBuilder sb=new StringBuilder(); |
|||
sb.append("{name:\""); |
|||
sb.append(columnName); |
|||
sb.append("\",db:\""); |
|||
sb.append(db); |
|||
sb.append("\",schema:\""); |
|||
sb.append(schema); |
|||
sb.append("\",tableName:\""); |
|||
sb.append(tableName); |
|||
// sb.append("\",vColumn:\"");
|
|||
// sb.append(vColumn);
|
|||
// sb.append("\",isStar:\"");
|
|||
// sb.append(isStar);
|
|||
sb.append("\",export:\""); |
|||
sb.append(export); |
|||
sb.append("\"}"); |
|||
return sb.toString(); |
|||
} |
|||
|
|||
public String queryDependsString(){ |
|||
StringBuilder sb=new StringBuilder(); |
|||
sb.append("Match (c:Column {name:\""); |
|||
sb.append(columnName); |
|||
sb.append("\",db:\""); |
|||
sb.append(db); |
|||
sb.append("\",schema:\""); |
|||
sb.append(schema); |
|||
sb.append("\",tableName:\""); |
|||
sb.append(tableName); |
|||
sb.append("\",export:'true'}),\n (c)-[:DEPENDS*1..10]->(c1 {export:'true'}) return c1"); |
|||
return sb.toString(); |
|||
} |
|||
|
|||
public List<KColumn> getRefColumns() { |
|||
return refColumns; |
|||
} |
|||
|
|||
public String getEtlFlag() { |
|||
return etlFlag; |
|||
} |
|||
|
|||
public void setEtlFlag(String etlFlag) { |
|||
this.etlFlag = etlFlag; |
|||
} |
|||
} |
|||
@ -0,0 +1,141 @@ |
|||
package com.guozhi.bloodanalysis.parser.vo; |
|||
|
|||
import java.util.ArrayList; |
|||
import java.util.List; |
|||
|
|||
/** |
|||
* Created by Walk.Lai on 2015/8/2. |
|||
*/ |
|||
public class VTable { |
|||
|
|||
/** |
|||
* 数据库中的表instId |
|||
*/ |
|||
public String tabId; |
|||
/** |
|||
* 数据库标识 |
|||
*/ |
|||
public String db; |
|||
/** |
|||
* 数据库Schema |
|||
*/ |
|||
public String schema; |
|||
/** |
|||
* 数据库表名 |
|||
*/ |
|||
public String name; |
|||
/** |
|||
* 表别名 |
|||
*/ |
|||
public String alias;// 只在同一个语句中起作用,上下文中该字段没意义
|
|||
/** |
|||
* 是否被依赖的表 |
|||
*/ |
|||
private boolean realTable = false; |
|||
/** |
|||
* 是否实体表,相对于临时表来讲 false临时表,true实体表 |
|||
*/ |
|||
private boolean created = true; |
|||
/** |
|||
* 表字段集合 |
|||
*/ |
|||
private List<KColumn> columns = new ArrayList<>(); |
|||
/** |
|||
* 来源表集合 |
|||
*/ |
|||
private List<VTable> fromTables = new ArrayList<>(); |
|||
/** |
|||
* grc 记录级解析标志 |
|||
*/ |
|||
public String etlFlag; |
|||
|
|||
public VTable(String name) { |
|||
this.name = name; |
|||
} |
|||
|
|||
public VTable(String name, String alias) { |
|||
this.name = name; |
|||
this.alias = alias; |
|||
} |
|||
|
|||
public String getName() { |
|||
return name; |
|||
} |
|||
|
|||
public String getFullName() { |
|||
StringBuilder sb = new StringBuilder(); |
|||
sb.append(db); |
|||
sb.append("."); |
|||
if (schema != null) { |
|||
sb.append(schema); |
|||
sb.append("."); |
|||
} |
|||
sb.append(name); |
|||
return sb.toString(); |
|||
} |
|||
|
|||
public List<KColumn> getColumns() { |
|||
return columns; |
|||
} |
|||
|
|||
public List<VTable> getFromTables() { |
|||
return fromTables; |
|||
} |
|||
|
|||
public void addColumn(KColumn column) { |
|||
columns.add(column); |
|||
} |
|||
|
|||
public void addColumns(List<KColumn> column) { |
|||
if (column != null) { |
|||
columns.addAll(column); |
|||
} |
|||
} |
|||
public void emptyColumns() { |
|||
columns.clear(); |
|||
} |
|||
|
|||
public void addTable(VTable table) { |
|||
fromTables.add(table); |
|||
} |
|||
|
|||
public boolean isRealTable() { |
|||
return realTable; |
|||
} |
|||
|
|||
public void setRealTable(boolean realTable) { |
|||
this.realTable = realTable; |
|||
} |
|||
|
|||
public String getAlias() { |
|||
return alias; |
|||
} |
|||
|
|||
public void setAlias(String alias) { |
|||
this.alias = alias; |
|||
} |
|||
|
|||
public boolean isCreated() { |
|||
return created; |
|||
} |
|||
|
|||
public void setCreated(boolean created) { |
|||
this.created = created; |
|||
} |
|||
|
|||
public String toCypherString() { |
|||
StringBuilder sb = new StringBuilder(); |
|||
sb.append("{db:\""); |
|||
sb.append(db); |
|||
sb.append("\",schema:\""); |
|||
sb.append(schema); |
|||
sb.append("\",name:\""); |
|||
sb.append(name); |
|||
sb.append("\",realTable:\""); |
|||
sb.append(realTable); |
|||
sb.append("\",created:\""); |
|||
sb.append(created); |
|||
sb.append("\"}"); |
|||
return sb.toString(); |
|||
} |
|||
} |
|||
@ -0,0 +1,110 @@ |
|||
package com.guozhi.bloodanalysis.service; |
|||
|
|||
import com.alibaba.fastjson.JSON; |
|||
import com.alibaba.fastjson.JSONArray; |
|||
import com.alibaba.fastjson.JSONObject; |
|||
import com.github.pagehelper.PageHelper; |
|||
import com.guozhi.bloodanalysis.entity.DataLineageInfo; |
|||
import com.guozhi.bloodanalysis.mapper.DataLineageInfoMapper; |
|||
import com.guozhi.bloodanalysis.mapper.MetaBloodAnalysisMapper; |
|||
import com.guozhi.bloodanalysis.parser.SqlParser; |
|||
import com.guozhi.bloodanalysis.utils.RedisUtils; |
|||
import org.apache.http.HttpEntity; |
|||
import org.apache.http.client.methods.CloseableHttpResponse; |
|||
import org.apache.http.client.methods.HttpGet; |
|||
import org.apache.http.impl.client.CloseableHttpClient; |
|||
import org.apache.http.impl.client.HttpClients; |
|||
import org.apache.http.util.EntityUtils; |
|||
import org.springframework.beans.factory.annotation.Autowired; |
|||
import org.springframework.beans.factory.annotation.Value; |
|||
import org.springframework.context.ApplicationContext; |
|||
import org.springframework.scheduling.annotation.Async; |
|||
import org.springframework.stereotype.Service; |
|||
|
|||
import javax.servlet.http.HttpServletRequest; |
|||
import java.util.ArrayList; |
|||
import java.util.HashMap; |
|||
import java.util.List; |
|||
import java.util.Map; |
|||
|
|||
@Service |
|||
public class BloodAnalysisService { |
|||
|
|||
@Autowired |
|||
DataLineageInfoMapper dataLineageInfoMapper; |
|||
|
|||
@Autowired |
|||
ApplicationContext applicationContext; |
|||
|
|||
@Value("${blood-analysis.pageNum}") |
|||
Integer pageNum; |
|||
|
|||
@Value("${blood-analysis.pageSize}") |
|||
Integer pageSize; |
|||
|
|||
@Value("${databaseUrl}") |
|||
String databaseUrl; |
|||
|
|||
@Autowired |
|||
MetaBloodAnalysisMapper mapper; |
|||
|
|||
@Autowired |
|||
RedisUtils redisUtils; |
|||
// @Autowired
|
|||
// HttpServletRequest request;
|
|||
|
|||
@Async |
|||
public void analysis(String dashUserName,String dashPassword) { |
|||
redisUtils.set("startBloodAnalysis",true); |
|||
try (CloseableHttpClient httpClient = HttpClients.createDefault()) { |
|||
// 1. 创建 POST 请求
|
|||
HttpGet get = new HttpGet(databaseUrl); |
|||
// 2. 设置请求头(可选)
|
|||
get.setHeader("Content-Type", "application/json"); |
|||
get.setHeader("dashUserName",dashUserName); |
|||
get.setHeader("dashPassword",dashPassword); |
|||
// 4. 执行请求
|
|||
try (CloseableHttpResponse response = httpClient.execute(get)) { |
|||
// 5. 获取响应
|
|||
HttpEntity entity = response.getEntity(); |
|||
if (entity != null) { |
|||
String responseStr = EntityUtils.toString(entity); |
|||
JSONObject obj = JSON.parseObject(responseStr); |
|||
JSONObject data = obj.getJSONObject("data"); |
|||
JSONArray totalList = data.getJSONArray("totalList"); |
|||
List<Map<String,String>> list = new ArrayList<>(); |
|||
if (totalList !=null && totalList.size()>0){ |
|||
for (int i = 0; i < totalList.size(); i++) { |
|||
JSONObject database = totalList.getJSONObject(i); |
|||
Map<String,String> map = new HashMap<>(); |
|||
map.put(database.getString("name"),database.getString("type")); |
|||
list.add(map); |
|||
} |
|||
mapper.deleteAllBloodData(); |
|||
parse(pageNum,pageSize,list); |
|||
} |
|||
} |
|||
} |
|||
} catch (Exception e) { |
|||
e.printStackTrace(); |
|||
} finally { |
|||
redisUtils.set("startBloodAnalysis",false); |
|||
} |
|||
} |
|||
|
|||
public void parse(Integer pageNum, Integer pageSize, List<Map<String,String>> databaseList) throws Exception { |
|||
PageHelper.startPage(pageNum,pageSize); |
|||
List<DataLineageInfo> list = dataLineageInfoMapper.search(); |
|||
if (list != null && list.size()>0){ |
|||
//访问dolphinscheduler接口,获取数据库名称以及对应的类型列表
|
|||
for (DataLineageInfo dataLineageInfo : list) { |
|||
SqlParser sqlParser = applicationContext.getBean(SqlParser.class); |
|||
sqlParser.parse(dataLineageInfo,databaseList); |
|||
} |
|||
} |
|||
if (list != null && list.size() == pageSize){ |
|||
parse(pageNum+1,pageSize,databaseList); |
|||
} |
|||
} |
|||
|
|||
} |
|||
@ -0,0 +1,81 @@ |
|||
package com.guozhi.bloodanalysis.utils; |
|||
|
|||
public class ApiResult <T>{ |
|||
private Integer code; // 状态码
|
|||
private String msg; // 返回的信息
|
|||
private T data; // 返回的数据
|
|||
|
|||
/** |
|||
* 成功时候的调用(有数据) |
|||
* @param data |
|||
* @param <T> |
|||
* @return |
|||
*/ |
|||
public static <T> ApiResult<T> success(T data){ |
|||
return new ApiResult<T>(data); |
|||
} |
|||
|
|||
/** |
|||
* 成功时候的调用(无数据) |
|||
* @param <T> |
|||
* @return |
|||
*/ |
|||
public static <T> ApiResult<T> success(){ |
|||
return new ApiResult<T>(); |
|||
} |
|||
|
|||
/** |
|||
* 异常时候的调用(有msg参数) |
|||
* @param msg |
|||
* @param <T> |
|||
* @return |
|||
*/ |
|||
public static <T> ApiResult<T> error(Integer code,String msg){ |
|||
return new ApiResult<T>(code,msg); |
|||
} |
|||
|
|||
public static <T> ApiResult<T> error(String msg){ |
|||
return new ApiResult<T>(msg); |
|||
} |
|||
|
|||
/** |
|||
* 异常时候的调用(无msg参数) |
|||
* @param <T> |
|||
* @return |
|||
*/ |
|||
public static <T> ApiResult<T> error(){ |
|||
return new ApiResult<T>("error"); |
|||
} |
|||
|
|||
private ApiResult(T data) { |
|||
this.code = 200; |
|||
this.msg = "success"; |
|||
this.data = data; |
|||
} |
|||
|
|||
private ApiResult() { |
|||
this.code = 200; |
|||
this.msg = "success"; |
|||
} |
|||
|
|||
private ApiResult(String msg) { |
|||
this.code = 400; |
|||
this.msg = msg; |
|||
} |
|||
private ApiResult(Integer code,String msg) { |
|||
this.code = code; |
|||
this.msg = msg; |
|||
} |
|||
|
|||
public Integer getCode() { |
|||
return code; |
|||
} |
|||
|
|||
public String getMsg() { |
|||
return msg; |
|||
} |
|||
|
|||
public T getData() { |
|||
return data; |
|||
} |
|||
} |
|||
@ -0,0 +1,15 @@ |
|||
package com.guozhi.bloodanalysis.utils; |
|||
|
|||
import org.springframework.stereotype.Component; |
|||
|
|||
import java.text.DateFormat; |
|||
import java.text.SimpleDateFormat; |
|||
import java.util.Date; |
|||
|
|||
@Component |
|||
public class DateUtils { |
|||
public String getFormateByDate(Date date){ |
|||
DateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); |
|||
return sdf.format(date); |
|||
} |
|||
} |
|||
@ -0,0 +1,31 @@ |
|||
package com.guozhi.bloodanalysis.utils; |
|||
|
|||
import java.security.MessageDigest; |
|||
import java.security.NoSuchAlgorithmException; |
|||
|
|||
public class EncryptUtils { |
|||
|
|||
public static String encryptSHA256(String str){ |
|||
return sha("SHA-256",str); |
|||
} |
|||
private static String sha(String type,String str){ |
|||
String result = null; |
|||
try { |
|||
MessageDigest md = MessageDigest.getInstance(type); |
|||
md.update(str.getBytes()); |
|||
byte[] byteBuffer = md.digest(); |
|||
StringBuilder strHexString = new StringBuilder(); |
|||
for (byte b : byteBuffer) { |
|||
String hex = Integer.toHexString(0xff & b); |
|||
if (hex.length() == 1) { |
|||
strHexString.append('0'); |
|||
} |
|||
strHexString.append(hex); |
|||
} |
|||
result = strHexString.toString(); |
|||
}catch (NoSuchAlgorithmException e){ |
|||
e.printStackTrace(); |
|||
} |
|||
return result; |
|||
} |
|||
} |
|||
@ -0,0 +1,588 @@ |
|||
package com.guozhi.bloodanalysis.utils; |
|||
|
|||
import org.springframework.data.redis.core.RedisTemplate; |
|||
import org.springframework.stereotype.Component; |
|||
import org.springframework.util.CollectionUtils; |
|||
|
|||
import javax.annotation.Resource; |
|||
import java.util.Collection; |
|||
import java.util.List; |
|||
import java.util.Map; |
|||
import java.util.Set; |
|||
import java.util.concurrent.TimeUnit; |
|||
|
|||
@Component |
|||
public final class RedisUtils { |
|||
|
|||
@Resource |
|||
private RedisTemplate<String, Object> redisTemplate; |
|||
|
|||
// =============================common============================
|
|||
|
|||
/** |
|||
* 指定缓存失效时间 |
|||
* |
|||
* @param key 键 |
|||
* @param time 时间(秒) |
|||
*/ |
|||
public boolean expire(String key, long time) { |
|||
try { |
|||
if (time > 0) { |
|||
redisTemplate.expire(key, time, TimeUnit.SECONDS); |
|||
} |
|||
return true; |
|||
} catch (Exception e) { |
|||
e.printStackTrace(); |
|||
return false; |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* 根据key 获取过期时间 |
|||
* |
|||
* @param key 键 不能为null |
|||
* @return 时间(秒) 返回0代表为永久有效 |
|||
*/ |
|||
public long getExpire(String key) { |
|||
return redisTemplate.getExpire(key, TimeUnit.SECONDS); |
|||
} |
|||
|
|||
|
|||
/** |
|||
* 判断key是否存在 |
|||
* |
|||
* @param key 键 |
|||
* @return true 存在 false不存在 |
|||
*/ |
|||
public boolean hasKey(String key) { |
|||
try { |
|||
return redisTemplate.hasKey(key); |
|||
} catch (Exception e) { |
|||
e.printStackTrace(); |
|||
return false; |
|||
} |
|||
} |
|||
|
|||
|
|||
/** |
|||
* 删除缓存 |
|||
* |
|||
* @param key 可以传一个值 或多个 |
|||
*/ |
|||
@SuppressWarnings("unchecked") |
|||
public void del(String... key) { |
|||
if (key != null && key.length > 0) { |
|||
if (key.length == 1) { |
|||
redisTemplate.delete(key[0]); |
|||
} else { |
|||
redisTemplate.delete((Collection<String>) CollectionUtils.arrayToList(key)); |
|||
} |
|||
} |
|||
} |
|||
|
|||
|
|||
// ============================String=============================
|
|||
|
|||
/** |
|||
* 普通缓存获取 |
|||
* |
|||
* @param key 键 |
|||
* @return 值 |
|||
*/ |
|||
public Object get(String key) { |
|||
return key == null ? null : redisTemplate.opsForValue().get(key); |
|||
} |
|||
|
|||
/** |
|||
* 普通缓存放入 |
|||
* |
|||
* @param key 键 |
|||
* @param value 值 |
|||
* @return true成功 false失败 |
|||
*/ |
|||
|
|||
public boolean set(String key, Object value) { |
|||
try { |
|||
redisTemplate.opsForValue().set(key, value); |
|||
return true; |
|||
} catch (Exception e) { |
|||
e.printStackTrace(); |
|||
return false; |
|||
} |
|||
} |
|||
|
|||
|
|||
/** |
|||
* 普通缓存放入并设置时间 |
|||
* |
|||
* @param key 键 |
|||
* @param value 值 |
|||
* @param time 时间(秒) time要大于0 如果time小于等于0 将设置无限期 |
|||
* @return true成功 false 失败 |
|||
*/ |
|||
|
|||
public boolean set(String key, Object value, long time) { |
|||
try { |
|||
if (time > 0) { |
|||
redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS); |
|||
} else { |
|||
set(key, value); |
|||
} |
|||
return true; |
|||
} catch (Exception e) { |
|||
e.printStackTrace(); |
|||
return false; |
|||
} |
|||
} |
|||
|
|||
|
|||
/** |
|||
* 递增 |
|||
* |
|||
* @param key 键 |
|||
* @param delta 要增加几(大于0) |
|||
*/ |
|||
public long incr(String key, long delta) { |
|||
if (delta < 0) { |
|||
throw new RuntimeException("递增因子必须大于0"); |
|||
} |
|||
return redisTemplate.opsForValue().increment(key, delta); |
|||
} |
|||
|
|||
|
|||
/** |
|||
* 递减 |
|||
* |
|||
* @param key 键 |
|||
* @param delta 要减少几(小于0) |
|||
*/ |
|||
public long decr(String key, long delta) { |
|||
if (delta < 0) { |
|||
throw new RuntimeException("递减因子必须大于0"); |
|||
} |
|||
return redisTemplate.opsForValue().increment(key, -delta); |
|||
} |
|||
|
|||
|
|||
// ================================Map=================================
|
|||
|
|||
/** |
|||
* HashGet |
|||
* |
|||
* @param key 键 不能为null |
|||
* @param item 项 不能为null |
|||
*/ |
|||
public Object hget(String key, String item) { |
|||
return redisTemplate.opsForHash().get(key, item); |
|||
} |
|||
|
|||
/** |
|||
* 获取hashKey对应的所有键值 |
|||
* |
|||
* @param key 键 |
|||
* @return 对应的多个键值 |
|||
*/ |
|||
public Map<Object, Object> hmget(String key) { |
|||
return redisTemplate.opsForHash().entries(key); |
|||
} |
|||
|
|||
/** |
|||
* HashSet |
|||
* |
|||
* @param key 键 |
|||
* @param map 对应多个键值 |
|||
*/ |
|||
public boolean hmset(String key, Map<String, Object> map) { |
|||
try { |
|||
redisTemplate.opsForHash().putAll(key, map); |
|||
return true; |
|||
} catch (Exception e) { |
|||
e.printStackTrace(); |
|||
return false; |
|||
} |
|||
} |
|||
|
|||
|
|||
/** |
|||
* HashSet 并设置时间 |
|||
* |
|||
* @param key 键 |
|||
* @param map 对应多个键值 |
|||
* @param time 时间(秒) |
|||
* @return true成功 false失败 |
|||
*/ |
|||
public boolean hmset(String key, Map<String, Object> map, long time) { |
|||
try { |
|||
redisTemplate.opsForHash().putAll(key, map); |
|||
if (time > 0) { |
|||
expire(key, time); |
|||
} |
|||
return true; |
|||
} catch (Exception e) { |
|||
e.printStackTrace(); |
|||
return false; |
|||
} |
|||
} |
|||
|
|||
|
|||
/** |
|||
* 向一张hash表中放入数据,如果不存在将创建 |
|||
* |
|||
* @param key 键 |
|||
* @param item 项 |
|||
* @param value 值 |
|||
* @return true 成功 false失败 |
|||
*/ |
|||
public boolean hset(String key, String item, Object value) { |
|||
try { |
|||
redisTemplate.opsForHash().put(key, item, value); |
|||
return true; |
|||
} catch (Exception e) { |
|||
e.printStackTrace(); |
|||
return false; |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* 向一张hash表中放入数据,如果不存在将创建 |
|||
* |
|||
* @param key 键 |
|||
* @param item 项 |
|||
* @param value 值 |
|||
* @param time 时间(秒) 注意:如果已存在的hash表有时间,这里将会替换原有的时间 |
|||
* @return true 成功 false失败 |
|||
*/ |
|||
public boolean hset(String key, String item, Object value, long time) { |
|||
try { |
|||
redisTemplate.opsForHash().put(key, item, value); |
|||
if (time > 0) { |
|||
expire(key, time); |
|||
} |
|||
return true; |
|||
} catch (Exception e) { |
|||
e.printStackTrace(); |
|||
return false; |
|||
} |
|||
} |
|||
|
|||
|
|||
/** |
|||
* 删除hash表中的值 |
|||
* |
|||
* @param key 键 不能为null |
|||
* @param item 项 可以使多个 不能为null |
|||
*/ |
|||
public void hdel(String key, Object... item) { |
|||
redisTemplate.opsForHash().delete(key, item); |
|||
} |
|||
|
|||
|
|||
/** |
|||
* 判断hash表中是否有该项的值 |
|||
* |
|||
* @param key 键 不能为null |
|||
* @param item 项 不能为null |
|||
* @return true 存在 false不存在 |
|||
*/ |
|||
public boolean hHasKey(String key, String item) { |
|||
return redisTemplate.opsForHash().hasKey(key, item); |
|||
} |
|||
|
|||
|
|||
/** |
|||
* hash递增 如果不存在,就会创建一个 并把新增后的值返回 |
|||
* |
|||
* @param key 键 |
|||
* @param item 项 |
|||
* @param by 要增加几(大于0) |
|||
*/ |
|||
public double hincr(String key, String item, double by) { |
|||
return redisTemplate.opsForHash().increment(key, item, by); |
|||
} |
|||
|
|||
|
|||
/** |
|||
* hash递减 |
|||
* |
|||
* @param key 键 |
|||
* @param item 项 |
|||
* @param by 要减少记(小于0) |
|||
*/ |
|||
public double hdecr(String key, String item, double by) { |
|||
return redisTemplate.opsForHash().increment(key, item, -by); |
|||
} |
|||
|
|||
|
|||
// ============================set=============================
|
|||
|
|||
/** |
|||
* 根据key获取Set中的所有值 |
|||
* |
|||
* @param key 键 |
|||
*/ |
|||
public Set<Object> sGet(String key) { |
|||
try { |
|||
return redisTemplate.opsForSet().members(key); |
|||
} catch (Exception e) { |
|||
e.printStackTrace(); |
|||
return null; |
|||
} |
|||
} |
|||
|
|||
|
|||
/** |
|||
* 根据value从一个set中查询,是否存在 |
|||
* |
|||
* @param key 键 |
|||
* @param value 值 |
|||
* @return true 存在 false不存在 |
|||
*/ |
|||
public boolean sHasKey(String key, Object value) { |
|||
try { |
|||
return redisTemplate.opsForSet().isMember(key, value); |
|||
} catch (Exception e) { |
|||
e.printStackTrace(); |
|||
return false; |
|||
} |
|||
} |
|||
|
|||
|
|||
/** |
|||
* 将数据放入set缓存 |
|||
* |
|||
* @param key 键 |
|||
* @param values 值 可以是多个 |
|||
* @return 成功个数 |
|||
*/ |
|||
public long sSet(String key, Object... values) { |
|||
try { |
|||
return redisTemplate.opsForSet().add(key, values); |
|||
} catch (Exception e) { |
|||
e.printStackTrace(); |
|||
return 0; |
|||
} |
|||
} |
|||
|
|||
|
|||
/** |
|||
* 将set数据放入缓存 |
|||
* |
|||
* @param key 键 |
|||
* @param time 时间(秒) |
|||
* @param values 值 可以是多个 |
|||
* @return 成功个数 |
|||
*/ |
|||
public long sSetAndTime(String key, long time, Object... values) { |
|||
try { |
|||
Long count = redisTemplate.opsForSet().add(key, values); |
|||
if (time > 0) |
|||
expire(key, time); |
|||
return count; |
|||
} catch (Exception e) { |
|||
e.printStackTrace(); |
|||
return 0; |
|||
} |
|||
} |
|||
|
|||
|
|||
/** |
|||
* 获取set缓存的长度 |
|||
* |
|||
* @param key 键 |
|||
*/ |
|||
public long sGetSetSize(String key) { |
|||
try { |
|||
return redisTemplate.opsForSet().size(key); |
|||
} catch (Exception e) { |
|||
e.printStackTrace(); |
|||
return 0; |
|||
} |
|||
} |
|||
|
|||
|
|||
/** |
|||
* 移除值为value的 |
|||
* |
|||
* @param key 键 |
|||
* @param values 值 可以是多个 |
|||
* @return 移除的个数 |
|||
*/ |
|||
|
|||
public long setRemove(String key, Object... values) { |
|||
try { |
|||
Long count = redisTemplate.opsForSet().remove(key, values); |
|||
return count; |
|||
} catch (Exception e) { |
|||
e.printStackTrace(); |
|||
return 0; |
|||
} |
|||
} |
|||
|
|||
// ===============================list=================================
|
|||
|
|||
/** |
|||
* 获取list缓存的内容 |
|||
* |
|||
* @param key 键 |
|||
* @param start 开始 |
|||
* @param end 结束 0 到 -1代表所有值 |
|||
*/ |
|||
public List<Object> lGet(String key, long start, long end) { |
|||
try { |
|||
return redisTemplate.opsForList().range(key, start, end); |
|||
} catch (Exception e) { |
|||
e.printStackTrace(); |
|||
return null; |
|||
} |
|||
} |
|||
|
|||
|
|||
/** |
|||
* 获取list缓存的长度 |
|||
* |
|||
* @param key 键 |
|||
*/ |
|||
public long lGetListSize(String key) { |
|||
try { |
|||
return redisTemplate.opsForList().size(key); |
|||
} catch (Exception e) { |
|||
e.printStackTrace(); |
|||
return 0; |
|||
} |
|||
} |
|||
|
|||
|
|||
/** |
|||
* 通过索引 获取list中的值 |
|||
* |
|||
* @param key 键 |
|||
* @param index 索引 index>=0时, 0 表头,1 第二个元素,依次类推;index<0时,-1,表尾,-2倒数第二个元素,依次类推 |
|||
*/ |
|||
public Object lGetIndex(String key, long index) { |
|||
try { |
|||
return redisTemplate.opsForList().index(key, index); |
|||
} catch (Exception e) { |
|||
e.printStackTrace(); |
|||
return null; |
|||
} |
|||
} |
|||
|
|||
|
|||
/** |
|||
* 将list放入缓存 |
|||
* |
|||
* @param key 键 |
|||
* @param value 值 |
|||
*/ |
|||
public boolean lSet(String key, Object value) { |
|||
try { |
|||
redisTemplate.opsForList().rightPush(key, value); |
|||
return true; |
|||
} catch (Exception e) { |
|||
e.printStackTrace(); |
|||
return false; |
|||
} |
|||
} |
|||
|
|||
|
|||
/** |
|||
* 将list放入缓存 |
|||
* |
|||
* @param key 键 |
|||
* @param value 值 |
|||
* @param time 时间(秒) |
|||
*/ |
|||
public boolean lSet(String key, Object value, long time) { |
|||
try { |
|||
redisTemplate.opsForList().rightPush(key, value); |
|||
if (time > 0) |
|||
expire(key, time); |
|||
return true; |
|||
} catch (Exception e) { |
|||
e.printStackTrace(); |
|||
return false; |
|||
} |
|||
|
|||
} |
|||
|
|||
|
|||
/** |
|||
* 将list放入缓存 |
|||
* |
|||
* @param key 键 |
|||
* @param value 值 |
|||
* @return |
|||
*/ |
|||
public boolean lSet(String key, List<Object> value) { |
|||
try { |
|||
redisTemplate.opsForList().rightPushAll(key, value); |
|||
return true; |
|||
} catch (Exception e) { |
|||
e.printStackTrace(); |
|||
return false; |
|||
} |
|||
|
|||
} |
|||
|
|||
|
|||
/** |
|||
* 将list放入缓存 |
|||
* |
|||
* @param key 键 |
|||
* @param value 值 |
|||
* @param time 时间(秒) |
|||
* @return |
|||
*/ |
|||
public boolean lSet(String key, List<Object> value, long time) { |
|||
try { |
|||
redisTemplate.opsForList().rightPushAll(key, value); |
|||
if (time > 0) |
|||
expire(key, time); |
|||
return true; |
|||
} catch (Exception e) { |
|||
e.printStackTrace(); |
|||
return false; |
|||
} |
|||
} |
|||
|
|||
|
|||
/** |
|||
* 根据索引修改list中的某条数据 |
|||
* |
|||
* @param key 键 |
|||
* @param index 索引 |
|||
* @param value 值 |
|||
* @return |
|||
*/ |
|||
|
|||
public boolean lUpdateIndex(String key, long index, Object value) { |
|||
try { |
|||
redisTemplate.opsForList().set(key, index, value); |
|||
return true; |
|||
} catch (Exception e) { |
|||
e.printStackTrace(); |
|||
return false; |
|||
} |
|||
} |
|||
|
|||
|
|||
/** |
|||
* 移除N个值为value |
|||
* |
|||
* @param key 键 |
|||
* @param count 移除多少个 |
|||
* @param value 值 |
|||
* @return 移除的个数 |
|||
*/ |
|||
|
|||
public long lRemove(String key, long count, Object value) { |
|||
try { |
|||
Long remove = redisTemplate.opsForList().remove(key, count, value); |
|||
return remove; |
|||
} catch (Exception e) { |
|||
e.printStackTrace(); |
|||
return 0; |
|||
} |
|||
|
|||
} |
|||
} |
|||
@ -0,0 +1,74 @@ |
|||
server: |
|||
port: 8082 |
|||
servlet: |
|||
context-path: /bloodAnalysis |
|||
spring: |
|||
main: |
|||
allow-circular-references: true |
|||
application: |
|||
name: blood-analysis |
|||
data: |
|||
redis: |
|||
repositories: |
|||
enabled: false |
|||
datasource: |
|||
type: com.alibaba.druid.pool.DruidDataSource |
|||
initialSize: 10 |
|||
minIdle: 10 |
|||
maxActive: 200 |
|||
# 配置获取连接等待超时的时间 |
|||
maxWait: 60000 |
|||
# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 |
|||
timeBetweenEvictionRunsMillis: 60000 |
|||
# 配置一个连接在池中最小生存的时间,单位是毫秒 |
|||
minEvictableIdleTimeMillis: 30000 |
|||
validationQuery: select 'x' |
|||
testWhileIdle: true |
|||
testOnBorrow: false |
|||
testOnReturn: false |
|||
# 打开PSCache,并且指定每个连接上PSCache的大小 |
|||
poolPreparedStatements: true |
|||
maxPoolPreparedStatementPerConnectionSize: 20 |
|||
# 配置监控统计拦截的filters |
|||
filters: stat,wall,slf4j |
|||
# 通过connectProperties属性来打开mergeSql功能;慢SQL记录 |
|||
connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000 |
|||
redis: |
|||
host: 192.168.0.3 |
|||
# host: 127.0.0.1 |
|||
port: 6379 |
|||
master: |
|||
datasource: |
|||
# url: jdbc:mysql://192.168.0.3:3306/TrunkSystem?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true |
|||
# username: admin |
|||
# password: 123456 |
|||
url: jdbc:mysql://47.113.147.166:3306/vfa_test_0115?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true |
|||
username: dbf |
|||
password: 1q2w3e4r |
|||
driverClassName: com.mysql.cj.jdbc.Driver |
|||
|
|||
|
|||
mybatis: |
|||
mapper-locations: classpath:mapper/*.xml |
|||
type-aliases-package: com.xgqc.dispatch.entity |
|||
configuration: |
|||
# log-impl: org.apache.ibatis.logging.stdout.StdOutImpl |
|||
log-impl: org.apache.ibatis.logging.log4j2.Log4j2Impl |
|||
type-handlers-package: com.xgqc.dispatch.typeHandler |
|||
pagehelper: |
|||
# helper-dialect: mysql |
|||
params: count=countSql |
|||
reasonable: true |
|||
support-methods-arguments: true |
|||
auto-runtime-dialect: true |
|||
auto-dialect: true |
|||
logging: |
|||
config: classpath:log4j2-dev.xml |
|||
level: |
|||
com.xgqc.dispatch.mapper: DEBUG |
|||
|
|||
blood-analysis: |
|||
pageNum: 1 |
|||
pageSize: 1000 |
|||
|
|||
databaseUrl: http://47.121.207.11:12345/dolphinscheduler/datasources/withpwdlist?pageNo=1&pageSize=100 |
|||
@ -0,0 +1,25 @@ |
|||
develop by yfxue |
|||
//////////////////////////////////////////////////////////////////// |
|||
// _ooOoo_ // |
|||
// o8888888o // |
|||
// 88" . "88 // |
|||
// (| ^_^ |) // |
|||
// O\ = /O // |
|||
// ____/`---'\____ // |
|||
// .' \\| |// `. // |
|||
// / \\||| : |||// \ // |
|||
// / _||||| -:- |||||- \ // |
|||
// | | \\\ - /// | | // |
|||
// | \_| ''\---/'' | | // |
|||
// \ .-\__ `-` ___/-. / // |
|||
// ___`. .' /--.--\ `. . ___ // |
|||
// ."" '< `.___\_<|>_/___.' >'"". // |
|||
// | | : `- \`.;`\ _ /`;.`/ - ` : | | // |
|||
// \ \ `-. \_ __\ /__ _/ .-` / / // |
|||
// ========`-.____`-.___\_____/___.-`____.-'======== // |
|||
// `=---=' // |
|||
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ // |
|||
// 佛祖保佑 永不宕机 永无BUG // |
|||
//////////////////////////////////////////////////////////////////// |
|||
${AnsiColor.BRIGHT_BLUE} |
|||
::: Project (version:${application.version}) ::: \(^O^)/ Spring-Boot ${spring-boot.version} |
|||
@ -0,0 +1,101 @@ |
|||
<?xml version="1.0" encoding="UTF-8"?> |
|||
<!--Configuration后面的status,这个用于设置log4j2自身内部的信息输出,可以不设置,当设置成trace时,你会看到log4j2内部各种详细输出--> |
|||
<!--monitorInterval:Log4j能够自动检测修改配置 文件和重新配置本身,设置间隔秒数--> |
|||
<configuration monitorInterval="5"> |
|||
<!--日志级别以及优先级排序: OFF > FATAL > ERROR > WARN > INFO > DEBUG > TRACE > ALL --> |
|||
<!--变量配置--> |
|||
<Properties> |
|||
<!-- 格式化输出:%date表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度 %msg:日志消息,%n是换行符--> |
|||
<!-- %logger{36} 表示 Logger 名字最长36个字符 --> |
|||
<property name="LOG_PATTERN" value="%date{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n" /> |
|||
<!-- 定义日志存储的路径,不要配置相对路径 --> |
|||
<property name="FILE_PATH" value="./logs/" /> |
|||
<property name="FILE_NAME" value="backend" /> |
|||
</Properties> |
|||
|
|||
<appenders> |
|||
|
|||
<console name="Console" target="SYSTEM_OUT"> |
|||
<!--输出日志的格式--> |
|||
<PatternLayout pattern="${LOG_PATTERN}"/> |
|||
<!--控制台只输出level及其以上级别的信息(onMatch),其他的直接拒绝(onMismatch)--> |
|||
<ThresholdFilter level="DEBUG" onMatch="ACCEPT" onMismatch="DENY"/> |
|||
</console> |
|||
|
|||
<!--文件会打印出所有信息,这个log每次运行程序会自动清空,由append属性决定,适合临时测试用--> |
|||
<File name="Filelog" fileName="${FILE_PATH}/test.log" append="false"> |
|||
<PatternLayout pattern="${LOG_PATTERN}"/> |
|||
</File> |
|||
|
|||
<!-- 这个会打印出所有的info及以下级别的信息,每次大小超过size,则这size大小的日志会自动存入按年份-月份建立的文件夹下面并进行压缩,作为存档--> |
|||
<RollingFile name="RollingFileInfo" fileName="${FILE_PATH}/info.log" filePattern="${FILE_PATH}/${FILE_NAME}-INFO-%d{yyyy-MM-dd}_%i.log.gz"> |
|||
<!--控制台只输出level及以上级别的信息(onMatch),其他的直接拒绝(onMismatch)--> |
|||
<ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY"/> |
|||
<PatternLayout pattern="${LOG_PATTERN}"/> |
|||
<Policies> |
|||
<!--interval属性用来指定多久滚动一次,默认是1 hour--> |
|||
<TimeBasedTriggeringPolicy interval="1"/> |
|||
<SizeBasedTriggeringPolicy size="10MB"/> |
|||
</Policies> |
|||
<!-- DefaultRolloverStrategy属性如不设置,则默认为最多同一文件夹下7个文件开始覆盖--> |
|||
<DefaultRolloverStrategy max="15"/> |
|||
</RollingFile> |
|||
|
|||
<!-- 这个会打印出所有的warn及以下级别的信息,每次大小超过size,则这size大小的日志会自动存入按年份-月份建立的文件夹下面并进行压缩,作为存档--> |
|||
<RollingFile name="RollingFileWarn" fileName="${FILE_PATH}/warn.log" filePattern="${FILE_PATH}/${FILE_NAME}-WARN-%d{yyyy-MM-dd}_%i.log.gz"> |
|||
<!--控制台只输出level及以上级别的信息(onMatch),其他的直接拒绝(onMismatch)--> |
|||
<ThresholdFilter level="warn" onMatch="ACCEPT" onMismatch="DENY"/> |
|||
<PatternLayout pattern="${LOG_PATTERN}"/> |
|||
<Policies> |
|||
<!--interval属性用来指定多久滚动一次,默认是1 hour--> |
|||
<TimeBasedTriggeringPolicy interval="1"/> |
|||
<SizeBasedTriggeringPolicy size="10MB"/> |
|||
</Policies> |
|||
<!-- DefaultRolloverStrategy属性如不设置,则默认为最多同一文件夹下7个文件开始覆盖--> |
|||
<DefaultRolloverStrategy max="15"/> |
|||
</RollingFile> |
|||
|
|||
<!-- 这个会打印出所有的error及以下级别的信息,每次大小超过size,则这size大小的日志会自动存入按年份-月份建立的文件夹下面并进行压缩,作为存档--> |
|||
<RollingFile name="RollingFileError" fileName="${FILE_PATH}/error.log" filePattern="${FILE_PATH}/${FILE_NAME}-ERROR-%d{yyyy-MM-dd}_%i.log.gz"> |
|||
<!--控制台只输出level及以上级别的信息(onMatch),其他的直接拒绝(onMismatch)--> |
|||
<ThresholdFilter level="error" onMatch="ACCEPT" onMismatch="DENY"/> |
|||
<PatternLayout pattern="${LOG_PATTERN}"/> |
|||
<Policies> |
|||
<!--interval属性用来指定多久滚动一次,默认是1 hour--> |
|||
<TimeBasedTriggeringPolicy interval="1"/> |
|||
<SizeBasedTriggeringPolicy size="10MB"/> |
|||
</Policies> |
|||
<!-- DefaultRolloverStrategy属性如不设置,则默认为最多同一文件夹下7个文件开始覆盖--> |
|||
<DefaultRolloverStrategy max="15"/> |
|||
</RollingFile> |
|||
</appenders> |
|||
|
|||
<!--Logger节点用来单独指定日志的形式,比如要为指定包下的class指定不同的日志级别等。--> |
|||
<!--然后定义loggers,只有定义了logger并引入的appender,appender才会生效--> |
|||
<loggers> |
|||
<!--过滤掉spring和mybatis的一些无用的DEBUG信息--> |
|||
<logger name="org.mybatis" level="info" additivity="false"> |
|||
<AppenderRef ref="Console"/> |
|||
</logger> |
|||
|
|||
<!--监控系统信息--> |
|||
<!--若是additivity设为false,则 子Logger 只会在自己的appender里输出,而不会在 父Logger 的appender里输出。--> |
|||
<Logger name="org.springframework" level="info" additivity="false"> |
|||
<AppenderRef ref="Console"/> |
|||
</Logger> |
|||
|
|||
<!--配置输出sql语句--> |
|||
<logger name="org.apache.ibatis" level="DEBUG"/> |
|||
<logger name="java.sql.Connection" level="DEBUG"/> |
|||
<logger name="java.sql.Statement" level="DEBUG"/> |
|||
<logger name="java.sql.PreparedStatement" level="DEBUG"/> |
|||
|
|||
<root level="info"> |
|||
<appender-ref ref="Console"/> |
|||
<appender-ref ref="Filelog"/> |
|||
<appender-ref ref="RollingFileInfo"/> |
|||
<appender-ref ref="RollingFileWarn"/> |
|||
<appender-ref ref="RollingFileError"/> |
|||
</root> |
|||
</loggers> |
|||
</configuration> |
|||
@ -0,0 +1,8 @@ |
|||
<?xml version="1.0" encoding="UTF-8"?> |
|||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> |
|||
<mapper namespace="com.guozhi.bloodanalysis.mapper.DataLineageInfoMapper"> |
|||
<select id="search" resultType="com.guozhi.bloodanalysis.entity.DataLineageInfo"> |
|||
select onum, ssys_cd as ssysCd,mdl_name as mdlName,proc_name as procName,proc_line as procLine,proc_text as procText |
|||
from t_metadata_data_lineage_info |
|||
</select> |
|||
</mapper> |
|||
@ -0,0 +1,55 @@ |
|||
<?xml version="1.0" encoding="UTF-8"?> |
|||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> |
|||
<mapper namespace="com.guozhi.bloodanalysis.mapper.MetaBloodAnalysisMapper"> |
|||
<insert id="insert" parameterType="com.guozhi.bloodanalysis.entity.MetaBloodAnalysis"> |
|||
insert into meta_blood_analysis (id,proId,proName, |
|||
targetSysCd,targetMdlName,targetTableName,targetTableCnName,targetColName,targetColCnName,targetColType, |
|||
sourceSysCd,sourceMdlName,sourceTableName,sourceTableCnName,sourceColName,sourceColCnName,sourceColType) |
|||
values( |
|||
#{blood.id,jdbcType=VARCHAR}, |
|||
#{blood.proId,jdbcType=INTEGER}, |
|||
#{blood.proName,jdbcType=VARCHAR}, |
|||
#{blood.targetSysCd,jdbcType=VARCHAR}, |
|||
#{blood.targetMdlName,jdbcType=BOOLEAN}, |
|||
#{blood.targetTableName,jdbcType=VARCHAR}, |
|||
#{blood.targetTableCnName,jdbcType=VARCHAR}, |
|||
#{blood.targetColName,jdbcType=VARCHAR}, |
|||
#{blood.targetColCnName,jdbcType=VARCHAR}, |
|||
#{blood.targetColType,jdbcType=VARCHAR}, |
|||
#{blood.sourceSysCd,jdbcType=VARCHAR}, |
|||
#{blood.sourceMdlName,jdbcType=BOOLEAN}, |
|||
#{blood.sourceTableName,jdbcType=VARCHAR}, |
|||
#{blood.sourceTableCnName,jdbcType=VARCHAR}, |
|||
#{blood.sourceColName,jdbcType=VARCHAR}, |
|||
#{blood.sourceColCnName,jdbcType=VARCHAR}, |
|||
#{blood.sourceColType,jdbcType=VARCHAR} |
|||
) |
|||
</insert> |
|||
<select id="isColExis" resultType="com.guozhi.bloodanalysis.entity.MetaColumn"> |
|||
select a.onum as onum,a.ssys_cd as ssysCd,a.mdl_name as mdlName,a.tab_eng_name as tabEngName, b.tab_cn_name as tabCnName, |
|||
a.fld_eng_name as fldEngName,a.fld_cn_name as fldCnName from t_metadata_fld_tab_extract_info a |
|||
left join t_metadata_extract_info b on a.ssys_cd = b.ssys_cd and a.mdl_name = b.mdl_name and a.tab_eng_name = b.tab_eng_name |
|||
where a.ssys_cd = #{db} and a.mdl_name = #{schema} and a.tab_eng_name = #{tableCode} and a.fld_eng_name = #{columnName} |
|||
</select> |
|||
<select id="getColumnsByTabId" resultType="java.util.Map"> |
|||
select fld_eng_name as colCode, fld_cn_name as colName,fld_no as fldNo from t_metadata_fld_tab_extract_info a |
|||
left join t_metadata_extract_info b on a.ssys_cd = b.ssys_cd and a.mdl_name = b.mdl_name and a.tab_eng_name = b.tab_eng_name |
|||
where b.onum = #{tableId} |
|||
<if test="colCode != null and colCode !=''"> |
|||
and a.fld_eng_name = #{colCode} |
|||
</if> |
|||
order by fld_no |
|||
</select> |
|||
<select id="getColumnsByTable" resultType="java.util.Map"> |
|||
select fld_eng_name as colCode, fld_cn_name as colName,fld_no as fldNo from t_metadata_fld_tab_extract_info a |
|||
where ssys_cd =#{ssysCd} and mdl_name = #{mdlName} and tab_eng_name = #{tableName} |
|||
order by fld_no |
|||
|
|||
</select> |
|||
<select id="getSystem" resultType="java.util.Map"> |
|||
select ssys_cd as SYS_CODE, ssys_cd as SYS_NAME, mdl_name as SCH_CODE, mdl_name as SCH_NAME, tab_eng_name as TAB_CODE, tab_cn_name as TAB_NAME, onum as TAB_ID from t_metadata_extract_info where mdl_name = #{schema} and tab_eng_name = #{tableCode} |
|||
</select> |
|||
<delete id="deleteAllBloodData"> |
|||
delete from meta_blood_analysis |
|||
</delete> |
|||
</mapper> |
|||
@ -0,0 +1,13 @@ |
|||
package com.guozhi.bloodanalysis; |
|||
|
|||
import org.junit.jupiter.api.Test; |
|||
import org.springframework.boot.test.context.SpringBootTest; |
|||
|
|||
@SpringBootTest |
|||
class BloodAnalysisApplicationTests { |
|||
|
|||
@Test |
|||
void contextLoads() { |
|||
} |
|||
|
|||
} |
|||
Loading…
Reference in new issue