This commit is contained in:
j 2024-10-08 17:34:03 +08:00
commit ae59f1521f
2947 changed files with 249033 additions and 0 deletions

1
.mvn/jvm.config Normal file
View File

@ -0,0 +1 @@
-Xmx1024m -XX:MaxPermSize=256m

114
.mvn/wrapper/MavenWrapperDownloader.java vendored Normal file
View File

@ -0,0 +1,114 @@
/*
* Copyright 2007-present the original author or authors.
*
* Licensed 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.
*/
import java.util.Properties;
public class MavenWrapperDownloader {
private static final String WRAPPER_VERSION = "0.5.5";
/**
* Default URL to download the maven-wrapper.jar from, if no 'downloadUrl' is provided.
*/
private static final String DEFAULT_DOWNLOAD_URL = "https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/"
+ WRAPPER_VERSION + "/maven-wrapper-" + WRAPPER_VERSION + ".jar";
/**
* Path to the maven-wrapper.properties file, which might contain a downloadUrl property to
* use instead of the default one.
*/
private static final String MAVEN_WRAPPER_PROPERTIES_PATH =
".mvn/wrapper/maven-wrapper.properties";
/**
* Path where the maven-wrapper.jar will be saved to.
*/
private static final String MAVEN_WRAPPER_JAR_PATH =
".mvn/wrapper/maven-wrapper.jar";
/**
* Name of the property which should be used to override the default download url for the wrapper.
*/
private static final String PROPERTY_NAME_WRAPPER_URL = "wrapperUrl";
public static void main(String args[]) {
System.out.println("- Downloader started");
File baseDirectory = new File(args[0]);
System.out.println("- Using base directory: " + baseDirectory.getAbsolutePath());
// If the maven-wrapper.properties exists, read it and check if it contains a custom
// wrapperUrl parameter.
File mavenWrapperPropertyFile = new File(baseDirectory, MAVEN_WRAPPER_PROPERTIES_PATH);
String url = DEFAULT_DOWNLOAD_URL;
if(mavenWrapperPropertyFile.exists()) {
FileInputStream mavenWrapperPropertyFileInputStream = null;
try {
mavenWrapperPropertyFileInputStream = new FileInputStream(mavenWrapperPropertyFile);
Properties mavenWrapperProperties = new Properties();
mavenWrapperProperties.load(mavenWrapperPropertyFileInputStream);
url = mavenWrapperProperties.getProperty(PROPERTY_NAME_WRAPPER_URL, url);
} catch (IOException e) {
System.out.println("- ERROR loading '" + MAVEN_WRAPPER_PROPERTIES_PATH + "'");
} finally {
try {
if(mavenWrapperPropertyFileInputStream != null) {
mavenWrapperPropertyFileInputStream.close();
}
} catch (IOException e) {
// Ignore ...
}
}
}
System.out.println("- Downloading from: " + url);
File outputFile = new File(baseDirectory.getAbsolutePath(), MAVEN_WRAPPER_JAR_PATH);
if(!outputFile.getParentFile().exists()) {
if(!outputFile.getParentFile().mkdirs()) {
System.out.println(
"- ERROR creating output directory '" + outputFile.getParentFile().getAbsolutePath() + "'");
}
}
System.out.println("- Downloading to: " + outputFile.getAbsolutePath());
try {
downloadFileFromURL(url, outputFile);
System.out.println("Done");
System.exit(0);
} catch (Throwable e) {
System.out.println("- Error downloading");
e.printStackTrace();
System.exit(1);
}
}
private static void downloadFileFromURL(String urlString, File destination) throws Exception {
if (System.getenv("MVNW_USERNAME") != null && System.getenv("MVNW_PASSWORD") != null) {
String username = System.getenv("MVNW_USERNAME");
char[] password = System.getenv("MVNW_PASSWORD").toCharArray();
Authenticator.setDefault(new Authenticator() {
@Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(username, password);
}
});
}
URL website = new URL(urlString);
ReadableByteChannel rbc;
rbc = Channels.newChannel(website.openStream());
FileOutputStream fos = new FileOutputStream(destination);
fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);
fos.close();
rbc.close();
}
}

3
.mvn/wrapper/maven-wrapper.properties vendored Normal file
View File

@ -0,0 +1,3 @@
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.1/apache-maven-3.6.1-bin.zip
wrapperUrl=https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.5/maven-wrapper-0.5.5.jar

53
CODE_OF_CONDUCT.md Normal file
View File

@ -0,0 +1,53 @@
# Contributor Covenant Code of Conduct
The following code of conduct is based on full compliance with [ASF CODE OF CONDUCT](https://www.apache.org/foundation/policies/conduct.html).
## Development Concept
- Write codes with heart. Pursue clean, simplified and extremely elegant codes. Agree with concepts in <Refactoring: Improving the Design of Existing Code> and <Clean Code: A Handbook of Agile Software Craftsmanship>.
- Be familiar with codes already had, to keep consistent with the style and use.
- Highly reusable, no duplicated codes or configurations.
- Delete codes out of use in time.
## Contributor Covenant Submitting of Conduct
- Make sure all the test cases are passed, Make sure `mvn clean install` can be compiled and tested successfully.
- Make sure the test coverage rate is not lower than the dev branch.
- Make sure to check codes with Checkstyle. codes that violate check rules should have special reasons. Find checkstyle template from `sharding-sphere/src/resources/sharding_checks.xml`, please use checkstyle `8.8` to run the rules.
## Contributor Covenant Code of Conduct
- Use linux line separators.
- Keep indents (including blank lines) consistent with the previous one.
- Keep one blank line after class definition.
- No meaningless blank lines.
- Use meaningful class, method and variable names, avoid to use abbreviate.
- Return values are named with `result`; Variables in the loop structure are named with `each`; Replace `each` with `entry` in map.
- Exceptions when catch are named with `ex`; Exceptions when catch but do nothing are named with `ignored`.
- Name property files with camel-case and lowercase first letters.
- Have constants on the left and variable on the right in `==` and `equals` conditional expressions; Have variable on the left and constants on the right in `greater than` and `less than` conditional expressions.
- Use `LinkedList` in priority. Use `ArrayList` for use index to get element only.
- Use capacity based `Collection` such as `ArrayList`, `HashMap` must indicate initial capacity to avoid recalculate capacity.
- Design class as `final` class expect abstract class for extend.
- Make nested loop structures a new method.
- Use guard clauses in priority.
- Minimize the access permission for classes and methods.
- Private method should be just next to the method in which it is used; writing private methods should be in the same as the appearance order of private methods.
- No `null` parameters or return values.
- Split codes that need to add notes with it into small methods, which are explained with method names.
- Replace constructors, getters, setter methods and log variable with lombok in priority.
- Use English in all the logs and javadoc.
- Include Javadoc, todo and fixme only in the comments.
- Only `public` classes and methods need javadoc, other methods, classes and override methods do not need javadoc.
## Contributor Covenant Unit Test of Conduct
- Test codes and production codes should follow the same kind of code of conduct.
- Without particular reasons, test cases should be fully covered.
- Environment preparation codes should be separate from test codes.
- Only those that relate to junit `Assert`, hamcrest `CoreMatchers` and `Mockito` can use static import.
- For single parameter asserts, `assertTrue`, `assertFalse`, `assertNull` and `assertNotNull` should be used.
- For multiple parameter asserts, `assertThat` should be used.
- For accurate asserts, try not to use `not`, `containsString` to make assertions.
- Actual values of test cases should be named `actualXXX`, expected values `expectedXXX`.
- Class for test case and `@Test` annotation do not need javadoc.

34
CONTRIBUTING.md Normal file
View File

@ -0,0 +1,34 @@
You can report a bug, submit a new feature enhancement recommendation, or commit codes by a pull request.
## Reporting Bugs
- Before report a bug, please search from google to confirm you cannot find any hint on it.
- Look [issues List](https://github.com/sharding-sphere/sharding-sphere/issues) to confirm this issue is not a duplicated one.
- [Create](https://github.com/sharding-sphere/sharding-sphere/issues/new) a new issue.
- Define a clear and descriptive title for the issue.
- If bug reported, please provide information below:
- Details for reproduce bug step by step. Include SQL, configuration, expected results, actual results and tracing log.
- Sharding and Operation System version.
- Source code to reproduce bug on github cna copy the link here.
- Stack trace if exception thrown.
- Screenshot and animated gif to help bug reproduce if necessary.
- Screenshot for CPU, Memory, Network and IO stat if performance issue.
- If enhancement recommendation reported, please provide information below:
- Details for enhancement behaviour.
- Explain why this enhancement is general feature for most developers.
- List similar features which already available in other product if possible. Both open source and commercial software are available.
- Assign label after create issue. Label should be bug, enhancement, discussion and so on.
- Please pay attention on the issue and provide more information during discuss.
- Please close issue when it is resolved. If you don't close it, we will close it after 3 days。
- If this issue has new information, please reopen it again. Please note, issue can reopen which only closed by yourself. If the issue is closed by us, you have no permission to reopen any more.
## Commit pull request
- Please choose a interested issue, or create a new issue and then settle a correct label.
- Reply a deadline message to pickup this issue.
- Find a mentor in [Core developers list](http://incubator.apache.org/projects/shardingsphere.html), he will give you feedback for design and implements.
- Fork to your github repo and begin to work.
- Please follow Sharding's [Development conventions](https://shardingsphere.apache.org/community/en/contribute/code-conduct/), and complete check before pull request submit.
- Submit a pull request to dev branch when finished, please do not submit pull request to master.
- Mentor will do code review and discuss some details, include design, implement, performance and code style. Code will be merged until mentor accepted.
- Finally, congratulations that you have become the official contributor for Sharding!

5
DISCLAIMER Normal file
View File

@ -0,0 +1,5 @@
Apache ShardingSphere (incubating) is an effort undergoing incubation at The Apache Software Foundation (ASF), sponsored by the Apache Incubator PMC.
Incubation is required of all newly accepted projects until a further review indicates that the infrastructure,
communications, and decision making process have stabilized in a manner consistent with other successful ASF projects.
While incubation status is not necessarily a reflection of the completeness or stability of the code,
it does indicate that the project has yet to be fully endorsed by the ASF.

218
LICENSE Normal file
View File

@ -0,0 +1,218 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "{}"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright {yyyy} {name of copyright owner}
Licensed 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 ShardingSphere Subcomponents:
The Apache ShardingSphere project contains subcomponents with separate copyright
notices and license terms. Your use of the source code for the these
subcomponents is subject to the terms and conditions of the following
licenses.
========================================================================
Apache 2.0 licenses
========================================================================
The following components are provided under the Apache License. See project link for details.
The text of each license is the standard Apache 2.0 license.
Maven Wrapper(mvnw, mvnw.cmd files in root path), https://github.com/takari/maven-wrapper Apache 2.0

86
MATURITY.md Normal file
View File

@ -0,0 +1,86 @@
# Podling Maturity Assessment for ShardingSphere
## Overview
This is an assessment of the ShardingSphere podlings maturity, meant to help inform the decision (of the mentors, community, Incubator PMC and ASF Board of Directors) to graduate it as a top-level Apache project.
It is based on the ASF project maturity model at https://community.apache.org/apache-way/apache-project-maturity-model.html
## Status of this document
All open items are updated with the latest status.
## Maturity model assessment
Mentors and community members are encouraged to contribute to this page and comment on it, the following table summarizes projects self-assessment against the Apache Maturity Model.
**CODE**
| **ID** | **Description** | **Status** |
| -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- |
| **CD10** | The project produces Open Source software, for distribution to the public at no charge. | **YES.** The project source code is licensed under the `Apache License 2.0`. |
| **CD20** | The project's code is easily discoverable and publicly accessible. | **YES.** The [website](https://shardingsphere.apache.org/) includes `SCM` link which can access GitHub directly. |
| **CD30** | The code can be built in a reproducible way using widely available standard tools. | **YES.** The build uses Apache Maven and Jenkins as the continuous integration tools, user can find `How to Build` in the [GitHub's README.md](https://github.com/apache/incubator-shardingsphere/blob/dev/README.md) for more information. |
| **CD40** | The full history of the project's code is available via a source code control system, in a way that allows any released version to be recreated. | **YES.** The project uses git to manage source code, demo code, documentation and website, all releases are tagged. |
| **CD50** | The provenance of each line of code is established via the source code control system, in a reliable way based on strong authentication of the committer. When third-party contributions are committed, commit messages provide reliable information about the code provenance. | **YES.** The project uses GitHub which managed by Apache Infra, it ensuring provenance of each line of code to a committer. The third-party contributions are accepted in accordance with the [contributor guide](https://shardingsphere.apache.org/community/en/contribute/contributor/) only. |
**Licenses and Copyright**
| **ID** | **Description** | **Status** |
| -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- |
| **LC10** | The code is released under the Apache License, version 2.0. | **YES.** The [LICENSE file](https://github.com/apache/incubator-shardingsphere/blob/dev/LICENSE) is in GitHub repository. |
| **LC20** | Libraries that are mandatory dependencies of the project's code do not create more restrictions than the Apache License does. | **YES.** The [list of dependencies](https://github.com/apache/incubator-shardingsphere/tree/dev/sharding-distribution/sharding-proxy-distribution/src/main/release-docs/licenses) for binary release and [list of dependencies](https://github.com/apache/incubator-shardingsphere/tree/dev/sharding-distribution/sharding-ui-distribution/src/main/release-docs/licenses) of UI binary release have been reviewed to contain compatible licenses only. |
| **LC30** | The libraries mentioned in LC20 are available as Open Source software. | **YES.** See LC20's dependencies list. |
| **LC40** | Committers are bound by an Individual Contributor Agreement (the "Apache iCLA") that defines which code they are allowed to commit and how they need to identify code that is not their own. | **YES.** All committers have iCLAs on file before they have an apache account. |
| **LC50** | The copyright ownership of everything that the project produces is clearly defined and documented. | **YES.** All files in the source code have appropriate headers and checked by `Apache rat plugin` when build. |
**Releases**
| **ID** | **Description** | **Status** |
| -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- |
| **RE10** | Releases consist of source code, distributed using standard and open archive formats that are expected to stay readable in the long term. | **YES.** Source release is distributed via [dist.apache.org](https://dist.apache.org/repos/dist/release/incubator/shardingsphere/) and linked from [download page](https://shardingsphere.apache.org/document/current/en/downloads/). |
| **RE20** | Releases are approved by the project's PMC (see CS10), in order to make them an act of the Foundation. | **YES.** All releases have been voted by ShardingSphere community and incubator, which have least 3 (P)PMC votes. |
| **RE30** | Releases are signed and/or distributed along with digests that can be reliably used to validate the downloaded archives. | **YES.** All releases are signed, and the [KEYS file](https://dist.apache.org/repos/dist/release/incubator/shardingsphere/KEYS) is provided on dist.apache.org. |
| **RE40** | Convenience binaries can be distributed alongside source code but they are not Apache Releases -- they are just a convenience provided with no guarantee. | **YES.** Convenience binaries are distributed via [Maven Central Repository](https://mvnrepository.com/artifact/org.apache.shardingsphere), [DockerHub](https://hub.docker.com/r/apache/sharding-proxy/tags) and [dist.apache.org](https://dist.apache.org/repos/dist/release/incubator/shardingsphere/) at the same time. |
| **RE50** | The release process is documented and repeatable to the extent that someone new to the project is able to independently generate the complete set of artifacts required for a release. | **YES.** [Release guide](https://shardingsphere.apache.org/community/en/contribute/release/) is available. The releases of the project have been performed by 3 different release managers. |
**Quality**
| **ID** | **Description** | **Status** |
| -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- |
| **QU10** | The project is open and honest about the quality of its code. Various levels of quality and maturity for various modules are natural and acceptable as long as they are clearly communicated. | **YES.** All [issues](https://github.com/apache/incubator-shardingsphere/issues) record in ShardingSphere's GitHub repository. |
| **QU20** | The project puts a very high priority on producing secure software. | **YES.** Security issues are treated with the highest priority. |
| **QU30** | The project provides a well-documented, secure and private channel to report security issues, along with a documented way of responding to them. | **YES.** Website provides a [security page](https://shardingsphere.apache.org/community/en/security/) |
| **QU40** | The project puts a high priority on backwards compatibility and aims to document any incompatible changes and provide tools and documentation to help users transition to new features. | **YES.** Each release note contains all related issues and pull requests in the milestone, and extract mainly updates and API changes from milestones. |
| **QU50** | The project strives to respond to documented bug reports in a timely manner. | **YES.** The project has resolved 2000+ issues and 1200+ pull requests during 3 years. The response times on are pretty good. |
**Community**
| **ID** | **Description** | **Status** |
| -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- |
| **CO10** | The project has a well-known homepage that points to all the information required to operate according to this maturity model. | **YES.** The [website](https://shardingsphere.apache.org/) describes of the project with download, user manual, technical details, how to contribute and team introduce. |
| **CO20** | The community welcomes contributions from anyone who acts in good faith and in a respectful manner and adds value to the project. | **YES.** There is [contributor guide](https://shardingsphere.apache.org/community/en/contribute/contributor/) and the current committers are really welcome contributions. |
| **CO30** | Contributions include not only source code, but also documentation, constructive bug reports, constructive discussions, marketing and generally anything that adds value to the project. | **YES.** The contribution guide refers to non source code contribution, like [documentation](https://shardingsphere.apache.org/community/en/contribute/document-contributor/). The community has elected some non-coding committers. |
| **CO40** | The community strives to be meritocratic and over time aims to give more rights and responsibilities to contributors who add value to the project. | **YES.** The community has elected 2 new PPMC members and 4 new committers during incubation, based on meritocracy. |
| **CO50** | The way in which contributors can be granted more rights such as commit access or decision power is clearly documented and is the same for all contributors. | **YES.** The criteria is documented in the [committer guide](https://shardingsphere.apache.org/community/en/contribute/committer/). |
| **CO60** | The community operates based on consensus of its members (see CS10) who have decision power. Dictators, benevolent or not, are not welcome in Apache projects. | **YES.** The project works to build consensus. All votes have been unanimous so far. |
| **CO70** | The project strives to answer user questions in a timely manner. | **YES.** The project typically provides detailed answers to user questions within a few days via [dev@ mailing list](mailto:dev@shardingsphere.apache.org) and [GitHub issues](https://github.com/apache/incubator-shardingsphere/issues). |
**Consensus**
| **ID** | **Description** | **Status** |
| -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- |
| **CS10** | The project maintains a public list of its contributors who have decision power -- the project's PMC (Project Management Committee) consists of those contributors. | **YES.** The [team page](https://shardingsphere.apache.org/community/en/team/) list all of PPMC members and committers. |
| **CS20** | Decisions are made by consensus among PMC members 9 and are documented on the project's main communications channel. Community opinions are taken into account but the PMC has the final word if needed. | **YES.** The project has been making important decisions on the mailing lists. |
| **CS30** | Documented voting rules are used to build consensus when discussion is not sufficient. | **YES.** The project uses the standard ASF voting rules. |
| **CS40** | In Apache projects, vetoes are only valid for code commits and are justified by a technical explanation, as per the Apache voting rules defined in CS30. | **YES.** The project has not used a veto at any point during incubating. |
| **CS50** | All "important" discussions happen asynchronously in written form on the project's main communications channel. Offline, face-to-face or private discussions 11 that affect the project are also documented on that channel. | **YES.** The project has been making important decisions on the project mailing lists. Minor decisions may occasionally happen during code reviews, which are also asynchronous and in written form. |
**Independence**
| **ID** | **Description** | **Status** |
| -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- |
| **IN10** | The project is independent from any corporate or organizational influence. | **YES.** The project team gathers people from different companies (JD.com, dangdang.com, CHINA TELECOM Bestpay, DAOCloud). No company or organization has significantly more influence than any other. We can note a growth of the contributions coming from different committers. |
| **IN20** | Contributors act as themselves as opposed to representatives of a corporation or organization. | **YES.** The contributors act on their own initiative without representing a corporation or organization. |
Mentors, PPMCs and committers please discuss and modify on [wiki](https://cwiki.apache.org/confluence/display/SHARDINGSPHERE/Podling+Maturity+Assessment+for+ShardingSphere).

5
NOTICE Normal file
View File

@ -0,0 +1,5 @@
Apache ShardingSphere (incubating)
Copyright 2019-2020 The Apache Software Foundation
This product includes software developed at
The Apache Software Foundation (http://www.apache.org/).

144
README.md Normal file
View File

@ -0,0 +1,144 @@
# [ShardingSphere - Distributed Database Middleware Ecosphere](https://shardingsphere.apache.org/)
**Official website: https://shardingsphere.apache.org/**
[![License](https://img.shields.io/badge/license-Apache%202-4EB1BA.svg)](https://www.apache.org/licenses/LICENSE-2.0.html)
[![Gitter](https://badges.gitter.im/shardingsphere/shardingsphere.svg)](https://gitter.im/shardingsphere/Lobby)
[![GitHub release](https://img.shields.io/github/release/apache/incubator-shardingsphere.svg)](https://github.com/apache/incubator-shardingsphere/releases)
[![Stargazers over time](https://starchart.cc/apache/incubator-shardingsphere.svg)](https://starchart.cc/apache/incubator-shardingsphere)
[![Total Lines](https://tokei.rs/b1/github/apache/incubator-shardingsphere?category=lines)](https://github.com/apache/incubator-shardingsphere)
[![Build Status](https://builds.apache.org/job/shardingsphere-ci-dev/badge/icon)](https://builds.apache.org/job/shardingsphere-ci-dev/)
[![Coverage Status](https://coveralls.io/repos/github/apache/incubator-shardingsphere/badge.svg?branch=dev)](https://coveralls.io/github/apache/incubator-shardingsphere?branch=dev)
[![Codacy Badge](https://api.codacy.com/project/badge/Grade/278600ed40ad48e988ab485b439abbcd)](https://www.codacy.com/app/terrymanu/sharding-sphere?utm_source=github.com&utm_medium=referral&utm_content=sharding-sphere/sharding-sphere&utm_campaign=Badge_Grade)
[![snyk](https://snyk.io/test/github/apache/incubator-shardingsphere/badge.svg?targetFile=pom.xml)](https://snyk.io/test/github/apache/incubator-shardingsphere?targetFile=pom.xml)
[![OpenTracing-1.0 Badge](https://img.shields.io/badge/OpenTracing--1.0-enabled-blue.svg)](http://opentracing.io)
[![Skywalking Tracing](https://img.shields.io/badge/Skywalking%20Tracing-enable-brightgreen.svg)](https://github.com/apache/skywalking)
## Document
[![EN doc](https://img.shields.io/badge/document-English-blue.svg)](https://shardingsphere.apache.org/document/current/en/overview/)
[![CN doc](https://img.shields.io/badge/文档-中文版-blue.svg)](https://shardingsphere.apache.org/document/current/cn/overview/)
## Overview
ShardingSphere is an open-source ecosystem consisted of a set of distributed database middleware solutions, including 2 independent products, Sharding-JDBC & Sharding-Proxy & Sharding-Sidecar (todo).
They all provide functions of data sharding, distributed transaction and database orchestration, applicable in a variety of situations such as Java isomorphism, heterogeneous language and cloud native.
Aiming at reasonably making full use of the computation and storage capacity of the database in a distributed system, ShardingSphere defines itself as a middleware, rather than a totally new type of database.
As the cornerstone of many enterprises, relational database still takes a huge market share.
Therefore, at the current stage, we prefer to focus on its increment instead of a total overturn.
__Apache releases are beginning from version 4.0.0__
![ShardingSphere Scope](https://shardingsphere.apache.org//document/current/img/shardingsphere-scope_en.png)
### Sharding-JDBC
[![Maven Status](https://maven-badges.herokuapp.com/maven-central/org.apache.shardingsphere/sharding-jdbc/badge.svg)](https://mvnrepository.com/artifact/org.apache.shardingsphere/sharding-jdbc)
Sharding-JDBC defines itself as a lightweight Java framework that provides extra service at Java JDBC layer.
With the client end connecting directly to the database, it provides service in the form of jar and requires no extra deployment and dependence.
It can be considered as an enhanced JDBC driver, which is fully compatible with JDBC and all kinds of ORM frameworks.
* Applicable in any ORM framework based on JDBC, such as JPA, Hibernate, Mybatis, Spring JDBC Template or direct use of JDBC.
* Support any third-party database connection pool, such as DBCP, C3P0, BoneCP, Druid, HikariCP.
* Support any kind of JDBC standard database: MySQL, Oracle, SQLServer, PostgreSQL and any SQL92 followed databases.
![Sharding-JDBC Architecture](https://shardingsphere.apache.org//document/current/img/sharding-jdbc-brief.png)
### Sharding-Proxy
[![Download](https://img.shields.io/badge/release-download-orange.svg)](https://www.apache.org/dyn/closer.cgi?path=incubator/shardingsphere/4.0.0-RC3/apache-shardingsphere-incubating-4.0.0-RC3-sharding-proxy-bin.tar.gz)
[![Docker Pulls](https://img.shields.io/docker/pulls/shardingsphere/sharding-proxy.svg)](https://store.docker.com/community/images/shardingsphere/sharding-proxy)
Sharding-Proxy defines itself as a transparent database proxy, providing a database server that encapsulates database binary protocol to support heterogeneous languages.
Friendlier to DBA, the MySQL/PostgreSQL version provided now can use any kind of client access (such as MySQL Command Client, MySQL Workbench, Navicat etc.) that is compatible of MySQL/PostgreSQL protocol to operate data.
* Totally transparent to applications, it can be used directly as MySQL and PostgreSQL.
* Applicable to any kind of compatible client end that is compatible with MySQL and PostgreSQL protocol.
![Sharding-Proxy Architecture](https://shardingsphere.apache.org//document/current/img/sharding-proxy-brief_v2.png)
### Sharding-Sidecar(TODO)
Sharding-Sidecar (TODO) defines itself as a cloud native database agent of the Kubernetes environment, in charge of all the access to the database in the form of sidecar.
It provides a mesh layer interacting with the database, we call this as `Database Mesh`.
Database Mesh emphasizes on how to connect distributed database access application with the database.
Focusing on interaction, it effectively organizes the interaction between messy applications and the database.
The application and database that use Database Mesh to visit database will form a large grid system, where they just need to be put into the right position accordingly.
They are all governed by the mesh layer.
![Sharding-Sidecar Architecture](https://shardingsphere.apache.org//document/current/img/sharding-sidecar-brief_v2.png)
| | *Sharding-JDBC* | *Sharding-Proxy* | *Sharding-Sidecar* |
| ----------------------- | --------------- | -------------------- | ------------------ |
| Database | Any | MySQL/PostgreSQL | MySQL/PostgreSQL |
| Connections Count Cost | High | Low | High |
| Supported Languages | Java Only | Any | Any |
| Performance | Low loss | Relatively High loss | Low loss |
| Decentralization | Yes | No | No |
| Static Entry | No | Yes | No |
### Hybrid Architecture
Sharding-JDBC adopts decentralized architecture, applicable to high-performance light-weight OLTP application developed with Java;
Sharding-Proxy provides static entry and all languages support, applicable for OLAP application and the sharding databases management and operation situation.
ShardingSphere is an ecosphere consists of multiple endpoints together.
Through a mixed use of Sharding-JDBC and Sharding-Proxy and unified sharding strategy by the same registry center, ShardingSphere can build an application system applicable to all kinds of scenarios.
Architects can adjust the system architecture to the most applicable one to current business more freely.
![ShardingSphere Hybrid Architecture](https://shardingsphere.apache.org//document/current/img/shardingsphere-hybrid.png)
## Features
### Data Sharding
* Database sharding & Table sharding
* Read-write splitting
* Sharding strategy customization
* Centre-less Distributed primary key
### Distributed Transaction
* Unified Transaction API
* XA transaction
* BASE transaction
### Database Orchestration
* Dynamic Configuration
* Orchestration & Governance
* Data Encryption
* Tracing & Observability
* Elastic scaling out (Planning)
## Project Status
![Status](https://shardingsphere.apache.org/document/current/img/shardingsphere-status_en.png)
## How to Build
```bash
./mvnw clean install -Prelease
```
Artifact:
```
sharding-distribution/sharding-jdbc-distribution/target/apache-shardingsphere-incubating-${latest.release.version}-sharding-jdbc-bin.tar.gz: Binary package of Sharding-JDBC
sharding-distribution/sharding-proxy-distribution/target/apache-shardingsphere-incubating-${latest.release.version}-sharding-proxy-bin.tar.gz: Binary package of Sharding-Proxy
sharding-distribution/sharding-ui-distribution/target/apache-shardingsphere-incubating-${latest.release.version}-sharding-ui-bin.tar.gz: Binary package of Sharding-UI
sharding-distribution/shardingsphere-src-distribution/target/apache-shardingsphere-incubating-${latest.release.version}-src.zip: Source code package of ShardingSphere
```
## Landscapes
<p align="center">
<br/><br/>
<img src="https://landscape.cncf.io/images/left-logo.svg" width="150"/>&nbsp;&nbsp;<img src="https://landscape.cncf.io/images/right-logo.svg" width="200"/>
<br/><br/>
ShardingSphere enriches the <a href="https://landscape.cncf.io/landscape=observability-and-analysis&license=apache-license-2-0">CNCF CLOUD NATIVE Landscape.</a>
</p>

141
README_ZH.md Normal file
View File

@ -0,0 +1,141 @@
# [ShardingSphere - 分布式数据库中间层生态圈](https://shardingsphere.apache.org/index_zh.html)
**官方网站: https://shardingsphere.apache.org/**
[![License](https://img.shields.io/badge/license-Apache%202-4EB1BA.svg)](https://www.apache.org/licenses/LICENSE-2.0.html)
[![Gitter](https://badges.gitter.im/shardingsphere/shardingsphere.svg)](https://gitter.im/shardingsphere/Lobby)
[![GitHub release](https://img.shields.io/github/release/apache/incubator-shardingsphere.svg)](https://github.com/apache/incubator-shardingsphere/releases)
[![Stargazers over time](https://starchart.cc/apache/incubator-shardingsphere.svg)](https://starchart.cc/apache/incubator-shardingsphere)
[![Total Lines](https://tokei.rs/b1/github/apache/incubator-shardingsphere?category=lines)](https://github.com/apache/incubator-shardingsphere)
[![Build Status](https://builds.apache.org/job/shardingsphere-ci-dev/badge/icon)](https://builds.apache.org/job/shardingsphere-ci-dev/)
[![Coverage Status](https://coveralls.io/repos/github/apache/incubator-shardingsphere/badge.svg?branch=dev)](https://coveralls.io/github/apache/incubator-shardingsphere?branch=dev)
[![Codacy Badge](https://api.codacy.com/project/badge/Grade/278600ed40ad48e988ab485b439abbcd)](https://www.codacy.com/app/terrymanu/sharding-sphere?utm_source=github.com&amp;utm_medium=referral&amp;utm_content=sharding-sphere/sharding-sphere&amp;utm_campaign=Badge_Grade)
[![snyk](https://snyk.io/test/github/apache/incubator-shardingsphere/badge.svg?targetFile=pom.xml)](https://snyk.io/test/github/apache/incubator-shardingsphere?targetFile=pom.xml)
[![OpenTracing-1.0 Badge](https://img.shields.io/badge/OpenTracing--1.0-enabled-blue.svg)](http://opentracing.io)
[![Skywalking Tracing](https://img.shields.io/badge/Skywalking%20Tracing-enable-brightgreen.svg)](https://github.com/apache/skywalking)
## 文档
[![CN doc](https://img.shields.io/badge/文档-中文版-blue.svg)](https://shardingsphere.apache.org/document/current/cn/overview/)
## 概述
ShardingSphere是一套开源的分布式数据库中间件解决方案组成的生态圈它由Sharding-JDBC、Sharding-Proxy和Sharding-Sidecar计划中这3款相互独立的产品组成。
他们均提供标准化的数据分片、分布式事务和数据库治理功能可适用于如Java同构、异构语言、云原生等各种多样化的应用场景。
ShardingSphere定位为关系型数据库中间件旨在充分合理地在分布式的场景下利用关系型数据库的计算和存储能力而并非实现一个全新的关系型数据库。
它与NoSQL和NewSQL是并存而非互斥的关系。NoSQL和NewSQL作为新技术探索的前沿放眼未来拥抱变化是非常值得推荐的。反之也可以用另一种思路看待问题放眼未来关注不变的东西进而抓住事物本质。
关系型数据库当今依然占有巨大市场,是各个公司核心业务的基石,未来也难于撼动,我们目前阶段更加关注在原有基础上的增量,而非颠覆。
ShardingSphere目前已经进入[Apache孵化器](http://incubator.apache.org/projects/shardingsphere.html)
欢迎通过[shardingsphere的dev邮件列表](mailto:dev@shardingsphere.apache.org)与我们讨论。
__Apache官方发布从4.0.0版本开始。__
![ShardingSphere Scope](https://shardingsphere.apache.org//document/current/img/shardingsphere-scope_cn.png)
### Sharding-JDBC
[![Maven Status](https://maven-badges.herokuapp.com/maven-central/org.apache.shardingsphere/sharding-jdbc/badge.svg)](https://mvnrepository.com/artifact/org.apache.shardingsphere/sharding-jdbc)
定位为轻量级Java框架在Java的JDBC层提供的额外服务。
它使用客户端直连数据库以jar包形式提供服务无需额外部署和依赖可理解为增强版的JDBC驱动完全兼容JDBC和各种ORM框架。
* 适用于任何基于JDBC的ORM框架JPA, Hibernate, Mybatis, Spring JDBC Template或直接使用JDBC。
* 支持任何第三方的数据库连接池DBCP, C3P0, BoneCP, Druid, HikariCP等。
* 支持任意实现JDBC规范的数据库。目前支持MySQLOracleSQLServerPostgreSQL以及任何遵循SQL92标准的数据库。
![Sharding-JDBC Architecture](https://shardingsphere.apache.org//document/current/img/sharding-jdbc-brief.png)
### Sharding-Proxy
[![Download](https://img.shields.io/badge/release-download-orange.svg)](https://www.apache.org/dyn/closer.cgi?path=incubator/shardingsphere/4.0.0-RC3/apache-shardingsphere-incubating-4.0.0-RC3-sharding-proxy-bin.tar.gz)
[![Docker Pulls](https://img.shields.io/docker/pulls/shardingsphere/sharding-proxy.svg)](https://store.docker.com/community/images/shardingsphere/sharding-proxy)
定位为透明化的数据库代理端,提供封装了数据库二进制协议的服务端版本,用于完成对异构语言的支持。
目前先提供MySQL和PostgreSQL版本它可以使用任何兼容MySQL和PostgreSQL协议的访问客户端(如MySQL Command Client, MySQL Workbench, Navicat等)操作数据对DBA更加友好。
* 向应用程序完全透明可直接当做MySQL或PostgreSQL使用。
* 适用于任何兼容MySQL或PostgreSQL协议的的客户端。
![Sharding-Proxy Architecture](https://shardingsphere.apache.org//document/current/img/sharding-proxy-brief_v2.png)
### Sharding-SidecarTODO
定位为Kubernetes的云原生数据库代理以Sidecar的形式代理所有对数据库的访问。
通过无中心、零侵入的方案提供与数据库交互的的啮合层即Database Mesh又可称数据库网格。
Database Mesh的关注重点在于如何将分布式的数据访问应用与数据库有机串联起来它更加关注的是交互是将杂乱无章的应用与数据库之间的交互有效的梳理。
使用Database Mesh访问数据库的应用和数据库终将形成一个巨大的网格体系应用和数据库只需在网格体系中对号入座即可它们都是被啮合层所治理的对象。
![Sharding-Sidecar Architecture](https://shardingsphere.apache.org//document/current/img/sharding-sidecar-brief_v2.png)
| | *Sharding-JDBC* | *Sharding-Proxy* | *Sharding-Sidecar* |
| --------- | --------------- | ---------------- | ------------------ |
| 数据库 | 任意 | MySQL/PostgreSQL | MySQL/PostgreSQL |
| 连接消耗数 | 高 | 低 | 高 |
| 异构语言 | 仅Java | 任意 | 任意 |
| 性能 | 损耗低 | 损耗略高 | 损耗低 |
| 无中心化 | 是 | 否 | 是 |
| 静态入口 | 无 | 有 | 无 |
### 混合架构
Sharding-JDBC采用无中心化架构适用于Java开发的高性能的轻量级OLTP应用Sharding-Proxy提供静态入口以及异构语言的支持适用于OLAP应用以及对分片数据库进行管理和运维的场景。
ShardingSphere是多接入端共同组成的生态圈。
通过混合使用Sharding-JDBC和Sharding-Proxy并采用同一注册中心统一配置分片策略能够灵活的搭建适用于各种场景的应用系统使得架构师更加自由的调整适合与当前业务的最佳系统架构。
![ShardingSphere Hybrid Architecture](https://shardingsphere.apache.org//document/current/img/shardingsphere-hybrid.png)
## 功能列表
### 数据分片
* 分库 & 分表
* 读写分离
* 分片策略定制化
* 无中心化分布式主键
### 分布式事务
* 标准化事务接口
* XA强一致事务
* 柔性事务
### 数据库治理
* 配置动态化
* 编排 & 治理
* 数据脱敏
* 可视化链路追踪
* 弹性伸缩(规划中)
## 项目状态
![Status](https://shardingsphere.apache.org/document/current/img/shardingsphere-status_cn.png)
## 如何构建
```bash
./mvnw clean install -Prelease
```
构建产物:
```
sharding-distribution/sharding-jdbc-distribution/target/apache-shardingsphere-incubating-${latest.release.version}-sharding-jdbc-bin.tar.gz: Sharding-JDBC的二进制包
sharding-distribution/sharding-proxy-distribution/target/apache-shardingsphere-incubating-${latest.release.version}-sharding-proxy-bin.tar.gz: Sharding-Proxy的二进制包
sharding-distribution/sharding-ui-distribution/target/apache-shardingsphere-incubating-${latest.release.version}-sharding-ui-bin.tar.gz: Sharding-UI的二进制包
sharding-distribution/shardingsphere-src-distribution/target/apache-shardingsphere-incubating-${latest.release.version}-src.zip: ShardingSphere的源码包
```
## 全景图
<p align="center">
<br/><br/>
<img src="https://landscape.cncf.io/images/left-logo.svg" width="150"/>&nbsp;&nbsp;<img src="https://landscape.cncf.io/images/right-logo.svg" width="200"/>
<br/><br/>
ShardingSphere进入了<a href="https://landscape.cncf.io/landscape=observability-and-analysis&license=apache-license-2-0">CNCF云原生全景图。</a>
</p>

612
RELEASE-NOTES.md Normal file
View File

@ -0,0 +1,612 @@
## 4.0.1
### Bug Fixes
1. Using guava cache to fix parsing deadlock.
1. Oracle insert SQL could not work in encrypt mode.
1. Proxy for PostgreSQL decode parameters error in all types except String.
1. COM_STM_EXECUTE of proxy for MySQL could not support sysbench.
1. None sharding strategy could not config in spring-boot.
1. Plain column could not get from resultSet in sharding-encrypt mode.
1. WasNull field was wrong in GroupByStreamMergeResult.
1. Metadata.getColumns could not work in JDBC.
1. IN operator contains space and `\n` `\t` `\r` could not supported by parser.
### Enhancement
1. Optimize antlr performance using two-stage parsing strategy.
1. Add class filter constructor to restrict the illegal class from YAML.
### Change Logs
1. [MILESTONE](https://github.com/sharding-sphere/sharding-sphere/milestone/11)
## 4.0.0
### API Changes
1. Change package and maven groupId form `io.shardingsphere` to `org.apache.shardingsphere`.
1. Adjust Sharding-JDBC configuration API.
1. Adjust persist structure for registry center.
### New Features
1. SQL92 Syntax available.
1. Sharding-Proxy for PostgreSQL protocol available.
1. SQL 100% compatible if route to single data node.
1. Less-than(<), greater-than(>) and Less-than-equal(<=), greater-than-equal(>=) for sharding key operator available.
1. DISTINCT SQL syntax available.
1. Broadcast table available.
1. LEAF key generator available.
1. XA Transaction available, Atomikos, Narayana and Bitronix integrated.
1. BASE Transaction available, Seata integrated.
1. Data encrypt available.
1. Skywalking plugin available.
1. Sharding-UI available, an orchestration management platform.
### Enhancement
1. MariaDB supported.
1. Improve the compatibility of SQL parsing.
1. `SELECT FOR UPDATE` route to master data source only.
1. Hint in Sharding-Proxy available.
1. Make configuration of orchestration consistent between Sharding-JDBC and Sharding-Proxy.
1. Renew modified data sources only, not renew all the data sources.
1. Vibrate configurable for Snowflake key generator.
### Bug Fixes
1. Improve the compatibility of JDBC Driver URL.
1. Delete statement with alias available.
1. Check and disable updating sharding column.
1. Fix wrong type of TINYINT and SMALLINT as INTEGER.
### Change Logs
1. [MILESTONE #3](https://github.com/sharding-sphere/sharding-sphere/milestone/3)
1. [MILESTONE #4](https://github.com/sharding-sphere/sharding-sphere/milestone/4)
1. [MILESTONE #5](https://github.com/sharding-sphere/sharding-sphere/milestone/5)
1. [MILESTONE #6](https://github.com/sharding-sphere/sharding-sphere/milestone/6)
1. [MILESTONE #7](https://github.com/apache/incubator-shardingsphere/milestone/7)
1. [MILESTONE #8](https://github.com/apache/incubator-shardingsphere/milestone/8)
1. [MILESTONE #9](https://github.com/apache/incubator-shardingsphere/milestone/9)
## 4.0.0.RC3
### New Features
1. Sharding-UI, an orchestration management platform for ShardingSphere comes online.
1. Not only SQLs from MySQL, PostgreSQL, SQLServer, Oracle, but any SQL92 Syntax can be parsed correctly and used in ShardingSphere.
### Enhancement
1. Support using less-than character(<) and greater-than character(>) for sharding data.
1. When master and slave dataSources exist, support executing `SELECT FOR UPDATE` on master dataSource.
1. Support hint in Sharding-Proxy.
1. Finish parsing DAL syntax for MySQL.
1. Make configuration of orchestration compatible between Sharding-JDBC and Sharding-Proxy.
### Bug Fixes
1. Through Bug fix, the feature of encryption becomes much stable and applicable.
1. Support delete statement with alias.
1. Check and disable updating sharding column.
1. Fix wrong type of TINYINT and SMALLINT as INTEGER.
### Refactor
1. Rename optimized module to preprocessor module.
1. Decouple rewrite core module and sharding/encrypt features.
### Change Logs
1. [MILESTONE](https://github.com/apache/incubator-shardingsphere/milestone/8)
## 4.0.0.RC2
### API Changes
1. Optimize and delete API and configuration item of sharding logic index.
1. Update the API of encryption to support the encrypted and plain data coexistence.
### New Features
1. Integration of Seata for distributed transaction.
1. User can do data encryption by using ShardingProxy.
1. User can use Leaf-segment generator to get distributed ID.
1. Support Skywalking plugin for application performance management.
### Enhancement
1. Renew modified dataSources, not all the datasources to improve performance for configuration orchestration.
1. Improve the compatibility of SQL parsing.
### Refactor
1. Remove DatabaseType enum, use dynamic SPI to load data source type.
1. The parse engine upgrade from the 2nd generation to 3rd.
1. The Refactoring of SQL rewriting module.
### Change Logs
1. [MILESTONE](https://github.com/apache/incubator-shardingsphere/milestone/7)
## 4.0.0.RC1
Merge all change logs of version 3.1.0.M1, 3.1.0, 3.1.0.1 and 4.0.0.M1. First apache release.
### API Changes
1. Adjust persist structure for orchestration's registry center.
1. Adjust Sharding-JDBC configuration API.
1. Change package and maven groupId form `io.shardingsphere` to `org.apache.shardingsphere`.
1. Adjust spring-boot-starter.
### New Features
1. XA Transaction available.
1. Data encrypt available.
1. Use PostgreSQL protocol access Sharding-Proxy available.
1. DISTINCT SQL syntax available.
1. Broadcast table.
1. All SQL 100% compatible if route to single data node (MySQL Only).
### Change Logs
1. [MILESTONE #3](https://github.com/sharding-sphere/sharding-sphere/milestone/3)
1. [MILESTONE #4](https://github.com/sharding-sphere/sharding-sphere/milestone/4)
1. [MILESTONE #5](https://github.com/sharding-sphere/sharding-sphere/milestone/5)
1. [MILESTONE #6](https://github.com/sharding-sphere/sharding-sphere/milestone/6)
## 3.0.0
### Milestones
1. Sharding-Proxy launch. Support the use of ShardingSphere in the form of database to support for MySQL CLI and GUI client
### New Features
#### Core
1. [ISSUE #290](https://github.com/sharding-sphere/sharding-sphere/issues/290) Support batch INSERT
1. [ISSUE #501](https://github.com/sharding-sphere/sharding-sphere/issues/501) Support OR
1. [ISSUE #980](https://github.com/sharding-sphere/sharding-sphere/issues/980) Support DCL
1. [ISSUE #1111](https://github.com/sharding-sphere/sharding-sphere/issues/1111) Support MySQL DAL
#### Sharding-Proxy
1. [ISSUE #902](https://github.com/sharding-sphere/sharding-sphere/issues/902) Support XA transaction
1. [ISSUE #916](https://github.com/sharding-sphere/sharding-sphere/issues/916) Support authorization
1. [ISSUE #936](https://github.com/sharding-sphere/sharding-sphere/issues/936) Support registry center
1. [ISSUE #1046](https://github.com/sharding-sphere/sharding-sphere/issues/1046) Support multiple logic databases
### Enhancements
#### Core
1. [ISSUE #373](https://github.com/sharding-sphere/sharding-sphere/issues/373) Support `order by ?`
1. [ISSUE #610](https://github.com/sharding-sphere/sharding-sphere/issues/610) Route unicast for DQL without table
1. [ISSUE #701](https://github.com/sharding-sphere/sharding-sphere/issues/701) Caching parsed results to improve performance
1. [ISSUE #773](https://github.com/sharding-sphere/sharding-sphere/issues/773) Support sharding and autoincrement key of INSERT without column names
1. [ISSUE #935](https://github.com/sharding-sphere/sharding-sphere/issues/935) Use `YAML` instead of `JSON` to store configurations in registry center
1. [ISSUE #1004](https://github.com/sharding-sphere/sharding-sphere/issues/1004) Properties can configure for Sharding and Master-slave independent
1. [ISSUE #1205](https://github.com/sharding-sphere/sharding-sphere/issues/1205) Execute engine enhancement
#### Sharding-JDBC
1. [ISSUE #652](https://github.com/sharding-sphere/sharding-sphere/issues/652) Support `Spring Boot Starter` 2.X
1. [ISSUE #702](https://github.com/sharding-sphere/sharding-sphere/issues/702) Support `$->{..}` for inline expression
1. [ISSUE #719](https://github.com/sharding-sphere/sharding-sphere/issues/719) Support inject key generator objects by spring namespace
1. [ISSUE #720](https://github.com/sharding-sphere/sharding-sphere/issues/720) Support inject sharding algorithm objects by spring namespace
#### Sharding-Opentracing
1. [ISSUE #1172](https://github.com/sharding-sphere/sharding-sphere/issues/1172) Opentracing enhancement
### API changes
1. [ISSUE #1153](https://github.com/sharding-sphere/sharding-sphere/issues/1153) Adjust the maven artifactId for Orchestration module
1. [ISSUE #1203](https://github.com/sharding-sphere/sharding-sphere/issues/1203) Adjust Spring namespace xsd for Sharding and Master-slave
1. [ISSUE #1289](https://github.com/sharding-sphere/sharding-sphere/issues/1289) Adjust Hint API
1. [ISSUE #1302](https://github.com/sharding-sphere/sharding-sphere/issues/1302) Refine package structure
1. [ISSUE #1305](https://github.com/sharding-sphere/sharding-sphere/issues/1305) Deprecated and remove sharding-jdbc-transaction-parent module
1. [ISSUE #1382](https://github.com/sharding-sphere/sharding-sphere/issues/1328) Remove type configuration in Orchestration module
### Bug Fixes
#### Core
1. [ISSUE #569](https://github.com/sharding-sphere/sharding-sphere/issues/569) Failed to parse SQL for Oracle when ROWNUM is not at end
1. [ISSUE #628](https://github.com/sharding-sphere/sharding-sphere/issues/628) Support data type jsonb for PostgreSQL
1. [ISSUE #646](https://github.com/sharding-sphere/sharding-sphere/issues/646) When aliases in `SELECT ITEMS` correspond to the real column names of `GROUP BY` or `ORDER BY`, there is no need to generate derived columns
1. [ISSUE #806](https://github.com/sharding-sphere/sharding-sphere/issues/806) `NOT IN` parse exception
1. [ISSUE #827](https://github.com/sharding-sphere/sharding-sphere/issues/827) Endless loop for bad SQL like `SELECT * FROM table WHERE id IN ()`
1. [ISSUE #919](https://github.com/sharding-sphere/sharding-sphere/issues/919) Inline expression with groovy may cause memory leak
1. [ISSUE #993](https://github.com/sharding-sphere/sharding-sphere/issues/993) Fail to parsing PostgreSQL due to the quotation
1. [ISSUE #1015](https://github.com/sharding-sphere/sharding-sphere/issues/1015) Support SQL like `SELECT id, COUNT(*) FROM table GROUP BY 1,2`
1. [ISSUE #1120](https://github.com/sharding-sphere/sharding-sphere/issues/1120) Derived columns of `GROUP BY / ORDER BY` appear in query result
1. [ISSUE #1186](https://github.com/sharding-sphere/sharding-sphere/issues/1186) Dead lock may occur on MEMORY_STRICTLY mode when get connection on concurrency environment
1. [ISSUE #1265](https://github.com/sharding-sphere/sharding-sphere/issues/1265) RoundRobinMasterSlaveLoadBalanceAlgorithm throw an ArrayIndexOutOfBoundsException when AtomicInteger overflow
#### Sharding-JDBC
1. [ISSUE #372](https://github.com/sharding-sphere/sharding-sphere/issues/372) Reuse PreparedStatement cause cache of route result do not clean
1. [ISSUE #629](https://github.com/sharding-sphere/sharding-sphere/issues/629) Support transaction isolation on JDBC
1. [ISSUE #735](https://github.com/sharding-sphere/sharding-sphere/issues/735) Unexpected slave datasource routing result when using `Round-robin` load-balance algorithm in Mybatis
1. [ISSUE #1011](https://github.com/sharding-sphere/sharding-sphere/issues/1011) Can't resolve placeholder in `Spring Boot YAML` configuration
## 2.0.3
### New Features
#### Core
1. [ISSUE #600](https://github.com/sharding-sphere/sharding-sphere/issues/600) Support TCL
### Bug Fixes
#### Core
1. [ISSUE #540](https://github.com/sharding-sphere/sharding-sphere/issues/540) Support SQL that alias is the keyword
1. [ISSUE #577](https://github.com/sharding-sphere/sharding-sphere/issues/577) Support new line for `YAML` configuration
#### Sharding-JDBC
1. [ISSUE #522](https://github.com/sharding-sphere/sharding-sphere/issues/522) Slave database does not need to execute the DDL for read-write splitting
## 2.0.2
### Enhancements
#### Core
1. [ISSUE #475](https://github.com/sharding-sphere/sharding-sphere/issues/475) Support `CREATE INDEX`
1. [ISSUE #525](https://github.com/sharding-sphere/sharding-sphere/issues/525) Support `DROP INDEX`
### Bug Fixes
#### Core
1. [ISSUE #521](https://github.com/sharding-sphere/sharding-sphere/issues/521) `ShardingProperties` is invalid in `YAML` configuration
1. [ISSUE #529](https://github.com/sharding-sphere/sharding-sphere/issues/529) Table name capitalization cannot be queried
1. [ISSUE #541](https://github.com/sharding-sphere/sharding-sphere/issues/541) `IS NOT NULL` parse error
1. [ISSUE #557](https://github.com/sharding-sphere/sharding-sphere/issues/557) When `GROUP BY` and `ORDER BY` aliases are inconsistent, stream merging should be used
1. [ISSUE #559](https://github.com/sharding-sphere/sharding-sphere/issues/559) Support parsing numbers beginning with minus and decimal (e.g. `-.12`)
1. [ISSUE #567](https://github.com/sharding-sphere/sharding-sphere/issues/567) Add escape char for derived columns or alias when using MySQL
#### Sharding-JDBC
1. [ISSUE #520](https://github.com/sharding-sphere/sharding-sphere/issues/520) Exception is no longer `DuplicateKeyException` when the unique key conflict
## 2.0.1
### Enhancements
#### Core
1. [ISSUE #490](https://github.com/sharding-sphere/sharding-sphere/issues/490) Using `rownum` greater than or equal to or less than or equal to the result of paging is incorrect in Oracle
1. [ISSUE #496](https://github.com/sharding-sphere/sharding-sphere/issues/496) Logical table names in sharding configuration can be case sensitive
1. [ISSUE #497](https://github.com/sharding-sphere/sharding-sphere/issues/497) Close registry center gracefully
### Bug Fixes
#### Sharding-JDBC
1. [ISSUE #489](https://github.com/sharding-sphere/sharding-sphere/issues/489) Uses `RuntimeBeanReference` to prevent the creation of `InnerBean` on spring namespace
1. [ISSUE #491](https://github.com/sharding-sphere/sharding-sphere/issues/491) Can't close connection by `ResultSet.getStatement().getConnection().close()`
## 2.0.0
### Milestones
1. API adjust. Brand new groupId and artifactId for `Maven`, package name and spring namespace name. Simplify and enhance API configuration, inline expression fully configuration support
1. Support `spring-boot-starter` of `Sharding-JDBC`
1. Dynamic configuration. `ZooKeeper` and `etcd` can be used as registry to dynamically modify data sources and sharding configurations
1. Database orchestration. Fusing database access procedures to access databases and disable access to slave databases
1. ConfigMap support. Predefined metadata can be obtained in the sharding and read-write separation strategy
1. Tracking system support. You can view the invocation chain of `Sharding-JDBC` through `sky-walking` and other `Opentracing` based APM systems
### Enhancements
#### Core
1. [ISSUE #386](https://github.com/sharding-sphere/sharding-sphere/issues/386) Support SQL that does not contain table names, such as `SELECT 1`
#### Sharding-JDBC
1. [ISSUE #407](https://github.com/sharding-sphere/sharding-sphere/issues/407) Support Hyphen properties for `sharding-jdbc-spring-boot-starter`
1. [ISSUE #424](https://github.com/sharding-sphere/sharding-sphere/issues/424) Providing SQL overall execution events
### Bug Fixes
#### Core
1. [ISSUE #387](https://github.com/sharding-sphere/sharding-sphere/issues/387) Prevent errors from keywords process when '`' exists in function + column name
1. [ISSUE #419](https://github.com/sharding-sphere/sharding-sphere/issues/419) When SQL is rewritten, it does not determine whether alias is a keyword without the escape character, which results in SQL exception
1. [ISSUE #464](https://github.com/sharding-sphere/sharding-sphere/issues/464) SQL if the varchar type is not closed due to the absence of matching single quotes, and the next varchar in SQL is the wrong SQL of Chinese characters, it will lead to higher use of CPU
#### Sharding-JDBC
1. [ISSUE #394](https://github.com/sharding-sphere/sharding-sphere/issues/394) Can't only close statement
1. [ISSUE #398](https://github.com/sharding-sphere/sharding-sphere/issues/398) Use Hint routing to shield case sensitivity
1. [ISSUE #404](https://github.com/sharding-sphere/sharding-sphere/issues/404) Sharding-jdbc's spring-boot-starter does not support HikariDataSource
1. [ISSUE #436](https://github.com/sharding-sphere/sharding-sphere/issues/436) Read-write splitting, when the RoundRobin algorithm is configured from the database and MyBatis is used, it can only be routed to the same slave library
1. [ISSUE #452](https://github.com/sharding-sphere/sharding-sphere/issues/452) Sharding of DDL statements to more than one table causes a connection leak
1. [ISSUE #472](https://github.com/sharding-sphere/sharding-sphere/issues/472) Before Connection executes createStatement, it calls getMetaData first and then setAutoCommit can not take effective connection to the database that was created later
## 1.5.4.1
### Bug Fixes
1. [ISSUE #382](https://github.com/sharding-sphere/sharding-sphere/issues/382) The query cannot be completed without sharding rule
## 1.5.4
### Bug Fixes
1. [ISSUE #356](https://github.com/sharding-sphere/sharding-sphere/issues/356) In the Where condition of SQL, the REGEXP operator is compatible with non sharding columns
1. [ISSUE #362](https://github.com/sharding-sphere/sharding-sphere/issues/362) Read-write separation using PreparedStatement does not invoke the setParameter method to cause errors
1. [ISSUE #370](https://github.com/sharding-sphere/sharding-sphere/issues/370) Error in calling getGeneratedKeys using native self increment primary key
1. [ISSUE #375](https://github.com/sharding-sphere/sharding-sphere/issues/375) Data can not be obtained after paging second pages route to a single node
1. [ISSUE #379](https://github.com/sharding-sphere/sharding-sphere/issues/379) When Mybatis is used to call Connection.getMetaData (), the connection is not close correct
## 1.5.3
### Enhancements
1. [ISSUE #98](https://github.com/sharding-sphere/sharding-sphere/issues/98) Read-write separation load balancing strategy support configuration
1. [ISSUE #196](https://github.com/sharding-sphere/sharding-sphere/issues/196) Read-write separation and sharding configuration independence
### Bug Fixes
1. [ISSUE #349](https://github.com/sharding-sphere/sharding-sphere/issues/349) Incorrect function of ResultSet.wasNull causes null numeric type in DB to zero
1. [ISSUE #351](https://github.com/sharding-sphere/sharding-sphere/issues/351) Tables that are included in the default data source but not in TableRule configuration are not properly executed
1. [ISSUE #353](https://github.com/sharding-sphere/sharding-sphere/issues/353) In the Where condition of SQL, it is compatible with non sharding columns !=, !> and !< operator
1. [ISSUE #354](https://github.com/sharding-sphere/sharding-sphere/issues/354) In the Where condition of SQL, NOT operators are compatible with non-sharding columns
## 1.5.2
### Milestones
1. The test engine of quality assurance, each SQL can run 60 test cases of different dimensions
### Enhancements
1. [ISSUE #335](https://github.com/sharding-sphere/sharding-sphere/issues/335) Support the GROUP BY + custom function SQL
1. [ISSUE #341](https://github.com/sharding-sphere/sharding-sphere/issues/341) Support ORDER BY xxx NULLS FIRST | LAST statement of Oracle
### Bug Fixes
1. [ISSUE #334](https://github.com/sharding-sphere/sharding-sphere/issues/334) Parsing ORDER BY with functions will resolve the following ASC and DESC to the name attribute of OrderItem
1. [ISSUE #335](https://github.com/sharding-sphere/sharding-sphere/issues/339) JOIN parsing is incorrect using the full name association of the table
1. [ISSUE #346](https://github.com/sharding-sphere/sharding-sphere/issues/346) Parsing table name error of DDL statement DROP TABLE IF EXISTS USER
## 1.5.1
### New Features
1. [ISSUE #314](https://github.com/sharding-sphere/sharding-sphere/issues/314) Support DDL type SQL
### Changes
1. [ISSUE #327](https://github.com/sharding-sphere/sharding-sphere/issues/327) Close sql.show configuration by default
### Bug Fixes
1. [ISSUE #308](https://github.com/sharding-sphere/sharding-sphere/issues/308) Invalid return of database native GeneratedKey
1. [ISSUE #309](https://github.com/sharding-sphere/sharding-sphere/issues/310) ORDER BY and GROUP BY in sub-queries are not included in the analytic context
1. [ISSUE #313](https://github.com/sharding-sphere/sharding-sphere/issues/313) Support <> operator
1. [ISSUE #317](https://github.com/sharding-sphere/sharding-sphere/issues/317) Parameter of LIMIT can not be type of Long
1. [ISSUE #320](https://github.com/sharding-sphere/sharding-sphere/issues/320) SQL rewriting error of GROUP BY + LIMIT
1. [ISSUE #323](https://github.com/sharding-sphere/sharding-sphere/issues/323) Parsing ORDER BY + Aggregation Expression error
## 1.5.0
### Milestones
1. The new SQL parsing module removes the dependence on Druid. We only need to parse the sharding context, and adopt a "semi understanding" concept for SQL to further improve performance and compatibility, and reduce code complexity
1. The new SQL rewrite module adds an optimized rewrite module
1. The new SQL merge module is rebuilt into 3 merging engines: streaming, memory and decorator
### New Features
1. Support Oracle, SQLServer and PostgreSQL
1. Non functional sub-query support
### Enhancements
1. [ISSUE #256](https://github.com/sharding-sphere/sharding-sphere/issues/256) Configurable display sharding execute to SQL log
1. [ISSUE #291](https://github.com/sharding-sphere/sharding-sphere/issues/291) Processing SQL use stream mode that contains only GroupBy
### Changes
1. Simplify the distributed self increasing sequence. Each table is supported by simplifying a multiple self increasing sequence to a single table supporting only a single distributed self increasing sequence, and no longer supporting workerID settings through environment variables
1. Remove support for OR
### Bug Fixes
1. [ISSUE #239](https://github.com/sharding-sphere/sharding-sphere/issues/239) LIMIT routes to multiple query result sets. If there is only one result set that is not empty, the result of paging is incorrect
1. [ISSUE #263](https://github.com/sharding-sphere/sharding-sphere/issues/263) Sharding and logical table configuration can be case insensitive
1. [ISSUE #292](https://github.com/sharding-sphere/sharding-sphere/issues/292) When the memory mode handles GROUP BY statement, if there is paging information, it needs to be rewritten
1. [ISSUE #295](https://github.com/sharding-sphere/sharding-sphere/issues/295) LIMIT 0 does not filter the result set according to paging restrictions
## 1.4.2
### Enhancements
1. [ISSUE #219](https://github.com/sharding-sphere/sharding-sphere/issues/219) Thread performance optimization
1. [ISSUE #215](https://github.com/sharding-sphere/sharding-sphere/issues/215) Aggregated result set of stream sort StreamingOrderByReducerResultSet performance optimization
1. [ISSUE #161](https://github.com/sharding-sphere/sharding-sphere/issues/161) When the result sets are merged, heap sort can be used to improve performance
### Bug Fixes
1. [ISSUE #212](https://github.com/sharding-sphere/sharding-sphere/issues/212) More meaningful hints for missing data source rules
1. [ISSUE #214](https://github.com/sharding-sphere/sharding-sphere/issues/214) table_name.column_name in (?,?) in WHERE can't parser expression
1. [ISSUE #180](https://github.com/sharding-sphere/sharding-sphere/issues/180) Batch execution of Update return inaccuracy
1. [ISSUE #225](https://github.com/sharding-sphere/sharding-sphere/issues/225) The last character of automatic generation of Id is not 0
## 1.4.1
### Enhancements
1. [ISSUE #191](https://github.com/sharding-sphere/sharding-sphere/issues/191) Generating KeyGenerator of workerId based on IP of host
1. [ISSUE #192](https://github.com/sharding-sphere/sharding-sphere/issues/192) Get workerId's KeyGenerator based on HOSTNAME's digital suffix
1. [ISSUE #210](https://github.com/sharding-sphere/sharding-sphere/issues/210) Routing to single library and single table to remove supplementary SQL statement fragments
### Bug Fixes
1. [ISSUE #194](https://github.com/sharding-sphere/sharding-sphere/issues/194) Some component exceptions in the close method of Connection, Statement, ResultSet and other interfaces cause the close method of another component to be not invoked
1. [ISSUE #199](https://github.com/sharding-sphere/sharding-sphere/issues/199) Sharding and reuse PreparedStatement object cause route error
1. [ISSUE #201](https://github.com/sharding-sphere/sharding-sphere/issues/201) Event transmission missing before batch operation execution
1. [ISSUE #203](https://github.com/sharding-sphere/sharding-sphere/issues/203) Merge events sent by the batch operation
1. [ISSUE #209](https://github.com/sharding-sphere/sharding-sphere/issues/209) Parallel execution of multiple limit queries leads to IndexOutOfBoundsException
## 1.4.0
### Enhancements
Automatic generation key implementation, including
1. [ISSUE #162](https://github.com/sharding-sphere/sharding-sphere/issues/162) Implementation of distributed primary key algorithm
1. [ISSUE #163](https://github.com/sharding-sphere/sharding-sphere/issues/163) Acquisition of a self increasing sequence of JDBC interfaces
1. [ISSUE #171](https://github.com/sharding-sphere/sharding-sphere/issues/171) Sharding-jdbc-core coordination automatic generation sequence transformation
1. [ISSUE #172](https://github.com/sharding-sphere/sharding-sphere/issues/172) The configuration of YAML and Spring supports the self increasing sequence
### Bug Fixes
1. [ISSUE #176](https://github.com/sharding-sphere/sharding-sphere/issues/176) The wasNull flag of AbstractMemoryResultSet is not reset in time
## 1.3.3
### Enhancements
1. [ISSUE #59](https://github.com/sharding-sphere/sharding-sphere/issues/59) PreparedStatement can call the correct underlying set method according to the parameter type when setting parameters
### Bug Fixes
1. [ISSUE #149](https://github.com/sharding-sphere/sharding-sphere/issues/149) When INSERT IGNORE INTO, if the data is duplicated, the value returned to -1 when ignored, and it should be returned to 0
1. [ISSUE #118](https://github.com/sharding-sphere/sharding-sphere/issues/118) In the same thread, DQL is executed first, then DML is executed, and DML operation is executed from the slave database
1. [ISSUE #122](https://github.com/sharding-sphere/sharding-sphere/issues/122) In cases where connections are not available (such as network interruption), transactions should be interrupted rather than retry
1. [ISSUE #152](https://github.com/sharding-sphere/sharding-sphere/issues/152) PreparedStatement's cache causes an array out of bound
1. [ISSUE #150](https://github.com/sharding-sphere/sharding-sphere/issues/150) With the latest SQLServer jdbc driver compatibility problem, Product Name should be changed from SQLServer to Microsoft SQL Server
1. [ISSUE #166](https://github.com/sharding-sphere/sharding-sphere/issues/166) Druid data source stat filter multi-thread error reporting should be added to database connection level synchronization
## 1.3.2
### Enhancements
1. [ISSUE #79](https://github.com/sharding-sphere/sharding-sphere/issues/79) Optimizes limit for only one target table, does not modify limit offset
### Bug Fixes
1. [ISSUE #36](https://github.com/sharding-sphere/sharding-sphere/issues/36) ShardingPreparedStatement cannot set parameters repeatedly
1. [ISSUE #114](https://github.com/sharding-sphere/sharding-sphere/issues/114) When ShardingPreparedStatement performs batch tasks, it repeatedly analyzes SQL and leads to OOM
1. [ISSUE #33](https://github.com/sharding-sphere/sharding-sphere/issues/33) According to the MySQL document, queries similar to limit 100 and -1 format are not supported
1. [ISSUE #124](https://github.com/sharding-sphere/sharding-sphere/issues/124) The return value of com.dangdang.ddframe.rdb.sharding.jdbc.adapter.AbstractStatementAdapter.getUpdateCount does not conform to the JDBC specification
1. [ISSUE #141](https://github.com/sharding-sphere/sharding-sphere/issues/141) Multi-thread executor parameter setting failure
## 1.3.1
### Enhancements
1. [ISSUE #91](https://github.com/sharding-sphere/sharding-sphere/issues/91) Open support for Statement.getGeneratedKeys can return the original database self increase primary key
1. [ISSUE #92](https://github.com/sharding-sphere/sharding-sphere/issues/92) Query DQL statement event sending
### Bug Fixes
1. [ISSUE #89](https://github.com/sharding-sphere/sharding-sphere/issues/89) Use read-write separation with sharding hint leads to conflict
1. [ISSUE #95](https://github.com/sharding-sphere/sharding-sphere/issues/95) Write operations in the same thread are read from the master database changed to the same thread and within the same connection
## 1.3.0
### New Features
1. [ISSUE #85](https://github.com/sharding-sphere/sharding-sphere/issues/85) Read-write separation
### Enhancements
1. [ISSUE #82](https://github.com/sharding-sphere/sharding-sphere/issues/82) TableRule can import the dataSourceName attribute to specify the data source corresponding to the TableRule
1. [ISSUE #88](https://github.com/sharding-sphere/sharding-sphere/issues/88) Release restrictions on other databases, support standard SQL, do not support personalized paging statements
### Bug Fixes
1. [ISSUE #81](https://github.com/sharding-sphere/sharding-sphere/issues/81) Associative table query uses OR query condition to resolve the result exceptions
## 1.2.1
### Refactor
1. [ISSUE #60](https://github.com/sharding-sphere/sharding-sphere/issues/60) API adjust, remove ShardingDataSource, use factory instead
1. [ISSUE #76](https://github.com/sharding-sphere/sharding-sphere/issues/76) ShardingRule and TableRule change to Builder pattern
1. [ISSUE #77](https://github.com/sharding-sphere/sharding-sphere/issues/77) ShardingRule and TableRule change to Builder pattern
### Enhancements
1. [ISSUE #61](https://github.com/sharding-sphere/sharding-sphere/issues/61) Add the logical table name to the ShardingValue class
1. [ISSUE #66](https://github.com/sharding-sphere/sharding-sphere/issues/66) Statement on the JDBC tier supports get/set MaxFieldSize, MaxRows and QueryTimeout
1. [ISSUE #72](https://github.com/sharding-sphere/sharding-sphere/issues/72) Batch inserts supporting select union all
1. [ISSUE #78](https://github.com/sharding-sphere/sharding-sphere/issues/78) Simplifying sharding only configuration, without configuring logical table and real table correspondence
1. [ISSUE #80](https://github.com/sharding-sphere/sharding-sphere/issues/80) Simplifying the configuration that does not sharding, specifying the default data source, do not need configure TableRule
### Bug Fixes
1. [ISSUE #63](https://github.com/sharding-sphere/sharding-sphere/issues/63) No table name or table alias is added to the ORDER BY and GROUP BY derivation columns
1. [ISSUE #65](https://github.com/sharding-sphere/sharding-sphere/issues/65) Performance enhancement for parsing condition context
1. [ISSUE #67](https://github.com/sharding-sphere/sharding-sphere/issues/67) The soft transaction log cannot be deleted when routed to multiple tables
1. [ISSUE #71](https://github.com/sharding-sphere/sharding-sphere/issues/71) Routing single sharding key by OFFSET of LIMIT error
1. [ISSUE #75](https://github.com/sharding-sphere/sharding-sphere/issues/75) MemoryTransactionLogStorage retry times update concurrency problem
## 1.2.0
### New Features
1. [ISSUE #53](https://github.com/sharding-sphere/sharding-sphere/issues/53) The relationship between the real table and the logical table is not configured, and the real table is dynamically calculated by the sharding algorithm
1. [ISSUE #58](https://github.com/sharding-sphere/sharding-sphere/issues/58) Soft transaction: the initial version of the best effort type
### Refactor
1. [ISSUE #49](https://github.com/sharding-sphere/sharding-sphere/issues/49) Adjust the property configuration
1. [ISSUE #51](https://github.com/sharding-sphere/sharding-sphere/issues/51) Refactor of Hint interface
### Bug Fixes
1. [ISSUE #43](https://github.com/sharding-sphere/sharding-sphere/issues/43) The yaml file contains Chinese, and the operating system mode is not UTF-8 encoding, resulting in yaml can not be parsed
1. [ISSUE #48](https://github.com/sharding-sphere/sharding-sphere/issues/48) Yaml file is not closed after reading
1. [ISSUE #57](https://github.com/sharding-sphere/sharding-sphere/issues/57) At the analytic level, we can identify subqueries to ensure that the behavior of supplementary columns can be accurately positioned
## 1.1.0
### New Features
1. [ISSUE #40](https://github.com/sharding-sphere/sharding-sphere/issues/40) Support YAML configuration
1. [ISSUE #41](https://github.com/sharding-sphere/sharding-sphere/issues/41) Support Spring namespace configuration
1. [ISSUE #42](https://github.com/sharding-sphere/sharding-sphere/issues/42) Support inline expression configuration
### Bug Fixes
1. [ISSUE #25](https://github.com/sharding-sphere/sharding-sphere/issues/25) The problem of repeated results will appear under the OR expression
## 1.0.1
### Enhancements
1. [ISSUE #39](https://github.com/sharding-sphere/sharding-sphere/issues/39) Support the use of Hint method to register the key value to SQL routing
### Bug Fixes
1. [ISSUE #11](https://github.com/sharding-sphere/sharding-sphere/issues/11) The count function returns incorrectly without aliases
1. [ISSUE #13](https://github.com/sharding-sphere/sharding-sphere/issues/13) The Insert statement does not write column names or write column names but column names do not contain sharding fields, occur broadcast route
1. [ISSUE #16](https://github.com/sharding-sphere/sharding-sphere/issues/16) For now a new connection pool is executed every time SQL is executed. Instead, each ShardingDataSource object should be changed to share a pool
1. [ISSUE #18](https://github.com/sharding-sphere/sharding-sphere/issues/18) When query Count, getObject() throws Exception: Unsupported data type: Object
1. [ISSUE #19](https://github.com/sharding-sphere/sharding-sphere/issues/19) In SUM and AVG functions, merger is not executed if aliases are not added, and null pointer exception fired if aliases are added
1. [ISSUE #38](https://github.com/sharding-sphere/sharding-sphere/issues/38) The compatibility between JPA and Sharding-JDBC. JPA automatically add the column aliases of SELECT, resulting in ORDER BY obtaining ResultSet data only by aliases rather than column names
## 1.0.0
1. Initial version

View File

@ -0,0 +1,41 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ 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.
-->
<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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.apache.shardingsphere</groupId>
<artifactId>encrypt-core</artifactId>
<version>4.0.1</version>
</parent>
<artifactId>encrypt-core-merge</artifactId>
<name>${project.artifactId}</name>
<dependencies>
<dependency>
<groupId>org.apache.shardingsphere</groupId>
<artifactId>shardingsphere-merge</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.shardingsphere</groupId>
<artifactId>sharding-core-common</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,56 @@
/*
* 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.
*/
package org.apache.shardingsphere.encrypt.merge.dal;
import lombok.RequiredArgsConstructor;
import org.apache.shardingsphere.underlying.execute.QueryResult;
import org.apache.shardingsphere.underlying.merge.MergeEngine;
import org.apache.shardingsphere.underlying.merge.MergedResult;
import org.apache.shardingsphere.underlying.merge.impl.TransparentMergedResult;
import org.apache.shardingsphere.core.rule.EncryptRule;
import org.apache.shardingsphere.sql.parser.relation.statement.SQLStatementContext;
import org.apache.shardingsphere.sql.parser.sql.statement.SQLStatement;
import org.apache.shardingsphere.sql.parser.sql.statement.dal.dialect.mysql.DescribeStatement;
import org.apache.shardingsphere.sql.parser.sql.statement.dal.dialect.mysql.ShowColumnsStatement;
import java.sql.SQLException;
import java.util.List;
/**
* DAL result set merge engine for encrypt.
*
* @author zhangliang
*/
@RequiredArgsConstructor
public final class DALEncryptMergeEngine implements MergeEngine {
private final EncryptRule encryptRule;
private final List<QueryResult> queryResults;
private final SQLStatementContext sqlStatementContext;
@Override
public MergedResult merge() throws SQLException {
SQLStatement dalStatement = sqlStatementContext.getSqlStatement();
if (dalStatement instanceof DescribeStatement || dalStatement instanceof ShowColumnsStatement) {
return new DescribeTableMergedResult(encryptRule, queryResults, sqlStatementContext);
}
return new TransparentMergedResult(queryResults.get(0));
}
}

View File

@ -0,0 +1,73 @@
/*
* 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.
*/
package org.apache.shardingsphere.encrypt.merge.dal;
import com.google.common.base.Optional;
import org.apache.shardingsphere.underlying.merge.impl.MemoryMergedResult;
import org.apache.shardingsphere.underlying.merge.impl.MemoryQueryResultRow;
import org.apache.shardingsphere.core.rule.EncryptRule;
import org.apache.shardingsphere.core.strategy.encrypt.EncryptTable;
import org.apache.shardingsphere.sql.parser.relation.metadata.RelationMetas;
import org.apache.shardingsphere.sql.parser.relation.statement.SQLStatementContext;
import org.apache.shardingsphere.underlying.execute.QueryResult;
import java.sql.SQLException;
import java.util.LinkedList;
import java.util.List;
/**
* Merged result for desc table.
*
* @author liya
*/
public final class DescribeTableMergedResult extends MemoryMergedResult<EncryptRule> {
public DescribeTableMergedResult(final EncryptRule encryptRule, final List<QueryResult> queryResults, final SQLStatementContext sqlStatementContext) throws SQLException {
super(encryptRule, null, sqlStatementContext, queryResults);
}
@Override
protected List<MemoryQueryResultRow> init(final EncryptRule encryptRule, final RelationMetas relationMetas,
final SQLStatementContext sqlStatementContext, final List<QueryResult> queryResults) throws SQLException {
List<MemoryQueryResultRow> result = new LinkedList<>();
for (QueryResult each : queryResults) {
while (each.next()) {
Optional<MemoryQueryResultRow> memoryQueryResultRow = optimize(encryptRule, sqlStatementContext, each);
if (memoryQueryResultRow.isPresent()) {
result.add(memoryQueryResultRow.get());
}
}
}
return result;
}
private Optional<MemoryQueryResultRow> optimize(final EncryptRule encryptRule, final SQLStatementContext sqlStatementContext, final QueryResult queryResult) throws SQLException {
MemoryQueryResultRow memoryQueryResultRow = new MemoryQueryResultRow(queryResult);
Optional<EncryptTable> encryptTable = encryptRule.findEncryptTable(sqlStatementContext.getTablesContext().getSingleTableName());
if (encryptTable.isPresent()) {
String columnName = memoryQueryResultRow.getCell(1).toString();
if (encryptTable.get().getAssistedQueryColumns().contains(columnName) || encryptTable.get().getPlainColumns().contains(columnName)) {
return Optional.absent();
}
if (encryptTable.get().getCipherColumns().contains(columnName)) {
memoryQueryResultRow.setCell(1, encryptTable.get().getLogicColumnOfCipher(columnName));
}
}
return Optional.of(memoryQueryResultRow);
}
}

View File

@ -0,0 +1,42 @@
/*
* 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.
*/
package org.apache.shardingsphere.encrypt.merge.dql;
import lombok.RequiredArgsConstructor;
import org.apache.shardingsphere.underlying.merge.MergeEngine;
import org.apache.shardingsphere.underlying.merge.MergedResult;
/**
* DQL result set merge engine for encrypt.
*
* @author zhangliang
*/
@RequiredArgsConstructor
public final class DQLEncryptMergeEngine implements MergeEngine {
private final EncryptorMetaData metaData;
private final MergedResult mergedResult;
private final boolean queryWithCipherColumn;
@Override
public MergedResult merge() {
return new EncryptMergedResult(metaData, mergedResult, queryWithCipherColumn);
}
}

View File

@ -0,0 +1,72 @@
/*
* 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.
*/
package org.apache.shardingsphere.encrypt.merge.dql;
import com.google.common.base.Optional;
import lombok.RequiredArgsConstructor;
import org.apache.shardingsphere.underlying.merge.MergedResult;
import org.apache.shardingsphere.spi.encrypt.ShardingEncryptor;
import java.io.InputStream;
import java.sql.SQLException;
import java.util.Calendar;
/**
* Merged result for encrypt.
*
* @author zhangliang
*/
@RequiredArgsConstructor
public final class EncryptMergedResult implements MergedResult {
private final EncryptorMetaData metaData;
private final MergedResult mergedResult;
private final boolean queryWithCipherColumn;
@Override
public boolean next() throws SQLException {
return mergedResult.next();
}
@Override
public Object getValue(final int columnIndex, final Class<?> type) throws SQLException {
Object value = mergedResult.getValue(columnIndex, type);
if (null == value || !queryWithCipherColumn) {
return value;
}
Optional<ShardingEncryptor> encryptor = metaData.findEncryptor(columnIndex);
return encryptor.isPresent() ? encryptor.get().decrypt(value.toString()) : value;
}
@Override
public Object getCalendarValue(final int columnIndex, final Class<?> type, final Calendar calendar) throws SQLException {
return mergedResult.getCalendarValue(columnIndex, type, calendar);
}
@Override
public InputStream getInputStream(final int columnIndex, final String type) throws SQLException {
return mergedResult.getInputStream(columnIndex, type);
}
@Override
public boolean wasNull() throws SQLException {
return mergedResult.wasNull();
}
}

View File

@ -0,0 +1,40 @@
/*
* 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.
*/
package org.apache.shardingsphere.encrypt.merge.dql;
import com.google.common.base.Optional;
import org.apache.shardingsphere.spi.encrypt.ShardingEncryptor;
import java.sql.SQLException;
/**
* Encryptor meta data.
*
* @author zhangliang
*/
public interface EncryptorMetaData {
/**
* Find encryptor.
*
* @param columnIndex column index
* @return encryptor
* @throws SQLException SQL exception
*/
Optional<ShardingEncryptor> findEncryptor(int columnIndex) throws SQLException;
}

View File

@ -0,0 +1,104 @@
/*
* 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.
*/
package org.apache.shardingsphere.encrypt.merge.dal;
import com.google.common.base.Optional;
import org.apache.shardingsphere.underlying.execute.QueryResult;
import org.apache.shardingsphere.core.rule.EncryptRule;
import org.apache.shardingsphere.core.strategy.encrypt.EncryptTable;
import org.apache.shardingsphere.sql.parser.relation.segment.table.TablesContext;
import org.apache.shardingsphere.sql.parser.relation.statement.SQLStatementContext;
import org.junit.Test;
import java.sql.SQLException;
import java.util.Collections;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
public final class DescribeTableMergedResultTest {
@Test
public void assertNextForEmptyQueryResult() throws SQLException {
EncryptRule encryptRule = mock(EncryptRule.class);
DescribeTableMergedResult actual = new DescribeTableMergedResult(encryptRule, Collections.<QueryResult>emptyList(), createSQLStatementContext());
assertFalse(actual.next());
}
@Test
public void assertFieldWithEncryptRule() throws SQLException {
EncryptRule encryptRule = createEncryptRule();
DescribeTableMergedResult actual = new DescribeTableMergedResult(encryptRule, Collections.singletonList(createQueryResult()), createSQLStatementContext());
assertTrue(actual.next());
assertThat(actual.getValue(1, String.class).toString(), is("id"));
assertTrue(actual.next());
assertThat(actual.getValue(1, String.class).toString(), is("logic_name"));
assertTrue(actual.next());
assertThat(actual.getValue(1, String.class).toString(), is("pre_name"));
assertFalse(actual.next());
}
@Test
public void assertAllWithEncryptRule() throws SQLException {
EncryptRule encryptRule = createEncryptRule();
DescribeTableMergedResult actual = new DescribeTableMergedResult(encryptRule, Collections.singletonList(createQueryResult()), createSQLStatementContext());
assertTrue(actual.next());
assertThat(actual.getValue(1, String.class).toString(), is("id"));
assertThat(actual.getValue(2, String.class).toString(), is("int(11) unsigned"));
assertThat(actual.getValue(3, String.class).toString(), is("NO"));
assertThat(actual.getValue(4, String.class).toString(), is("PRI"));
assertThat(actual.getValue(5, String.class).toString(), is(""));
assertThat(actual.getValue(6, String.class).toString(), is("auto_increment"));
}
private EncryptRule createEncryptRule() {
EncryptRule result = mock(EncryptRule.class);
EncryptTable encryptTable = mock(EncryptTable.class);
when(result.findEncryptTable("user")).thenReturn(Optional.of(encryptTable));
when(encryptTable.getAssistedQueryColumns()).thenReturn(Collections.singletonList("name_assisted"));
when(encryptTable.getPlainColumns()).thenReturn(Collections.singletonList("name_plain"));
when(encryptTable.getCipherColumns()).thenReturn(Collections.singletonList("name"));
when(encryptTable.getLogicColumnOfCipher("name")).thenReturn("logic_name");
return result;
}
private QueryResult createQueryResult() throws SQLException {
QueryResult result = mock(QueryResult.class);
when(result.getColumnCount()).thenReturn(6);
when(result.next()).thenReturn(true, true, true, true, true, false);
when(result.getValue(1, Object.class)).thenReturn("id", "name", "pre_name", "name_assisted", "name_plain");
when(result.getValue(2, Object.class)).thenReturn("int(11) unsigned", "varchar(100)");
when(result.getValue(3, Object.class)).thenReturn("NO", "YES");
when(result.getValue(4, Object.class)).thenReturn("PRI", "");
when(result.getValue(5, Object.class)).thenReturn("");
when(result.getValue(6, Object.class)).thenReturn("auto_increment", "");
return result;
}
private SQLStatementContext createSQLStatementContext() {
SQLStatementContext result = mock(SQLStatementContext.class);
TablesContext tablesContext = mock(TablesContext.class);
when(tablesContext.getSingleTableName()).thenReturn("user");
when(result.getTablesContext()).thenReturn(tablesContext);
return result;
}
}

View File

@ -0,0 +1,92 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ 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.
-->
<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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.apache.shardingsphere</groupId>
<artifactId>encrypt-core</artifactId>
<version>4.0.1</version>
</parent>
<artifactId>encrypt-core-rewrite</artifactId>
<name>${project.artifactId}</name>
<dependencies>
<dependency>
<groupId>org.apache.shardingsphere</groupId>
<artifactId>sharding-core-common</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.shardingsphere</groupId>
<artifactId>shardingsphere-sql-parser-relation</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.shardingsphere</groupId>
<artifactId>shardingsphere-rewrite-engine</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.shardingsphere</groupId>
<artifactId>shardingsphere-rewrite-test</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.shardingsphere</groupId>
<artifactId>shardingsphere-sql-parser-sql92</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.shardingsphere</groupId>
<artifactId>shardingsphere-sql-parser-mysql</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.shardingsphere</groupId>
<artifactId>shardingsphere-sql-parser-postgresql</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.shardingsphere</groupId>
<artifactId>shardingsphere-sql-parser-oracle</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.shardingsphere</groupId>
<artifactId>shardingsphere-sql-parser-sqlserver</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
</dependency>
<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP-java7</artifactId>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,107 @@
/*
* 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.
*/
package org.apache.shardingsphere.encrypt.rewrite;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.ToString;
import org.apache.shardingsphere.core.constant.ShardingOperator;
import org.apache.shardingsphere.sql.parser.sql.segment.dml.expr.ExpressionSegment;
import org.apache.shardingsphere.sql.parser.sql.segment.dml.expr.simple.LiteralExpressionSegment;
import org.apache.shardingsphere.sql.parser.sql.segment.dml.expr.simple.ParameterMarkerExpressionSegment;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
/**
* Encrypt condition.
*
* @author zhangliang
* @author maxiaoguang
*/
@Getter
@EqualsAndHashCode
@ToString
public final class EncryptCondition {
private final String columnName;
private final String tableName;
private final int startIndex;
private final int stopIndex;
private final ShardingOperator operator;
private final Map<Integer, Integer> positionIndexMap = new LinkedHashMap<>();
private final Map<Integer, Object> positionValueMap = new LinkedHashMap<>();
public EncryptCondition(final String columnName, final String tableName, final int startIndex, final int stopIndex, final ExpressionSegment expressionSegment) {
this.columnName = columnName;
this.tableName = tableName;
this.startIndex = startIndex;
this.stopIndex = stopIndex;
operator = ShardingOperator.EQUAL;
putPositionMap(0, expressionSegment);
}
public EncryptCondition(final String columnName, final String tableName, final int startIndex, final int stopIndex, final List<ExpressionSegment> expressionSegments) {
this.columnName = columnName;
this.tableName = tableName;
this.startIndex = startIndex;
this.stopIndex = stopIndex;
operator = ShardingOperator.IN;
int count = 0;
for (ExpressionSegment each : expressionSegments) {
putPositionMap(count, each);
count++;
}
}
private void putPositionMap(final int position, final ExpressionSegment expressionSegment) {
if (expressionSegment instanceof ParameterMarkerExpressionSegment) {
positionIndexMap.put(position, ((ParameterMarkerExpressionSegment) expressionSegment).getParameterMarkerIndex());
} else if (expressionSegment instanceof LiteralExpressionSegment) {
positionValueMap.put(position, ((LiteralExpressionSegment) expressionSegment).getLiterals());
}
}
/**
* Get values.
*
* @param parameters SQL parameters
* @return values
*/
public List<Object> getValues(final List<Object> parameters) {
List<Object> result = new ArrayList<>(positionValueMap.values());
for (Entry<Integer, Integer> entry : positionIndexMap.entrySet()) {
Object parameter = parameters.get(entry.getValue());
if (entry.getKey() < result.size()) {
result.add(entry.getKey(), parameter);
} else {
result.add(parameter);
}
}
return result;
}
}

View File

@ -0,0 +1,138 @@
/*
* 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.
*/
package org.apache.shardingsphere.encrypt.rewrite;
import com.google.common.base.Optional;
import lombok.RequiredArgsConstructor;
import org.apache.shardingsphere.core.exception.ShardingException;
import org.apache.shardingsphere.core.rule.EncryptRule;
import org.apache.shardingsphere.sql.parser.relation.metadata.RelationMetas;
import org.apache.shardingsphere.sql.parser.relation.segment.table.TablesContext;
import org.apache.shardingsphere.sql.parser.relation.statement.SQLStatementContext;
import org.apache.shardingsphere.sql.parser.sql.segment.dml.expr.ExpressionSegment;
import org.apache.shardingsphere.sql.parser.sql.segment.dml.expr.simple.SimpleExpressionSegment;
import org.apache.shardingsphere.sql.parser.sql.segment.dml.predicate.AndPredicate;
import org.apache.shardingsphere.sql.parser.sql.segment.dml.predicate.PredicateSegment;
import org.apache.shardingsphere.sql.parser.sql.segment.dml.predicate.SubqueryPredicateSegment;
import org.apache.shardingsphere.sql.parser.sql.segment.dml.predicate.WhereSegment;
import org.apache.shardingsphere.sql.parser.sql.segment.dml.predicate.value.PredicateBetweenRightValue;
import org.apache.shardingsphere.sql.parser.sql.segment.dml.predicate.value.PredicateCompareRightValue;
import org.apache.shardingsphere.sql.parser.sql.segment.dml.predicate.value.PredicateInRightValue;
import org.apache.shardingsphere.sql.parser.sql.statement.generic.WhereSegmentAvailable;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
/**
* Encrypt condition engine.
*
* @author zhangliang
*/
@RequiredArgsConstructor
public final class EncryptConditionEngine {
private final EncryptRule encryptRule;
private final RelationMetas relationMetas;
/**
* Create encrypt conditions.
*
* @param sqlStatementContext SQL statement context
* @return encrypt conditions
*/
public List<EncryptCondition> createEncryptConditions(final SQLStatementContext sqlStatementContext) {
if (!(sqlStatementContext.getSqlStatement() instanceof WhereSegmentAvailable)) {
return Collections.emptyList();
}
Optional<WhereSegment> whereSegment = ((WhereSegmentAvailable) sqlStatementContext.getSqlStatement()).getWhere();
if (!whereSegment.isPresent()) {
return Collections.emptyList();
}
List<EncryptCondition> result = new LinkedList<>();
for (AndPredicate each : whereSegment.get().getAndPredicates()) {
result.addAll(createEncryptConditions(each, sqlStatementContext.getTablesContext()));
}
for (SubqueryPredicateSegment each : sqlStatementContext.getSqlStatement().findSQLSegments(SubqueryPredicateSegment.class)) {
for (AndPredicate andPredicate : each.getAndPredicates()) {
result.addAll(createEncryptConditions(andPredicate, sqlStatementContext.getTablesContext()));
}
}
return result;
}
private Collection<EncryptCondition> createEncryptConditions(final AndPredicate andPredicate, final TablesContext tablesContext) {
Collection<EncryptCondition> result = new LinkedList<>();
Collection<Integer> stopIndexes = new HashSet<>();
for (PredicateSegment predicate : andPredicate.getPredicates()) {
if (stopIndexes.add(predicate.getStopIndex())) {
Optional<EncryptCondition> condition = createEncryptCondition(predicate, tablesContext);
if (condition.isPresent()) {
result.add(condition.get());
}
}
}
return result;
}
private Optional<EncryptCondition> createEncryptCondition(final PredicateSegment predicateSegment, final TablesContext tablesContext) {
Optional<String> tableName = tablesContext.findTableName(predicateSegment.getColumn(), relationMetas);
return tableName.isPresent() && encryptRule.findShardingEncryptor(tableName.get(), predicateSegment.getColumn().getName()).isPresent()
? createEncryptCondition(predicateSegment, tableName.get()) : Optional.<EncryptCondition>absent();
}
private Optional<EncryptCondition> createEncryptCondition(final PredicateSegment predicateSegment, final String tableName) {
if (predicateSegment.getRightValue() instanceof PredicateCompareRightValue) {
PredicateCompareRightValue compareRightValue = (PredicateCompareRightValue) predicateSegment.getRightValue();
return isSupportedOperator(compareRightValue.getOperator()) ? createCompareEncryptCondition(tableName, predicateSegment, compareRightValue) : Optional.<EncryptCondition>absent();
}
if (predicateSegment.getRightValue() instanceof PredicateInRightValue) {
return createInEncryptCondition(tableName, predicateSegment, (PredicateInRightValue) predicateSegment.getRightValue());
}
if (predicateSegment.getRightValue() instanceof PredicateBetweenRightValue) {
throw new ShardingException("The SQL clause 'BETWEEN...AND...' is unsupported in encrypt rule.");
}
return Optional.absent();
}
private static Optional<EncryptCondition> createCompareEncryptCondition(final String tableName, final PredicateSegment predicateSegment, final PredicateCompareRightValue compareRightValue) {
return compareRightValue.getExpression() instanceof SimpleExpressionSegment
? Optional.of(new EncryptCondition(predicateSegment.getColumn().getName(), tableName, compareRightValue.getExpression().getStartIndex(),
predicateSegment.getStopIndex(), compareRightValue.getExpression()))
: Optional.<EncryptCondition>absent();
}
private static Optional<EncryptCondition> createInEncryptCondition(final String tableName, final PredicateSegment predicateSegment, final PredicateInRightValue inRightValue) {
List<ExpressionSegment> expressionSegments = new LinkedList<>();
for (ExpressionSegment each : inRightValue.getSqlExpressions()) {
if (each instanceof SimpleExpressionSegment) {
expressionSegments.add(each);
}
}
EncryptCondition encryptInCondition = new EncryptCondition(predicateSegment.getColumn().getName(), tableName,
inRightValue.getPredicateBracketValue().getPredicateLeftBracketValue().getStartIndex(), predicateSegment.getStopIndex(), expressionSegments);
return expressionSegments.isEmpty() ? Optional.<EncryptCondition>absent() : Optional.<EncryptCondition>of(encryptInCondition);
}
private boolean isSupportedOperator(final String operator) {
return "=".equals(operator) || "<>".equals(operator) || "!=".equals(operator);
}
}

View File

@ -0,0 +1,33 @@
/*
* 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.
*/
package org.apache.shardingsphere.encrypt.rewrite.aware;
/**
* Query with cipher column aware.
*
* @author zhangliang
*/
public interface QueryWithCipherColumnAware {
/**
* Set is query with cipher column or not.
*
* @param queryWithCipherColumn is query with cipher column or not
*/
void setQueryWithCipherColumn(boolean queryWithCipherColumn);
}

View File

@ -0,0 +1,49 @@
/*
* 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.
*/
package org.apache.shardingsphere.encrypt.rewrite.context;
import lombok.RequiredArgsConstructor;
import org.apache.shardingsphere.core.rule.EncryptRule;
import org.apache.shardingsphere.underlying.rewrite.context.SQLRewriteContext;
import org.apache.shardingsphere.underlying.rewrite.context.SQLRewriteContextDecorator;
import org.apache.shardingsphere.encrypt.rewrite.parameter.EncryptParameterRewriterBuilder;
import org.apache.shardingsphere.encrypt.rewrite.token.EncryptTokenGenerateBuilder;
import org.apache.shardingsphere.underlying.rewrite.parameter.rewriter.ParameterRewriter;
/**
* SQL rewrite context decorator for encrypt.
*
* @author zhangliang
*/
@RequiredArgsConstructor
public final class EncryptSQLRewriteContextDecorator implements SQLRewriteContextDecorator {
private final EncryptRule encryptRule;
private final boolean isQueryWithCipherColumn;
@Override
public void decorate(final SQLRewriteContext sqlRewriteContext) {
for (ParameterRewriter each : new EncryptParameterRewriterBuilder(encryptRule, isQueryWithCipherColumn).getParameterRewriters(sqlRewriteContext.getRelationMetas())) {
if (!sqlRewriteContext.getParameters().isEmpty() && each.isNeedRewrite(sqlRewriteContext.getSqlStatementContext())) {
each.rewrite(sqlRewriteContext.getParameterBuilder(), sqlRewriteContext.getSqlStatementContext(), sqlRewriteContext.getParameters());
}
}
sqlRewriteContext.addSQLTokenGenerators(new EncryptTokenGenerateBuilder(encryptRule, isQueryWithCipherColumn).getSQLTokenGenerators());
}
}

View File

@ -0,0 +1,53 @@
/*
* 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.
*/
package org.apache.shardingsphere.encrypt.rewrite.parameter;
import lombok.Getter;
import lombok.Setter;
import org.apache.shardingsphere.core.rule.EncryptRule;
import org.apache.shardingsphere.sql.parser.relation.statement.SQLStatementContext;
import org.apache.shardingsphere.core.rule.aware.EncryptRuleAware;
import org.apache.shardingsphere.underlying.rewrite.parameter.rewriter.ParameterRewriter;
/**
* Parameter rewriter for encrypt.
*
* @author zhangliang
*/
@Getter
@Setter
public abstract class EncryptParameterRewriter implements ParameterRewriter, EncryptRuleAware {
private EncryptRule encryptRule;
@Override
public final boolean isNeedRewrite(final SQLStatementContext sqlStatementContext) {
return isNeedRewriteForEncrypt(sqlStatementContext) && isNeedEncrypt(sqlStatementContext);
}
protected abstract boolean isNeedRewriteForEncrypt(SQLStatementContext sqlStatementContext);
private boolean isNeedEncrypt(final SQLStatementContext sqlStatementContext) {
for (String each : sqlStatementContext.getTablesContext().getTableNames()) {
if (encryptRule.findEncryptTable(each).isPresent()) {
return true;
}
}
return false;
}
}

View File

@ -0,0 +1,75 @@
/*
* 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.
*/
package org.apache.shardingsphere.encrypt.rewrite.parameter;
import lombok.RequiredArgsConstructor;
import org.apache.shardingsphere.core.rule.EncryptRule;
import org.apache.shardingsphere.sql.parser.relation.metadata.RelationMetas;
import org.apache.shardingsphere.core.rule.aware.EncryptRuleAware;
import org.apache.shardingsphere.encrypt.rewrite.aware.QueryWithCipherColumnAware;
import org.apache.shardingsphere.encrypt.rewrite.parameter.impl.EncryptAssignmentParameterRewriter;
import org.apache.shardingsphere.encrypt.rewrite.parameter.impl.EncryptInsertValueParameterRewriter;
import org.apache.shardingsphere.encrypt.rewrite.parameter.impl.EncryptPredicateParameterRewriter;
import org.apache.shardingsphere.underlying.rewrite.parameter.rewriter.ParameterRewriter;
import org.apache.shardingsphere.underlying.rewrite.parameter.rewriter.ParameterRewriterBuilder;
import org.apache.shardingsphere.underlying.rewrite.sql.token.generator.aware.RelationMetasAware;
import java.util.Collection;
import java.util.LinkedList;
/**
* Parameter rewriter builder for encrypt.
*
* @author zhangliang
*/
@RequiredArgsConstructor
public final class EncryptParameterRewriterBuilder implements ParameterRewriterBuilder {
private final EncryptRule encryptRule;
private final boolean queryWithCipherColumn;
@Override
public Collection<ParameterRewriter> getParameterRewriters(final RelationMetas relationMetas) {
Collection<ParameterRewriter> result = getParameterRewriters();
for (ParameterRewriter each : result) {
setUpParameterRewriters(each, relationMetas);
}
return result;
}
private Collection<ParameterRewriter> getParameterRewriters() {
Collection<ParameterRewriter> result = new LinkedList<>();
result.add(new EncryptAssignmentParameterRewriter());
result.add(new EncryptPredicateParameterRewriter());
result.add(new EncryptInsertValueParameterRewriter());
return result;
}
private void setUpParameterRewriters(final ParameterRewriter parameterRewriter, final RelationMetas relationMetas) {
if (parameterRewriter instanceof RelationMetasAware) {
((RelationMetasAware) parameterRewriter).setRelationMetas(relationMetas);
}
if (parameterRewriter instanceof EncryptRuleAware) {
((EncryptRuleAware) parameterRewriter).setEncryptRule(encryptRule);
}
if (parameterRewriter instanceof QueryWithCipherColumnAware) {
((QueryWithCipherColumnAware) parameterRewriter).setQueryWithCipherColumn(queryWithCipherColumn);
}
}
}

View File

@ -0,0 +1,92 @@
/*
* 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.
*/
package org.apache.shardingsphere.encrypt.rewrite.parameter.impl;
import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
import org.apache.shardingsphere.encrypt.rewrite.parameter.EncryptParameterRewriter;
import org.apache.shardingsphere.sql.parser.relation.statement.SQLStatementContext;
import org.apache.shardingsphere.sql.parser.relation.statement.impl.InsertSQLStatementContext;
import org.apache.shardingsphere.sql.parser.sql.segment.dml.assignment.AssignmentSegment;
import org.apache.shardingsphere.sql.parser.sql.segment.dml.assignment.SetAssignmentsSegment;
import org.apache.shardingsphere.sql.parser.sql.segment.dml.expr.simple.ParameterMarkerExpressionSegment;
import org.apache.shardingsphere.sql.parser.sql.statement.SQLStatement;
import org.apache.shardingsphere.sql.parser.sql.statement.dml.InsertStatement;
import org.apache.shardingsphere.sql.parser.sql.statement.dml.UpdateStatement;
import org.apache.shardingsphere.underlying.rewrite.parameter.builder.ParameterBuilder;
import org.apache.shardingsphere.underlying.rewrite.parameter.builder.impl.GroupedParameterBuilder;
import org.apache.shardingsphere.underlying.rewrite.parameter.builder.impl.StandardParameterBuilder;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
/**
* Assignment parameter rewriter for encrypt.
*
* @author zhangliang
*/
public final class EncryptAssignmentParameterRewriter extends EncryptParameterRewriter {
@Override
protected boolean isNeedRewriteForEncrypt(final SQLStatementContext sqlStatementContext) {
return sqlStatementContext.getSqlStatement() instanceof UpdateStatement
|| sqlStatementContext instanceof InsertSQLStatementContext && sqlStatementContext.getSqlStatement().findSQLSegment(SetAssignmentsSegment.class).isPresent();
}
@Override
public void rewrite(final ParameterBuilder parameterBuilder, final SQLStatementContext sqlStatementContext, final List<Object> parameters) {
String tableName = sqlStatementContext.getTablesContext().getSingleTableName();
for (AssignmentSegment each : getSetAssignmentsSegment(sqlStatementContext.getSqlStatement()).getAssignments()) {
if (each.getValue() instanceof ParameterMarkerExpressionSegment && getEncryptRule().findShardingEncryptor(tableName, each.getColumn().getName()).isPresent()) {
StandardParameterBuilder standardParameterBuilder = parameterBuilder instanceof StandardParameterBuilder
? (StandardParameterBuilder) parameterBuilder : ((GroupedParameterBuilder) parameterBuilder).getParameterBuilders().get(0);
encryptParameters(standardParameterBuilder, tableName, each, parameters);
}
}
}
private SetAssignmentsSegment getSetAssignmentsSegment(final SQLStatement sqlStatement) {
if (sqlStatement instanceof InsertStatement) {
Optional<SetAssignmentsSegment> result = ((InsertStatement) sqlStatement).getSetAssignment();
Preconditions.checkState(result.isPresent());
return result.get();
}
return ((UpdateStatement) sqlStatement).getSetAssignment();
}
private void encryptParameters(final StandardParameterBuilder parameterBuilder, final String tableName, final AssignmentSegment assignmentSegment, final List<Object> parameters) {
String columnName = assignmentSegment.getColumn().getName();
int parameterMarkerIndex = ((ParameterMarkerExpressionSegment) assignmentSegment.getValue()).getParameterMarkerIndex();
Object originalValue = parameters.get(parameterMarkerIndex);
Object cipherValue = getEncryptRule().getEncryptValues(tableName, columnName, Collections.singletonList(originalValue)).iterator().next();
parameterBuilder.addReplacedParameters(parameterMarkerIndex, cipherValue);
Collection<Object> addedParameters = new LinkedList<>();
if (getEncryptRule().findAssistedQueryColumn(tableName, columnName).isPresent()) {
Object assistedQueryValue = getEncryptRule().getEncryptAssistedQueryValues(tableName, columnName, Collections.singletonList(originalValue)).iterator().next();
addedParameters.add(assistedQueryValue);
}
if (getEncryptRule().findPlainColumn(tableName, columnName).isPresent()) {
addedParameters.add(originalValue);
}
if (!addedParameters.isEmpty()) {
parameterBuilder.addAddedParameters(parameterMarkerIndex + 1, addedParameters);
}
}
}

View File

@ -0,0 +1,110 @@
/*
* 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.
*/
package org.apache.shardingsphere.encrypt.rewrite.parameter.impl;
import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
import org.apache.shardingsphere.encrypt.rewrite.parameter.EncryptParameterRewriter;
import org.apache.shardingsphere.spi.encrypt.ShardingEncryptor;
import org.apache.shardingsphere.spi.encrypt.ShardingQueryAssistedEncryptor;
import org.apache.shardingsphere.sql.parser.relation.statement.SQLStatementContext;
import org.apache.shardingsphere.sql.parser.relation.statement.impl.InsertSQLStatementContext;
import org.apache.shardingsphere.sql.parser.sql.statement.dml.InsertStatement;
import org.apache.shardingsphere.underlying.rewrite.parameter.builder.ParameterBuilder;
import org.apache.shardingsphere.underlying.rewrite.parameter.builder.impl.GroupedParameterBuilder;
import org.apache.shardingsphere.underlying.rewrite.parameter.builder.impl.StandardParameterBuilder;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
/**
* Insert value parameter rewriter for encrypt.
*
* @author zhangliang
*/
public final class EncryptInsertValueParameterRewriter extends EncryptParameterRewriter {
@Override
protected boolean isNeedRewriteForEncrypt(final SQLStatementContext sqlStatementContext) {
return sqlStatementContext instanceof InsertSQLStatementContext && !((InsertStatement) sqlStatementContext.getSqlStatement()).getSetAssignment().isPresent();
}
@Override
public void rewrite(final ParameterBuilder parameterBuilder, final SQLStatementContext sqlStatementContext, final List<Object> parameters) {
String tableName = sqlStatementContext.getTablesContext().getSingleTableName();
Iterator<String> descendingColumnNames = ((InsertSQLStatementContext) sqlStatementContext).getDescendingColumnNames();
while (descendingColumnNames.hasNext()) {
String columnName = descendingColumnNames.next();
Optional<ShardingEncryptor> shardingEncryptor = getEncryptRule().findShardingEncryptor(tableName, columnName);
if (shardingEncryptor.isPresent()) {
encryptInsertValues((GroupedParameterBuilder) parameterBuilder, (InsertSQLStatementContext) sqlStatementContext, shardingEncryptor.get(), tableName, columnName);
}
}
}
private void encryptInsertValues(final GroupedParameterBuilder parameterBuilder,
final InsertSQLStatementContext sqlStatementContext, final ShardingEncryptor shardingEncryptor, final String tableName, final String encryptLogicColumnName) {
int columnIndex = getColumnIndex(parameterBuilder, sqlStatementContext, encryptLogicColumnName);
int count = 0;
for (List<Object> each : sqlStatementContext.getGroupedParameters()) {
if (!each.isEmpty()) {
StandardParameterBuilder standardParameterBuilder = parameterBuilder.getParameterBuilders().get(count);
encryptInsertValue(
shardingEncryptor, tableName, columnIndex, sqlStatementContext.getInsertValueContexts().get(count).getValue(columnIndex), standardParameterBuilder, encryptLogicColumnName);
}
count++;
}
}
private int getColumnIndex(final GroupedParameterBuilder parameterBuilder, final InsertSQLStatementContext sqlStatementContext, final String encryptLogicColumnName) {
List<String> columnNames;
if (parameterBuilder.getDerivedColumnName().isPresent()) {
columnNames = new ArrayList<>(sqlStatementContext.getColumnNames());
columnNames.remove(parameterBuilder.getDerivedColumnName().get());
} else {
columnNames = sqlStatementContext.getColumnNames();
}
return columnNames.indexOf(encryptLogicColumnName);
}
private void encryptInsertValue(final ShardingEncryptor shardingEncryptor, final String tableName, final int columnIndex,
final Object originalValue, final StandardParameterBuilder parameterBuilder, final String encryptLogicColumnName) {
// FIXME: can process all part of insert value is ? or literal, can not process mix ? and literal
// For example: values (?, ?), (1, 1) can process
// For example: values (?, 1), (?, 2) can not process
parameterBuilder.addReplacedParameters(columnIndex, shardingEncryptor.encrypt(originalValue));
Collection<Object> addedParameters = new LinkedList<>();
if (shardingEncryptor instanceof ShardingQueryAssistedEncryptor) {
Optional<String> assistedColumnName = getEncryptRule().findAssistedQueryColumn(tableName, encryptLogicColumnName);
Preconditions.checkArgument(assistedColumnName.isPresent(), "Can not find assisted query Column Name");
addedParameters.add(((ShardingQueryAssistedEncryptor) shardingEncryptor).queryAssistedEncrypt(originalValue.toString()));
}
if (getEncryptRule().findPlainColumn(tableName, encryptLogicColumnName).isPresent()) {
addedParameters.add(originalValue);
}
if (!addedParameters.isEmpty()) {
if (!parameterBuilder.getAddedIndexAndParameters().containsKey(columnIndex + 1)) {
parameterBuilder.getAddedIndexAndParameters().put(columnIndex + 1, new LinkedList<>());
}
parameterBuilder.getAddedIndexAndParameters().get(columnIndex + 1).addAll(addedParameters);
}
}
}

View File

@ -0,0 +1,79 @@
/*
* 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.
*/
package org.apache.shardingsphere.encrypt.rewrite.parameter.impl;
import lombok.Setter;
import org.apache.shardingsphere.encrypt.rewrite.parameter.EncryptParameterRewriter;
import org.apache.shardingsphere.sql.parser.relation.metadata.RelationMetas;
import org.apache.shardingsphere.sql.parser.relation.statement.SQLStatementContext;
import org.apache.shardingsphere.encrypt.rewrite.EncryptCondition;
import org.apache.shardingsphere.encrypt.rewrite.EncryptConditionEngine;
import org.apache.shardingsphere.encrypt.rewrite.aware.QueryWithCipherColumnAware;
import org.apache.shardingsphere.underlying.rewrite.parameter.builder.ParameterBuilder;
import org.apache.shardingsphere.underlying.rewrite.parameter.builder.impl.StandardParameterBuilder;
import org.apache.shardingsphere.underlying.rewrite.sql.token.generator.aware.RelationMetasAware;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
/**
* Predicate parameter rewriter for encrypt.
*
* @author zhangliang
*/
@Setter
public final class EncryptPredicateParameterRewriter extends EncryptParameterRewriter implements RelationMetasAware, QueryWithCipherColumnAware {
private RelationMetas relationMetas;
private boolean queryWithCipherColumn;
@Override
protected boolean isNeedRewriteForEncrypt(final SQLStatementContext sqlStatementContext) {
return true;
}
@Override
public void rewrite(final ParameterBuilder parameterBuilder, final SQLStatementContext sqlStatementContext, final List<Object> parameters) {
List<EncryptCondition> encryptConditions = new EncryptConditionEngine(getEncryptRule(), relationMetas).createEncryptConditions(sqlStatementContext);
if (encryptConditions.isEmpty()) {
return;
}
for (EncryptCondition each : encryptConditions) {
if (queryWithCipherColumn) {
encryptParameters(parameterBuilder, each.getPositionIndexMap(), getEncryptedValues(each, each.getValues(parameters)));
}
}
}
private List<Object> getEncryptedValues(final EncryptCondition encryptCondition, final List<Object> originalValues) {
String tableName = encryptCondition.getTableName();
String columnName = encryptCondition.getColumnName();
return getEncryptRule().findAssistedQueryColumn(tableName, columnName).isPresent()
? getEncryptRule().getEncryptAssistedQueryValues(tableName, columnName, originalValues) : getEncryptRule().getEncryptValues(tableName, columnName, originalValues);
}
private void encryptParameters(final ParameterBuilder parameterBuilder, final Map<Integer, Integer> positionIndexes, final List<Object> encryptValues) {
if (!positionIndexes.isEmpty()) {
for (Entry<Integer, Integer> entry : positionIndexes.entrySet()) {
((StandardParameterBuilder) parameterBuilder).addReplacedParameters(entry.getValue(), encryptValues.get(entry.getKey()));
}
}
}
}

View File

@ -0,0 +1,77 @@
/*
* 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.
*/
package org.apache.shardingsphere.encrypt.rewrite.token;
import lombok.RequiredArgsConstructor;
import org.apache.shardingsphere.core.rule.EncryptRule;
import org.apache.shardingsphere.encrypt.rewrite.token.generator.impl.EncryptForUseDefaultInsertColumnsTokenGenerator;
import org.apache.shardingsphere.encrypt.rewrite.token.generator.impl.EncryptPredicateColumnTokenGenerator;
import org.apache.shardingsphere.encrypt.rewrite.token.generator.impl.EncryptPredicateRightValueTokenGenerator;
import org.apache.shardingsphere.encrypt.rewrite.token.generator.impl.InsertCipherNameTokenGenerator;
import org.apache.shardingsphere.core.rule.aware.EncryptRuleAware;
import org.apache.shardingsphere.encrypt.rewrite.aware.QueryWithCipherColumnAware;
import org.apache.shardingsphere.encrypt.rewrite.token.generator.impl.AssistQueryAndPlainInsertColumnsTokenGenerator;
import org.apache.shardingsphere.encrypt.rewrite.token.generator.impl.EncryptAssignmentTokenGenerator;
import org.apache.shardingsphere.encrypt.rewrite.token.generator.impl.EncryptInsertValuesTokenGenerator;
import org.apache.shardingsphere.encrypt.rewrite.token.generator.impl.EncryptProjectionTokenGenerator;
import org.apache.shardingsphere.underlying.rewrite.sql.token.generator.SQLTokenGenerator;
import org.apache.shardingsphere.underlying.rewrite.sql.token.generator.builder.SQLTokenGeneratorBuilder;
import java.util.Collection;
import java.util.LinkedList;
/**
* SQL token generator builder for encrypt.
*
* @author panjuan
* @author zhangliang
*/
@RequiredArgsConstructor
public final class EncryptTokenGenerateBuilder implements SQLTokenGeneratorBuilder {
private final EncryptRule encryptRule;
private final boolean queryWithCipherColumn;
@Override
public Collection<SQLTokenGenerator> getSQLTokenGenerators() {
Collection<SQLTokenGenerator> result = buildSQLTokenGenerators();
for (SQLTokenGenerator each : result) {
if (each instanceof EncryptRuleAware) {
((EncryptRuleAware) each).setEncryptRule(encryptRule);
}
if (each instanceof QueryWithCipherColumnAware) {
((QueryWithCipherColumnAware) each).setQueryWithCipherColumn(queryWithCipherColumn);
}
}
return result;
}
private Collection<SQLTokenGenerator> buildSQLTokenGenerators() {
Collection<SQLTokenGenerator> result = new LinkedList<>();
result.add(new EncryptProjectionTokenGenerator());
result.add(new EncryptAssignmentTokenGenerator());
result.add(new EncryptPredicateColumnTokenGenerator());
result.add(new EncryptPredicateRightValueTokenGenerator());
result.add(new EncryptInsertValuesTokenGenerator());
result.add(new EncryptForUseDefaultInsertColumnsTokenGenerator());
result.add(new InsertCipherNameTokenGenerator());
result.add(new AssistQueryAndPlainInsertColumnsTokenGenerator());
return result;
}
}

View File

@ -0,0 +1,53 @@
/*
* 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.
*/
package org.apache.shardingsphere.encrypt.rewrite.token.generator;
import lombok.Getter;
import lombok.Setter;
import org.apache.shardingsphere.core.rule.EncryptRule;
import org.apache.shardingsphere.core.rule.aware.EncryptRuleAware;
import org.apache.shardingsphere.sql.parser.relation.statement.SQLStatementContext;
import org.apache.shardingsphere.underlying.rewrite.sql.token.generator.SQLTokenGenerator;
/**
* Base SQL token generator for encrypt.
*
* @author zhangliang
*/
@Getter
@Setter
public abstract class BaseEncryptSQLTokenGenerator implements SQLTokenGenerator, EncryptRuleAware {
private EncryptRule encryptRule;
@Override
public final boolean isGenerateSQLToken(final SQLStatementContext sqlStatementContext) {
return isGenerateSQLTokenForEncrypt(sqlStatementContext) && isNeedEncrypt(sqlStatementContext);
}
protected abstract boolean isGenerateSQLTokenForEncrypt(SQLStatementContext sqlStatementContext);
private boolean isNeedEncrypt(final SQLStatementContext sqlStatementContext) {
for (String each : sqlStatementContext.getTablesContext().getTableNames()) {
if (encryptRule.findEncryptTable(each).isPresent()) {
return true;
}
}
return false;
}
}

View File

@ -0,0 +1,76 @@
/*
* 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.
*/
package org.apache.shardingsphere.encrypt.rewrite.token.generator.impl;
import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
import org.apache.shardingsphere.core.strategy.encrypt.EncryptTable;
import org.apache.shardingsphere.sql.parser.relation.statement.SQLStatementContext;
import org.apache.shardingsphere.sql.parser.relation.statement.impl.InsertSQLStatementContext;
import org.apache.shardingsphere.sql.parser.sql.segment.dml.column.ColumnSegment;
import org.apache.shardingsphere.sql.parser.sql.segment.dml.column.InsertColumnsSegment;
import org.apache.shardingsphere.sql.parser.sql.statement.dml.InsertStatement;
import org.apache.shardingsphere.encrypt.rewrite.token.generator.BaseEncryptSQLTokenGenerator;
import org.apache.shardingsphere.underlying.rewrite.sql.token.generator.CollectionSQLTokenGenerator;
import org.apache.shardingsphere.underlying.rewrite.sql.token.pojo.generic.InsertColumnsToken;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
/**
* Assist query and plain insert columns token generator.
*
* @author panjuan
* @author zhangliang
*/
public final class AssistQueryAndPlainInsertColumnsTokenGenerator extends BaseEncryptSQLTokenGenerator implements CollectionSQLTokenGenerator {
@Override
protected boolean isGenerateSQLTokenForEncrypt(final SQLStatementContext sqlStatementContext) {
return sqlStatementContext instanceof InsertSQLStatementContext && sqlStatementContext.getSqlStatement().findSQLSegment(InsertColumnsSegment.class).isPresent()
&& !((InsertStatement) sqlStatementContext.getSqlStatement()).useDefaultColumns();
}
@Override
public Collection<InsertColumnsToken> generateSQLTokens(final SQLStatementContext sqlStatementContext) {
Collection<InsertColumnsToken> result = new LinkedList<>();
Optional<EncryptTable> encryptTable = getEncryptRule().findEncryptTable(sqlStatementContext.getTablesContext().getSingleTableName());
Preconditions.checkState(encryptTable.isPresent());
for (ColumnSegment each : ((InsertStatement) sqlStatementContext.getSqlStatement()).getColumns()) {
List<String> columns = getColumns(encryptTable.get(), each);
if (!columns.isEmpty()) {
result.add(new InsertColumnsToken(each.getStopIndex() + 1, columns));
}
}
return result;
}
private List<String> getColumns(final EncryptTable encryptTable, final ColumnSegment columnSegment) {
List<String> result = new LinkedList<>();
Optional<String> assistedQueryColumn = encryptTable.findAssistedQueryColumn(columnSegment.getName());
if (assistedQueryColumn.isPresent()) {
result.add(assistedQueryColumn.get());
}
Optional<String> plainColumn = encryptTable.findPlainColumn(columnSegment.getName());
if (plainColumn.isPresent()) {
result.add(plainColumn.get());
}
return result;
}
}

View File

@ -0,0 +1,145 @@
/*
* 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.
*/
package org.apache.shardingsphere.encrypt.rewrite.token.generator.impl;
import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
import org.apache.shardingsphere.encrypt.rewrite.token.pojo.EncryptAssignmentToken;
import org.apache.shardingsphere.encrypt.rewrite.token.pojo.EncryptParameterAssignmentToken;
import org.apache.shardingsphere.sql.parser.relation.statement.SQLStatementContext;
import org.apache.shardingsphere.sql.parser.relation.statement.impl.InsertSQLStatementContext;
import org.apache.shardingsphere.sql.parser.sql.segment.dml.assignment.AssignmentSegment;
import org.apache.shardingsphere.sql.parser.sql.segment.dml.assignment.SetAssignmentsSegment;
import org.apache.shardingsphere.sql.parser.sql.segment.dml.expr.simple.LiteralExpressionSegment;
import org.apache.shardingsphere.sql.parser.sql.segment.dml.expr.simple.ParameterMarkerExpressionSegment;
import org.apache.shardingsphere.sql.parser.sql.statement.SQLStatement;
import org.apache.shardingsphere.sql.parser.sql.statement.dml.InsertStatement;
import org.apache.shardingsphere.sql.parser.sql.statement.dml.UpdateStatement;
import org.apache.shardingsphere.encrypt.rewrite.token.generator.BaseEncryptSQLTokenGenerator;
import org.apache.shardingsphere.encrypt.rewrite.token.pojo.EncryptLiteralAssignmentToken;
import org.apache.shardingsphere.underlying.rewrite.sql.token.generator.CollectionSQLTokenGenerator;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedList;
/**
* Assignment generator for encrypt.
*
* @author panjuan
*/
public final class EncryptAssignmentTokenGenerator extends BaseEncryptSQLTokenGenerator implements CollectionSQLTokenGenerator {
@Override
protected boolean isGenerateSQLTokenForEncrypt(final SQLStatementContext sqlStatementContext) {
return sqlStatementContext.getSqlStatement() instanceof UpdateStatement
|| sqlStatementContext instanceof InsertSQLStatementContext && sqlStatementContext.getSqlStatement().findSQLSegment(SetAssignmentsSegment.class).isPresent();
}
@Override
public Collection<EncryptAssignmentToken> generateSQLTokens(final SQLStatementContext sqlStatementContext) {
Collection<EncryptAssignmentToken> result = new LinkedList<>();
String tableName = sqlStatementContext.getTablesContext().getSingleTableName();
for (AssignmentSegment each : getSetAssignmentsSegment(sqlStatementContext.getSqlStatement()).getAssignments()) {
if (getEncryptRule().findShardingEncryptor(tableName, each.getColumn().getName()).isPresent()) {
Optional<EncryptAssignmentToken> sqlToken = generateSQLToken(tableName, each);
if (sqlToken.isPresent()) {
result.add(sqlToken.get());
}
}
}
return result;
}
private SetAssignmentsSegment getSetAssignmentsSegment(final SQLStatement sqlStatement) {
if (sqlStatement instanceof InsertStatement) {
Optional<SetAssignmentsSegment> result = ((InsertStatement) sqlStatement).getSetAssignment();
Preconditions.checkState(result.isPresent());
return result.get();
}
return ((UpdateStatement) sqlStatement).getSetAssignment();
}
private Optional<EncryptAssignmentToken> generateSQLToken(final String tableName, final AssignmentSegment assignmentSegment) {
if (assignmentSegment.getValue() instanceof ParameterMarkerExpressionSegment) {
return Optional.of(generateParameterSQLToken(tableName, assignmentSegment));
}
if (assignmentSegment.getValue() instanceof LiteralExpressionSegment) {
return Optional.of(generateLiteralSQLToken(tableName, assignmentSegment));
}
return Optional.absent();
}
private EncryptAssignmentToken generateParameterSQLToken(final String tableName, final AssignmentSegment assignmentSegment) {
EncryptParameterAssignmentToken result = new EncryptParameterAssignmentToken(assignmentSegment.getColumn().getStartIndex(), assignmentSegment.getStopIndex());
String columnName = assignmentSegment.getColumn().getName();
addCipherColumn(tableName, columnName, result);
addAssistedQueryColumn(tableName, columnName, result);
addPlainColumn(tableName, columnName, result);
return result;
}
private void addCipherColumn(final String tableName, final String columnName, final EncryptParameterAssignmentToken token) {
token.addColumnName(getEncryptRule().getCipherColumn(tableName, columnName));
}
private void addAssistedQueryColumn(final String tableName, final String columnName, final EncryptParameterAssignmentToken token) {
Optional<String> assistedQueryColumn = getEncryptRule().findAssistedQueryColumn(tableName, columnName);
if (assistedQueryColumn.isPresent()) {
token.addColumnName(assistedQueryColumn.get());
}
}
private void addPlainColumn(final String tableName, final String columnName, final EncryptParameterAssignmentToken token) {
Optional<String> plainColumn = getEncryptRule().findPlainColumn(tableName, columnName);
if (plainColumn.isPresent()) {
token.addColumnName(plainColumn.get());
}
}
private EncryptAssignmentToken generateLiteralSQLToken(final String tableName, final AssignmentSegment assignmentSegment) {
EncryptLiteralAssignmentToken result = new EncryptLiteralAssignmentToken(assignmentSegment.getColumn().getStartIndex(), assignmentSegment.getStopIndex());
addCipherAssignment(tableName, assignmentSegment, result);
addAssistedQueryAssignment(tableName, assignmentSegment, result);
addPlainAssignment(tableName, assignmentSegment, result);
return result;
}
private void addCipherAssignment(final String tableName, final AssignmentSegment assignmentSegment, final EncryptLiteralAssignmentToken token) {
Object originalValue = ((LiteralExpressionSegment) assignmentSegment.getValue()).getLiterals();
Object cipherValue = getEncryptRule().getEncryptValues(tableName, assignmentSegment.getColumn().getName(), Collections.singletonList(originalValue)).iterator().next();
token.addAssignment(getEncryptRule().getCipherColumn(tableName, assignmentSegment.getColumn().getName()), cipherValue);
}
private void addAssistedQueryAssignment(final String tableName, final AssignmentSegment assignmentSegment, final EncryptLiteralAssignmentToken token) {
Object originalValue = ((LiteralExpressionSegment) assignmentSegment.getValue()).getLiterals();
Optional<String> assistedQueryColumn = getEncryptRule().findAssistedQueryColumn(tableName, assignmentSegment.getColumn().getName());
if (assistedQueryColumn.isPresent()) {
Object assistedQueryValue = getEncryptRule().getEncryptAssistedQueryValues(tableName, assignmentSegment.getColumn().getName(), Collections.singletonList(originalValue)).iterator().next();
token.addAssignment(assistedQueryColumn.get(), assistedQueryValue);
}
}
private void addPlainAssignment(final String tableName, final AssignmentSegment assignmentSegment, final EncryptLiteralAssignmentToken token) {
Object originalValue = ((LiteralExpressionSegment) assignmentSegment.getValue()).getLiterals();
Optional<String> plainColumn = getEncryptRule().findPlainColumn(tableName, assignmentSegment.getColumn().getName());
if (plainColumn.isPresent()) {
token.addAssignment(plainColumn.get(), originalValue);
}
}
}

View File

@ -0,0 +1,122 @@
/*
* 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.
*/
package org.apache.shardingsphere.encrypt.rewrite.token.generator.impl;
import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
import lombok.Setter;
import org.apache.shardingsphere.core.strategy.encrypt.EncryptTable;
import org.apache.shardingsphere.sql.parser.relation.statement.SQLStatementContext;
import org.apache.shardingsphere.sql.parser.relation.statement.impl.InsertSQLStatementContext;
import org.apache.shardingsphere.sql.parser.sql.segment.dml.column.InsertColumnsSegment;
import org.apache.shardingsphere.sql.parser.sql.statement.dml.InsertStatement;
import org.apache.shardingsphere.encrypt.rewrite.token.generator.BaseEncryptSQLTokenGenerator;
import org.apache.shardingsphere.underlying.rewrite.sql.token.generator.OptionalSQLTokenGenerator;
import org.apache.shardingsphere.underlying.rewrite.sql.token.generator.aware.PreviousSQLTokensAware;
import org.apache.shardingsphere.underlying.rewrite.sql.token.pojo.SQLToken;
import org.apache.shardingsphere.underlying.rewrite.sql.token.pojo.generic.UseDefaultInsertColumnsToken;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
/**
* Use default insert columns token generator for encrypt.
*
* @author panjuan
* @author zhangliang
*/
@Setter
public final class EncryptForUseDefaultInsertColumnsTokenGenerator extends BaseEncryptSQLTokenGenerator implements OptionalSQLTokenGenerator, PreviousSQLTokensAware {
private List<SQLToken> previousSQLTokens;
@Override
protected boolean isGenerateSQLTokenForEncrypt(final SQLStatementContext sqlStatementContext) {
return sqlStatementContext instanceof InsertSQLStatementContext && ((InsertStatement) sqlStatementContext.getSqlStatement()).useDefaultColumns();
}
@Override
public UseDefaultInsertColumnsToken generateSQLToken(final SQLStatementContext sqlStatementContext) {
String tableName = sqlStatementContext.getTablesContext().getSingleTableName();
Optional<UseDefaultInsertColumnsToken> previousSQLToken = findInsertColumnsToken();
if (previousSQLToken.isPresent()) {
processPreviousSQLToken(previousSQLToken.get(), (InsertSQLStatementContext) sqlStatementContext, tableName);
return previousSQLToken.get();
}
return generateNewSQLToken((InsertSQLStatementContext) sqlStatementContext, tableName);
}
private Optional<UseDefaultInsertColumnsToken> findInsertColumnsToken() {
for (SQLToken each : previousSQLTokens) {
if (each instanceof UseDefaultInsertColumnsToken) {
return Optional.of((UseDefaultInsertColumnsToken) each);
}
}
return Optional.absent();
}
private void processPreviousSQLToken(final UseDefaultInsertColumnsToken previousSQLToken, final InsertSQLStatementContext sqlStatementContext, final String tableName) {
Optional<EncryptTable> encryptTable = getEncryptRule().findEncryptTable(tableName);
Preconditions.checkState(encryptTable.isPresent());
List<String> columnNames = getColumnNames(sqlStatementContext, encryptTable.get(), previousSQLToken.getColumns());
previousSQLToken.getColumns().clear();
previousSQLToken.getColumns().addAll(columnNames);
}
private UseDefaultInsertColumnsToken generateNewSQLToken(final InsertSQLStatementContext sqlStatementContext, final String tableName) {
Optional<InsertColumnsSegment> insertColumnsSegment = sqlStatementContext.getSqlStatement().findSQLSegment(InsertColumnsSegment.class);
Preconditions.checkState(insertColumnsSegment.isPresent());
Optional<EncryptTable> encryptTable = getEncryptRule().findEncryptTable(tableName);
Preconditions.checkState(encryptTable.isPresent());
return new UseDefaultInsertColumnsToken(insertColumnsSegment.get().getStopIndex(), getColumnNames(sqlStatementContext, encryptTable.get(), sqlStatementContext.getColumnNames()));
}
private List<String> getColumnNames(final InsertSQLStatementContext sqlStatementContext, final EncryptTable encryptTable, final List<String> currentColumnNames) {
List<String> result = new LinkedList<>(currentColumnNames);
Iterator<String> descendingColumnNames = sqlStatementContext.getDescendingColumnNames();
while (descendingColumnNames.hasNext()) {
String columnName = descendingColumnNames.next();
if (encryptTable.findShardingEncryptor(columnName).isPresent()) {
int columnIndex = result.indexOf(columnName);
addPlainColumn(result, encryptTable, columnName, columnIndex);
addAssistedQueryColumn(result, encryptTable, columnName, columnIndex);
setCipherColumn(result, encryptTable, columnName, columnIndex);
}
}
return result;
}
private void addPlainColumn(final List<String> columnNames, final EncryptTable encryptTable, final String columnName, final int columnIndex) {
Optional<String> plainColumn = encryptTable.findPlainColumn(columnName);
if (plainColumn.isPresent()) {
columnNames.add(columnIndex + 1, plainColumn.get());
}
}
private void addAssistedQueryColumn(final List<String> columnNames, final EncryptTable encryptTable, final String columnName, final int columnIndex) {
Optional<String> assistedQueryColumn = encryptTable.findAssistedQueryColumn(columnName);
if (assistedQueryColumn.isPresent()) {
columnNames.add(columnIndex + 1, assistedQueryColumn.get());
}
}
private void setCipherColumn(final List<String> columnNames, final EncryptTable encryptTable, final String columnName, final int columnIndex) {
columnNames.set(columnIndex, encryptTable.getCipherColumn(columnName));
}
}

View File

@ -0,0 +1,170 @@
/*
* 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.
*/
package org.apache.shardingsphere.encrypt.rewrite.token.generator.impl;
import com.google.common.base.Optional;
import lombok.Setter;
import org.apache.shardingsphere.encrypt.rewrite.token.pojo.EncryptInsertValuesToken;
import org.apache.shardingsphere.spi.encrypt.ShardingEncryptor;
import org.apache.shardingsphere.spi.encrypt.ShardingQueryAssistedEncryptor;
import org.apache.shardingsphere.sql.parser.relation.segment.insert.InsertValueContext;
import org.apache.shardingsphere.sql.parser.relation.segment.insert.expression.DerivedLiteralExpressionSegment;
import org.apache.shardingsphere.sql.parser.relation.segment.insert.expression.DerivedParameterMarkerExpressionSegment;
import org.apache.shardingsphere.sql.parser.relation.segment.insert.expression.DerivedSimpleExpressionSegment;
import org.apache.shardingsphere.sql.parser.relation.statement.SQLStatementContext;
import org.apache.shardingsphere.sql.parser.relation.statement.impl.InsertSQLStatementContext;
import org.apache.shardingsphere.sql.parser.sql.segment.dml.assignment.InsertValuesSegment;
import org.apache.shardingsphere.sql.parser.sql.segment.dml.expr.ExpressionSegment;
import org.apache.shardingsphere.sql.parser.sql.segment.dml.expr.simple.LiteralExpressionSegment;
import org.apache.shardingsphere.sql.parser.sql.segment.dml.expr.simple.ParameterMarkerExpressionSegment;
import org.apache.shardingsphere.encrypt.rewrite.token.generator.BaseEncryptSQLTokenGenerator;
import org.apache.shardingsphere.underlying.rewrite.sql.token.generator.OptionalSQLTokenGenerator;
import org.apache.shardingsphere.underlying.rewrite.sql.token.generator.aware.PreviousSQLTokensAware;
import org.apache.shardingsphere.underlying.rewrite.sql.token.pojo.SQLToken;
import org.apache.shardingsphere.underlying.rewrite.sql.token.pojo.generic.InsertValue;
import org.apache.shardingsphere.underlying.rewrite.sql.token.pojo.generic.InsertValuesToken;
import org.apache.shardingsphere.underlying.rewrite.sql.token.pojo.generic.UseDefaultInsertColumnsToken;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
/**
* Insert values token generator for encrypt.
*
* @author panjuan
*/
@Setter
public final class EncryptInsertValuesTokenGenerator extends BaseEncryptSQLTokenGenerator implements OptionalSQLTokenGenerator, PreviousSQLTokensAware {
private List<SQLToken> previousSQLTokens;
@Override
protected boolean isGenerateSQLTokenForEncrypt(final SQLStatementContext sqlStatementContext) {
return sqlStatementContext instanceof InsertSQLStatementContext && !sqlStatementContext.getSqlStatement().findSQLSegments(InsertValuesSegment.class).isEmpty();
}
@Override
public InsertValuesToken generateSQLToken(final SQLStatementContext sqlStatementContext) {
Optional<SQLToken> insertValuesToken = findPreviousSQLToken(InsertValuesToken.class);
if (insertValuesToken.isPresent()) {
processPreviousSQLToken((InsertSQLStatementContext) sqlStatementContext, (InsertValuesToken) insertValuesToken.get());
return (InsertValuesToken) insertValuesToken.get();
}
return generateNewSQLToken((InsertSQLStatementContext) sqlStatementContext);
}
private Optional<SQLToken> findPreviousSQLToken(final Class<?> sqlToken) {
for (SQLToken each : previousSQLTokens) {
if (sqlToken.isAssignableFrom(each.getClass())) {
return Optional.of(each);
}
}
return Optional.absent();
}
private void processPreviousSQLToken(final InsertSQLStatementContext sqlStatementContext, final InsertValuesToken insertValuesToken) {
String tableName = sqlStatementContext.getTablesContext().getSingleTableName();
int count = 0;
for (InsertValueContext each : sqlStatementContext.getInsertValueContexts()) {
encryptToken(insertValuesToken.getInsertValues().get(count), tableName, sqlStatementContext, each);
count++;
}
}
private InsertValuesToken generateNewSQLToken(final InsertSQLStatementContext sqlStatementContext) {
String tableName = sqlStatementContext.getTablesContext().getSingleTableName();
Collection<InsertValuesSegment> insertValuesSegments = sqlStatementContext.getSqlStatement().findSQLSegments(InsertValuesSegment.class);
InsertValuesToken result = new EncryptInsertValuesToken(getStartIndex(insertValuesSegments), getStopIndex(insertValuesSegments));
for (InsertValueContext each : sqlStatementContext.getInsertValueContexts()) {
InsertValue insertValueToken = new InsertValue(each.getValueExpressions());
encryptToken(insertValueToken, tableName, sqlStatementContext, each);
result.getInsertValues().add(insertValueToken);
}
return result;
}
private int getStartIndex(final Collection<InsertValuesSegment> segments) {
int result = segments.iterator().next().getStartIndex();
for (InsertValuesSegment each : segments) {
result = Math.min(result, each.getStartIndex());
}
return result;
}
private int getStopIndex(final Collection<InsertValuesSegment> segments) {
int result = segments.iterator().next().getStopIndex();
for (InsertValuesSegment each : segments) {
result = Math.max(result, each.getStopIndex());
}
return result;
}
private void encryptToken(final InsertValue insertValueToken, final String tableName, final InsertSQLStatementContext sqlStatementContext, final InsertValueContext insertValueContext) {
Optional<SQLToken> useDefaultInsertColumnsToken = findPreviousSQLToken(UseDefaultInsertColumnsToken.class);
Iterator<String> descendingColumnNames = sqlStatementContext.getDescendingColumnNames();
while (descendingColumnNames.hasNext()) {
String columnName = descendingColumnNames.next();
Optional<ShardingEncryptor> encryptor = getEncryptRule().findShardingEncryptor(tableName, columnName);
if (encryptor.isPresent()) {
int columnIndex = useDefaultInsertColumnsToken.isPresent()
? ((UseDefaultInsertColumnsToken) useDefaultInsertColumnsToken.get()).getColumns().indexOf(columnName) : sqlStatementContext.getColumnNames().indexOf(columnName);
Object originalValue = insertValueContext.getValue(columnIndex);
addPlainColumn(insertValueToken, columnIndex, tableName, columnName, insertValueContext, originalValue);
addAssistedQueryColumn(insertValueToken, encryptor.get(), columnIndex, tableName, columnName, insertValueContext, originalValue);
setCipherColumn(insertValueToken, encryptor.get(), columnIndex, insertValueContext.getValueExpressions().get(columnIndex), originalValue);
}
}
}
private void addPlainColumn(final InsertValue insertValueToken, final int columnIndex,
final String tableName, final String columnName, final InsertValueContext insertValueContext, final Object originalValue) {
if (getEncryptRule().findPlainColumn(tableName, columnName).isPresent()) {
DerivedSimpleExpressionSegment derivedExpressionSegment = insertValueContext.getParameters().isEmpty()
? new DerivedLiteralExpressionSegment(originalValue) : new DerivedParameterMarkerExpressionSegment(getParameterIndexCount(insertValueToken));
insertValueToken.getValues().add(columnIndex + 1, derivedExpressionSegment);
}
}
private void addAssistedQueryColumn(final InsertValue insertValueToken, final ShardingEncryptor encryptor, final int columnIndex,
final String tableName, final String columnName, final InsertValueContext insertValueContext, final Object originalValue) {
if (getEncryptRule().findAssistedQueryColumn(tableName, columnName).isPresent()) {
DerivedSimpleExpressionSegment derivedExpressionSegment = insertValueContext.getParameters().isEmpty()
? new DerivedLiteralExpressionSegment(((ShardingQueryAssistedEncryptor) encryptor).queryAssistedEncrypt(null == originalValue ? null : originalValue.toString()))
: new DerivedParameterMarkerExpressionSegment(getParameterIndexCount(insertValueToken));
insertValueToken.getValues().add(columnIndex + 1, derivedExpressionSegment);
}
}
private int getParameterIndexCount(final InsertValue insertValueToken) {
int result = 0;
for (ExpressionSegment each : insertValueToken.getValues()) {
if (each instanceof ParameterMarkerExpressionSegment) {
result++;
}
}
return result;
}
private void setCipherColumn(final InsertValue insertValueToken, final ShardingEncryptor encryptor,
final int columnIndex, final ExpressionSegment valueExpression, final Object originalValue) {
if (valueExpression instanceof LiteralExpressionSegment) {
insertValueToken.getValues().set(columnIndex, new LiteralExpressionSegment(valueExpression.getStartIndex(), valueExpression.getStopIndex(), encryptor.encrypt(originalValue)));
}
}
}

View File

@ -0,0 +1,94 @@
/*
* 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.
*/
package org.apache.shardingsphere.encrypt.rewrite.token.generator.impl;
import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
import lombok.Setter;
import org.apache.shardingsphere.core.strategy.encrypt.EncryptTable;
import org.apache.shardingsphere.sql.parser.relation.metadata.RelationMetas;
import org.apache.shardingsphere.sql.parser.relation.statement.SQLStatementContext;
import org.apache.shardingsphere.sql.parser.sql.segment.dml.predicate.AndPredicate;
import org.apache.shardingsphere.sql.parser.sql.segment.dml.predicate.PredicateSegment;
import org.apache.shardingsphere.sql.parser.sql.statement.generic.WhereSegmentAvailable;
import org.apache.shardingsphere.encrypt.rewrite.aware.QueryWithCipherColumnAware;
import org.apache.shardingsphere.encrypt.rewrite.token.generator.BaseEncryptSQLTokenGenerator;
import org.apache.shardingsphere.underlying.rewrite.sql.token.generator.CollectionSQLTokenGenerator;
import org.apache.shardingsphere.underlying.rewrite.sql.token.generator.aware.RelationMetasAware;
import org.apache.shardingsphere.underlying.rewrite.sql.token.pojo.generic.SubstitutableColumnNameToken;
import java.util.Collection;
import java.util.LinkedList;
/**
* Predicate column token generator for encrypt.
*
* @author panjuan
* @author zhangliang
*/
@Setter
public final class EncryptPredicateColumnTokenGenerator extends BaseEncryptSQLTokenGenerator implements CollectionSQLTokenGenerator, RelationMetasAware, QueryWithCipherColumnAware {
private RelationMetas relationMetas;
private boolean queryWithCipherColumn;
@Override
protected boolean isGenerateSQLTokenForEncrypt(final SQLStatementContext sqlStatementContext) {
return sqlStatementContext.getSqlStatement() instanceof WhereSegmentAvailable && ((WhereSegmentAvailable) sqlStatementContext.getSqlStatement()).getWhere().isPresent();
}
@Override
public Collection<SubstitutableColumnNameToken> generateSQLTokens(final SQLStatementContext sqlStatementContext) {
Preconditions.checkState(((WhereSegmentAvailable) sqlStatementContext.getSqlStatement()).getWhere().isPresent());
Collection<SubstitutableColumnNameToken> result = new LinkedList<>();
for (AndPredicate each : ((WhereSegmentAvailable) sqlStatementContext.getSqlStatement()).getWhere().get().getAndPredicates()) {
result.addAll(generateSQLTokens(sqlStatementContext, each));
}
return result;
}
private Collection<SubstitutableColumnNameToken> generateSQLTokens(final SQLStatementContext sqlStatementContext, final AndPredicate andPredicate) {
Collection<SubstitutableColumnNameToken> result = new LinkedList<>();
for (PredicateSegment each : andPredicate.getPredicates()) {
Optional<EncryptTable> encryptTable = findEncryptTable(sqlStatementContext, each);
if (!encryptTable.isPresent() || !encryptTable.get().findShardingEncryptor(each.getColumn().getName()).isPresent()) {
continue;
}
int startIndex = each.getColumn().getOwner().isPresent() ? each.getColumn().getOwner().get().getStopIndex() + 2 : each.getColumn().getStartIndex();
int stopIndex = each.getColumn().getStopIndex();
if (!queryWithCipherColumn) {
Optional<String> plainColumn = encryptTable.get().findPlainColumn(each.getColumn().getName());
if (plainColumn.isPresent()) {
result.add(new SubstitutableColumnNameToken(startIndex, stopIndex, plainColumn.get()));
continue;
}
}
Optional<String> assistedQueryColumn = encryptTable.get().findAssistedQueryColumn(each.getColumn().getName());
SubstitutableColumnNameToken encryptColumnNameToken = assistedQueryColumn.isPresent() ? new SubstitutableColumnNameToken(startIndex, stopIndex, assistedQueryColumn.get())
: new SubstitutableColumnNameToken(startIndex, stopIndex, encryptTable.get().getCipherColumn(each.getColumn().getName()));
result.add(encryptColumnNameToken);
}
return result;
}
private Optional<EncryptTable> findEncryptTable(final SQLStatementContext sqlStatementContext, final PredicateSegment segment) {
Optional<String> tableName = sqlStatementContext.getTablesContext().findTableName(segment.getColumn(), relationMetas);
return tableName.isPresent() ? getEncryptRule().findEncryptTable(tableName.get()) : Optional.<EncryptTable>absent();
}
}

View File

@ -0,0 +1,108 @@
/*
* 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.
*/
package org.apache.shardingsphere.encrypt.rewrite.token.generator.impl;
import com.google.common.base.Optional;
import lombok.Setter;
import org.apache.shardingsphere.encrypt.rewrite.EncryptCondition;
import org.apache.shardingsphere.encrypt.rewrite.EncryptConditionEngine;
import org.apache.shardingsphere.encrypt.rewrite.aware.QueryWithCipherColumnAware;
import org.apache.shardingsphere.encrypt.rewrite.token.generator.BaseEncryptSQLTokenGenerator;
import org.apache.shardingsphere.encrypt.rewrite.token.pojo.EncryptPredicateRightValueToken;
import org.apache.shardingsphere.sql.parser.relation.metadata.RelationMetas;
import org.apache.shardingsphere.sql.parser.relation.statement.SQLStatementContext;
import org.apache.shardingsphere.sql.parser.sql.statement.generic.WhereSegmentAvailable;
import org.apache.shardingsphere.underlying.rewrite.sql.token.generator.CollectionSQLTokenGenerator;
import org.apache.shardingsphere.underlying.rewrite.sql.token.generator.aware.ParametersAware;
import org.apache.shardingsphere.underlying.rewrite.sql.token.generator.aware.RelationMetasAware;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
/**
* Predicate right value token generator for encrypt.
*
* @author panjuan
* @author zhangliang
*/
@Setter
public final class EncryptPredicateRightValueTokenGenerator extends BaseEncryptSQLTokenGenerator implements CollectionSQLTokenGenerator,
RelationMetasAware, ParametersAware, QueryWithCipherColumnAware {
private RelationMetas relationMetas;
private List<Object> parameters;
private boolean queryWithCipherColumn;
@Override
protected boolean isGenerateSQLTokenForEncrypt(final SQLStatementContext sqlStatementContext) {
return sqlStatementContext.getSqlStatement() instanceof WhereSegmentAvailable && ((WhereSegmentAvailable) sqlStatementContext.getSqlStatement()).getWhere().isPresent();
}
@Override
public Collection<EncryptPredicateRightValueToken> generateSQLTokens(final SQLStatementContext sqlStatementContext) {
List<EncryptCondition> encryptConditions = new EncryptConditionEngine(getEncryptRule(), relationMetas).createEncryptConditions(sqlStatementContext);
return encryptConditions.isEmpty() ? Collections.<EncryptPredicateRightValueToken>emptyList() : generateSQLTokens(encryptConditions);
}
private Collection<EncryptPredicateRightValueToken> generateSQLTokens(final List<EncryptCondition> encryptConditions) {
Collection<EncryptPredicateRightValueToken> result = new LinkedList<>();
for (EncryptCondition each : encryptConditions) {
result.add(generateSQLToken(each));
}
return result;
}
private EncryptPredicateRightValueToken generateSQLToken(final EncryptCondition encryptCondition) {
List<Object> originalValues = encryptCondition.getValues(parameters);
int startIndex = encryptCondition.getStartIndex();
return queryWithCipherColumn ? generateSQLTokenForQueryWithCipherColumn(encryptCondition, originalValues, startIndex)
: generateSQLTokenForQueryWithoutCipherColumn(encryptCondition, originalValues, startIndex);
}
private EncryptPredicateRightValueToken generateSQLTokenForQueryWithCipherColumn(final EncryptCondition encryptCondition, final List<Object> originalValues, final int startIndex) {
List<Object> encryptedValues = getEncryptedValues(encryptCondition, originalValues);
return new EncryptPredicateRightValueToken(startIndex, encryptCondition.getStopIndex(), getPositionValues(encryptCondition.getPositionValueMap().keySet(), encryptedValues),
encryptCondition.getPositionIndexMap().keySet(), encryptCondition.getOperator());
}
private List<Object> getEncryptedValues(final EncryptCondition encryptCondition, final List<Object> originalValues) {
Optional<String> assistedQueryColumn = getEncryptRule().findAssistedQueryColumn(encryptCondition.getTableName(), encryptCondition.getColumnName());
return assistedQueryColumn.isPresent()
? getEncryptRule().getEncryptAssistedQueryValues(encryptCondition.getTableName(), encryptCondition.getColumnName(), originalValues)
: getEncryptRule().getEncryptValues(encryptCondition.getTableName(), encryptCondition.getColumnName(), originalValues);
}
private EncryptPredicateRightValueToken generateSQLTokenForQueryWithoutCipherColumn(final EncryptCondition encryptCondition, final List<Object> originalValues, final int startIndex) {
return new EncryptPredicateRightValueToken(startIndex, encryptCondition.getStopIndex(),
getPositionValues(encryptCondition.getPositionValueMap().keySet(), originalValues), encryptCondition.getPositionIndexMap().keySet(), encryptCondition.getOperator());
}
private Map<Integer, Object> getPositionValues(final Collection<Integer> valuePositions, final List<Object> encryptValues) {
Map<Integer, Object> result = new LinkedHashMap<>();
for (int each : valuePositions) {
result.put(each, encryptValues.get(each));
}
return result;
}
}

View File

@ -0,0 +1,85 @@
/*
* 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.
*/
package org.apache.shardingsphere.encrypt.rewrite.token.generator.impl;
import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
import lombok.Setter;
import org.apache.shardingsphere.core.strategy.encrypt.EncryptTable;
import org.apache.shardingsphere.encrypt.rewrite.aware.QueryWithCipherColumnAware;
import org.apache.shardingsphere.sql.parser.relation.statement.SQLStatementContext;
import org.apache.shardingsphere.sql.parser.sql.segment.dml.item.ColumnSelectItemSegment;
import org.apache.shardingsphere.sql.parser.sql.segment.dml.item.SelectItemSegment;
import org.apache.shardingsphere.sql.parser.sql.segment.dml.item.SelectItemsSegment;
import org.apache.shardingsphere.sql.parser.sql.statement.dml.SelectStatement;
import org.apache.shardingsphere.encrypt.rewrite.token.generator.BaseEncryptSQLTokenGenerator;
import org.apache.shardingsphere.underlying.rewrite.sql.token.generator.CollectionSQLTokenGenerator;
import org.apache.shardingsphere.underlying.rewrite.sql.token.pojo.generic.SubstitutableColumnNameToken;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedList;
/**
* Projection token generator for encrypt.
*
* @author panjuan
*/
@Setter
public final class EncryptProjectionTokenGenerator extends BaseEncryptSQLTokenGenerator implements CollectionSQLTokenGenerator, QueryWithCipherColumnAware {
private boolean queryWithCipherColumn;
@Override
protected boolean isGenerateSQLTokenForEncrypt(final SQLStatementContext sqlStatementContext) {
if (!(sqlStatementContext.getSqlStatement() instanceof SelectStatement && !sqlStatementContext.getTablesContext().isEmpty())) {
return false;
}
Optional<SelectItemsSegment> selectItemsSegment = sqlStatementContext.getSqlStatement().findSQLSegment(SelectItemsSegment.class);
return selectItemsSegment.isPresent() && !selectItemsSegment.get().getSelectItems().isEmpty();
}
@Override
public Collection<SubstitutableColumnNameToken> generateSQLTokens(final SQLStatementContext sqlStatementContext) {
Collection<SubstitutableColumnNameToken> result = new LinkedList<>();
Optional<SelectItemsSegment> selectItemsSegment = sqlStatementContext.getSqlStatement().findSQLSegment(SelectItemsSegment.class);
Preconditions.checkState(selectItemsSegment.isPresent());
String tableName = sqlStatementContext.getTablesContext().getSingleTableName();
Optional<EncryptTable> encryptTable = getEncryptRule().findEncryptTable(tableName);
if (!encryptTable.isPresent()) {
return Collections.emptyList();
}
for (SelectItemSegment each : selectItemsSegment.get().getSelectItems()) {
if (isEncryptLogicColumn(each, encryptTable.get())) {
result.add(generateSQLToken((ColumnSelectItemSegment) each, tableName));
}
}
return result;
}
private boolean isEncryptLogicColumn(final SelectItemSegment selectItemSegment, final EncryptTable encryptTable) {
return selectItemSegment instanceof ColumnSelectItemSegment && encryptTable.getLogicColumns().contains(((ColumnSelectItemSegment) selectItemSegment).getName());
}
private SubstitutableColumnNameToken generateSQLToken(final ColumnSelectItemSegment segment, final String tableName) {
Optional<String> plainColumn = getEncryptRule().findPlainColumn(tableName, segment.getName());
String columnName = plainColumn.isPresent() && !queryWithCipherColumn ? plainColumn.get() : getEncryptRule().getCipherColumn(tableName, segment.getName());
return segment.getOwner().isPresent() ? new SubstitutableColumnNameToken(segment.getOwner().get().getStopIndex() + 2, segment.getStopIndex(), columnName)
: new SubstitutableColumnNameToken(segment.getStartIndex(), segment.getStopIndex(), columnName);
}
}

View File

@ -0,0 +1,60 @@
/*
* 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.
*/
package org.apache.shardingsphere.encrypt.rewrite.token.generator.impl;
import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
import org.apache.shardingsphere.sql.parser.relation.statement.SQLStatementContext;
import org.apache.shardingsphere.sql.parser.relation.statement.impl.InsertSQLStatementContext;
import org.apache.shardingsphere.sql.parser.sql.segment.dml.column.ColumnSegment;
import org.apache.shardingsphere.sql.parser.sql.segment.dml.column.InsertColumnsSegment;
import org.apache.shardingsphere.encrypt.rewrite.token.generator.BaseEncryptSQLTokenGenerator;
import org.apache.shardingsphere.underlying.rewrite.sql.token.generator.CollectionSQLTokenGenerator;
import org.apache.shardingsphere.underlying.rewrite.sql.token.pojo.generic.SubstitutableColumnNameToken;
import java.util.Collection;
import java.util.LinkedList;
import java.util.Map;
/**
* Insert cipher column name token generator.
*
* @author panjuan
*/
public final class InsertCipherNameTokenGenerator extends BaseEncryptSQLTokenGenerator implements CollectionSQLTokenGenerator {
@Override
protected boolean isGenerateSQLTokenForEncrypt(final SQLStatementContext sqlStatementContext) {
Optional<InsertColumnsSegment> insertColumnsSegment = sqlStatementContext.getSqlStatement().findSQLSegment(InsertColumnsSegment.class);
return sqlStatementContext instanceof InsertSQLStatementContext && insertColumnsSegment.isPresent() && !insertColumnsSegment.get().getColumns().isEmpty();
}
@Override
public Collection<SubstitutableColumnNameToken> generateSQLTokens(final SQLStatementContext sqlStatementContext) {
Optional<InsertColumnsSegment> sqlSegment = sqlStatementContext.getSqlStatement().findSQLSegment(InsertColumnsSegment.class);
Preconditions.checkState(sqlSegment.isPresent());
Map<String, String> logicAndCipherColumns = getEncryptRule().getLogicAndCipherColumns(sqlStatementContext.getTablesContext().getSingleTableName());
Collection<SubstitutableColumnNameToken> result = new LinkedList<>();
for (ColumnSegment each : sqlSegment.get().getColumns()) {
if (logicAndCipherColumns.keySet().contains(each.getName())) {
result.add(new SubstitutableColumnNameToken(each.getStartIndex(), each.getStopIndex(), logicAndCipherColumns.get(each.getName())));
}
}
return result;
}
}

View File

@ -0,0 +1,38 @@
/*
* 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.
*/
package org.apache.shardingsphere.encrypt.rewrite.token.pojo;
import lombok.Getter;
import org.apache.shardingsphere.underlying.rewrite.sql.token.pojo.SQLToken;
import org.apache.shardingsphere.underlying.rewrite.sql.token.pojo.Substitutable;
/**
* Assignment token for encrypt.
*
* @author panjuan
*/
@Getter
public abstract class EncryptAssignmentToken extends SQLToken implements Substitutable {
private final int stopIndex;
public EncryptAssignmentToken(final int startIndex, final int stopIndex) {
super(startIndex);
this.stopIndex = stopIndex;
}
}

View File

@ -0,0 +1,43 @@
/*
* 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.
*/
package org.apache.shardingsphere.encrypt.rewrite.token.pojo;
import org.apache.shardingsphere.underlying.rewrite.sql.token.pojo.generic.InsertValue;
import org.apache.shardingsphere.underlying.rewrite.sql.token.pojo.generic.InsertValuesToken;
/**
* Insert values token for encrypt.
*
* @author zhangliang
*/
public final class EncryptInsertValuesToken extends InsertValuesToken {
public EncryptInsertValuesToken(final int startIndex, final int stopIndex) {
super(startIndex, stopIndex);
}
@Override
public String toString() {
StringBuilder result = new StringBuilder();
for (InsertValue each : getInsertValues()) {
result.append(each).append(", ");
}
result.delete(result.length() - 2, result.length());
return result.toString();
}
}

View File

@ -0,0 +1,70 @@
/*
* 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.
*/
package org.apache.shardingsphere.encrypt.rewrite.token.pojo;
import com.google.common.base.Joiner;
import lombok.RequiredArgsConstructor;
import java.util.Collection;
import java.util.LinkedList;
/**
* Literal assignment token for encrypt.
*
* @author panjuan
*/
public final class EncryptLiteralAssignmentToken extends EncryptAssignmentToken {
private final Collection<LiteralAssignment> assignments = new LinkedList<>();
public EncryptLiteralAssignmentToken(final int startIndex, final int stopIndex) {
super(startIndex, stopIndex);
}
/**
* Add assignment.
*
* @param columnName column name
* @param value assignment value
*/
public void addAssignment(final String columnName, final Object value) {
assignments.add(new LiteralAssignment(columnName, value));
}
@Override
public String toString() {
return Joiner.on(", ").join(assignments);
}
@RequiredArgsConstructor
private final class LiteralAssignment {
private final String columnName;
private final Object value;
@Override
public String toString() {
return String.format("%s = %s", columnName, toString(value));
}
private String toString(final Object value) {
return String.class == value.getClass() ? String.format("'%s'", value) : value.toString();
}
}
}

View File

@ -0,0 +1,60 @@
/*
* 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.
*/
package org.apache.shardingsphere.encrypt.rewrite.token.pojo;
import com.google.common.base.Function;
import com.google.common.base.Joiner;
import com.google.common.collect.Collections2;
import java.util.Collection;
import java.util.LinkedList;
/**
* Parameter assignment token for encrypt.
*
* @author panjuan
*/
public final class EncryptParameterAssignmentToken extends EncryptAssignmentToken {
private final Collection<String> columnNames = new LinkedList<>();
public EncryptParameterAssignmentToken(final int startIndex, final int stopIndex) {
super(startIndex, stopIndex);
}
/**
* Add column name.
*
* @param columnName column name
*/
public void addColumnName(final String columnName) {
columnNames.add(columnName);
}
@Override
public String toString() {
Collection<String> items = Collections2.transform(columnNames, new Function<String, String>() {
@Override
public String apply(final String input) {
return String.format("%s = ?", input);
}
});
return Joiner.on(", ").join(items);
}
}

View File

@ -0,0 +1,91 @@
/*
* 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.
*/
package org.apache.shardingsphere.encrypt.rewrite.token.pojo;
import lombok.Getter;
import org.apache.shardingsphere.core.constant.ShardingOperator;
import org.apache.shardingsphere.core.exception.ShardingException;
import org.apache.shardingsphere.underlying.rewrite.sql.token.pojo.SQLToken;
import org.apache.shardingsphere.underlying.rewrite.sql.token.pojo.Substitutable;
import java.util.Collection;
import java.util.Map;
/**
* Predicate right value token for encrypt.
*
* @author panjuan
*/
public final class EncryptPredicateRightValueToken extends SQLToken implements Substitutable {
@Getter
private final int stopIndex;
private final Map<Integer, Object> indexValues;
private final Collection<Integer> parameterMarkerIndexes;
private final ShardingOperator operator;
public EncryptPredicateRightValueToken(final int startIndex, final int stopIndex,
final Map<Integer, Object> indexValues, final Collection<Integer> parameterMarkerIndexes, final ShardingOperator operator) {
super(startIndex);
this.stopIndex = stopIndex;
this.indexValues = indexValues;
this.parameterMarkerIndexes = parameterMarkerIndexes;
this.operator = operator;
}
@Override
public String toString() {
switch (operator) {
case EQUAL:
return toStringForEqual();
case IN:
return toStringForIn();
default:
throw new ShardingException("Sharding operator do not support.");
}
}
private String toStringForEqual() {
if (parameterMarkerIndexes.isEmpty()) {
return indexValues.get(0) instanceof String ? String.format("'%s'", indexValues.get(0)) : indexValues.get(0).toString();
}
return "?";
}
private String toStringForIn() {
StringBuilder result = new StringBuilder();
result.append("(");
for (int i = 0; i < indexValues.size() + parameterMarkerIndexes.size(); i++) {
if (parameterMarkerIndexes.contains(i)) {
result.append("?");
} else {
if (indexValues.get(i) instanceof String) {
result.append("'").append(indexValues.get(i)).append("'");
} else {
result.append(indexValues.get(i));
}
}
result.append(", ");
}
result.delete(result.length() - 2, result.length()).append(")");
return result.toString();
}
}

View File

@ -0,0 +1,48 @@
/*
* 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.
*/
package org.apache.shardingsphere.encrypt.rewrite;
import org.apache.shardingsphere.sql.parser.sql.segment.dml.expr.ExpressionSegment;
import org.apache.shardingsphere.sql.parser.sql.segment.dml.expr.simple.LiteralExpressionSegment;
import org.junit.Test;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;
public final class EncryptConditionTest {
@Test
public void assertGetConditionValuesForEqual() {
List<Object> actual = new EncryptCondition("col", null, 0, 0, new LiteralExpressionSegment(0, 0, 1)).getValues(Collections.emptyList());
assertThat(actual.size(), is(1));
assertThat((Integer) actual.get(0), is(1));
}
@Test
public void assertGetConditionValuesForIn() {
List<Object> actual = new EncryptCondition(
"col", null, 0, 0, Arrays.<ExpressionSegment>asList(new LiteralExpressionSegment(0, 0, 1), new LiteralExpressionSegment(0, 0, 2))).getValues(Collections.emptyList());
assertThat(actual.size(), is(2));
assertThat((Integer) actual.get(0), is(1));
assertThat((Integer) actual.get(1), is(2));
}
}

View File

@ -0,0 +1,50 @@
/*
* 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.
*/
package org.apache.shardingsphere.encrypt.rewrite.fixture;
import lombok.Getter;
import lombok.Setter;
import org.apache.shardingsphere.spi.encrypt.ShardingEncryptor;
import java.util.Properties;
@Getter
@Setter
public final class NormalEncryptorFixture implements ShardingEncryptor {
private Properties properties = new Properties();
@Override
public String getType() {
return "NORMAL_ENCRYPT";
}
@Override
public void init() {
}
@Override
public String encrypt(final Object plaintext) {
return "encrypt_" + plaintext;
}
@Override
public Object decrypt(final String ciphertext) {
return ciphertext.replaceAll("encrypt_", "");
}
}

View File

@ -0,0 +1,55 @@
/*
* 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.
*/
package org.apache.shardingsphere.encrypt.rewrite.fixture;
import lombok.Getter;
import lombok.Setter;
import org.apache.shardingsphere.spi.encrypt.ShardingQueryAssistedEncryptor;
import java.util.Properties;
@Getter
@Setter
public final class QueryAssistedEncryptorFixture implements ShardingQueryAssistedEncryptor {
private Properties properties = new Properties();
@Override
public String getType() {
return "ASSISTED_QUERY_ENCRYPT";
}
@Override
public void init() {
}
@Override
public String encrypt(final Object plaintext) {
return "encrypt_" + plaintext;
}
@Override
public Object decrypt(final String ciphertext) {
return ciphertext.replaceAll("encrypt_", "");
}
@Override
public String queryAssistedEncrypt(final String plaintext) {
return "assisted_query_" + plaintext;
}
}

View File

@ -0,0 +1,93 @@
/*
* 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.
*/
package org.apache.shardingsphere.encrypt.rewrite.parameterized;
import com.google.common.base.Preconditions;
import org.apache.shardingsphere.core.rule.EncryptRule;
import org.apache.shardingsphere.core.yaml.config.encrypt.YamlRootEncryptRuleConfiguration;
import org.apache.shardingsphere.core.yaml.engine.YamlEngine;
import org.apache.shardingsphere.core.yaml.swapper.impl.EncryptRuleConfigurationYamlSwapper;
import org.apache.shardingsphere.encrypt.rewrite.context.EncryptSQLRewriteContextDecorator;
import org.apache.shardingsphere.sql.parser.SQLParseEngineFactory;
import org.apache.shardingsphere.sql.parser.relation.SQLStatementContextFactory;
import org.apache.shardingsphere.sql.parser.relation.metadata.RelationMetas;
import org.apache.shardingsphere.sql.parser.relation.statement.SQLStatementContext;
import org.apache.shardingsphere.sql.parser.sql.statement.SQLStatement;
import org.apache.shardingsphere.underlying.rewrite.context.SQLRewriteContext;
import org.apache.shardingsphere.underlying.rewrite.engine.SQLRewriteResult;
import org.apache.shardingsphere.underlying.rewrite.engine.impl.DefaultSQLRewriteEngine;
import org.apache.shardingsphere.underlying.rewrite.parameterized.engine.AbstractSQLRewriterParameterizedTest;
import org.apache.shardingsphere.underlying.rewrite.parameterized.engine.parameter.SQLRewriteEngineTestParameters;
import org.apache.shardingsphere.underlying.rewrite.parameterized.engine.parameter.SQLRewriteEngineTestParametersBuilder;
import org.junit.runners.Parameterized.Parameters;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
public final class EncryptSQLRewriterParameterizedTest extends AbstractSQLRewriterParameterizedTest {
private static final String PATH = "encrypt";
public EncryptSQLRewriterParameterizedTest(final String type, final String name, final String fileName, final SQLRewriteEngineTestParameters testParameters) {
super(testParameters);
}
@Parameters(name = "{0}: {1} -> {2}")
public static Collection<Object[]> loadTestParameters() {
return SQLRewriteEngineTestParametersBuilder.loadTestParameters(PATH.toUpperCase(), PATH, EncryptSQLRewriterParameterizedTest.class);
}
@Override
protected Collection<SQLRewriteResult> createSQLRewriteResults() throws IOException {
YamlRootEncryptRuleConfiguration ruleConfiguration = createRuleConfiguration();
EncryptRule encryptRule = new EncryptRule(new EncryptRuleConfigurationYamlSwapper().swap(ruleConfiguration.getEncryptRule()));
boolean isQueryWithCipherColumn = (boolean) ruleConfiguration.getProps().get("query.with.cipher.column");
SQLRewriteContext sqlRewriteContext = createSQLRewriteContext();
new EncryptSQLRewriteContextDecorator(encryptRule, isQueryWithCipherColumn).decorate(sqlRewriteContext);
sqlRewriteContext.generateSQLTokens();
return Collections.singletonList(new DefaultSQLRewriteEngine().rewrite(sqlRewriteContext));
}
private YamlRootEncryptRuleConfiguration createRuleConfiguration() throws IOException {
URL url = EncryptSQLRewriterParameterizedTest.class.getClassLoader().getResource(getTestParameters().getRuleFile());
Preconditions.checkNotNull(url, "Cannot found rewrite rule yaml configuration.");
return YamlEngine.unmarshal(new File(url.getFile()), YamlRootEncryptRuleConfiguration.class);
}
private SQLRewriteContext createSQLRewriteContext() {
SQLStatement sqlStatement = SQLParseEngineFactory.getSQLParseEngine(
null == getTestParameters().getDatabaseType() ? "SQL92" : getTestParameters().getDatabaseType()).parse(getTestParameters().getInputSQL(), false);
SQLStatementContext sqlStatementContext = SQLStatementContextFactory.newInstance(
createRelationMetas(), getTestParameters().getInputSQL(), getTestParameters().getInputParameters(), sqlStatement);
return new SQLRewriteContext(mock(RelationMetas.class), sqlStatementContext, getTestParameters().getInputSQL(), getTestParameters().getInputParameters());
}
private RelationMetas createRelationMetas() {
RelationMetas result = mock(RelationMetas.class);
when(result.getAllColumnNames("t_account")).thenReturn(Arrays.asList("account_id", "certificate_number", "password", "amount", "status"));
when(result.getAllColumnNames("t_account_bak")).thenReturn(Arrays.asList("account_id", "certificate_number", "password", "amount", "status"));
return result;
}
}

View File

@ -0,0 +1,35 @@
/*
* 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.
*/
package org.apache.shardingsphere.encrypt.rewrite.pojo;
import org.apache.shardingsphere.encrypt.rewrite.token.pojo.EncryptLiteralAssignmentToken;
import org.junit.Test;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;
public final class EncryptLiteralAssignmentTokenTest {
@Test
public void assertToString() {
EncryptLiteralAssignmentToken actual = new EncryptLiteralAssignmentToken(0, 1);
actual.addAssignment("c1", "c1");
actual.addAssignment("c2", 1);
assertThat(actual.toString(), is("c1 = 'c1', c2 = 1"));
}
}

View File

@ -0,0 +1,35 @@
/*
* 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.
*/
package org.apache.shardingsphere.encrypt.rewrite.pojo;
import org.apache.shardingsphere.encrypt.rewrite.token.pojo.EncryptParameterAssignmentToken;
import org.junit.Test;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;
public final class EncryptParameterAssignmentTokenTest {
@Test
public void assertToString() {
EncryptParameterAssignmentToken actual = new EncryptParameterAssignmentToken(0, 1);
actual.addColumnName("c1");
actual.addColumnName("c2");
assertThat(actual.toString(), is("c1 = ?, c2 = ?"));
}
}

View File

@ -0,0 +1,61 @@
/*
* 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.
*/
package org.apache.shardingsphere.encrypt.rewrite.pojo;
import org.apache.shardingsphere.core.constant.ShardingOperator;
import org.apache.shardingsphere.encrypt.rewrite.token.pojo.EncryptPredicateRightValueToken;
import org.junit.Test;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.Map;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;
public final class EncryptPredicateTokenTest {
@Test
public void assertToStringWithoutPlaceholderWithoutTableOwnerWithEqual() {
Map<Integer, Object> indexValues = new LinkedHashMap<>();
indexValues.put(0, "a");
EncryptPredicateRightValueToken actual = new EncryptPredicateRightValueToken(0, 0, indexValues, Collections.<Integer>emptyList(), ShardingOperator.EQUAL);
assertThat(actual.toString(), is("'a'"));
}
@Test
public void assertToStringWithPlaceholderWithoutTableOwnerWithEqual() {
EncryptPredicateRightValueToken actual = new EncryptPredicateRightValueToken(0, 0, Collections.<Integer, Object>emptyMap(), Collections.singletonList(0), ShardingOperator.EQUAL);
assertThat(actual.toString(), is("?"));
}
@Test
public void assertToStringWithoutPlaceholderWithoutTableOwnerWithIn() {
Map<Integer, Object> indexValues = new LinkedHashMap<>();
indexValues.put(0, "a");
indexValues.put(1, "b");
EncryptPredicateRightValueToken actual = new EncryptPredicateRightValueToken(0, 0, indexValues, Collections.<Integer>emptyList(), ShardingOperator.IN);
assertThat(actual.toString(), is("('a', 'b')"));
}
@Test
public void assertToStringWithPlaceholderWithoutTableOwnerWithIn() {
EncryptPredicateRightValueToken actual = new EncryptPredicateRightValueToken(0, 0, Collections.<Integer, Object>emptyMap(), Collections.singletonList(0), ShardingOperator.IN);
assertThat(actual.toString(), is("(?)"));
}
}

View File

@ -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.
#
org.apache.shardingsphere.encrypt.rewrite.fixture.NormalEncryptorFixture
org.apache.shardingsphere.encrypt.rewrite.fixture.QueryAssistedEncryptorFixture

View File

@ -0,0 +1,39 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ 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.
-->
<rewrite-assertions yaml-rule="yaml/encrypt/query-with-cipher.yaml">
<rewrite-assertion id="delete_for_parameters">
<input sql="DELETE FROM t_account WHERE account_id = ? AND password = ? AND amount = ? AND status = ?" parameters="1, aaa, 1000, OK" />
<output sql="DELETE FROM t_account WHERE account_id = ? AND assisted_query_password = ? AND cipher_amount = ? AND status = ?" parameters="1, assisted_query_aaa, encrypt_1000, OK" />
</rewrite-assertion>
<rewrite-assertion id="delete_for_literals">
<input sql="DELETE FROM t_account WHERE account_id = 1 AND password = 'aaa' AND amount = 1000 AND status = 'OK'" />
<output sql="DELETE FROM t_account WHERE account_id = 1 AND assisted_query_password = 'assisted_query_aaa' AND cipher_amount = 'encrypt_1000' AND status = 'OK'" />
</rewrite-assertion>
<rewrite-assertion id="delete_plain_for_parameters">
<input sql="DELETE FROM t_account_bak WHERE account_id = ? AND password = ? AND amount = ? AND status = ?" parameters="1, aaa, 1000, OK" />
<output sql="DELETE FROM t_account_bak WHERE account_id = ? AND assisted_query_password = ? AND cipher_amount = ? AND status = ?" parameters="1, assisted_query_aaa, encrypt_1000, OK" />
</rewrite-assertion>
<rewrite-assertion id="delete_for_literals">
<input sql="DELETE FROM t_account_bak WHERE account_id = 1 AND password = 'aaa' AND amount = 1000 AND status = 'OK'" />
<output sql="DELETE FROM t_account_bak WHERE account_id = 1 AND assisted_query_password = 'assisted_query_aaa' AND cipher_amount = 'encrypt_1000' AND status = 'OK'" />
</rewrite-assertion>
</rewrite-assertions>

View File

@ -0,0 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ 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.
-->
<rewrite-assertions yaml-rule="yaml/encrypt/query-with-plain.yaml">
<rewrite-assertion id="delete_plain_for_parameters">
<input sql="DELETE FROM t_account_bak WHERE account_id = ? AND password = ? AND amount = ? AND status = ?" parameters="1, aaa, 1000, OK" />
<output sql="DELETE FROM t_account_bak WHERE account_id = ? AND plain_password = ? AND plain_amount = ? AND status = ?" parameters="1, aaa, 1000, OK" />
</rewrite-assertion>
<rewrite-assertion id="delete_for_literals">
<input sql="DELETE FROM t_account_bak WHERE account_id = 1 AND password = 'aaa' AND amount = 1000 AND status = 'OK'" />
<output sql="DELETE FROM t_account_bak WHERE account_id = 1 AND plain_password = 'aaa' AND plain_amount = 1000 AND status = 'OK'" />
</rewrite-assertion>
</rewrite-assertions>

View File

@ -0,0 +1,89 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ 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.
-->
<rewrite-assertions yaml-rule="yaml/encrypt/query-with-cipher.yaml">
<rewrite-assertion id="insert_values_with_columns_for_parameters">
<input sql="INSERT INTO t_account(account_id, certificate_number, password, amount, status) VALUES (?, ?, ?, ?, ?), (2, '222X', 'bbb', 2000, 'OK'), (?, ?, ?, ?, ?), (4, '444X', 'ddd', 4000, 'OK')" parameters="1, 111X, aaa, 1000, OK, 3, 333X, ccc, 3000, OK" />
<output sql="INSERT INTO t_account(account_id, cipher_certificate_number, assisted_query_certificate_number, cipher_password, assisted_query_password, cipher_amount, status) VALUES (?, ?, ?, ?, ?, ?, ?), (2, 'encrypt_222X', 'assisted_query_222X', 'encrypt_bbb', 'assisted_query_bbb', 'encrypt_2000', 'OK'), (?, ?, ?, ?, ?, ?, ?), (4, 'encrypt_444X', 'assisted_query_444X', 'encrypt_ddd', 'assisted_query_ddd', 'encrypt_4000', 'OK')" parameters="1, encrypt_111X, assisted_query_111X, encrypt_aaa, assisted_query_aaa, encrypt_1000, OK, 3, encrypt_333X, assisted_query_333X, encrypt_ccc, assisted_query_ccc, encrypt_3000, OK" />
</rewrite-assertion>
<rewrite-assertion id="insert_values_with_columns_for_literals">
<input sql="INSERT INTO t_account(account_id, certificate_number, password, amount, status) VALUES (1, '111X', 'aaa', 1000, 'OK'), (2, '222X', 'bbb', 2000, 'OK'), (3, '333X', 'ccc', 3000, 'OK'), (4, '444X', 'ddd', 4000, 'OK')" />
<output sql="INSERT INTO t_account(account_id, cipher_certificate_number, assisted_query_certificate_number, cipher_password, assisted_query_password, cipher_amount, status) VALUES (1, 'encrypt_111X', 'assisted_query_111X', 'encrypt_aaa', 'assisted_query_aaa', 'encrypt_1000', 'OK'), (2, 'encrypt_222X', 'assisted_query_222X', 'encrypt_bbb', 'assisted_query_bbb', 'encrypt_2000', 'OK'), (3, 'encrypt_333X', 'assisted_query_333X', 'encrypt_ccc', 'assisted_query_ccc', 'encrypt_3000', 'OK'), (4, 'encrypt_444X', 'assisted_query_444X', 'encrypt_ddd', 'assisted_query_ddd', 'encrypt_4000', 'OK')" />
</rewrite-assertion>
<rewrite-assertion id="insert_values_with_columns_and_configuration_for_different_sequence_for_parameters">
<input sql="INSERT INTO t_account(password, certificate_number, account_id, amount, status) VALUES (?, ?, ?, ?, ?), ('bbb', '222X', 2, 2000, 'OK'), (?, ?, ?, ?, ?), ('ddd', '444X', 4, 4000, 'OK')" parameters="aaa, 111X, 1, 1000, OK, ccc, 333X, 3, 3000, OK" />
<output sql="INSERT INTO t_account(cipher_password, assisted_query_password, cipher_certificate_number, assisted_query_certificate_number, account_id, cipher_amount, status) VALUES (?, ?, ?, ?, ?, ?, ?), ('encrypt_bbb', 'assisted_query_bbb', 'encrypt_222X', 'assisted_query_222X', 2, 'encrypt_2000', 'OK'), (?, ?, ?, ?, ?, ?, ?), ('encrypt_ddd', 'assisted_query_ddd', 'encrypt_444X', 'assisted_query_444X', 4, 'encrypt_4000', 'OK')" parameters="encrypt_aaa, assisted_query_aaa, encrypt_111X, assisted_query_111X, 1, encrypt_1000, OK, encrypt_ccc, assisted_query_ccc, encrypt_333X, assisted_query_333X, 3, encrypt_3000, OK" />
</rewrite-assertion>
<rewrite-assertion id="insert_values_with_columns_and_configuration_for_different_sequence_for_literals">
<input sql="INSERT INTO t_account(password, certificate_number, account_id, amount, status) VALUES ('aaa', '111X', 1, 1000, 'OK'), ('bbb', '222X', 2, 2000, 'OK'), ('ccc', '333X', 3, 3000, 'OK'), ('ddd', '444X', 4, 4000, 'OK')" />
<output sql="INSERT INTO t_account(cipher_password, assisted_query_password, cipher_certificate_number, assisted_query_certificate_number, account_id, cipher_amount, status) VALUES ('encrypt_aaa', 'assisted_query_aaa', 'encrypt_111X', 'assisted_query_111X', 1, 'encrypt_1000', 'OK'), ('encrypt_bbb', 'assisted_query_bbb', 'encrypt_222X', 'assisted_query_222X', 2, 'encrypt_2000', 'OK'), ('encrypt_ccc', 'assisted_query_ccc', 'encrypt_333X', 'assisted_query_333X', 3, 'encrypt_3000', 'OK'), ('encrypt_ddd', 'assisted_query_ddd', 'encrypt_444X', 'assisted_query_444X', 4, 'encrypt_4000', 'OK')" />
</rewrite-assertion>
<rewrite-assertion id="insert_values_with_columns_with_plain_for_parameters">
<input sql="INSERT INTO t_account_bak(account_id, certificate_number, password, amount, status) VALUES (?, ?, ?, ?, ?), (2, '222X', 'bbb', 2000, 'OK'), (?, ?, ?, ?, ?), (4, '444X', 'ddd', 4000, 'OK')" parameters="1, 111X, aaa, 1000, OK, 3, 333X, ccc, 3000, OK" />
<output sql="INSERT INTO t_account_bak(account_id, cipher_certificate_number, assisted_query_certificate_number, plain_certificate_number, cipher_password, assisted_query_password, plain_password, cipher_amount, plain_amount, status) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?), (2, 'encrypt_222X', 'assisted_query_222X', '222X', 'encrypt_bbb', 'assisted_query_bbb', 'bbb', 'encrypt_2000', 2000, 'OK'), (?, ?, ?, ?, ?, ?, ?, ?, ?, ?), (4, 'encrypt_444X', 'assisted_query_444X', '444X', 'encrypt_ddd', 'assisted_query_ddd', 'ddd', 'encrypt_4000', 4000, 'OK')" parameters="1, encrypt_111X, assisted_query_111X, 111X, encrypt_aaa, assisted_query_aaa, aaa, encrypt_1000, 1000, OK, 3, encrypt_333X, assisted_query_333X, 333X, encrypt_ccc, assisted_query_ccc, ccc, encrypt_3000, 3000, OK" />
</rewrite-assertion>
<rewrite-assertion id="insert_values_with_columns_with_plain_for_literals">
<input sql="INSERT INTO t_account_bak(account_id, certificate_number, password, amount, status) VALUES (1, '111X', 'aaa', 1000, 'OK'), (2, '222X', 'bbb', 2000, 'OK'), (3, '333X', 'ccc', 3000, 'OK'), (4, '444X', 'ddd', 4000, 'OK')" />
<output sql="INSERT INTO t_account_bak(account_id, cipher_certificate_number, assisted_query_certificate_number, plain_certificate_number, cipher_password, assisted_query_password, plain_password, cipher_amount, plain_amount, status) VALUES (1, 'encrypt_111X', 'assisted_query_111X', '111X', 'encrypt_aaa', 'assisted_query_aaa', 'aaa', 'encrypt_1000', 1000, 'OK'), (2, 'encrypt_222X', 'assisted_query_222X', '222X', 'encrypt_bbb', 'assisted_query_bbb', 'bbb', 'encrypt_2000', 2000, 'OK'), (3, 'encrypt_333X', 'assisted_query_333X', '333X', 'encrypt_ccc', 'assisted_query_ccc', 'ccc', 'encrypt_3000', 3000, 'OK'), (4, 'encrypt_444X', 'assisted_query_444X', '444X', 'encrypt_ddd', 'assisted_query_ddd', 'ddd', 'encrypt_4000', 4000, 'OK')" />
</rewrite-assertion>
<rewrite-assertion id="insert_values_without_columns_for_parameters">
<input sql="INSERT INTO t_account VALUES (?, ?, ?, ?, ?), (2, '222X', 'bbb', 2000, 'OK'), (?, ?, ?, ?, ?), (4, '444X', 'ddd', 4000, 'OK')" parameters="1, 111X, aaa, 1000, OK, 3, 333X, ccc, 3000, OK" />
<output sql="INSERT INTO t_account(account_id, cipher_certificate_number, assisted_query_certificate_number, cipher_password, assisted_query_password, cipher_amount, status) VALUES (?, ?, ?, ?, ?, ?, ?), (2, 'encrypt_222X', 'assisted_query_222X', 'encrypt_bbb', 'assisted_query_bbb', 'encrypt_2000', 'OK'), (?, ?, ?, ?, ?, ?, ?), (4, 'encrypt_444X', 'assisted_query_444X', 'encrypt_ddd', 'assisted_query_ddd', 'encrypt_4000', 'OK')" parameters="1, encrypt_111X, assisted_query_111X, encrypt_aaa, assisted_query_aaa, encrypt_1000, OK, 3, encrypt_333X, assisted_query_333X, encrypt_ccc, assisted_query_ccc, encrypt_3000, OK" />
</rewrite-assertion>
<rewrite-assertion id="insert_values_without_columns_for_literals">
<input sql="INSERT INTO t_account VALUES (1, '111X', 'aaa', 1000, 'OK'), (2, '222X', 'bbb', 2000, 'OK'), (3, '333X', 'ccc', 3000, 'OK'), (4, '444X', 'ddd', 4000, 'OK')" />
<output sql="INSERT INTO t_account(account_id, cipher_certificate_number, assisted_query_certificate_number, cipher_password, assisted_query_password, cipher_amount, status) VALUES (1, 'encrypt_111X', 'assisted_query_111X', 'encrypt_aaa', 'assisted_query_aaa', 'encrypt_1000', 'OK'), (2, 'encrypt_222X', 'assisted_query_222X', 'encrypt_bbb', 'assisted_query_bbb', 'encrypt_2000', 'OK'), (3, 'encrypt_333X', 'assisted_query_333X', 'encrypt_ccc', 'assisted_query_ccc', 'encrypt_3000', 'OK'), (4, 'encrypt_444X', 'assisted_query_444X', 'encrypt_ddd', 'assisted_query_ddd', 'encrypt_4000', 'OK')" />
</rewrite-assertion>
<rewrite-assertion id="insert_values_without_columns_with_plain_for_parameters">
<input sql="INSERT INTO t_account_bak VALUES (?, ?, ?, ?, ?), (2, '222X', 'bbb', 2000, 'OK'), (?, ?, ?, ?, ?), (4, '444X', 'ddd', 4000, 'OK')" parameters="1, 111X, aaa, 1000, OK, 3, 333X, ccc, 3000, OK" />
<output sql="INSERT INTO t_account_bak(account_id, cipher_certificate_number, assisted_query_certificate_number, plain_certificate_number, cipher_password, assisted_query_password, plain_password, cipher_amount, plain_amount, status) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?), (2, 'encrypt_222X', 'assisted_query_222X', '222X', 'encrypt_bbb', 'assisted_query_bbb', 'bbb', 'encrypt_2000', 2000, 'OK'), (?, ?, ?, ?, ?, ?, ?, ?, ?, ?), (4, 'encrypt_444X', 'assisted_query_444X', '444X', 'encrypt_ddd', 'assisted_query_ddd', 'ddd', 'encrypt_4000', 4000, 'OK')" parameters="1, encrypt_111X, assisted_query_111X, 111X, encrypt_aaa, assisted_query_aaa, aaa, encrypt_1000, 1000, OK, 3, encrypt_333X, assisted_query_333X, 333X, encrypt_ccc, assisted_query_ccc, ccc, encrypt_3000, 3000, OK" />
</rewrite-assertion>
<rewrite-assertion id="insert_values_without_columns_with_plain_for_literals">
<input sql="INSERT INTO t_account_bak VALUES (1, '111X', 'aaa', 1000, 'OK'), (2, '222X', 'bbb', 2000, 'OK'), (3, '333X', 'ccc', 3000, 'OK'), (4, '444X', 'ddd', 4000, 'OK')" />
<output sql="INSERT INTO t_account_bak(account_id, cipher_certificate_number, assisted_query_certificate_number, plain_certificate_number, cipher_password, assisted_query_password, plain_password, cipher_amount, plain_amount, status) VALUES (1, 'encrypt_111X', 'assisted_query_111X', '111X', 'encrypt_aaa', 'assisted_query_aaa', 'aaa', 'encrypt_1000', 1000, 'OK'), (2, 'encrypt_222X', 'assisted_query_222X', '222X', 'encrypt_bbb', 'assisted_query_bbb', 'bbb', 'encrypt_2000', 2000, 'OK'), (3, 'encrypt_333X', 'assisted_query_333X', '333X', 'encrypt_ccc', 'assisted_query_ccc', 'ccc', 'encrypt_3000', 3000, 'OK'), (4, 'encrypt_444X', 'assisted_query_444X', '444X', 'encrypt_ddd', 'assisted_query_ddd', 'ddd', 'encrypt_4000', 4000, 'OK')" />
</rewrite-assertion>
<rewrite-assertion id="insert_set_for_parameters" db-type="MySQL">
<input sql="INSERT INTO t_account SET account_id = ?, certificate_number = ?, password = ?, amount = ?, status = ?" parameters="1, 111X, aaa, 1000, OK" />
<output sql="INSERT INTO t_account SET account_id = ?, cipher_certificate_number = ?, assisted_query_certificate_number = ?, cipher_password = ?, assisted_query_password = ?, cipher_amount = ?, status = ?" parameters="1, encrypt_111X, assisted_query_111X, encrypt_aaa, assisted_query_aaa, encrypt_1000, OK" />
</rewrite-assertion>
<rewrite-assertion id="insert_set_for_literals" db-type="MySQL">
<input sql="INSERT INTO t_account SET account_id = 1, certificate_number = '111X', password = 'aaa', amount = 1000, status = 'OK'" />
<output sql="INSERT INTO t_account SET account_id = 1, cipher_certificate_number = 'encrypt_111X', assisted_query_certificate_number = 'assisted_query_111X', cipher_password = 'encrypt_aaa', assisted_query_password = 'assisted_query_aaa', cipher_amount = 'encrypt_1000', status = 'OK'" />
</rewrite-assertion>
<rewrite-assertion id="insert_set_with_plain_for_parameters" db-type="MySQL">
<input sql="INSERT INTO t_account_bak SET account_id = ?, certificate_number = ?, password = ?, amount = ?, status = ?" parameters="1, 111X, aaa, 1000, OK" />
<output sql="INSERT INTO t_account_bak SET account_id = ?, cipher_certificate_number = ?, assisted_query_certificate_number = ?, plain_certificate_number = ?, cipher_password = ?, assisted_query_password = ?, plain_password = ?, cipher_amount = ?, plain_amount = ?, status = ?" parameters="1, encrypt_111X, assisted_query_111X, 111X, encrypt_aaa, assisted_query_aaa, aaa, encrypt_1000, 1000, OK" />
</rewrite-assertion>
<rewrite-assertion id="insert_set_with_plain_for_literals" db-type="MySQL">
<input sql="INSERT INTO t_account_bak SET account_id = 1, certificate_number = '111X', password = 'aaa', amount = 1000, status = 'OK'" />
<output sql="INSERT INTO t_account_bak SET account_id = 1, cipher_certificate_number = 'encrypt_111X', assisted_query_certificate_number = 'assisted_query_111X', plain_certificate_number = '111X', cipher_password = 'encrypt_aaa', assisted_query_password = 'assisted_query_aaa', plain_password = 'aaa', cipher_amount = 'encrypt_1000', plain_amount = 1000, status = 'OK'" />
</rewrite-assertion>
</rewrite-assertions>

View File

@ -0,0 +1,61 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ 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.
-->
<rewrite-assertions yaml-rule="yaml/encrypt/query-with-cipher.yaml">
<rewrite-assertion id="select_for_parameters">
<input sql="SELECT account_id, password, amount AS a, status AS s FROM t_account WHERE account_id = ? AND password = ? AND amount = ? AND status = ?" parameters="1, aaa, 1000, OK" />
<output sql="SELECT account_id, cipher_password, cipher_amount AS a, status AS s FROM t_account WHERE account_id = ? AND assisted_query_password = ? AND cipher_amount = ? AND status = ?" parameters="1, assisted_query_aaa, encrypt_1000, OK" />
</rewrite-assertion>
<rewrite-assertion id="select_for_literals">
<input sql="SELECT account_id, password, amount AS a, status AS s FROM t_account WHERE account_id = 1 AND password = 'aaa' AND amount = 1000 AND status = 'OK'" />
<output sql="SELECT account_id, cipher_password, cipher_amount AS a, status AS s FROM t_account WHERE account_id = 1 AND assisted_query_password = 'assisted_query_aaa' AND cipher_amount = 'encrypt_1000' AND status = 'OK'" />
</rewrite-assertion>
<rewrite-assertion id="select_plain_for_parameters">
<input sql="SELECT a.account_id, a.password, a.amount AS a, a.status AS s FROM t_account_bak AS a WHERE a.account_id = ? AND a.password = ? AND a.amount = ? AND a.status = ?" parameters="1, aaa, 1000, OK" />
<output sql="SELECT a.account_id, a.cipher_password, a.cipher_amount AS a, a.status AS s FROM t_account_bak AS a WHERE a.account_id = ? AND a.assisted_query_password = ? AND a.cipher_amount = ? AND a.status = ?" parameters="1, assisted_query_aaa, encrypt_1000, OK" />
</rewrite-assertion>
<rewrite-assertion id="select_plain_for_literals">
<input sql="SELECT a.account_id, a.password, a.amount AS a, a.status AS s FROM t_account_bak AS a WHERE a.account_id = 1 AND a.password = 'aaa' AND a.amount = 1000 AND a.status = 'OK'" />
<output sql="SELECT a.account_id, a.cipher_password, a.cipher_amount AS a, a.status AS s FROM t_account_bak AS a WHERE a.account_id = 1 AND a.assisted_query_password = 'assisted_query_aaa' AND a.cipher_amount = 'encrypt_1000' AND a.status = 'OK'" />
</rewrite-assertion>
<rewrite-assertion id="select_plain_for_parameters_with_in_has_no_left_space">
<input sql="SELECT a.account_id, a.password, a.amount AS a, a.status AS s FROM t_account_bak AS a WHERE a.password in(?, ?) AND a.amount in (?, ?)" parameters="aaa, aaa, 1000, 1000" />
<output sql="SELECT a.account_id, a.cipher_password, a.cipher_amount AS a, a.status AS s FROM t_account_bak AS a WHERE a.assisted_query_password in(?, ?) AND a.cipher_amount in (?, ?)" parameters="assisted_query_aaa, assisted_query_aaa, encrypt_1000, encrypt_1000" />
</rewrite-assertion>
<rewrite-assertion id="select_plain_for_parameters_with_in_has_no_left_space_and_parameter_has_left_space">
<input sql="SELECT a.account_id, a.password, a.amount AS a, a.status AS s FROM t_account_bak AS a WHERE a.password in( ?, ?) AND a.amount in (?, ?)" parameters="aaa, aaa, 1000, 1000" />
<output sql="SELECT a.account_id, a.cipher_password, a.cipher_amount AS a, a.status AS s FROM t_account_bak AS a WHERE a.assisted_query_password in(?, ?) AND a.cipher_amount in (?, ?)" parameters="assisted_query_aaa, assisted_query_aaa, encrypt_1000, encrypt_1000" />
</rewrite-assertion>
<rewrite-assertion id="select_plain_for_parameters_with_in_has_no_left_space_and_parameter_has_left_newline">
<input sql="SELECT a.account_id, a.password, a.amount AS a, a.status AS s FROM t_account_bak AS a WHERE a.password in(
?, ?) AND a.amount in (?, ?)" parameters="aaa, aaa, 1000, 1000" />
<output sql="SELECT a.account_id, a.cipher_password, a.cipher_amount AS a, a.status AS s FROM t_account_bak AS a WHERE a.assisted_query_password in(?, ?) AND a.cipher_amount in (?, ?)" parameters="assisted_query_aaa, assisted_query_aaa, encrypt_1000, encrypt_1000" />
</rewrite-assertion>
<rewrite-assertion id="select_plain_for_parameters_with_in_has_more_than_one_left_space_and_parameter_has_left_newline">
<input sql="SELECT a.account_id, a.password, a.amount AS a, a.status AS s FROM t_account_bak AS a WHERE a.password in (
?, ?) AND a.amount in (?, ?)" parameters="aaa, aaa, 1000, 1000" />
<output sql="SELECT a.account_id, a.cipher_password, a.cipher_amount AS a, a.status AS s FROM t_account_bak AS a WHERE a.assisted_query_password in (?, ?) AND a.cipher_amount in (?, ?)" parameters="assisted_query_aaa, assisted_query_aaa, encrypt_1000, encrypt_1000" />
</rewrite-assertion>
</rewrite-assertions>

View File

@ -0,0 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ 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.
-->
<rewrite-assertions yaml-rule="yaml/encrypt/query-with-plain.yaml">
<rewrite-assertion id="select_plain_for_parameters">
<input sql="SELECT a.account_id, a.password, a.amount AS a, a.status AS s FROM t_account_bak AS a WHERE a.account_id = ? AND a.password = ? AND a.amount = ? AND a.status = ?" parameters="1, aaa, 1000, OK" />
<output sql="SELECT a.account_id, a.plain_password, a.plain_amount AS a, a.status AS s FROM t_account_bak AS a WHERE a.account_id = ? AND a.plain_password = ? AND a.plain_amount = ? AND a.status = ?" parameters="1, aaa, 1000, OK" />
</rewrite-assertion>
<rewrite-assertion id="select_plain_for_literals">
<input sql="SELECT a.account_id, a.password, a.amount AS a, a.status AS s FROM t_account_bak AS a WHERE a.account_id = 1 AND a.password = 'aaa' AND a.amount = 1000 AND a.status = 'OK'" />
<output sql="SELECT a.account_id, a.plain_password, a.plain_amount AS a, a.status AS s FROM t_account_bak AS a WHERE a.account_id = 1 AND a.plain_password = 'aaa' AND a.plain_amount = 1000 AND a.status = 'OK'" />
</rewrite-assertion>
</rewrite-assertions>

View File

@ -0,0 +1,39 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ 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.
-->
<rewrite-assertions yaml-rule="yaml/encrypt/query-with-cipher.yaml">
<rewrite-assertion id="update_for_parameters">
<input sql="UPDATE t_account SET account_id = ?, certificate_number = ?, password = ?, amount = ?, status = ? WHERE account_id = ? AND certificate_number = ? AND password = ? AND amount = ? AND status = ?" parameters="1, 111X, aaa, 1000, OK, 1, 111X, aaa, 1000, OK" />
<output sql="UPDATE t_account SET account_id = ?, cipher_certificate_number = ?, assisted_query_certificate_number = ?, cipher_password = ?, assisted_query_password = ?, cipher_amount = ?, status = ? WHERE account_id = ? AND assisted_query_certificate_number = ? AND assisted_query_password = ? AND cipher_amount = ? AND status = ?" parameters="1, encrypt_111X, assisted_query_111X, encrypt_aaa, assisted_query_aaa, encrypt_1000, OK, 1, assisted_query_111X, assisted_query_aaa, encrypt_1000, OK" />
</rewrite-assertion>
<rewrite-assertion id="update_for_literals">
<input sql="UPDATE t_account SET account_id = 1, certificate_number = '111X', password = 'aaa', amount = 1000, status = 'OK' WHERE account_id = 1 AND certificate_number = '111X' AND password = 'aaa' AND amount = 1000 AND status = 'OK'" />
<output sql="UPDATE t_account SET account_id = 1, cipher_certificate_number = 'encrypt_111X', assisted_query_certificate_number = 'assisted_query_111X', cipher_password = 'encrypt_aaa', assisted_query_password = 'assisted_query_aaa', cipher_amount = 'encrypt_1000', status = 'OK' WHERE account_id = 1 AND assisted_query_certificate_number = 'assisted_query_111X' AND assisted_query_password = 'assisted_query_aaa' AND cipher_amount = 'encrypt_1000' AND status = 'OK'" />
</rewrite-assertion>
<rewrite-assertion id="update_plain_for_parameters">
<input sql="UPDATE t_account_bak SET account_id = ?, certificate_number = ?, password = ?, amount = ?, status = ? WHERE account_id = ? AND certificate_number = ? AND password = ? AND amount = ? AND status = ?" parameters="1, 111X, aaa, 1000, OK, 1, 111X, aaa, 1000, OK" />
<output sql="UPDATE t_account_bak SET account_id = ?, cipher_certificate_number = ?, assisted_query_certificate_number = ?, plain_certificate_number = ?, cipher_password = ?, assisted_query_password = ?, plain_password = ?, cipher_amount = ?, plain_amount = ?, status = ? WHERE account_id = ? AND assisted_query_certificate_number = ? AND assisted_query_password = ? AND cipher_amount = ? AND status = ?" parameters="1, encrypt_111X, assisted_query_111X, 111X, encrypt_aaa, assisted_query_aaa, aaa, encrypt_1000, 1000, OK, 1, assisted_query_111X, assisted_query_aaa, encrypt_1000, OK" />
</rewrite-assertion>
<rewrite-assertion id="update_plain_for_literals">
<input sql="UPDATE t_account_bak SET account_id = 1, certificate_number = '111X', password = 'aaa', amount = 1000, status = 'OK' WHERE account_id = 1 AND certificate_number = '111X' AND password = 'aaa' AND amount = 1000 AND status = 'OK'" />
<output sql="UPDATE t_account_bak SET account_id = 1, cipher_certificate_number = 'encrypt_111X', assisted_query_certificate_number = 'assisted_query_111X', plain_certificate_number = '111X', cipher_password = 'encrypt_aaa', assisted_query_password = 'assisted_query_aaa', plain_password = 'aaa', cipher_amount = 'encrypt_1000', plain_amount = 1000, status = 'OK' WHERE account_id = 1 AND assisted_query_certificate_number = 'assisted_query_111X' AND assisted_query_password = 'assisted_query_aaa' AND cipher_amount = 'encrypt_1000' AND status = 'OK'" />
</rewrite-assertion>
</rewrite-assertions>

View File

@ -0,0 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ 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.
-->
<rewrite-assertions yaml-rule="yaml/encrypt/query-with-plain.yaml">
<rewrite-assertion id="update_plain_for_parameters">
<input sql="UPDATE t_account_bak SET account_id = ?, password = ?, amount = ?, status = ? WHERE account_id = ? AND password = ? AND amount = ? AND status = ?" parameters="1, aaa, 1000, OK, 1, aaa, 1000, OK" />
<output sql="UPDATE t_account_bak SET account_id = ?, cipher_password = ?, assisted_query_password = ?, plain_password = ?, cipher_amount = ?, plain_amount = ?, status = ? WHERE account_id = ? AND plain_password = ? AND plain_amount = ? AND status = ?" parameters="1, encrypt_aaa, assisted_query_aaa, aaa, encrypt_1000, 1000, OK, 1, aaa, 1000, OK" />
</rewrite-assertion>
<rewrite-assertion id="update_plain_for_literals">
<input sql="UPDATE t_account_bak SET account_id = 1, password = 'aaa', amount = 1000, status = 'OK' WHERE account_id = 1 AND password = 'aaa' AND amount = 1000 AND status = 'OK'" />
<output sql="UPDATE t_account_bak SET account_id = 1, cipher_password = 'encrypt_aaa', assisted_query_password = 'assisted_query_aaa', plain_password = 'aaa', cipher_amount = 'encrypt_1000', plain_amount = 1000, status = 'OK' WHERE account_id = 1 AND plain_password = 'aaa' AND plain_amount = 1000 AND status = 'OK'" />
</rewrite-assertion>
</rewrite-assertions>

View File

@ -0,0 +1,35 @@
<?xml version="1.0"?>
<!--
~ 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.
-->
<configuration>
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>[%-5level] %d{HH:mm:ss.SSS} [%thread] %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<logger name="org.apache.shardingsphere" level="info" additivity="false">
<appender-ref ref="console"/>
</logger>
<logger name="org.apache.shardingsphere.core.execute.sql.execute.threadlocal.ExecutorExceptionHandler" level="off" />
<logger name="org.apache.shardingsphere.core.config.log.ConfigurationLogger" level="off" />
<root>
<level value="error" />
<appender-ref ref="console" />
</root>
</configuration>

View File

@ -0,0 +1,62 @@
#
# 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.
#
dataSource: !!com.zaxxer.hikari.HikariDataSource
driverClassName: org.h2.Driver
jdbcUrl: jdbc:h2:mem:ds_encrypt;DB_CLOSE_DELAY=-1;DATABASE_TO_UPPER=false;MODE=MYSQL
username: sa
password:
encryptRule:
tables:
t_account:
columns:
certificate_number:
cipherColumn: cipher_certificate_number
assistedQueryColumn: assisted_query_certificate_number
encryptor: assisted_query
password:
cipherColumn: cipher_password
assistedQueryColumn: assisted_query_password
encryptor: assisted_query
amount:
cipherColumn: cipher_amount
encryptor: normal
t_account_bak:
columns:
certificate_number:
cipherColumn: cipher_certificate_number
assistedQueryColumn: assisted_query_certificate_number
plainColumn: plain_certificate_number
encryptor: assisted_query
password:
cipherColumn: cipher_password
assistedQueryColumn: assisted_query_password
plainColumn: plain_password
encryptor: assisted_query
amount:
cipherColumn: cipher_amount
plainColumn: plain_amount
encryptor: normal
encryptors:
normal:
type: NORMAL_ENCRYPT
assisted_query:
type: ASSISTED_QUERY_ENCRYPT
props:
query.with.cipher.column: true

View File

@ -0,0 +1,53 @@
#
# 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.
#
dataSource: !!com.zaxxer.hikari.HikariDataSource
driverClassName: org.h2.Driver
jdbcUrl: jdbc:h2:mem:ds_encrypt;DB_CLOSE_DELAY=-1;DATABASE_TO_UPPER=false;MODE=MYSQL
username: sa
password:
encryptRule:
tables:
t_account:
columns:
password:
cipherColumn: cipher_password
assistedQueryColumn: assisted_query_password
encryptor: assisted_query
amount:
cipherColumn: cipher_amount
encryptor: normal
t_account_bak:
columns:
password:
cipherColumn: cipher_password
assistedQueryColumn: assisted_query_password
plainColumn: plain_password
encryptor: assisted_query
amount:
cipherColumn: cipher_amount
plainColumn: plain_amount
encryptor: normal
encryptors:
normal:
type: NORMAL_ENCRYPT
assisted_query:
type: ASSISTED_QUERY_ENCRYPT
props:
query.with.cipher.column: false

35
encrypt-core/pom.xml Normal file
View File

@ -0,0 +1,35 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ 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.
-->
<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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.apache.shardingsphere</groupId>
<artifactId>shardingsphere</artifactId>
<version>4.0.1</version>
</parent>
<artifactId>encrypt-core</artifactId>
<name>${project.artifactId}</name>
<packaging>pom</packaging>
<modules>
<module>encrypt-core-rewrite</module>
<module>encrypt-core-merge</module>
</modules>
</project>

78
jenkinsfile Normal file
View File

@ -0,0 +1,78 @@
/*
* 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.
*
*/
def ssBuildBadge = addEmbeddableBadgeConfiguration(id: "ssbuild", subject: "Build")
pipeline {
agent {
label 'ubuntu'
}
options {
buildDiscarder(logRotator(
numToKeepStr: '60',
))
timestamps()
skipStagesAfterUnstable()
timeout time: 60, unit: 'MINUTES'
}
stages {
stage('SCM checkout') {
steps {
script {
try {
deleteDir()
checkout scm
sh 'git submodule update --init'
} catch (exc) {
error 'Build failed'
sh 'exit 1'
}
}
}
}
stage('Build & Test') {
tools {
// use at least Apache Maven 3.3.1 to have .mvn/jvm.config support
maven 'Maven 3.6.2'
jdk 'JDK 1.8 (latest)'
}
steps {
script {
ssBuildBadge.setStatus('running')
try {
sh '''
mvn clean verify cobertura:cobertura coveralls:report -DrepoToken=${COVERALLS_REPO_TOKEN} -DpullRequest=${ghprbPullLink} -Prelease
'''
ssBuildBadge.setStatus('passing')
} catch (Exception err) {
ssBuildBadge.setStatus('failing')
ssBuildBadge.setColor('pink')
error 'Build failed'
}
}
}
}
}
post {
success {
junit '**/target/surefire-reports/*.xml'
}
cleanup {
deleteDir()
}
}
}

19
lombok.config Normal file
View File

@ -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.
#
# this config is to ignore lombok code in jacoco
lombok.addLombokGeneratedAnnotation = true

310
mvnw vendored Executable file
View File

@ -0,0 +1,310 @@
#!/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.
# ----------------------------------------------------------------------------
# ----------------------------------------------------------------------------
# Maven Start Up Batch script
#
# Required ENV vars:
# ------------------
# JAVA_HOME - location of a JDK home dir
#
# Optional ENV vars
# -----------------
# M2_HOME - location of maven2's installed home dir
# MAVEN_OPTS - parameters passed to the Java VM when running Maven
# e.g. to debug Maven itself, use
# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
# MAVEN_SKIP_RC - flag to disable loading of mavenrc files
# ----------------------------------------------------------------------------
if [ -z "$MAVEN_SKIP_RC" ] ; then
if [ -f /etc/mavenrc ] ; then
. /etc/mavenrc
fi
if [ -f "$HOME/.mavenrc" ] ; then
. "$HOME/.mavenrc"
fi
fi
# OS specific support. $var _must_ be set to either true or false.
cygwin=false;
darwin=false;
mingw=false
case "`uname`" in
CYGWIN*) cygwin=true ;;
MINGW*) mingw=true;;
Darwin*) darwin=true
# Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home
# See https://developer.apple.com/library/mac/qa/qa1170/_index.html
if [ -z "$JAVA_HOME" ]; then
if [ -x "/usr/libexec/java_home" ]; then
export JAVA_HOME="`/usr/libexec/java_home`"
else
export JAVA_HOME="/Library/Java/Home"
fi
fi
;;
esac
if [ -z "$JAVA_HOME" ] ; then
if [ -r /etc/gentoo-release ] ; then
JAVA_HOME=`java-config --jre-home`
fi
fi
if [ -z "$M2_HOME" ] ; then
## resolve links - $0 may be a link to maven's home
PRG="$0"
# need this for relative symlinks
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG="`dirname "$PRG"`/$link"
fi
done
saveddir=`pwd`
M2_HOME=`dirname "$PRG"`/..
# make it fully qualified
M2_HOME=`cd "$M2_HOME" && pwd`
cd "$saveddir"
# echo Using m2 at $M2_HOME
fi
# For Cygwin, ensure paths are in UNIX format before anything is touched
if $cygwin ; then
[ -n "$M2_HOME" ] &&
M2_HOME=`cygpath --unix "$M2_HOME"`
[ -n "$JAVA_HOME" ] &&
JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
[ -n "$CLASSPATH" ] &&
CLASSPATH=`cygpath --path --unix "$CLASSPATH"`
fi
# For Mingw, ensure paths are in UNIX format before anything is touched
if $mingw ; then
[ -n "$M2_HOME" ] &&
M2_HOME="`(cd "$M2_HOME"; pwd)`"
[ -n "$JAVA_HOME" ] &&
JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`"
fi
if [ -z "$JAVA_HOME" ]; then
javaExecutable="`which javac`"
if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then
# readlink(1) is not available as standard on Solaris 10.
readLink=`which readlink`
if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then
if $darwin ; then
javaHome="`dirname \"$javaExecutable\"`"
javaExecutable="`cd \"$javaHome\" && pwd -P`/javac"
else
javaExecutable="`readlink -f \"$javaExecutable\"`"
fi
javaHome="`dirname \"$javaExecutable\"`"
javaHome=`expr "$javaHome" : '\(.*\)/bin'`
JAVA_HOME="$javaHome"
export JAVA_HOME
fi
fi
fi
if [ -z "$JAVACMD" ] ; then
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"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
else
JAVACMD="`which java`"
fi
fi
if [ ! -x "$JAVACMD" ] ; then
echo "Error: JAVA_HOME is not defined correctly." >&2
echo " We cannot execute $JAVACMD" >&2
exit 1
fi
if [ -z "$JAVA_HOME" ] ; then
echo "Warning: JAVA_HOME environment variable is not set."
fi
CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher
# traverses directory structure from process work directory to filesystem root
# first directory with .mvn subdirectory is considered project base directory
find_maven_basedir() {
if [ -z "$1" ]
then
echo "Path not specified to find_maven_basedir"
return 1
fi
basedir="$1"
wdir="$1"
while [ "$wdir" != '/' ] ; do
if [ -d "$wdir"/.mvn ] ; then
basedir=$wdir
break
fi
# workaround for JBEAP-8937 (on Solaris 10/Sparc)
if [ -d "${wdir}" ]; then
wdir=`cd "$wdir/.."; pwd`
fi
# end of workaround
done
echo "${basedir}"
}
# concatenates all lines of a file
concat_lines() {
if [ -f "$1" ]; then
echo "$(tr -s '\n' ' ' < "$1")"
fi
}
BASE_DIR=`find_maven_basedir "$(pwd)"`
if [ -z "$BASE_DIR" ]; then
exit 1;
fi
##########################################################################################
# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
# This allows using the maven wrapper in projects that prohibit checking in binary data.
##########################################################################################
if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then
if [ "$MVNW_VERBOSE" = true ]; then
echo "Found .mvn/wrapper/maven-wrapper.jar"
fi
else
if [ "$MVNW_VERBOSE" = true ]; then
echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..."
fi
if [ -n "$MVNW_REPOURL" ]; then
jarUrl="$MVNW_REPOURL/io/takari/maven-wrapper/0.5.5/maven-wrapper-0.5.5.jar"
else
jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.5/maven-wrapper-0.5.5.jar"
fi
while IFS="=" read key value; do
case "$key" in (wrapperUrl) jarUrl="$value"; break ;;
esac
done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties"
if [ "$MVNW_VERBOSE" = true ]; then
echo "Downloading from: $jarUrl"
fi
wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar"
if $cygwin; then
wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"`
fi
if command -v wget > /dev/null; then
if [ "$MVNW_VERBOSE" = true ]; then
echo "Found wget ... using wget"
fi
if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
wget "$jarUrl" -O "$wrapperJarPath"
else
wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath"
fi
elif command -v curl > /dev/null; then
if [ "$MVNW_VERBOSE" = true ]; then
echo "Found curl ... using curl"
fi
if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
curl -o "$wrapperJarPath" "$jarUrl" -f
else
curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f
fi
else
if [ "$MVNW_VERBOSE" = true ]; then
echo "Falling back to using Java to download"
fi
javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java"
# For Cygwin, switch paths to Windows format before running javac
if $cygwin; then
javaClass=`cygpath --path --windows "$javaClass"`
fi
if [ -e "$javaClass" ]; then
if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
if [ "$MVNW_VERBOSE" = true ]; then
echo " - Compiling MavenWrapperDownloader.java ..."
fi
# Compiling the Java class
("$JAVA_HOME/bin/javac" "$javaClass")
fi
if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
# Running the downloader
if [ "$MVNW_VERBOSE" = true ]; then
echo " - Running MavenWrapperDownloader.java ..."
fi
("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR")
fi
fi
fi
fi
##########################################################################################
# End of extension
##########################################################################################
export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}
if [ "$MVNW_VERBOSE" = true ]; then
echo $MAVEN_PROJECTBASEDIR
fi
MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS"
# For Cygwin, switch paths to Windows format before running java
if $cygwin; then
[ -n "$M2_HOME" ] &&
M2_HOME=`cygpath --path --windows "$M2_HOME"`
[ -n "$JAVA_HOME" ] &&
JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"`
[ -n "$CLASSPATH" ] &&
CLASSPATH=`cygpath --path --windows "$CLASSPATH"`
[ -n "$MAVEN_PROJECTBASEDIR" ] &&
MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"`
fi
# Provide a "standardized" way to retrieve the CLI args that will
# work with both Windows and non-Windows executions.
MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@"
export MAVEN_CMD_LINE_ARGS
WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
exec "$JAVACMD" \
$MAVEN_OPTS \
-classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \
"-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@"

182
mvnw.cmd vendored Executable file
View File

@ -0,0 +1,182 @@
@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 Maven Start Up Batch script
@REM
@REM Required ENV vars:
@REM JAVA_HOME - location of a JDK home dir
@REM
@REM Optional ENV vars
@REM M2_HOME - location of maven2's installed home dir
@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending
@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
@REM e.g. to debug Maven itself, use
@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
@REM ----------------------------------------------------------------------------
@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
@echo off
@REM set title of command window
title %0
@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on'
@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO%
@REM set %HOME% to equivalent of $HOME
if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
@REM Execute a user defined script before this one
if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
@REM check for pre script, once with legacy .bat ending and once with .cmd ending
if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat"
if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd"
:skipRcPre
@setlocal
set ERROR_CODE=0
@REM To isolate internal variables from possible post scripts, we use another setlocal
@setlocal
@REM ==== START VALIDATION ====
if not "%JAVA_HOME%" == "" goto OkJHome
echo.
echo Error: JAVA_HOME not found in your environment. >&2
echo Please set the JAVA_HOME variable in your environment to match the >&2
echo location of your Java installation. >&2
echo.
goto error
:OkJHome
if exist "%JAVA_HOME%\bin\java.exe" goto init
echo.
echo Error: JAVA_HOME is set to an invalid directory. >&2
echo JAVA_HOME = "%JAVA_HOME%" >&2
echo Please set the JAVA_HOME variable in your environment to match the >&2
echo location of your Java installation. >&2
echo.
goto error
@REM ==== END VALIDATION ====
:init
@REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
@REM Fallback to current working directory if not found.
set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
set EXEC_DIR=%CD%
set WDIR=%EXEC_DIR%
:findBaseDir
IF EXIST "%WDIR%"\.mvn goto baseDirFound
cd ..
IF "%WDIR%"=="%CD%" goto baseDirNotFound
set WDIR=%CD%
goto findBaseDir
:baseDirFound
set MAVEN_PROJECTBASEDIR=%WDIR%
cd "%EXEC_DIR%"
goto endDetectBaseDir
:baseDirNotFound
set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
cd "%EXEC_DIR%"
:endDetectBaseDir
IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
@setlocal EnableExtensions EnableDelayedExpansion
for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
:endReadAdditionalConfig
SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar"
set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.5/maven-wrapper-0.5.5.jar"
FOR /F "tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO (
IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B
)
@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
@REM This allows using the maven wrapper in projects that prohibit checking in binary data.
if exist %WRAPPER_JAR% (
if "%MVNW_VERBOSE%" == "true" (
echo Found %WRAPPER_JAR%
)
) else (
if not "%MVNW_REPOURL%" == "" (
SET DOWNLOAD_URL="%MVNW_REPOURL%/io/takari/maven-wrapper/0.5.5/maven-wrapper-0.5.5.jar"
)
if "%MVNW_VERBOSE%" == "true" (
echo Couldn't find %WRAPPER_JAR%, downloading it ...
echo Downloading from: %DOWNLOAD_URL%
)
powershell -Command "&{"^
"$webclient = new-object System.Net.WebClient;"^
"if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^
"$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^
"}"^
"[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^
"}"
if "%MVNW_VERBOSE%" == "true" (
echo Finished downloading %WRAPPER_JAR%
)
)
@REM End of extension
@REM Provide a "standardized" way to retrieve the CLI args that will
@REM work with both Windows and non-Windows executions.
set MAVEN_CMD_LINE_ARGS=%*
%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %*
if ERRORLEVEL 1 goto error
goto end
:error
set ERROR_CODE=1
:end
@endlocal & set ERROR_CODE=%ERROR_CODE%
if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost
@REM check for post script, once with legacy .bat ending and once with .cmd ending
if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat"
if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd"
:skipRcPost
@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
if "%MAVEN_BATCH_PAUSE%" == "on" pause
if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE%
exit /B %ERROR_CODE%

918
pom.xml Normal file
View File

@ -0,0 +1,918 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ 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.
-->
<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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.apache</groupId>
<artifactId>apache</artifactId>
<version>21</version>
</parent>
<groupId>org.apache.shardingsphere</groupId>
<artifactId>shardingsphere</artifactId>
<version>4.0.1</version>
<packaging>pom</packaging>
<name>${project.artifactId}</name>
<modules>
<module>shardingsphere-spi</module>
<module>shardingsphere-sql-parser</module>
<module>shardingsphere-underlying</module>
<module>sharding-core</module>
<module>encrypt-core</module>
<module>sharding-jdbc</module>
<module>sharding-proxy</module>
<module>sharding-ui</module>
<module>sharding-transaction</module>
<module>sharding-orchestration</module>
<module>sharding-opentracing</module>
<module>sharding-spring</module>
<module>sharding-sql-test</module>
<module>sharding-distribution</module>
<module>sharding-integration-test</module>
</modules>
<properties>
<java.version>1.7</java.version>
<maven.version.range>[3.0.4,)</maven.version.range>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.build.locale>zh_CN</project.build.locale>
<guava.version>18.0</guava.version>
<slf4j.version>1.7.7</slf4j.version>
<antlr4.version>4.7.2</antlr4.version>
<groovy.version>2.4.5</groovy.version>
<snakeyaml.version>1.16</snakeyaml.version>
<netty.version>4.1.42.Final</netty.version>
<commons-codec.version>1.10</commons-codec.version>
<commons-collections4.version>4.2</commons-collections4.version>
<javax.transaction.version>1.1</javax.transaction.version>
<atomikos.version>4.0.6</atomikos.version>
<seata.version>0.5.1</seata.version>
<narayana.version>5.9.1.Final</narayana.version>
<jboss-transaction-spi.version>7.6.0.Final</jboss-transaction-spi.version>
<btm.version>2.1.3</btm.version>
<curator.version>2.10.0</curator.version>
<opentracing.version>0.30.0</opentracing.version>
<lombok.version>1.16.4</lombok.version>
<springframework.version>[4.3.6.RELEASE,5.0.0.M1)</springframework.version>
<spring-boot.version>[1.5.20.RELEASE,2.0.0.M1)</spring-boot.version>
<junit.version>4.12</junit.version>
<hamcrest.version>1.3</hamcrest.version>
<mockito.version>2.7.21</mockito.version>
<logback.version>1.2.0</logback.version>
<hikari-cp.version>2.4.11</hikari-cp.version>
<commons-dbcp2.version>2.2.0</commons-dbcp2.version>
<commons-pool.version>1.6</commons-pool.version>
<h2.version>1.4.196</h2.version>
<mysql-connector-java.version>5.1.47</mysql-connector-java.version>
<postgresql.version>42.2.5.jre7</postgresql.version>
<mssql.version>6.1.7.jre7-preview</mssql.version>
<mariadb-java-client.version>2.4.2</mariadb-java-client.version>
<!-- Plugin versions -->
<takari-maven-plugin.version>0.6.1</takari-maven-plugin.version>
<maven-compiler-plugin.version>3.3</maven-compiler-plugin.version>
<maven-assembly-plugin.version>3.1.0</maven-assembly-plugin.version>
<maven-resources-plugin.version>2.7</maven-resources-plugin.version>
<maven-jar-plugin.version>2.6</maven-jar-plugin.version>
<maven-surefire-plugin.version>2.18.1</maven-surefire-plugin.version>
<maven-deploy-plugin.version>2.8.2</maven-deploy-plugin.version>
<maven-release-plugin.version>2.5.3</maven-release-plugin.version>
<maven-site-plugin.version>3.4</maven-site-plugin.version>
<maven-enforcer-plugin.version>1.4</maven-enforcer-plugin.version>
<maven-project-info-reports-plugin.version>2.8</maven-project-info-reports-plugin.version>
<maven-plugin-plugin.version>3.4</maven-plugin-plugin.version>
<maven-javadoc-plugin.version>2.10.3</maven-javadoc-plugin.version>
<maven-source-plugin.version>2.4</maven-source-plugin.version>
<maven-jxr-plugin.version>2.5</maven-jxr-plugin.version>
<lifecycle-mapping.version>1.0.0</lifecycle-mapping.version>
<coveralls-maven-plugin.version>4.3.0</coveralls-maven-plugin.version>
<cobertura-maven-plugin.version>2.7</cobertura-maven-plugin.version>
<jacoco.version>0.8.0</jacoco.version>
<findbugs-maven-plugin.version>3.0.2</findbugs-maven-plugin.version>
<maven-checkstyle-plugin.version>3.1.0</maven-checkstyle-plugin.version>
<maven-pmd-plugin.version>3.5</maven-pmd-plugin.version>
<frontend-maven-plugin.version>1.6</frontend-maven-plugin.version>
<jdepend-maven-plugin.version>2.0</jdepend-maven-plugin.version>
<taglist-maven-plugin.version>2.4</taglist-maven-plugin.version>
<os-maven-plugin.version>1.5.0.Final</os-maven-plugin.version>
<docker-maven-plugin.version>0.4.14</docker-maven-plugin.version>
<apache-rat-plugin.version>0.12</apache-rat-plugin.version>
<javadocExecutable>${java.home}/../bin/javadoc</javadocExecutable>
<maven.deploy.skip>false</maven.deploy.skip>
<argLine>-Xmx1024m -XX:MaxPermSize=256m</argLine>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>${guava.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jul-to-slf4j</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>org.antlr</groupId>
<artifactId>antlr4-runtime</artifactId>
<version>${antlr4.version}</version>
</dependency>
<dependency>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy</artifactId>
<version>${groovy.version}</version>
<classifier>indy</classifier>
</dependency>
<dependency>
<groupId>org.yaml</groupId>
<artifactId>snakeyaml</artifactId>
<version>${snakeyaml.version}</version>
</dependency>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>${netty.version}</version>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>${commons-codec.version}</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-collections4</artifactId>
<version>${commons-collections4.version}</version>
</dependency>
<dependency>
<groupId>javax.transaction</groupId>
<artifactId>jta</artifactId>
<version>${javax.transaction.version}</version>
</dependency>
<dependency>
<groupId>com.atomikos</groupId>
<artifactId>transactions</artifactId>
<version>${atomikos.version}</version>
</dependency>
<dependency>
<groupId>com.atomikos</groupId>
<artifactId>transactions-jta</artifactId>
<version>${atomikos.version}</version>
</dependency>
<dependency>
<groupId>com.atomikos</groupId>
<artifactId>transactions-jdbc</artifactId>
<version>${atomikos.version}</version>
</dependency>
<dependency>
<groupId>org.jboss.narayana.jta</groupId>
<artifactId>jta</artifactId>
<version>${narayana.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.jboss.narayana.jts</groupId>
<artifactId>narayana-jts-integration</artifactId>
<version>${narayana.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.jboss</groupId>
<artifactId>jboss-transaction-spi</artifactId>
<version>${jboss-transaction-spi.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.codehaus.btm</groupId>
<artifactId>btm</artifactId>
<version>${btm.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>io.seata</groupId>
<artifactId>seata-rm-datasource</artifactId>
<version>${seata.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>io.seata</groupId>
<artifactId>seata-tm</artifactId>
<version>${seata.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
<version>${curator.version}</version>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-client</artifactId>
<version>${curator.version}</version>
<exclusions>
<exclusion>
<artifactId>netty</artifactId>
<groupId>io.netty</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
<version>${curator.version}</version>
</dependency>
<dependency>
<groupId>io.opentracing</groupId>
<artifactId>opentracing-util</artifactId>
<version>${opentracing.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>${springframework.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<version>${spring-boot.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>${h2.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql-connector-java.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.mariadb.jdbc</groupId>
<artifactId>mariadb-java-client</artifactId>
<version>${mariadb-java-client.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>${postgresql.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.microsoft.sqlserver</groupId>
<artifactId>mssql-jdbc</artifactId>
<version>${mssql.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<version>${spring-boot.version}</version>
<scope>provided</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-library</artifactId>
<version>${hamcrest.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>${mockito.version}</version>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-core</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-inline</artifactId>
<version>${mockito.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>${logback.version}</version>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</exclusion>
</exclusions>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP-java7</artifactId>
<version>${hikari-cp.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>commons-pool</groupId>
<artifactId>commons-pool</artifactId>
<version>${commons-pool.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-dbcp2</artifactId>
<version>${commons-dbcp2.version}</version>
<exclusions>
<exclusion>
<groupId>commons-pool</groupId>
<artifactId>commons-pool</artifactId>
</exclusion>
</exclusions>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-test</artifactId>
<version>${curator.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.opentracing</groupId>
<artifactId>opentracing-mock</artifactId>
<version>${opentracing.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${springframework.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<version>${spring-boot.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-library</artifactId>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-inline</artifactId>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
</dependency>
</dependencies>
<build>
<finalName>apache-shardingsphere-incubating-${project.version}</finalName>
<extensions>
<extension>
<groupId>kr.motd.maven</groupId>
<artifactId>os-maven-plugin</artifactId>
<version>${os-maven-plugin.version}</version>
</extension>
</extensions>
<pluginManagement>
<plugins>
<!-- mvn -N io.takari:maven:wrapper -Dmaven=3.5.4 -->
<plugin>
<groupId>io.takari</groupId>
<artifactId>maven</artifactId>
<version>${takari-maven-plugin.version}</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
<testSource>${java.version}</testSource>
<testTarget>${java.version}</testTarget>
</configuration>
<version>${maven-compiler-plugin.version}</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>${maven-resources-plugin.version}</version>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring-boot.version}</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>${maven-jar-plugin.version}</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
<version>${maven-deploy-plugin.version}</version>
<configuration>
<skip>${maven.deploy.skip}</skip>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-release-plugin</artifactId>
<version>${maven-release-plugin.version}</version>
<configuration>
<tagNameFormat>@{project.version}</tagNameFormat>
</configuration>
</plugin>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>${maven-assembly-plugin.version}</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-site-plugin</artifactId>
<version>${maven-site-plugin.version}</version>
<configuration>
<locales>${project.build.locale}</locales>
</configuration>
</plugin>
<plugin>
<groupId>org.eclipse.m2e</groupId>
<artifactId>lifecycle-mapping</artifactId>
<version>${lifecycle-mapping.version}</version>
<configuration>
<lifecycleMappingMetadata>
<pluginExecutions>
<pluginExecution>
<pluginExecutionFilter>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<versionRange>[1.0.0,)</versionRange>
<goals>
<goal>enforce</goal>
</goals>
</pluginExecutionFilter>
<action>
<ignore />
</action>
</pluginExecution>
<pluginExecution>
<pluginExecutionFilter>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-plugin-plugin</artifactId>
<versionRange>[1.0.0,)</versionRange>
<goals>
<goal>descriptor</goal>
</goals>
</pluginExecutionFilter>
<action>
<ignore />
</action>
</pluginExecution>
</pluginExecutions>
</lifecycleMappingMetadata>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-plugin-plugin</artifactId>
<version>${maven-plugin-plugin.version}</version>
<configuration>
<skipErrorNoDescriptorsFound>true</skipErrorNoDescriptorsFound>
</configuration>
<executions>
<execution>
<id>default-descriptor</id>
<phase>process-classes</phase>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>${maven-javadoc-plugin.version}</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>${maven-source-plugin.version}</version>
</plugin>
<plugin>
<groupId>org.antlr</groupId>
<artifactId>antlr4-maven-plugin</artifactId>
<version>${antlr4.version}</version>
</plugin>
</plugins>
</pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<executions>
<execution>
<id>attach-sources</id>
<phase>verify</phase>
<goals>
<goal>jar-no-fork</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<executions>
<execution>
<id>attach-javadocs</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
<configuration>
<aggregate>true</aggregate>
<charset>${project.build.sourceEncoding}</charset>
<encoding>${project.build.sourceEncoding}</encoding>
<docencoding>${project.build.sourceEncoding}</docencoding>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<version>${maven-enforcer-plugin.version}</version>
<executions>
<execution>
<id>enforce-banned-dependencies</id>
<goals>
<goal>enforce</goal>
</goals>
<configuration>
<rules>
<requireMavenVersion>
<version>${maven.version.range}</version>
</requireMavenVersion>
<requireJavaVersion>
<version>${java.version}</version>
</requireJavaVersion>
</rules>
<fail>true</fail>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
<version>${maven-checkstyle-plugin.version}</version>
<configuration>
<configLocation>src/resources/checkstyle_ci.xml</configLocation>
<includeTestSourceDirectory>true</includeTestSourceDirectory>
<excludes>**/autogen/**/*</excludes>
</configuration>
<executions>
<execution>
<id>validate</id>
<phase>validate</phase>
<goals>
<goal>check</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.eluder.coveralls</groupId>
<artifactId>coveralls-maven-plugin</artifactId>
<version>${coveralls-maven-plugin.version}</version>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>cobertura-maven-plugin</artifactId>
<version>${cobertura-maven-plugin.version}</version>
<configuration>
<check>
<!--<branchRate>85</branchRate>-->
<!--<lineRate>85</lineRate>-->
<!--<haltOnFailure>true</haltOnFailure>-->
<!--<totalBranchRate>85</totalBranchRate>-->
<!--<totalLineRate>85</totalLineRate>-->
<!--<packageLineRate>85</packageLineRate>-->
<!--<packageBranchRate>85</packageBranchRate>-->
</check>
<aggregate>true</aggregate>
<encoding>${project.build.sourceEncoding}</encoding>
<quiet>true</quiet>
<format>xml</format>
<instrumentation>
<ignoreTrivial>true</ignoreTrivial>
<ignoreMethodAnnotations>
<ignoreMethodAnnotation>lombok.Generated</ignoreMethodAnnotation>
</ignoreMethodAnnotations>
<excludes>
<exclude>org/apache/shardingsphere/sql/parser/autogen/*.class</exclude>
<exclude>org/apache/shardingsphere/orchestration/reg/zookeeper/*.class</exclude>
<exclude>org/apache/shardingsphere/**/*Test.class</exclude>
<exclude>org/apache/shardingsphere/**/Test*.class</exclude>
</excludes>
</instrumentation>
</configuration>
</plugin>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>${jacoco.version}</version>
<executions>
<execution>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>report</id>
<phase>test</phase>
<goals>
<goal>report</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>com.spotify</groupId>
<artifactId>docker-maven-plugin</artifactId>
<version>${docker-maven-plugin.version}</version>
</plugin>
<plugin>
<groupId>org.apache.rat</groupId>
<artifactId>apache-rat-plugin</artifactId>
<version>${apache-rat-plugin.version}</version>
<configuration>
<excludes>
<exclude>**/target/**</exclude>
<exclude>**/logs/**</exclude>
<exclude>**/*.log</exclude>
<!-- IDE files -->
<exclude>**/*.iml</exclude>
<exclude>**/.idea/**</exclude>
<exclude>**/*.classpath</exclude>
<exclude>**/.project</exclude>
<exclude>**/.settings/**</exclude>
<exclude>**/dependency-reduced-pom.xml</exclude>
<!-- git files -->
<exclude>**/.gitignore</exclude>
<exclude>**/.gitmodules</exclude>
<exclude>**/.git/**</exclude>
<!-- CI files -->
<exclude>**/.travis.yml</exclude>
<exclude>**/.mvn/jvm.config</exclude>
<exclude>**/.mvn/wrapper/maven-wrapper.properties</exclude>
<!-- GitHub files -->
<exclude>**/.github/**</exclude>
<!-- document files -->
<exclude>**/*.md</exclude>
<excldue>**/*.MD</excldue>
<exclude>**/*.txt</exclude>
<exclude>**/docs/**</exclude>
<!-- UI files -->
<exclude>**/.babelrc</exclude>
<exclude>**/.editorconfig</exclude>
<exclude>**/.eslintignore</exclude>
<exclude>**/package.json</exclude>
<exclude>**/assets/**</exclude>
<exclude>/dist/**</exclude>
<exclude>/etc/**</exclude>
<exclude>/node/**</exclude>
<exclude>/node_modules/**</exclude>
<exclude>/test/coverage/**</exclude>
<exclude>**/package-lock.json</exclude>
</excludes>
</configuration>
<executions>
<execution>
<phase>verify</phase>
<goals>
<goal>check</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<reporting>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-project-info-reports-plugin</artifactId>
<version>${maven-project-info-reports-plugin.version}</version>
<configuration>
<dependencyLocationsEnabled>false</dependencyLocationsEnabled>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>${maven-javadoc-plugin.version}</version>
<configuration>
<aggregate>true</aggregate>
<charset>${project.build.sourceEncoding}</charset>
<encoding>${project.build.sourceEncoding}</encoding>
<docencoding>${project.build.sourceEncoding}</docencoding>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jxr-plugin</artifactId>
<version>${maven-jxr-plugin.version}</version>
<reportSets>
<reportSet>
<id>aggregate</id>
<inherited>false</inherited>
<reports>
<report>aggregate</report>
</reports>
</reportSet>
</reportSets>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>findbugs-maven-plugin</artifactId>
<version>${findbugs-maven-plugin.version}</version>
<configuration>
<xmlOutput>true</xmlOutput>
<effort>Max</effort>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
<version>${maven-checkstyle-plugin.version}</version>
<configuration>
<configLocation>src/resources/checkstyle.xml</configLocation>
<includeTestSourceDirectory>true</includeTestSourceDirectory>
<excludes>**/autogen/**/*</excludes>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-pmd-plugin</artifactId>
<version>${maven-pmd-plugin.version}</version>
<configuration>
<aggregate>true</aggregate>
<sourceEncoding>${project.build.sourceEncoding}</sourceEncoding>
<targetJdk>${java.version}</targetJdk>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>jdepend-maven-plugin</artifactId>
<version>${jdepend-maven-plugin.version}</version>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>taglist-maven-plugin</artifactId>
<version>${taglist-maven-plugin.version}</version>
<configuration>
<aggregate>true</aggregate>
</configuration>
</plugin>
</plugins>
</reporting>
<url>http://shardingsphere.apache.org</url>
<description>Distributed database middleware ecosphere</description>
<licenses>
<license>
<name>Apache License 2.0</name>
<url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
<distribution>repo</distribution>
</license>
</licenses>
<scm>
<connection>scm:git:https://github.com/apache/incubator-shardingsphere.git</connection>
<developerConnection>scm:git:https://github.com/apache/incubator-shardingsphere.git</developerConnection>
<url>https://github.com/apache/incubator-shardingsphere.git</url>
<tag>4.0.1</tag>
</scm>
<mailingLists>
<mailingList>
<name>ShardingSphere Developer List</name>
<post>dev@shardingsphere.incubator.apache.org</post>
<subscribe>dev-subscribe@shardingsphere.incubator.apache.org</subscribe>
<unsubscribe>dev-unsubscribe@shardingsphere.incubator.apache.org</unsubscribe>
</mailingList>
</mailingLists>
</project>

View File

@ -0,0 +1,62 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ 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.
-->
<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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.apache.shardingsphere</groupId>
<artifactId>sharding-core</artifactId>
<version>4.0.1</version>
</parent>
<artifactId>database-time-service</artifactId>
<name>${project.artifactId}</name>
<dependencies>
<dependency>
<groupId>org.apache.shardingsphere</groupId>
<artifactId>sharding-core-route</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP-java7</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mariadb.jdbc</groupId>
<artifactId>mariadb-java-client</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.microsoft.sqlserver</groupId>
<artifactId>mssql-jdbc</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,38 @@
/*
* 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.
*/
package org.apache.shardingsphere.route.time;
import org.apache.shardingsphere.core.route.spi.TimeService;
import org.apache.shardingsphere.route.time.impl.TimeServiceFactory;
import java.util.Date;
/**
* Delegate database time service.
*
* @author chenchuangliu
*/
public final class DatabaseTimeServiceDelegate implements TimeService {
private static final TimeService TIME_SERVICE = TimeServiceFactory.createTimeService();
@Override
public Date getTime() {
return TIME_SERVICE.getTime();
}
}

View File

@ -0,0 +1,80 @@
/*
* 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.
*/
package org.apache.shardingsphere.route.time;
import lombok.Getter;
import org.apache.shardingsphere.route.time.exception.TimeServiceInitException;
import javax.sql.DataSource;
import java.beans.IntrospectionException;
import java.beans.PropertyDescriptor;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Properties;
/**
* Time service configuration.
*
* <p>
* Need to create a time-service.properties under the classpath.
* </p>
*
* @author chenchuangliu
*/
@Getter
public final class TimeServiceConfiguration {
private static final TimeServiceConfiguration CONFIG = new TimeServiceConfiguration();
private String driverClassName;
private DataSource dataSource;
private TimeServiceConfiguration() {
init();
}
private void init() {
try (InputStream inputStream = TimeServiceConfiguration.class.getResourceAsStream("/time-service.properties")) {
Properties properties = new Properties();
properties.load(inputStream);
String dataSourceType = (String) properties.remove("dataSourceType");
driverClassName = (String) properties.get("driverClassName");
Class dataSourceClass = Class.forName(dataSourceType);
dataSource = (DataSource) dataSourceClass.newInstance();
for (String each : properties.stringPropertyNames()) {
PropertyDescriptor propertyDescriptor = new PropertyDescriptor(each, dataSourceClass);
Method writeMethod = propertyDescriptor.getWriteMethod();
writeMethod.invoke(dataSource, properties.getProperty(each));
}
} catch (final ClassNotFoundException | InstantiationException | IllegalAccessException | IntrospectionException | InvocationTargetException | IOException ex) {
throw new TimeServiceInitException("please check your time-service.properties", ex);
}
}
/**
* Get configuration instance.
*
* @return time service configuration
*/
public static TimeServiceConfiguration getInstance() {
return CONFIG;
}
}

View File

@ -0,0 +1,28 @@
/*
* 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.
*/
package org.apache.shardingsphere.route.time.exception;
/**
* No database SQL entry support.
*
* @author chenchuangliu
*/
public final class NoDatabaseSQLEntrySupportException extends RuntimeException {
private static final long serialVersionUID = 2153295582601133739L;
}

View File

@ -0,0 +1,32 @@
/*
* 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.
*/
package org.apache.shardingsphere.route.time.exception;
/**
* Time service init exception.
*
* @author chenchuangliu
*/
public final class TimeServiceInitException extends RuntimeException {
private static final long serialVersionUID = -834638295454826244L;
public TimeServiceInitException(final String message, final Throwable cause) {
super(message, cause);
}
}

View File

@ -0,0 +1,54 @@
/*
* 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.
*/
package org.apache.shardingsphere.route.time.impl;
import lombok.RequiredArgsConstructor;
import org.apache.shardingsphere.core.route.spi.TimeService;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Date;
/**
* Database time service.
*
* @author chenchuangliu
*/
@RequiredArgsConstructor
public final class DatabaseTimeService implements TimeService {
private final DataSource dataSource;
private final String sql;
@Override
public Date getTime() {
try (Connection connection = dataSource.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement(sql)) {
try (ResultSet resultSet = preparedStatement.executeQuery()) {
resultSet.next();
return (Date) resultSet.getObject(1);
}
} catch (final SQLException ignore) {
}
return new Date();
}
}

View File

@ -0,0 +1,40 @@
/*
* 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.
*/
package org.apache.shardingsphere.route.time.impl;
import org.apache.shardingsphere.core.route.spi.TimeService;
import org.apache.shardingsphere.route.time.TimeServiceConfiguration;
import org.apache.shardingsphere.route.time.spi.SPIDataBaseSQLEntry;
/**
* Time service factory.
*
* @author chenchuangliu
*/
public final class TimeServiceFactory {
/**
* Create time service by {@link TimeServiceConfiguration}.
*
* @return time service instance
*/
public static TimeService createTimeService() {
TimeServiceConfiguration timeServiceConfiguration = TimeServiceConfiguration.getInstance();
return new DatabaseTimeService(timeServiceConfiguration.getDataSource(), new SPIDataBaseSQLEntry(timeServiceConfiguration.getDriverClassName()).getSQL());
}
}

View File

@ -0,0 +1,41 @@
/*
* 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.
*/
package org.apache.shardingsphere.route.time.spi;
/**
* Database SQL entry.
*
* @author chenchuangliu
*/
public interface DatabaseSQLEntry {
/**
* Get SQL for getting time.
*
* @return SQL
*/
String getSQL();
/**
* Determine whether it supports.
*
* @param driverClassName driver class name
* @return support or not
*/
boolean isSupport(String driverClassName);
}

View File

@ -0,0 +1,36 @@
/*
* 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.
*/
package org.apache.shardingsphere.route.time.spi;
/**
* MySQL entry.
*
* @author chenchuangliu
*/
public final class MySQLDatabaseSQLEntry implements DatabaseSQLEntry {
@Override
public String getSQL() {
return "SELECT NOW()";
}
@Override
public boolean isSupport(final String driverClassName) {
return driverClassName.contains("mysql") || driverClassName.contains("mariadb");
}
}

View File

@ -0,0 +1,36 @@
/*
* 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.
*/
package org.apache.shardingsphere.route.time.spi;
/**
* Oracle entry.
*
* @author chenchuangliu
*/
public final class OracleDatabaseSQLEntry implements DatabaseSQLEntry {
@Override
public String getSQL() {
return "SELECT sysdate FROM DUAL";
}
@Override
public boolean isSupport(final String driverClassName) {
return driverClassName.contains("oracle");
}
}

View File

@ -0,0 +1,36 @@
/*
* 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.
*/
package org.apache.shardingsphere.route.time.spi;
/**
* PostgreSQL entry.
*
* @author chenchuangliu
*/
public final class PostgreSQLDatabaseSQLEntry implements DatabaseSQLEntry {
@Override
public String getSQL() {
return "SELECT NOW()";
}
@Override
public boolean isSupport(final String driverClassName) {
return driverClassName.contains("postgresql");
}
}

View File

@ -0,0 +1,56 @@
/*
* 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.
*/
package org.apache.shardingsphere.route.time.spi;
import lombok.RequiredArgsConstructor;
import org.apache.shardingsphere.route.time.exception.NoDatabaseSQLEntrySupportException;
import org.apache.shardingsphere.spi.NewInstanceServiceLoader;
import java.util.Collection;
/**
* SPI for DatabaseSQLEntry.
*
* @author chenchuangliu
*/
@RequiredArgsConstructor
public final class SPIDataBaseSQLEntry implements DatabaseSQLEntry {
static {
NewInstanceServiceLoader.register(DatabaseSQLEntry.class);
}
private final Collection<DatabaseSQLEntry> sqlEntries = NewInstanceServiceLoader.newServiceInstances(DatabaseSQLEntry.class);
private final String driverClassName;
@Override
public String getSQL() {
for (DatabaseSQLEntry each : sqlEntries) {
if (each.isSupport(driverClassName)) {
return each.getSQL();
}
}
throw new NoDatabaseSQLEntrySupportException();
}
@Override
public boolean isSupport(final String driverClassName) {
return true;
}
}

View File

@ -0,0 +1,36 @@
/*
* 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.
*/
package org.apache.shardingsphere.route.time.spi;
/**
* SQLServer entry.
*
* @author chenchuangliu
*/
public final class SQLServerDatabaseSQLEntry implements DatabaseSQLEntry {
@Override
public String getSQL() {
return "SELECT GETDATE()";
}
@Override
public boolean isSupport(final String driverClassName) {
return driverClassName.contains("sqlserver");
}
}

View File

@ -0,0 +1,18 @@
#
# 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.
#
org.apache.shardingsphere.route.time.DatabaseTimeServiceDelegate

View File

@ -0,0 +1,21 @@
#
# 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.
#
org.apache.shardingsphere.route.time.spi.MySQLDatabaseSQLEntry
org.apache.shardingsphere.route.time.spi.OracleDatabaseSQLEntry
org.apache.shardingsphere.route.time.spi.PostgreSQLDatabaseSQLEntry
org.apache.shardingsphere.route.time.spi.SQLServerDatabaseSQLEntry

View File

@ -0,0 +1,22 @@
#
# 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.
#
#dataSourceType=
#driverClassName=
#username=
#password=
#url=

View File

@ -0,0 +1,61 @@
/*
* 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.
*/
package org.apache.shardingsphere.route.time;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Properties;
public final class PropertiesUtils {
private static final File FILE = new File(PropertiesUtils.class.getResource("/").getPath() + "time-service.properties");
/**
* Create a time-service.properties file.
*
* @param driverClassName driver class name
* @param sql SQL
*/
public static void createProperties(final String driverClassName, final String sql) {
try {
Properties properties = new Properties();
properties.put("dataSourceType", "com.zaxxer.hikari.HikariDataSource");
properties.put("jdbcUrl", "jdbc:test");
properties.put("username", "root");
properties.put("password", "root");
properties.put("driverClassName", driverClassName);
if (null != sql) {
properties.put("sql", sql);
}
FileOutputStream stream = new FileOutputStream(FILE);
properties.store(stream, null);
stream.close();
} catch (IOException ignore) {
}
}
/**
* Delete time-service.properties.
*
* @return true if delete successfully or false
*/
public static boolean remove() {
return FILE.delete();
}
}

View File

@ -0,0 +1,34 @@
/*
* 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.
*/
package org.apache.shardingsphere.route.time;
import org.junit.Test;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
public final class TimeServiceConfigurationTest {
@Test
public void assertInitDataSource() {
PropertiesUtils.createProperties("com.mysql.jdbc.Driver", null);
TimeServiceConfiguration config = TimeServiceConfiguration.getInstance();
assertNotNull(config.getDataSource());
assertTrue(PropertiesUtils.remove());
}
}

40
sharding-core/pom.xml Normal file
View File

@ -0,0 +1,40 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ 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.
-->
<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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.apache.shardingsphere</groupId>
<artifactId>shardingsphere</artifactId>
<version>4.0.1</version>
</parent>
<artifactId>sharding-core</artifactId>
<name>${project.artifactId}</name>
<packaging>pom</packaging>
<modules>
<module>sharding-core-api</module>
<module>sharding-core-common</module>
<module>sharding-core-route</module>
<module>database-time-service</module>
<module>sharding-core-rewrite</module>
<module>sharding-core-execute</module>
<module>sharding-core-merge</module>
<module>sharding-core-entry</module>
</modules>
</project>

View File

@ -0,0 +1,36 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ 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.
-->
<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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.apache.shardingsphere</groupId>
<artifactId>sharding-core</artifactId>
<version>4.0.1</version>
</parent>
<artifactId>sharding-core-api</artifactId>
<name>${project.artifactId}</name>
<dependencies>
<dependency>
<groupId>org.apache.shardingsphere</groupId>
<artifactId>shardingsphere-spi</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,26 @@
/*
* 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.
*/
package org.apache.shardingsphere.api.config;
/**
* Rule configuration.
*
* @author panjuan
*/
public interface RuleConfiguration {
}

View File

@ -0,0 +1,47 @@
/*
* 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.
*/
package org.apache.shardingsphere.api.config;
import com.google.common.base.Preconditions;
import com.google.common.base.Strings;
import lombok.Getter;
import java.util.Properties;
/**
* Type based SPI configuration.
*
* @author zhangliang
*/
@Getter
public abstract class TypeBasedSPIConfiguration {
private final String type;
private final Properties properties;
public TypeBasedSPIConfiguration(final String type) {
this(type, null);
}
public TypeBasedSPIConfiguration(final String type, final Properties properties) {
Preconditions.checkArgument(!Strings.isNullOrEmpty(type), "Type is required.");
this.type = type;
this.properties = null == properties ? new Properties() : properties;
}
}

View File

@ -0,0 +1,39 @@
/*
* 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.
*/
package org.apache.shardingsphere.api.config.encrypt;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
/**
* Encrypt column rule configuration.
*
* @author panjuan
*/
@RequiredArgsConstructor
@Getter
public final class EncryptColumnRuleConfiguration {
private final String plainColumn;
private final String cipherColumn;
private final String assistedQueryColumn;
private final String encryptor;
}

View File

@ -0,0 +1,43 @@
/*
* 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.
*/
package org.apache.shardingsphere.api.config.encrypt;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import org.apache.shardingsphere.api.config.RuleConfiguration;
import java.util.LinkedHashMap;
import java.util.Map;
/**
* Encrypt rule configuration.
*
* @author panjuan
*/
@RequiredArgsConstructor
@Getter
public final class EncryptRuleConfiguration implements RuleConfiguration {
private final Map<String, EncryptorRuleConfiguration> encryptors;
private final Map<String, EncryptTableRuleConfiguration> tables;
public EncryptRuleConfiguration() {
this(new LinkedHashMap<String, EncryptorRuleConfiguration>(), new LinkedHashMap<String, EncryptTableRuleConfiguration>());
}
}

View File

@ -0,0 +1,40 @@
/*
* 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.
*/
package org.apache.shardingsphere.api.config.encrypt;
import lombok.Getter;
import lombok.NoArgsConstructor;
import java.util.LinkedHashMap;
import java.util.Map;
/**
* Encrypt table rule configuration.
*
* @author panjuan
*/
@NoArgsConstructor
@Getter
public final class EncryptTableRuleConfiguration {
private final Map<String, EncryptColumnRuleConfiguration> columns = new LinkedHashMap<>();
public EncryptTableRuleConfiguration(final Map<String, EncryptColumnRuleConfiguration> columns) {
this.columns.putAll(columns);
}
}

View File

@ -0,0 +1,36 @@
/*
* 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.
*/
package org.apache.shardingsphere.api.config.encrypt;
import lombok.Getter;
import org.apache.shardingsphere.api.config.TypeBasedSPIConfiguration;
import java.util.Properties;
/**
* Encryptor configuration.
*
* @author panjuan
*/
@Getter
public final class EncryptorRuleConfiguration extends TypeBasedSPIConfiguration {
public EncryptorRuleConfiguration(final String type, final Properties properties) {
super(type, properties);
}
}

View File

@ -0,0 +1,40 @@
/*
* 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.
*/
package org.apache.shardingsphere.api.config.masterslave;
import lombok.Getter;
import org.apache.shardingsphere.api.config.TypeBasedSPIConfiguration;
import java.util.Properties;
/**
* Master-slave load balance strategy configuration.
*
* @author zhangliang
*/
@Getter
public final class LoadBalanceStrategyConfiguration extends TypeBasedSPIConfiguration {
public LoadBalanceStrategyConfiguration(final String type) {
super(type);
}
public LoadBalanceStrategyConfiguration(final String type, final Properties properties) {
super(type, properties);
}
}

View File

@ -0,0 +1,57 @@
/*
* 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.
*/
package org.apache.shardingsphere.api.config.masterslave;
import com.google.common.base.Preconditions;
import com.google.common.base.Strings;
import lombok.Getter;
import org.apache.shardingsphere.api.config.RuleConfiguration;
import java.util.List;
/**
* Master-slave rule configuration.
*
* @author zhangliang
* @author panjuan
*/
@Getter
public class MasterSlaveRuleConfiguration implements RuleConfiguration {
private final String name;
private final String masterDataSourceName;
private final List<String> slaveDataSourceNames;
private final LoadBalanceStrategyConfiguration loadBalanceStrategyConfiguration;
public MasterSlaveRuleConfiguration(final String name, final String masterDataSourceName, final List<String> slaveDataSourceNames) {
this(name, masterDataSourceName, slaveDataSourceNames, null);
}
public MasterSlaveRuleConfiguration(final String name,
final String masterDataSourceName, final List<String> slaveDataSourceNames, final LoadBalanceStrategyConfiguration loadBalanceStrategyConfiguration) {
Preconditions.checkArgument(!Strings.isNullOrEmpty(name), "Name is required.");
Preconditions.checkArgument(!Strings.isNullOrEmpty(masterDataSourceName), "MasterDataSourceName is required.");
Preconditions.checkArgument(null != slaveDataSourceNames && !slaveDataSourceNames.isEmpty(), "SlaveDataSourceNames is required.");
this.name = name;
this.masterDataSourceName = masterDataSourceName;
this.slaveDataSourceNames = slaveDataSourceNames;
this.loadBalanceStrategyConfiguration = loadBalanceStrategyConfiguration;
}
}

View File

@ -0,0 +1,48 @@
/*
* 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.
*/
package org.apache.shardingsphere.api.config.sharding;
import com.google.common.base.Preconditions;
import com.google.common.base.Strings;
import lombok.Getter;
import org.apache.shardingsphere.api.config.TypeBasedSPIConfiguration;
import java.util.Properties;
/**
* Key generator configuration.
*
* @author panjuan
*/
@Getter
public final class KeyGeneratorConfiguration extends TypeBasedSPIConfiguration {
private final String column;
public KeyGeneratorConfiguration(final String type, final String column) {
super(type);
Preconditions.checkArgument(!Strings.isNullOrEmpty(column), "Column is required.");
this.column = column;
}
public KeyGeneratorConfiguration(final String type, final String column, final Properties properties) {
super(type, properties);
Preconditions.checkArgument(!Strings.isNullOrEmpty(column), "Column is required.");
this.column = column;
}
}

View File

@ -0,0 +1,58 @@
/*
* 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.
*/
package org.apache.shardingsphere.api.config.sharding;
import lombok.Getter;
import lombok.Setter;
import org.apache.shardingsphere.api.config.RuleConfiguration;
import org.apache.shardingsphere.api.config.encrypt.EncryptRuleConfiguration;
import org.apache.shardingsphere.api.config.masterslave.MasterSlaveRuleConfiguration;
import org.apache.shardingsphere.api.config.sharding.strategy.ShardingStrategyConfiguration;
import java.util.Collection;
import java.util.LinkedList;
/**
* Sharding rule configuration.
*
* @author zhangliang
* @author maxiaoguang
* @author panjuan
*/
@Getter
@Setter
public final class ShardingRuleConfiguration implements RuleConfiguration {
private Collection<TableRuleConfiguration> tableRuleConfigs = new LinkedList<>();
private Collection<String> bindingTableGroups = new LinkedList<>();
private Collection<String> broadcastTables = new LinkedList<>();
private String defaultDataSourceName;
private ShardingStrategyConfiguration defaultDatabaseShardingStrategyConfig;
private ShardingStrategyConfiguration defaultTableShardingStrategyConfig;
private KeyGeneratorConfiguration defaultKeyGeneratorConfig;
private Collection<MasterSlaveRuleConfiguration> masterSlaveRuleConfigs = new LinkedList<>();
private EncryptRuleConfiguration encryptRuleConfig;
}

View File

@ -0,0 +1,55 @@
/*
* 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.
*/
package org.apache.shardingsphere.api.config.sharding;
import com.google.common.base.Preconditions;
import com.google.common.base.Strings;
import lombok.Getter;
import lombok.Setter;
import org.apache.shardingsphere.api.config.sharding.strategy.ShardingStrategyConfiguration;
/**
* Table rule configuration.
*
* @author zhangliang
* @author panjuan
*/
@Getter
@Setter
public final class TableRuleConfiguration {
private final String logicTable;
private final String actualDataNodes;
private ShardingStrategyConfiguration databaseShardingStrategyConfig;
private ShardingStrategyConfiguration tableShardingStrategyConfig;
private KeyGeneratorConfiguration keyGeneratorConfig;
public TableRuleConfiguration(final String logicTable) {
this(logicTable, null);
}
public TableRuleConfiguration(final String logicTable, final String actualDataNodes) {
Preconditions.checkArgument(!Strings.isNullOrEmpty(logicTable), "LogicTable is required.");
this.logicTable = logicTable;
this.actualDataNodes = actualDataNodes;
}
}

View File

@ -0,0 +1,43 @@
/*
* 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.
*/
package org.apache.shardingsphere.api.config.sharding.strategy;
import com.google.common.base.Preconditions;
import com.google.common.base.Strings;
import lombok.Getter;
import org.apache.shardingsphere.api.sharding.complex.ComplexKeysShardingAlgorithm;
/**
* Complex sharding strategy configuration.
*
* @author zhangliang
*/
@Getter
public final class ComplexShardingStrategyConfiguration implements ShardingStrategyConfiguration {
private final String shardingColumns;
private final ComplexKeysShardingAlgorithm shardingAlgorithm;
public ComplexShardingStrategyConfiguration(final String shardingColumns, final ComplexKeysShardingAlgorithm shardingAlgorithm) {
Preconditions.checkArgument(!Strings.isNullOrEmpty(shardingColumns), "ShardingColumns is required.");
Preconditions.checkNotNull(shardingAlgorithm, "ShardingAlgorithm is required.");
this.shardingColumns = shardingColumns;
this.shardingAlgorithm = shardingAlgorithm;
}
}

Some files were not shown because too many files have changed in this diff Show More