mirror of
https://github.com/dbeaver/cloudbeaver.git
synced 2026-10-25 09:34:18 +08:00
Cloudbeaver 1.0 initial
This commit is contained in:
@@ -0,0 +1,22 @@
|
||||
Manifest-Version: 1.0
|
||||
Bundle-ManifestVersion: 2
|
||||
Bundle-Vendor: %Bundle-Vendor
|
||||
Bundle-Name: %Bundle-Name
|
||||
Bundle-SymbolicName: io.cloudbeaver.connect.provider.sample;singleton:=true
|
||||
Bundle-Version: 1.0.3.qualifier
|
||||
Bundle-Release-Date: 20200420
|
||||
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
|
||||
Bundle-ActivationPolicy: lazy
|
||||
Bundle-ClassPath: .
|
||||
Require-Bundle: org.eclipse.core.runtime,
|
||||
org.eclipse.core.expressions,
|
||||
org.apache.commons.logging,
|
||||
org.eclipse.core.commands,
|
||||
org.eclipse.core.resources,
|
||||
io.cloudbeaver.server,
|
||||
com.google.gson,
|
||||
org.jkiss.bundle.graphql.java,
|
||||
org.jkiss.dbeaver.model,
|
||||
org.jkiss.dbeaver.model.sql
|
||||
Bundle-Localization: OSGI-INF/l10n/bundle
|
||||
Automatic-Module-Name: io.cloudbeaver.connect.provider.sample
|
||||
@@ -0,0 +1,2 @@
|
||||
Bundle-Vendor = DBeaver Corp
|
||||
Bundle-Name = Cloudbeaver - Connections configuration - Sample
|
||||
@@ -0,0 +1,6 @@
|
||||
source.. = src/
|
||||
output.. = target/classes/
|
||||
bin.includes = .,\
|
||||
META-INF/,\
|
||||
OSGI-INF/,\
|
||||
plugin.xml
|
||||
@@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<?eclipse version="3.2"?>
|
||||
|
||||
<plugin>
|
||||
|
||||
<extension point="org.jkiss.dbeaver.dataSourceStorage">
|
||||
<storage id="sample" name="Sample configuration storage" description="Preconfigured sample connection set" class="io.cloudbeaver.connect.provider.sample.SampleDataSourceConfigurationStorage">
|
||||
|
||||
</storage>
|
||||
</extension>
|
||||
|
||||
</plugin>
|
||||
@@ -0,0 +1,16 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
|
||||
xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>io.cloudbeaver</groupId>
|
||||
<artifactId>bundles</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
<relativePath>../</relativePath>
|
||||
</parent>
|
||||
<artifactId>io.cloudbeaver.connect.provider.sample</artifactId>
|
||||
<version>1.0.3-SNAPSHOT</version>
|
||||
<packaging>eclipse-plugin</packaging>
|
||||
|
||||
</project>
|
||||
+83
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* DBeaver - Universal Database Manager
|
||||
* Copyright (C) 2010-2020 DBeaver Corp and others
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
package io.cloudbeaver.connect.provider.sample;
|
||||
|
||||
import org.eclipse.core.resources.IFile;
|
||||
import org.eclipse.core.resources.IFolder;
|
||||
import org.jkiss.dbeaver.DBException;
|
||||
import org.jkiss.dbeaver.Log;
|
||||
import org.jkiss.dbeaver.model.DBPDataSourceConfigurationStorage;
|
||||
import org.jkiss.dbeaver.model.DBPDataSourceContainer;
|
||||
import org.jkiss.dbeaver.model.app.DBPDataSourceRegistry;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Sample configuration storage.
|
||||
* Is the main source of data in web application
|
||||
*/
|
||||
public class SampleDataSourceConfigurationStorage implements DBPDataSourceConfigurationStorage {
|
||||
|
||||
private static final Log log = Log.getLog(SampleDataSourceConfigurationStorage.class);
|
||||
|
||||
public static final String SAMPLE_CONFIG_NAME = "provided-connections.json";
|
||||
|
||||
@Override
|
||||
public String getStorageId() {
|
||||
return "Sample";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValid() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDefault() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getStatus() {
|
||||
return "Valid";
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<? extends DBPDataSourceContainer> loadDataSources(DBPDataSourceRegistry registry, Map<String, Object> options) throws DBException {
|
||||
IFolder metadataFolder = registry.getProject().getMetadataFolder(false);
|
||||
if (metadataFolder.exists()) {
|
||||
IFile sampleConfigFile = metadataFolder.getFile(SAMPLE_CONFIG_NAME);
|
||||
if (sampleConfigFile.exists()) {
|
||||
log.debug("Loading provided connections from [" + sampleConfigFile.getFullPath().toString() + "]");
|
||||
List<? extends DBPDataSourceContainer> dsList = registry.loadDataSourcesFromFile(this, sampleConfigFile);
|
||||
for (DBPDataSourceContainer ds : dsList) {
|
||||
log.debug("\tProvided connection: " + ds.getName());
|
||||
}
|
||||
return dsList;
|
||||
}
|
||||
}
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getConfigurationFileSuffix() {
|
||||
return "sample";
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
Manifest-Version: 1.0
|
||||
Bundle-ManifestVersion: 2
|
||||
Bundle-Name: Base JDBC drivers
|
||||
Bundle-SymbolicName: io.cloudbeaver.resources.drivers.base;singleton:=true
|
||||
Bundle-Version: 1.0.0
|
||||
Bundle-Vendor: DBeaver Corp
|
||||
Bundle-ActivationPolicy: lazy
|
||||
Eclipse-BundleShape: dir
|
||||
Automatic-Module-Name: io.cloudbeaver.resources.drivers.base
|
||||
Require-Bundle: io.cloudbeaver.server
|
||||
@@ -0,0 +1,3 @@
|
||||
source.. =
|
||||
bin.includes = plugin.xml,META-INF/,drivers/
|
||||
src.includes =
|
||||
@@ -0,0 +1,5 @@
|
||||
Jaybird JCA/JDBC driver is distributed under the GNU Lesser General Public License (LGPL). Text of the license can be obtained from http://www.gnu.org/copyleft/lesser.html.
|
||||
|
||||
Using Jaybird (by importing Jaybird's public interfaces in your Java code), and extending Jaybird by subclassing or implementation of an extension interface (but not abstract or concrete class) is considered by the authors of Jaybird to be dynamic linking. Hence our interpretation of the LGPL is that the use of the unmodified Jaybird source does not affect the license of your application code.
|
||||
|
||||
Even more, all extension interfaces to which application might want to link are released under dual LGPL/modified BSD license. Latter is basically “AS IS” license that allows any kind of use of that source code. Jaybird should be viewed as an implementation of that interfaces and LGPL section for dynamic linking is applicable in this case.
|
||||
BIN
Binary file not shown.
@@ -0,0 +1 @@
|
||||
MariaDB JDBC driver is distributed under the GNU Lesser General Public License (LGPL). Text of the license can be obtained from http://www.gnu.org/copyleft/lesser.html.
|
||||
BIN
Binary file not shown.
@@ -0,0 +1,307 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Lesser General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software
|
||||
interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as
|
||||
a special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and
|
||||
"any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it
|
||||
does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version
|
||||
2 of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details
|
||||
type 'show w'. This is free software, and you are welcome
|
||||
to redistribute it under certain conditions; type 'show c'
|
||||
for details.
|
||||
|
||||
The hypothetical commands 'show w' and 'show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than 'show w' and
|
||||
'show c'; they could even be mouse-clicks or menu items--whatever
|
||||
suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the
|
||||
program 'Gnomovision' (which makes passes at compilers) written
|
||||
by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use
|
||||
the GNU Lesser General Public License instead of this License.
|
||||
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
@@ -0,0 +1,26 @@
|
||||
Copyright (c) 1997-2010, PostgreSQL Global Development Group
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
3. Neither the name of the PostgreSQL Global Development Group nor the names
|
||||
of its contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
BIN
Binary file not shown.
+62
@@ -0,0 +1,62 @@
|
||||
SQLite JDBC driver developed by Taro L. Saito is an extension of Zentus's SQLite JDBC driver that enables Java to access SQLite database files.
|
||||
This program follows the Apache License version 2.0 (http://www.apache.org/licenses/ )
|
||||
|
||||
|
||||
/* ====================================================================
|
||||
* The Apache Software License, Version 1.1
|
||||
*
|
||||
* Copyright (c) 2000 The Apache Software Foundation. All rights
|
||||
* reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. The end-user documentation included with the redistribution,
|
||||
* if any, must include the following acknowledgment:
|
||||
* "This product includes software developed by the
|
||||
* Apache Software Foundation (http://www.apache.org/)."
|
||||
* Alternately, this acknowledgment may appear in the software itself,
|
||||
* if and wherever such third-party acknowledgments normally appear.
|
||||
*
|
||||
* 4. The names "Apache" and "Apache Software Foundation" must
|
||||
* not be used to endorse or promote products derived from this
|
||||
* software without prior written permission. For written
|
||||
* permission, please contact apache@apache.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "Apache",
|
||||
* nor may "Apache" appear in their name, without prior written
|
||||
* permission of the Apache Software Foundation.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This software consists of voluntary contributions made by many
|
||||
* individuals on behalf of the Apache Software Foundation. For more
|
||||
* information on the Apache Software Foundation, please see
|
||||
* <http://www.apache.org/>.
|
||||
*
|
||||
* Portions of this software are based upon public domain software
|
||||
* originally written at the National Center for Supercomputing Applications,
|
||||
* University of Illinois, Urbana-Champaign.
|
||||
*/
|
||||
|
||||
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
@@ -0,0 +1,62 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<plugin>
|
||||
<!-- PostgreSQL -->
|
||||
<extension point="org.jkiss.dbeaver.resources">
|
||||
<resource name="drivers/postgresql/LICENSE.txt"/>
|
||||
<resource name="drivers/postgresql/postgresql-42.2.5.jar" alias="drivers/postgresql/postgresql.jar"/>
|
||||
<resource name="drivers/postgis/postgis-jdbc-2.2.1.jar" alias="drivers/postgis/postgis-jdbc.jar"/>
|
||||
<resource name="drivers/waffle/waffle-jna-1.9.0.jar" alias="drivers/waffle/waffle-jna.jar"/>
|
||||
<resource name="drivers/waffle/caffeine-2.6.2.jar" alias="drivers/waffle/caffeine.jar"/>
|
||||
</extension>
|
||||
|
||||
<!-- MySQL -->
|
||||
<extension point="org.jkiss.dbeaver.resources">
|
||||
<resource name="drivers/mysql/LICENSE.txt"/>
|
||||
<resource name="drivers/mysql/mysql-connector-java-5.1.44.jar" alias="drivers/mysql/mysql-connector-java.jar"/>
|
||||
<resource name="drivers/mysql/mysql-connector-java-8.0.11.jar" alias="drivers/mysql/mysql-connector-java-8.jar"/>
|
||||
<resource name="drivers/mysql/protobuf-java-2.6.0.jar" alias="drivers/mysql/protobuf-java.jar"/>
|
||||
</extension>
|
||||
|
||||
<!-- MariaDB -->
|
||||
<extension point="org.jkiss.dbeaver.resources">
|
||||
<resource name="drivers/mariadb/LICENSE.txt"/>
|
||||
<resource name="drivers/mariadb/mariadb-java-client-2.6.0.jar" alias="drivers/mariadb/mariadb-java-client.jar"/>
|
||||
</extension>
|
||||
|
||||
<!-- Firebird -->
|
||||
|
||||
<extension point="org.jkiss.dbeaver.resources">
|
||||
<resource name="drivers/firebird3/LICENSE.txt"/>
|
||||
<resource name="drivers/firebird3/jaybird-full-3.0.3.jar" alias="drivers/firebird3/jaybird-full.jar"/>
|
||||
<resource name="drivers/firebird3/jna-4.4.0.jar" alias="drivers/firebird3/jna.jar"/>
|
||||
</extension>
|
||||
|
||||
<!-- SQLite -->
|
||||
|
||||
<extension point="org.jkiss.dbeaver.resources">
|
||||
<resource name="drivers/sqlite/xerial/LICENSE.txt"/>
|
||||
<resource name="drivers/sqlite/xerial/sqlite-jdbc-3.30.1.jar" alias="drivers/sqlite/xerial/sqlite-jdbc.jar"/>
|
||||
</extension>
|
||||
|
||||
<!-- Drivers config -->
|
||||
|
||||
<extension point="org.jkiss.dbeaver.product.bundles">
|
||||
<bundle id="drivers.postgresql" label="PostgreSQL drivers"/>
|
||||
<bundle id="drivers.mysql" label="MySQL drivers"/>
|
||||
<bundle id="drivers.mariadb" label="MariaDB drivers"/>
|
||||
<bundle id="drivers.firebird" label="FireBird drivers"/>
|
||||
<bundle id="drivers.sqlite.xerial" label="SQLite drivers"/>
|
||||
</extension>
|
||||
|
||||
<!-- Enabled drivers -->
|
||||
<extension point="io.cloudbeaver.driver">
|
||||
<driver id="postgresql:postgres-jdbc"/>
|
||||
<driver id="mysql:mysql8"/>
|
||||
<driver id="mysql:mariaDB"/>
|
||||
<driver id="generic:sqlite_jdbc"/>
|
||||
<driver id="generic:derby_server"/>
|
||||
<driver id="jaybird:jaybird"/>
|
||||
</extension>
|
||||
|
||||
|
||||
</plugin>
|
||||
@@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>io.cloudbeaver</groupId>
|
||||
<artifactId>bundles</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
<relativePath>../</relativePath>
|
||||
</parent>
|
||||
<artifactId>io.cloudbeaver.resources.drivers.base</artifactId>
|
||||
<version>1.0.0</version>
|
||||
<packaging>eclipse-plugin</packaging>
|
||||
</project>
|
||||
@@ -0,0 +1,38 @@
|
||||
Manifest-Version: 1.0
|
||||
Bundle-ManifestVersion: 2
|
||||
Bundle-Vendor: %Bundle-Vendor
|
||||
Bundle-Name: %Bundle-Name
|
||||
Bundle-SymbolicName: io.cloudbeaver.server;singleton:=true
|
||||
Bundle-Version: 7.0.3.qualifier
|
||||
Bundle-Release-Date: 20200420
|
||||
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
|
||||
Bundle-ActivationPolicy: lazy
|
||||
Bundle-Activator: io.cloudbeaver.server.WebPlatformActivator
|
||||
Bundle-ClassPath: .
|
||||
Require-Bundle: org.eclipse.core.runtime,
|
||||
org.eclipse.core.expressions,
|
||||
org.apache.commons.logging,
|
||||
org.eclipse.core.commands,
|
||||
org.eclipse.core.resources,
|
||||
org.apache.commons.jexl,
|
||||
org.jkiss.utils,
|
||||
org.jkiss.dbeaver.model,
|
||||
org.jkiss.dbeaver.model.sql,
|
||||
org.jkiss.dbeaver.registry,
|
||||
org.jkiss.dbeaver.data.gis,
|
||||
javax.servlet,
|
||||
org.eclipse.jetty.server,
|
||||
org.eclipse.jetty.servlet,
|
||||
org.eclipse.jetty.util,
|
||||
com.google.gson,
|
||||
org.jkiss.bundle.graphql.java
|
||||
Export-Package: io.cloudbeaver,
|
||||
io.cloudbeaver.api,
|
||||
io.cloudbeaver.server,
|
||||
io.cloudbeaver.server.model,
|
||||
io.cloudbeaver.server.model.resources,
|
||||
io.cloudbeaver.server.model.session,
|
||||
io.cloudbeaver.server.model.sql
|
||||
Import-Package: org.slf4j
|
||||
Bundle-Localization: OSGI-INF/l10n/bundle
|
||||
Automatic-Module-Name: io.cloudbeaver.server
|
||||
@@ -0,0 +1,2 @@
|
||||
Bundle-Vendor = DBeaver Corp
|
||||
Bundle-Name = Cloudbeaver Web Server
|
||||
@@ -0,0 +1,8 @@
|
||||
source.. = src/
|
||||
output.. = target/classes/
|
||||
bin.includes = .,\
|
||||
META-INF/,\
|
||||
OSGI-INF/,\
|
||||
schema/,\
|
||||
static/,\
|
||||
plugin.xml
|
||||
@@ -0,0 +1,9 @@
|
||||
# Sample property file
|
||||
|
||||
ServerPort = 8080
|
||||
ServerName = Cloudbeaver Web Server
|
||||
|
||||
ContentRoot = /var/www/cloudbeaver/static
|
||||
|
||||
RootURI = /
|
||||
ServicesURI = /cloudbeaver/
|
||||
@@ -0,0 +1,37 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<?eclipse version="3.2"?>
|
||||
|
||||
<plugin>
|
||||
|
||||
<extension-point id="io.cloudbeaver.service" name="Web services" schema="schema/io.cloudbeaver.service.exsd"/>
|
||||
<extension-point id="io.cloudbeaver.driver" name="Web drivers" schema="schema/io.cloudbeaver.driver.exsd"/>
|
||||
|
||||
<extension point="org.eclipse.core.runtime.applications" id="standalone" name="Cloudbeaver Web Application">
|
||||
<application visible="true">
|
||||
<run class="io.cloudbeaver.server.CloudbeaverApplication"/>
|
||||
</application>
|
||||
</extension>
|
||||
|
||||
<extension point="org.eclipse.core.runtime.products" id="product">
|
||||
<product application="io.cloudbeaver.server.standalone" description="Cloudbeaver Web UI Application" name="Cloudbeaver Web Server">
|
||||
<property name="appName" value="Cloudbeaver Web Server"/>
|
||||
</product>
|
||||
</extension>
|
||||
|
||||
<extension point="org.jkiss.dbeaver.application">
|
||||
<application id="cloudbeaver-server" name="Cloudbeaver Web Server" description="Cloudbeaver Web UI"/>
|
||||
</extension>
|
||||
|
||||
<extension point="org.eclipse.core.runtime.adapters">
|
||||
<factory adaptableType="org.jkiss.dbeaver.runtime.DBWorkbench" class="io.cloudbeaver.server.WebPlatformAdapterFactory">
|
||||
<adapter type="org.jkiss.dbeaver.model.app.DBPPlatform"/>
|
||||
<adapter type="org.jkiss.dbeaver.runtime.ui.DBPPlatformUI"/>
|
||||
</factory>
|
||||
</extension>
|
||||
|
||||
<!-- Needed to instantiate connections thru navigator model -->
|
||||
<extension point="org.jkiss.dbeaver.service">
|
||||
<service name="org.jkiss.dbeaver.runtime.DBServiceConnections" class="io.cloudbeaver.server.WebServiceConnectionsImpl"/>
|
||||
</extension>
|
||||
|
||||
</plugin>
|
||||
@@ -0,0 +1,16 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
|
||||
xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>io.cloudbeaver</groupId>
|
||||
<artifactId>bundles</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
<relativePath>../</relativePath>
|
||||
</parent>
|
||||
<artifactId>io.cloudbeaver.server</artifactId>
|
||||
<version>7.0.3-SNAPSHOT</version>
|
||||
<packaging>eclipse-plugin</packaging>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,34 @@
|
||||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<schema targetNamespace="org.jkiss.dbeaver.core" xmlns="http://www.w3.org/2001/XMLSchema">
|
||||
<annotation>
|
||||
<appInfo>
|
||||
<meta.schema plugin="io.cloudbeaver.server" id="io.cloudbeaver.driver" name="Web drivers"/>
|
||||
</appInfo>
|
||||
<documentation>
|
||||
DBeaver data source provider
|
||||
</documentation>
|
||||
</annotation>
|
||||
|
||||
<element name="extension">
|
||||
<annotation>
|
||||
<appInfo>
|
||||
<meta.element />
|
||||
</appInfo>
|
||||
</annotation>
|
||||
<complexType>
|
||||
<sequence>
|
||||
<element ref="driver"/>
|
||||
</sequence>
|
||||
</complexType>
|
||||
</element>
|
||||
|
||||
<element name="driver">
|
||||
<annotation>
|
||||
<documentation>
|
||||
Web service description
|
||||
</documentation>
|
||||
</annotation>
|
||||
</element>
|
||||
|
||||
|
||||
</schema>
|
||||
@@ -0,0 +1,34 @@
|
||||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<schema targetNamespace="org.jkiss.dbeaver.core" xmlns="http://www.w3.org/2001/XMLSchema">
|
||||
<annotation>
|
||||
<appInfo>
|
||||
<meta.schema plugin="io.cloudbeaver.server" id="io.cloudbeaver.service" name="Web services"/>
|
||||
</appInfo>
|
||||
<documentation>
|
||||
DBeaver data source provider
|
||||
</documentation>
|
||||
</annotation>
|
||||
|
||||
<element name="extension">
|
||||
<annotation>
|
||||
<appInfo>
|
||||
<meta.element />
|
||||
</appInfo>
|
||||
</annotation>
|
||||
<complexType>
|
||||
<sequence>
|
||||
<element ref="service"/>
|
||||
</sequence>
|
||||
</complexType>
|
||||
</element>
|
||||
|
||||
<element name="service">
|
||||
<annotation>
|
||||
<documentation>
|
||||
Web service description
|
||||
</documentation>
|
||||
</annotation>
|
||||
</element>
|
||||
|
||||
|
||||
</schema>
|
||||
@@ -0,0 +1,531 @@
|
||||
# Any object (JSON)
|
||||
scalar Object
|
||||
# Date/Time
|
||||
scalar DateTime
|
||||
|
||||
####################################################
|
||||
# General stuff
|
||||
####################################################
|
||||
|
||||
# Async types
|
||||
|
||||
union AsyncTaskResult = SQLExecuteInfo
|
||||
|
||||
type AsyncTaskInfo {
|
||||
id: String!
|
||||
name: String
|
||||
running: Boolean!
|
||||
|
||||
status: String
|
||||
error: ServerError
|
||||
|
||||
result: SQLExecuteInfo
|
||||
}
|
||||
|
||||
# Various server errors descriptor
|
||||
|
||||
type ServerError {
|
||||
message: String
|
||||
errorCode: String
|
||||
stackTrace: String
|
||||
causedBy: ServerError
|
||||
}
|
||||
|
||||
type ServerMessage {
|
||||
time: String
|
||||
message: String
|
||||
}
|
||||
|
||||
# Languages supported by server
|
||||
|
||||
type ServerLanguage {
|
||||
isoCode: String!
|
||||
displayName: String
|
||||
nativeName: String
|
||||
}
|
||||
|
||||
type WebServiceConfig {
|
||||
id: String!
|
||||
name: String!
|
||||
description: String!
|
||||
bundleVersion: String!
|
||||
}
|
||||
|
||||
type ServerConfig {
|
||||
name: String
|
||||
version: String
|
||||
supportsPredefinedConnections: Boolean
|
||||
supportsProvidedConnections: Boolean
|
||||
supportsCustomConnections: Boolean
|
||||
supportsConnectionBrowser: Boolean
|
||||
supportsWorkspaces: Boolean
|
||||
supportedLanguages: [ ServerLanguage ]
|
||||
services: [ WebServiceConfig ]
|
||||
}
|
||||
|
||||
type SessionInfo {
|
||||
id: ID!
|
||||
|
||||
createTime: String
|
||||
lastAccessTime: String
|
||||
locale: String
|
||||
|
||||
serverMessages: [ ServerMessage ]
|
||||
connections: [ ConnectionInfo ]
|
||||
}
|
||||
|
||||
####################################################
|
||||
# Drivers and connections
|
||||
####################################################
|
||||
|
||||
type DriverInfo {
|
||||
id: ID!
|
||||
name: String
|
||||
description: String
|
||||
icon: String
|
||||
iconBig: String
|
||||
|
||||
# Driver provider ID
|
||||
providerId: ID
|
||||
# Driver Java class name
|
||||
driverClassName: String
|
||||
defaultPort: String
|
||||
sampleURL: String
|
||||
driverInfoURL: String
|
||||
driverPropertiesURL: String
|
||||
embedded: Boolean
|
||||
anonymousAccess: Boolean
|
||||
allowsEmptyPassword: Boolean
|
||||
licenseRequired: Boolean
|
||||
license: String
|
||||
custom: Boolean
|
||||
# Driver score for ordering, biggest first
|
||||
promotedScore: Int
|
||||
|
||||
connectionProperties: Object
|
||||
defaultConnectionProperties: Object
|
||||
# Driver properties.
|
||||
# Note: it is expensive property and it may produce database server roundtrips.
|
||||
# Call it only when you really need it.
|
||||
driverProperties: [DriverPropertyInfo]
|
||||
driverParameters: Object
|
||||
}
|
||||
|
||||
type DriverPropertyInfo {
|
||||
id: ID!
|
||||
displayName: String
|
||||
description: String
|
||||
category: String
|
||||
dataType: String
|
||||
defaultValue: Object
|
||||
validValues: [ Object ]
|
||||
}
|
||||
|
||||
# Data source info is a description of some remote database. Doesn't include user credentials
|
||||
type DataSourceInfo {
|
||||
id: ID!
|
||||
driverId: ID!
|
||||
name: String!
|
||||
description: String
|
||||
|
||||
host: String
|
||||
server: String
|
||||
port: String
|
||||
url: String
|
||||
properties: String
|
||||
}
|
||||
|
||||
# Configuration of particular connection. Used for new connection create. Includes auth info
|
||||
input ConnectionConfig {
|
||||
name: String
|
||||
description: String
|
||||
|
||||
# ID of predefined datasource
|
||||
dataSourceId: ID
|
||||
|
||||
# Custom connection parameters (all optional)
|
||||
|
||||
# Driver ID
|
||||
driverId: ID
|
||||
# Host
|
||||
host: String
|
||||
# Port
|
||||
port: String
|
||||
# Databae name
|
||||
databaseName: String
|
||||
# Databae name
|
||||
url: String
|
||||
# Properties
|
||||
properties: Object
|
||||
|
||||
# User credentials
|
||||
|
||||
userName: String
|
||||
userPassword: String
|
||||
}
|
||||
|
||||
# Connection instance
|
||||
type ConnectionInfo {
|
||||
id: ID!
|
||||
driverId: ID!
|
||||
|
||||
name: String!
|
||||
description: String
|
||||
properties: String
|
||||
|
||||
connected: Boolean!
|
||||
provided: Boolean!
|
||||
connectTime: String
|
||||
connectionError: ServerError
|
||||
serverVersion: String
|
||||
clientVersion: String
|
||||
|
||||
# Supported features (provided etc)
|
||||
features: [ String! ]
|
||||
}
|
||||
|
||||
####################################################
|
||||
# Nodes, objects and properties
|
||||
####################################################
|
||||
|
||||
type ObjectDescriptor {
|
||||
id: Int
|
||||
displayName: String
|
||||
fullName: String
|
||||
uniqueName: String
|
||||
description: String
|
||||
value: String
|
||||
}
|
||||
|
||||
type ObjectPropertyInfo {
|
||||
# ID
|
||||
id: String
|
||||
# Human readable name
|
||||
displayName: String
|
||||
# Property description
|
||||
description: String
|
||||
# Property category (may be used if object has a lot of properties)
|
||||
category: String
|
||||
# Property data type (int, String, etc)
|
||||
dataType: String
|
||||
|
||||
# Property value. Note: for some properties value reading may take a lot of time (e.g. RowCount for tables)
|
||||
value: Object
|
||||
|
||||
# List of values this property can take. Makes sense only for enumerable properties
|
||||
validValues: [ Object ]
|
||||
# Supported features (system, hidden, inherited, foreign, expensive, etc)
|
||||
features: [ String! ]
|
||||
}
|
||||
|
||||
input ObjectPropertyFilter {
|
||||
ids: [String]
|
||||
features: [String]
|
||||
categories: [String]
|
||||
dataTypes: [String]
|
||||
}
|
||||
|
||||
type DatabaseObjectInfo {
|
||||
# Object name
|
||||
name: String
|
||||
# Description - optional
|
||||
description: String
|
||||
# Object type. Java class name in most cases
|
||||
type: String
|
||||
|
||||
# Read object properties.
|
||||
# Optional parameter 'ids' filters properties by id. null means all properties.
|
||||
# Note: property value reading may take a lot of time so don't read all property values always
|
||||
# Examine property meta (features in particular) before reading them
|
||||
properties(filter: ObjectPropertyFilter): [ ObjectPropertyInfo ]
|
||||
|
||||
# Optional properties
|
||||
|
||||
ordinalPosition: Int
|
||||
fullyQualifiedName: String
|
||||
overloadedName: String
|
||||
uniqueName: String
|
||||
state: String
|
||||
|
||||
# Features: script, scriptExtended, dataContainer, dataManipulator, entity, schema, catalog
|
||||
features: [ String ]
|
||||
|
||||
# Supported editors: ddl, permissions, sourceDeclaration, sourceDefinition
|
||||
editors: [ String ]
|
||||
}
|
||||
|
||||
type NavigatorNodeInfo {
|
||||
# Node ID - generally a full path to the node from root of tree
|
||||
id: ID!
|
||||
# Node human readable name
|
||||
name: String
|
||||
# Node icon path
|
||||
icon: String
|
||||
# Node description
|
||||
description: String
|
||||
# Node type
|
||||
nodeType: String
|
||||
# Can this property have child nodes?
|
||||
hasChildren: Boolean
|
||||
|
||||
# Associated object. Maybe null for non-database objects
|
||||
object: DatabaseObjectInfo
|
||||
|
||||
# Supported features: item, container, leaf
|
||||
features: [ String ]
|
||||
|
||||
folder: Boolean
|
||||
inline: Boolean
|
||||
navigable: Boolean
|
||||
}
|
||||
|
||||
####################################################
|
||||
# SQL helpers
|
||||
####################################################
|
||||
|
||||
type SQLDialectInfo {
|
||||
name: String
|
||||
|
||||
dataTypes: [ String ]
|
||||
functions: [ String ]
|
||||
reservedWords: [ String ]
|
||||
quoteStrings: [ [ String ] ]
|
||||
singleLineComments: [ String ]
|
||||
multiLineComments: [ [ String ] ]
|
||||
|
||||
catalogSeparator: String
|
||||
structSeparator: String
|
||||
scriptDelimiter: String
|
||||
|
||||
}
|
||||
|
||||
type SQLCompletionProposal {
|
||||
displayString: String
|
||||
type: String
|
||||
score: Int
|
||||
|
||||
replacementString: String
|
||||
replacementOffset: Int
|
||||
replacementLength: Int
|
||||
cursorPosition: Int
|
||||
|
||||
icon: String
|
||||
nodePath: String
|
||||
}
|
||||
|
||||
####################################################
|
||||
# Data read / SQL execution
|
||||
####################################################
|
||||
|
||||
# SQL context must be created for each SQL editor
|
||||
type SQLContextInfo {
|
||||
|
||||
id: ID!
|
||||
defaultCatalog: String
|
||||
defaultSchema: String
|
||||
|
||||
}
|
||||
|
||||
type DatabaseStructContainers {
|
||||
|
||||
catalogList: [ DatabaseObjectInfo! ]!
|
||||
schemaList: [ DatabaseObjectInfo! ]!
|
||||
|
||||
}
|
||||
|
||||
input SQLDataFilterConstraint {
|
||||
attribute: String!
|
||||
orderPosition: Int
|
||||
orderAsc: Boolean
|
||||
|
||||
criteria: String
|
||||
operator: String
|
||||
value: Object
|
||||
}
|
||||
|
||||
input SQLDataFilter {
|
||||
|
||||
offset: Int
|
||||
limit: Int
|
||||
|
||||
constraints: [ SQLDataFilterConstraint ]
|
||||
where: String
|
||||
}
|
||||
|
||||
type SQLResultColumn {
|
||||
position: Int
|
||||
name: String
|
||||
label: String
|
||||
icon: String
|
||||
entityName: String
|
||||
|
||||
dataKind: String
|
||||
typeName: String
|
||||
fullTypeName: String
|
||||
maxLength: Int
|
||||
scale: Int
|
||||
precision: Int
|
||||
}
|
||||
|
||||
type SQLResultSet {
|
||||
id: ID!
|
||||
columns: [ SQLResultColumn ]
|
||||
rows: [ [ Object ] ]
|
||||
# server always returns hasMoreData = false
|
||||
hasMoreData: Boolean
|
||||
}
|
||||
|
||||
type SQLQueryResults {
|
||||
title: String
|
||||
updateRowCount: Int
|
||||
sourceQuery: String
|
||||
|
||||
resultSet: SQLResultSet
|
||||
}
|
||||
|
||||
type SQLExecuteInfo {
|
||||
|
||||
statusMessage: String
|
||||
duration: Int
|
||||
results: [ SQLQueryResults! ]
|
||||
}
|
||||
|
||||
type LogEntry {
|
||||
time: DateTime
|
||||
type: String!
|
||||
message: String
|
||||
stackTrace: String
|
||||
}
|
||||
|
||||
####################################################
|
||||
# Main API
|
||||
####################################################
|
||||
|
||||
type Query {
|
||||
# Returns server config
|
||||
serverConfig: ServerConfig
|
||||
|
||||
# Returns session state ( initialize if not )
|
||||
sessionState: SessionInfo
|
||||
|
||||
# Get driver info
|
||||
driverList( id: ID ): [ DriverInfo! ]
|
||||
|
||||
# Get list of predefined data sources
|
||||
dataSourceList: [ DataSourceInfo! ]
|
||||
|
||||
# Return connection state
|
||||
connectionState( id: ID! ): ConnectionInfo
|
||||
|
||||
readSessionLog(maxEntries: Int, clearEntries: Boolean): [ LogEntry! ]
|
||||
|
||||
# Get child nodes
|
||||
navNodeChildren(
|
||||
parentPath: ID!,
|
||||
offset: Int,
|
||||
limit: Int,
|
||||
onlyFolders: Boolean): [ NavigatorNodeInfo! ]
|
||||
|
||||
navNodeInfo( nodePath: ID! ): NavigatorNodeInfo
|
||||
|
||||
navRefreshNode( nodePath: ID! ): Boolean
|
||||
|
||||
navGetStructContainers( connectionId: ID!, catalog: ID ): DatabaseStructContainers!
|
||||
|
||||
sqlDialectInfo( connectionId: ID! ): SQLDialectInfo
|
||||
|
||||
sqlListContexts( connectionId: ID! ): [ SQLContextInfo ]
|
||||
|
||||
sqlCompletionProposals(
|
||||
connectionId: ID!,
|
||||
contextId: ID!,
|
||||
query: String!,
|
||||
position: Int!,
|
||||
maxResults: Int
|
||||
): [ SQLCompletionProposal ]
|
||||
|
||||
}
|
||||
|
||||
type Mutation {
|
||||
# Initialize session
|
||||
openSession: SessionInfo
|
||||
|
||||
# Destroy session
|
||||
closeSession: Boolean
|
||||
|
||||
# Refreshes session on server and returns its state
|
||||
touchSession: Boolean
|
||||
|
||||
# Refreshes session on server and returns its state
|
||||
changeSessionLanguage(locale: String): Boolean
|
||||
|
||||
# Create new connection
|
||||
createConnection( config: ConnectionConfig! ): ConnectionInfo
|
||||
|
||||
# Test connection configuration. Returns remote server version
|
||||
testConnection( config: ConnectionConfig! ): ConnectionInfo
|
||||
|
||||
# Connect to database
|
||||
openConnection( config: ConnectionConfig! ): ConnectionInfo
|
||||
|
||||
# Disconnect from database
|
||||
closeConnection( id: ID! ): Boolean!
|
||||
|
||||
sqlContextCreate( connectionId: ID!, defaultCatalog: String, defaultSchema: String ): SQLContextInfo!
|
||||
|
||||
sqlContextSetDefaults( connectionId: ID!, contextId: ID!, defaultCatalog: ID, defaultSchema: ID ): Boolean!
|
||||
|
||||
sqlContextDestroy( connectionId: ID!, contextId: ID! ): Boolean!
|
||||
|
||||
sqlExecuteQuery(
|
||||
connectionId: ID!,
|
||||
contextId: ID!,
|
||||
sql: String!,
|
||||
filter: SQLDataFilter
|
||||
): SQLExecuteInfo
|
||||
|
||||
sqlResultClose(connectionId: ID!, contextId: ID!, resultId: ID!): Boolean!
|
||||
|
||||
readDataFromContainer(
|
||||
connectionId: ID!,
|
||||
contextId: ID!,
|
||||
containerNodePath: ID!,
|
||||
filter: SQLDataFilter
|
||||
): SQLExecuteInfo
|
||||
|
||||
updateResultsData(
|
||||
connectionId: ID!,
|
||||
contextId: ID!,
|
||||
resultsId: ID!,
|
||||
|
||||
updateRow: [ Object ]!,
|
||||
# Map<Int,Object>
|
||||
updateValues: Object
|
||||
): SQLExecuteInfo
|
||||
|
||||
### Async API
|
||||
|
||||
# Returns SQLExecuteInfo
|
||||
asyncSqlExecuteQuery(
|
||||
connectionId: ID!,
|
||||
contextId: ID!,
|
||||
sql: String!,
|
||||
filter: SQLDataFilter
|
||||
): AsyncTaskInfo!
|
||||
|
||||
#### Generic async functions
|
||||
|
||||
asyncTaskCancel(id: String!): Boolean
|
||||
|
||||
asyncTaskStatus(id: String!): AsyncTaskInfo!
|
||||
|
||||
}
|
||||
|
||||
####################################################
|
||||
# Schema
|
||||
####################################################
|
||||
|
||||
schema {
|
||||
query: Query
|
||||
mutation: Mutation
|
||||
}
|
||||
@@ -0,0 +1,129 @@
|
||||
/*
|
||||
* DBeaver - Universal Database Manager
|
||||
* Copyright (C) 2010-2020 DBeaver Corp and others
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
package io.cloudbeaver;
|
||||
|
||||
import graphql.ErrorClassification;
|
||||
import graphql.ErrorType;
|
||||
import graphql.GraphQLError;
|
||||
import graphql.language.SourceLocation;
|
||||
import io.cloudbeaver.server.graphql.GraphQLEndpoint;
|
||||
import org.jkiss.dbeaver.DBException;
|
||||
import org.jkiss.dbeaver.model.DBPDataSource;
|
||||
import org.jkiss.dbeaver.utils.GeneralUtils;
|
||||
import org.jkiss.utils.CommonUtils;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* The activator class controls the plug-in life cycle
|
||||
*/
|
||||
public class DBWebException extends DBException implements GraphQLError {
|
||||
|
||||
public static final String ERROR_CODE_SESSION_EXPIRED = "sessionExpired";
|
||||
|
||||
private List<Object> path;
|
||||
private List<SourceLocation> locations;
|
||||
private String webErrorCode;
|
||||
|
||||
public DBWebException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public DBWebException(String message, String errorCode) {
|
||||
super(message);
|
||||
this.webErrorCode = errorCode;
|
||||
}
|
||||
|
||||
public DBWebException(String message, Throwable cause) {
|
||||
super(makeMessage(message, cause), cause);
|
||||
}
|
||||
|
||||
public DBWebException(Throwable cause, DBPDataSource dataSource) {
|
||||
super(cause, dataSource);
|
||||
}
|
||||
|
||||
public DBWebException(String message, Throwable cause, DBPDataSource dataSource) {
|
||||
super(makeMessage(message, cause), cause, dataSource);
|
||||
}
|
||||
|
||||
public String getWebErrorCode() {
|
||||
return webErrorCode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Object> getPath() {
|
||||
return path;
|
||||
}
|
||||
|
||||
public void setPath(List<Object> path) {
|
||||
this.path = path;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SourceLocation> getLocations() {
|
||||
return locations;
|
||||
}
|
||||
|
||||
public void setLocations(List<SourceLocation> locations) {
|
||||
this.locations = locations;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ErrorClassification getErrorType() {
|
||||
return ErrorType.DataFetchingException;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> getExtensions() {
|
||||
StringWriter buf = new StringWriter();
|
||||
GeneralUtils.getRootCause(this).printStackTrace(new PrintWriter(buf, true));
|
||||
|
||||
Map<String, Object> extensions = new LinkedHashMap<>();
|
||||
String stString = buf.toString();
|
||||
int divPos = stString.indexOf(GraphQLEndpoint.class.getName());
|
||||
if (divPos != -1) {
|
||||
stString = stString.substring(0, divPos);
|
||||
divPos = stString.lastIndexOf(")");
|
||||
if (divPos != -1) {
|
||||
stString = stString.substring(0, divPos + 1);
|
||||
}
|
||||
}
|
||||
extensions.put("stackTrace", stString);
|
||||
int errorCode = getErrorCode();
|
||||
if (errorCode != ERROR_CODE_NONE) {
|
||||
extensions.put("errorCode", errorCode);
|
||||
}
|
||||
if (!CommonUtils.isEmpty(webErrorCode)) {
|
||||
extensions.put("webErrorCode", webErrorCode);
|
||||
}
|
||||
String databaseState = getDatabaseState();
|
||||
if (databaseState != null) {
|
||||
extensions.put("databaseState", databaseState);
|
||||
}
|
||||
|
||||
return extensions;
|
||||
}
|
||||
|
||||
private static String makeMessage(String message, Throwable cause) {
|
||||
return message + ":\n" + cause.getMessage();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* DBeaver - Universal Database Manager
|
||||
* Copyright (C) 2010-2020 DBeaver Corp and others
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
package io.cloudbeaver;
|
||||
|
||||
import org.jkiss.code.NotNull;
|
||||
import org.jkiss.dbeaver.Log;
|
||||
import org.jkiss.dbeaver.model.DBPImage;
|
||||
import org.jkiss.dbeaver.model.app.DBPDataSourceRegistry;
|
||||
import org.jkiss.dbeaver.model.connection.DBPDriver;
|
||||
import org.jkiss.dbeaver.registry.DataSourceProviderDescriptor;
|
||||
import org.jkiss.dbeaver.registry.DataSourceProviderRegistry;
|
||||
import org.jkiss.dbeaver.registry.driver.DriverDescriptor;
|
||||
import org.jkiss.dbeaver.runtime.DBWorkbench;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
||||
/**
|
||||
* Various constants
|
||||
*/
|
||||
public class WebServiceUtils {
|
||||
|
||||
private static final Log log = Log.getLog(WebServiceUtils.class);
|
||||
|
||||
public static String makeIconId(DBPImage icon) {
|
||||
return icon.getLocation();
|
||||
}
|
||||
|
||||
public static String makeDriverFullId(DBPDriver driver) {
|
||||
return driver.getProviderId() + ":" + driver.getId();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static DBPDriver getDriverById(String id) throws DBWebException {
|
||||
int divPos = id.indexOf(':');
|
||||
if (divPos < 0) {
|
||||
throw new DBWebException("Bad driver id [" + id + "]");
|
||||
}
|
||||
String dsId = id.substring(0, divPos);
|
||||
String driverId = id.substring(divPos + 1);
|
||||
DataSourceProviderDescriptor dsProvider = DataSourceProviderRegistry.getInstance().getDataSourceProvider(dsId);
|
||||
if (dsProvider == null) {
|
||||
throw new DBWebException("Data source provider '" + dsId + "' not found");
|
||||
}
|
||||
DriverDescriptor driver = dsProvider.getDriver(driverId);
|
||||
if (driver == null) {
|
||||
throw new DBWebException("Driver '" + driverId + "' not found in provider '" + dsId + "'");
|
||||
}
|
||||
return driver;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static DBPDataSourceRegistry getDataSourceRegistry() throws DBWebException {
|
||||
DBPDataSourceRegistry registry = DBWorkbench.getPlatform().getWorkspace().getDefaultDataSourceRegistry();
|
||||
if (registry == null) {
|
||||
throw new DBWebException("No activate data source registry");
|
||||
}
|
||||
return registry;
|
||||
}
|
||||
|
||||
public static InputStream openStaticResource(String path) {
|
||||
return WebServiceUtils.class.getClassLoader().getResourceAsStream(path);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* DBeaver - Universal Database Manager
|
||||
* Copyright (C) 2010-2020 DBeaver Corp and others
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
package io.cloudbeaver.api;
|
||||
|
||||
import graphql.schema.idl.TypeRuntimeWiring;
|
||||
import io.cloudbeaver.server.CloudbeaverPlatform;
|
||||
import io.cloudbeaver.server.model.session.WebSessionManager;
|
||||
|
||||
/**
|
||||
* Web service implementation
|
||||
*/
|
||||
public interface DBWModel {
|
||||
|
||||
CloudbeaverPlatform getPlatform();
|
||||
|
||||
WebSessionManager getSessionManager();
|
||||
|
||||
TypeRuntimeWiring.Builder getQueryType();
|
||||
|
||||
TypeRuntimeWiring.Builder getMutationType();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* DBeaver - Universal Database Manager
|
||||
* Copyright (C) 2010-2020 DBeaver Corp and others
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
package io.cloudbeaver.api;
|
||||
|
||||
/**
|
||||
* Web service implementation
|
||||
*/
|
||||
public interface DBWService {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* DBeaver - Universal Database Manager
|
||||
* Copyright (C) 2010-2020 DBeaver Corp and others
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
package io.cloudbeaver.api;
|
||||
|
||||
import graphql.schema.idl.TypeDefinitionRegistry;
|
||||
import io.cloudbeaver.DBWebException;
|
||||
|
||||
/**
|
||||
* Web service implementation
|
||||
*/
|
||||
public interface DBWServiceGraphQL extends DBWService {
|
||||
|
||||
TypeDefinitionRegistry getTypeDefinition() throws DBWebException;
|
||||
|
||||
void bindWiring(DBWModel model) throws DBWebException;
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* DBeaver - Universal Database Manager
|
||||
* Copyright (C) 2010-2020 DBeaver Corp and others
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
package io.cloudbeaver.api;
|
||||
|
||||
import graphql.GraphQLContext;
|
||||
import graphql.schema.DataFetchingEnvironment;
|
||||
import io.cloudbeaver.DBWebException;
|
||||
import io.cloudbeaver.server.model.session.WebSessionManager;
|
||||
import io.cloudbeaver.server.model.sql.WebSQLContextInfo;
|
||||
import io.cloudbeaver.server.model.sql.WebSQLProcessor;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
/**
|
||||
* Web utils
|
||||
*/
|
||||
public class DBWUtils {
|
||||
|
||||
public static WebSQLProcessor getSQLProcessor(WebSessionManager sessionManager, DataFetchingEnvironment env) throws DBWebException {
|
||||
return sessionManager.getWebSession(getServletRequest(env)).getSQLProcessor(env.getArgument("connectionId"));
|
||||
}
|
||||
|
||||
public static WebSQLContextInfo getSQLContext(WebSessionManager sessionManager, DataFetchingEnvironment env) throws DBWebException {
|
||||
WebSQLProcessor processor = getSQLProcessor(sessionManager, env);
|
||||
String contextId = env.getArgument("contextId");
|
||||
WebSQLContextInfo context = processor.getContext(contextId);
|
||||
if (context == null) {
|
||||
throw new DBWebException("SQL context '" + contextId + "' not found");
|
||||
}
|
||||
return context;
|
||||
}
|
||||
|
||||
public static HttpServletRequest getServletRequest(DataFetchingEnvironment env) {
|
||||
GraphQLContext context = env.getContext();
|
||||
HttpServletRequest request = context.get("request");
|
||||
if (request == null) {
|
||||
throw new IllegalStateException("Null request");
|
||||
}
|
||||
return request;
|
||||
}
|
||||
}
|
||||
+244
@@ -0,0 +1,244 @@
|
||||
/*
|
||||
* DBeaver - Universal Database Manager
|
||||
* Copyright (C) 2010-2020 DBeaver Corp and others
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
package io.cloudbeaver.server;
|
||||
|
||||
import io.cloudbeaver.server.jetty.CloudbeaverJettyServer;
|
||||
import org.eclipse.core.runtime.Platform;
|
||||
import org.eclipse.equinox.app.IApplicationContext;
|
||||
import org.eclipse.osgi.service.datalocation.Location;
|
||||
import org.jkiss.code.NotNull;
|
||||
import org.jkiss.dbeaver.Log;
|
||||
import org.jkiss.dbeaver.ModelPreferences;
|
||||
import org.jkiss.dbeaver.model.app.DBPApplication;
|
||||
import org.jkiss.dbeaver.registry.BaseApplicationImpl;
|
||||
import org.jkiss.dbeaver.runtime.DBWorkbench;
|
||||
import org.jkiss.dbeaver.utils.GeneralUtils;
|
||||
import org.jkiss.dbeaver.utils.PrefUtils;
|
||||
import org.jkiss.dbeaver.utils.SystemVariablesResolver;
|
||||
import org.jkiss.utils.CommonUtils;
|
||||
import org.jkiss.utils.StandardConstants;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URL;
|
||||
import java.util.Properties;
|
||||
|
||||
/**
|
||||
* This class controls all aspects of the application's execution
|
||||
*/
|
||||
public class CloudbeaverApplication extends BaseApplicationImpl {
|
||||
|
||||
private static final Log log = Log.getLog(CloudbeaverApplication.class);
|
||||
|
||||
public static final String APPLICATION_PLUGIN_ID = "io.cloudbeaver.server";
|
||||
|
||||
private int serverPort = CloudbeaverConstants.DEFAULT_SERVER_PORT;
|
||||
private String serverName = CloudbeaverConstants.DEFAULT_SERVER_NAME;
|
||||
private String contentRoot = CloudbeaverConstants.DEFAULT_CONTENT_ROOT;
|
||||
private String rootURI = CloudbeaverConstants.DEFAULT_ROOT_URI;
|
||||
private String servicesURI = CloudbeaverConstants.DEFAULT_SERVICES_URI;
|
||||
|
||||
private String workspaceLocation = CloudbeaverConstants.DEFAULT_WORKSPACE_LOCATION;
|
||||
private String driversLocation = CloudbeaverConstants.DEFAULT_DRIVERS_LOCATION;
|
||||
|
||||
private long maxSessionIdleTime = CloudbeaverConstants.MAX_SESSION_IDLE_TIME;
|
||||
|
||||
private boolean develMode = false;
|
||||
|
||||
public CloudbeaverApplication() {
|
||||
}
|
||||
|
||||
public int getServerPort() {
|
||||
return serverPort;
|
||||
}
|
||||
|
||||
public String getServerName() {
|
||||
return serverName;
|
||||
}
|
||||
|
||||
public String getContentRoot() {
|
||||
return contentRoot;
|
||||
}
|
||||
|
||||
public String getRootURI() {
|
||||
return rootURI;
|
||||
}
|
||||
|
||||
public String getServicesURI() {
|
||||
return servicesURI;
|
||||
}
|
||||
|
||||
public String getDriversLocation() {
|
||||
return driversLocation;
|
||||
}
|
||||
|
||||
public long getMaxSessionIdleTime() {
|
||||
return maxSessionIdleTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets singleton instance of DBeaver application
|
||||
*
|
||||
* @return application or null if application wasn't started or was stopped.
|
||||
*/
|
||||
public static CloudbeaverApplication getInstance() {
|
||||
return (CloudbeaverApplication) BaseApplicationImpl.getInstance();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isHeadlessMode() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object start(IApplicationContext context) {
|
||||
String configPath = CloudbeaverConstants.DEFAULT_CONFIG_FILE_PATH;
|
||||
|
||||
String[] args = Platform.getCommandLineArgs();
|
||||
for (int i = 0; i < args.length; i++) {
|
||||
if (args[i].equals(CloudbeaverConstants.CLI_PARAM_WEB_CONFIG) & args.length > i + 1) {
|
||||
configPath = args[i + 1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
loadConfiguration(configPath);
|
||||
|
||||
final Runtime runtime = Runtime.getRuntime();
|
||||
|
||||
Location instanceLoc = Platform.getInstanceLocation();
|
||||
try {
|
||||
if (!instanceLoc.isSet()) {
|
||||
URL wsLocationURL = new URL(
|
||||
"file", //$NON-NLS-1$
|
||||
null,
|
||||
workspaceLocation);
|
||||
instanceLoc.set(wsLocationURL, true);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.debug("Error setting workspace location to " + workspaceLocation, e);
|
||||
}
|
||||
|
||||
CloudbeaverPlatform.setApplication(this);
|
||||
|
||||
log.debug(GeneralUtils.getProductName() + " " + GeneralUtils.getProductVersion() + " is starting"); //$NON-NLS-1$
|
||||
log.debug("\tOS: " + System.getProperty(StandardConstants.ENV_OS_NAME) + " " + System.getProperty(StandardConstants.ENV_OS_VERSION) + " (" + System.getProperty(StandardConstants.ENV_OS_ARCH) + ")");
|
||||
log.debug("\tJava version: " + System.getProperty(StandardConstants.ENV_JAVA_VERSION) + " by " + System.getProperty(StandardConstants.ENV_JAVA_VENDOR) + " (" + System.getProperty(StandardConstants.ENV_JAVA_ARCH) + "bit)");
|
||||
log.debug("\tInstall path: '" + SystemVariablesResolver.getInstallPath() + "'"); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
log.debug("\tGlobal workspace: '" + instanceLoc.getURL() + "'"); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
log.debug("\tMemory available " + (runtime.totalMemory() / (1024 * 1024)) + "Mb/" + (runtime.maxMemory() / (1024 * 1024)) + "Mb");
|
||||
|
||||
DBPApplication application = DBWorkbench.getPlatform().getApplication();
|
||||
|
||||
log.debug("\tContent root: " + contentRoot);
|
||||
//log.debug("\tDrivers root: " + driversLocation);
|
||||
log.debug("\tProduct details: " + application.getInfoDetails());
|
||||
log.debug("\tBase port: " + serverPort);
|
||||
log.debug("\tBase URI: " + servicesURI);
|
||||
if (develMode) {
|
||||
log.debug("\tDevelopment mode");
|
||||
} else {
|
||||
log.debug("\tProduction mode");
|
||||
}
|
||||
|
||||
runWebServer();
|
||||
|
||||
log.debug("Shutdown");
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private void loadConfiguration(String configPath) {
|
||||
log.debug("Using configuration " + configPath);
|
||||
|
||||
File configFile = new File(configPath);
|
||||
if (!configFile.exists()) {
|
||||
log.debug("Configuration file " + configPath + " doesn't exist. Use defaults.");
|
||||
} else {
|
||||
Properties props = new Properties();
|
||||
try (InputStream is = new FileInputStream(configFile)) {
|
||||
props.load(is);
|
||||
parseConfiguration(props);
|
||||
} catch (IOException e) {
|
||||
log.debug("Error reading config file", e);
|
||||
}
|
||||
}
|
||||
// Set default preferences
|
||||
PrefUtils.setDefaultPreferenceValue(ModelPreferences.getPreferences(), ModelPreferences.UI_DRIVERS_HOME, getDriversLocation());
|
||||
}
|
||||
|
||||
private void parseConfiguration(Properties props) {
|
||||
serverPort = CommonUtils.toInt(getConfigParameter(props, CloudbeaverConstants.PARAM_SERVER_PORT, String.valueOf(CloudbeaverConstants.DEFAULT_SERVER_PORT)));
|
||||
serverName = getConfigParameter(props, CloudbeaverConstants.PARAM_SERVER_NAME, CloudbeaverConstants.DEFAULT_SERVER_NAME);
|
||||
contentRoot = getConfigParameter(props, CloudbeaverConstants.PARAM_CONTENT_ROOT, CloudbeaverConstants.DEFAULT_CONTENT_ROOT);
|
||||
rootURI = getConfigParameter(props, CloudbeaverConstants.PARAM_ROOT_URI, CloudbeaverConstants.DEFAULT_ROOT_URI);
|
||||
servicesURI = getConfigParameter(props, CloudbeaverConstants.PARAM_SERVICES_URI, CloudbeaverConstants.DEFAULT_SERVICES_URI);
|
||||
driversLocation = getConfigParameter(props, CloudbeaverConstants.PARAM_DRIVERS_LOCATION, CloudbeaverConstants.DEFAULT_DRIVERS_LOCATION);
|
||||
workspaceLocation = getConfigParameter(props, CloudbeaverConstants.PARAM_WORKSPACE_LOCATION, CloudbeaverConstants.DEFAULT_WORKSPACE_LOCATION);
|
||||
|
||||
maxSessionIdleTime = getConfigParameter(props, CloudbeaverConstants.PARAM_SESSION_EXPIRE_PERIOD, CloudbeaverConstants.MAX_SESSION_IDLE_TIME);
|
||||
|
||||
develMode = CommonUtils.toBoolean(getConfigParameter(props, CloudbeaverConstants.PARAM_DEVEL_MODE, "false"));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private String getConfigParameter(@NotNull Properties props, @NotNull String paramName, @NotNull String defValue) {
|
||||
String property = props.getProperty(paramName);
|
||||
if (property == null) {
|
||||
property = defValue;
|
||||
}
|
||||
return property;
|
||||
}
|
||||
|
||||
private long getConfigParameter(@NotNull Properties props, @NotNull String paramName, long defValue) {
|
||||
String property = props.getProperty(paramName);
|
||||
if (property == null) {
|
||||
return defValue;
|
||||
}
|
||||
return CommonUtils.toLong(property, defValue);
|
||||
}
|
||||
|
||||
private void runWebServer() {
|
||||
log.debug("Starting Jetty server (" + serverPort + ") ");
|
||||
new CloudbeaverJettyServer().runServer();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void stop() {
|
||||
shutdown();
|
||||
}
|
||||
|
||||
private void shutdown() {
|
||||
log.debug("Cloudbeaver Server is stopping"); //$NON-NLS-1$
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getInfoDetails() {
|
||||
return serverName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDefaultProjectName() {
|
||||
return "GlobalConfiguration";
|
||||
}
|
||||
|
||||
public boolean isDevelMode() {
|
||||
return develMode;
|
||||
}
|
||||
}
|
||||
+60
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* DBeaver - Universal Database Manager
|
||||
* Copyright (C) 2010-2020 DBeaver Corp and others
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
package io.cloudbeaver.server;
|
||||
|
||||
import org.jkiss.dbeaver.model.DBConstants;
|
||||
|
||||
import java.text.DateFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
|
||||
/**
|
||||
* Various constants
|
||||
*/
|
||||
public class CloudbeaverConstants {
|
||||
|
||||
public static final DateFormat ISO_DATE_FORMAT = new SimpleDateFormat(DBConstants.DEFAULT_ISO_TIMESTAMP_FORMAT);
|
||||
|
||||
public static final String DEFAULT_CONFIG_FILE_PATH = "/etc/cloudbeaver.conf";
|
||||
|
||||
public static final String CLI_PARAM_WEB_CONFIG = "-web-config";
|
||||
|
||||
public static final String PARAM_SERVER_PORT = "ServerPort";
|
||||
public static final String PARAM_SERVER_NAME = "ServerName";
|
||||
public static final String PARAM_CONTENT_ROOT = "ContentRoot";
|
||||
public static final String PARAM_ROOT_URI = "RootURI";
|
||||
public static final String PARAM_SERVICES_URI = "ServiceURI";
|
||||
public static final String PARAM_DRIVERS_LOCATION = "DriversLocation";
|
||||
public static final String PARAM_WORKSPACE_LOCATION = "WorkspaceLocation";
|
||||
|
||||
public static final String PARAM_SESSION_EXPIRE_PERIOD = "ExpireSessionAfterPeriod";
|
||||
|
||||
public static final String PARAM_DEVEL_MODE = "DevelMode";
|
||||
|
||||
public static final int DEFAULT_SERVER_PORT = 8080;
|
||||
public static final String DEFAULT_SERVER_NAME = "Cloudbeaver Web Server";
|
||||
public static final String DEFAULT_CONTENT_ROOT = "/var/www/cloudbeaver";
|
||||
public static final String DEFAULT_ROOT_URI = "/";
|
||||
public static final String DEFAULT_SERVICES_URI = "/dbeaver/";
|
||||
|
||||
public static final String DEFAULT_DEPLOY_LOCATION = "/opt/cloudbeaver";
|
||||
public static final String DEFAULT_DRIVERS_LOCATION = DEFAULT_DEPLOY_LOCATION + "/drivers";
|
||||
public static final String DEFAULT_WORKSPACE_LOCATION = DEFAULT_DEPLOY_LOCATION + "/workspace";
|
||||
|
||||
// Default max idle time (10 minutes)
|
||||
public static final long MAX_SESSION_IDLE_TIME = 10 * 60 * 1000;
|
||||
|
||||
}
|
||||
+356
@@ -0,0 +1,356 @@
|
||||
/*
|
||||
* DBeaver - Universal Database Manager
|
||||
* Copyright (C) 2010-2020 DBeaver Corp and others
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package io.cloudbeaver.server;
|
||||
|
||||
import io.cloudbeaver.DBWebException;
|
||||
import io.cloudbeaver.WebServiceUtils;
|
||||
import io.cloudbeaver.server.model.WebDataSourceConfig;
|
||||
import io.cloudbeaver.server.model.WebServerConfig;
|
||||
import io.cloudbeaver.server.model.session.WebSessionManager;
|
||||
import io.cloudbeaver.server.registry.WebDriverRegistry;
|
||||
import org.eclipse.core.resources.ResourcesPlugin;
|
||||
import org.eclipse.core.runtime.Platform;
|
||||
import org.jkiss.code.NotNull;
|
||||
import org.jkiss.code.Nullable;
|
||||
import org.jkiss.dbeaver.DBException;
|
||||
import org.jkiss.dbeaver.Log;
|
||||
import org.jkiss.dbeaver.model.DBPDataSourceContainer;
|
||||
import org.jkiss.dbeaver.model.DBPExternalFileManager;
|
||||
import org.jkiss.dbeaver.model.app.*;
|
||||
import org.jkiss.dbeaver.model.connection.DBPDataSourceProviderDescriptor;
|
||||
import org.jkiss.dbeaver.model.connection.DBPDataSourceProviderRegistry;
|
||||
import org.jkiss.dbeaver.model.connection.DBPDriver;
|
||||
import org.jkiss.dbeaver.model.connection.DBPDriverLibrary;
|
||||
import org.jkiss.dbeaver.model.impl.app.DefaultCertificateStorage;
|
||||
import org.jkiss.dbeaver.model.preferences.DBPPreferenceStore;
|
||||
import org.jkiss.dbeaver.model.qm.QMController;
|
||||
import org.jkiss.dbeaver.model.qm.QMUtils;
|
||||
import org.jkiss.dbeaver.model.runtime.DBRProgressMonitor;
|
||||
import org.jkiss.dbeaver.model.runtime.VoidProgressMonitor;
|
||||
import org.jkiss.dbeaver.registry.BasePlatformImpl;
|
||||
import org.jkiss.dbeaver.registry.DataSourceProviderRegistry;
|
||||
import org.jkiss.dbeaver.runtime.SecurityProviderUtils;
|
||||
import org.jkiss.dbeaver.runtime.qm.QMControllerImpl;
|
||||
import org.jkiss.dbeaver.runtime.qm.QMLogFileWriter;
|
||||
import org.jkiss.dbeaver.utils.ContentUtils;
|
||||
import org.jkiss.dbeaver.utils.GeneralUtils;
|
||||
import org.jkiss.utils.CommonUtils;
|
||||
import org.jkiss.utils.StandardConstants;
|
||||
import org.osgi.framework.Bundle;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* CloudbeaverPlatform
|
||||
*/
|
||||
public class CloudbeaverPlatform extends BasePlatformImpl {
|
||||
|
||||
// The plug-in ID
|
||||
public static final String PLUGIN_ID = "io.cloudbeaver.server"; //$NON-NLS-1$
|
||||
|
||||
private static final Log log = Log.getLog(CloudbeaverPlatform.class);
|
||||
|
||||
private static final String TEMP_PROJECT_NAME = "cloudbeaver-temp";
|
||||
|
||||
static CloudbeaverPlatform instance;
|
||||
|
||||
@Nullable
|
||||
private static CloudbeaverApplication application = null;
|
||||
|
||||
private File tempFolder;
|
||||
|
||||
private QMControllerImpl queryManager;
|
||||
private QMLogFileWriter qmLogWriter;
|
||||
private DBACertificateStorage certificateStorage;
|
||||
private CloudbeaverWorkspace workspace;
|
||||
|
||||
private WebSessionManager sessionManager;
|
||||
private final List<DBPDriver> applicableDrivers = new ArrayList<>();
|
||||
|
||||
|
||||
public static CloudbeaverPlatform getInstance() {
|
||||
if (instance == null) {
|
||||
synchronized (CloudbeaverPlatform.class) {
|
||||
if (instance == null) {
|
||||
// Initialize DBeaver Core
|
||||
CloudbeaverPlatform.createInstance();
|
||||
}
|
||||
}
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
private static CloudbeaverPlatform createInstance() {
|
||||
log.debug("Initializing product: " + GeneralUtils.getProductTitle());
|
||||
if (Platform.getProduct() != null) {
|
||||
Bundle definingBundle = Platform.getProduct().getDefiningBundle();
|
||||
if (definingBundle != null) {
|
||||
log.debug("Host plugin: " + definingBundle.getSymbolicName() + " " + definingBundle.getVersion());
|
||||
} else {
|
||||
log.debug("!!! No product bundle found");
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
instance = new CloudbeaverPlatform();
|
||||
instance.initialize();
|
||||
return instance;
|
||||
} catch (Throwable e) {
|
||||
log.error("Error initializing CloudbeaverPlatform", e);
|
||||
throw new IllegalStateException("Error initializing CloudbeaverPlatform", e);
|
||||
}
|
||||
}
|
||||
|
||||
public static DBPPreferenceStore getGlobalPreferenceStore() {
|
||||
return WebPlatformActivator.getInstance().getPreferences();
|
||||
}
|
||||
|
||||
private CloudbeaverPlatform() {
|
||||
}
|
||||
|
||||
public static void setApplication(CloudbeaverApplication application) {
|
||||
CloudbeaverPlatform.application = application;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initialize() {
|
||||
long startTime = System.currentTimeMillis();
|
||||
log.debug("Initialize web platform...");
|
||||
|
||||
// Register BC security provider
|
||||
SecurityProviderUtils.registerSecurityProvider();
|
||||
|
||||
// Register properties adapter
|
||||
this.workspace = new CloudbeaverWorkspace(this, ResourcesPlugin.getWorkspace());
|
||||
this.workspace.initializeProjects();
|
||||
|
||||
QMUtils.initApplication(this);
|
||||
this.queryManager = new QMControllerImpl();
|
||||
|
||||
this.qmLogWriter = new QMLogFileWriter();
|
||||
this.queryManager.registerMetaListener(qmLogWriter);
|
||||
|
||||
// Init default network settings
|
||||
installProxySelector();
|
||||
|
||||
this.certificateStorage = new DefaultCertificateStorage(
|
||||
new File(WebPlatformActivator.getInstance().getStateLocation().toFile(), "security"));
|
||||
|
||||
super.initialize();
|
||||
|
||||
for (DBPDataSourceProviderDescriptor dspd : DataSourceProviderRegistry.getInstance().getEnabledDataSourceProviders()) {
|
||||
for (DBPDriver driver : dspd.getEnabledDrivers()) {
|
||||
if (!WebDriverRegistry.getInstance().isDriverEnabled(driver)) {
|
||||
continue;
|
||||
}
|
||||
List<? extends DBPDriverLibrary> libraries = driver.getDriverLibraries();
|
||||
if (!libraries.isEmpty()) {
|
||||
boolean hasAllFiles = true;
|
||||
for (DBPDriverLibrary lib : libraries) {
|
||||
if (!lib.isOptional() && (lib.getLocalFile() == null || !lib.getLocalFile().exists())) {
|
||||
hasAllFiles = false;
|
||||
log.error("Driver '" + driver.getId() + "' is missing library '" + lib.getDisplayName() + "'");
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (hasAllFiles) {
|
||||
applicableDrivers.add(driver);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sessionManager = WebSessionManager.getInstance();
|
||||
|
||||
new WebSessionMonitorJob(this).scheduleMonitor();
|
||||
|
||||
log.debug("Web platform initialized (" + (System.currentTimeMillis() - startTime) + "ms)");
|
||||
}
|
||||
|
||||
public synchronized void dispose() {
|
||||
long startTime = System.currentTimeMillis();
|
||||
log.debug("Shutdown Core...");
|
||||
|
||||
super.dispose();
|
||||
|
||||
if (this.qmLogWriter != null) {
|
||||
this.queryManager.unregisterMetaListener(qmLogWriter);
|
||||
this.qmLogWriter.dispose();
|
||||
this.qmLogWriter = null;
|
||||
}
|
||||
if (this.queryManager != null) {
|
||||
this.queryManager.dispose();
|
||||
//queryManager = null;
|
||||
}
|
||||
DataSourceProviderRegistry.getInstance().dispose();
|
||||
|
||||
if (workspace != null) {
|
||||
try {
|
||||
workspace.save(new VoidProgressMonitor());
|
||||
} catch (DBException ex) {
|
||||
log.error("Can't save workspace", ex); //$NON-NLS-1$
|
||||
}
|
||||
}
|
||||
|
||||
// Remove temp folder
|
||||
if (tempFolder != null) {
|
||||
|
||||
if (!ContentUtils.deleteFileRecursive(tempFolder)) {
|
||||
log.warn("Can't delete temp folder '" + tempFolder.getAbsolutePath() + "'");
|
||||
}
|
||||
tempFolder = null;
|
||||
}
|
||||
|
||||
CloudbeaverPlatform.application = null;
|
||||
CloudbeaverPlatform.instance = null;
|
||||
System.gc();
|
||||
log.debug("Shutdown completed in " + (System.currentTimeMillis() - startTime) + "ms");
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public DBPWorkspace getWorkspace() {
|
||||
return workspace;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public DBPResourceHandler getDefaultResourceHandler() {
|
||||
return CloudbeaverResourceHandler.INSTANCE;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public CloudbeaverApplication getApplication() {
|
||||
return application;
|
||||
}
|
||||
|
||||
public List<DBPDriver> getApplicableDrivers() {
|
||||
return applicableDrivers;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public DBPDataSourceProviderRegistry getDataSourceProviderRegistry() {
|
||||
return DataSourceProviderRegistry.getInstance();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public QMController getQueryManager() {
|
||||
return queryManager;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public DBPPreferenceStore getPreferenceStore() {
|
||||
return WebPlatformActivator.getInstance().getPreferences();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public DBACertificateStorage getCertificateStorage() {
|
||||
return certificateStorage;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public DBASecureStorage getSecureStorage() {
|
||||
return application.getSecureStorage();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public DBPExternalFileManager getExternalFileManager() {
|
||||
return workspace;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public File getTempFolder(DBRProgressMonitor monitor, String name) {
|
||||
if (tempFolder == null) {
|
||||
// Make temp folder
|
||||
monitor.subTask("Create temp folder");
|
||||
try {
|
||||
final java.nio.file.Path tempDirectory = Files.createTempDirectory(TEMP_PROJECT_NAME);
|
||||
tempFolder = tempDirectory.toFile();
|
||||
} catch (IOException e) {
|
||||
final String sysTempFolder = System.getProperty(StandardConstants.ENV_TMP_DIR);
|
||||
if (!CommonUtils.isEmpty(sysTempFolder)) {
|
||||
tempFolder = new File(sysTempFolder, TEMP_PROJECT_NAME);
|
||||
if (!tempFolder.mkdirs()) {
|
||||
final String sysUserFolder = System.getProperty(StandardConstants.ENV_USER_HOME);
|
||||
if (!CommonUtils.isEmpty(sysUserFolder)) {
|
||||
tempFolder = new File(sysUserFolder, TEMP_PROJECT_NAME);
|
||||
if (!tempFolder.mkdirs()) {
|
||||
tempFolder = new File(TEMP_PROJECT_NAME);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!tempFolder.exists() && !tempFolder.mkdirs()) {
|
||||
log.error("Can't create temp directory!");
|
||||
}
|
||||
return tempFolder;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public File getConfigurationFile(String fileName) {
|
||||
return WebPlatformActivator.getConfigurationFile(fileName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isShuttingDown() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public WebServerConfig getServerConfig() {
|
||||
WebServerConfig config = new WebServerConfig(
|
||||
CloudbeaverApplication.getInstance().getServerName(),
|
||||
GeneralUtils.getProductVersion().toString()
|
||||
);
|
||||
config.setSupportsPredefinedConnections(true);
|
||||
return config;
|
||||
}
|
||||
|
||||
public WebSessionManager getSessionManager() {
|
||||
return sessionManager;
|
||||
}
|
||||
|
||||
public List<WebDataSourceConfig> getGlobalDataSources() throws DBWebException {
|
||||
List<WebDataSourceConfig> result = new ArrayList<>();
|
||||
DBPDataSourceRegistry dsRegistry = WebServiceUtils.getDataSourceRegistry();
|
||||
|
||||
for (DBPDataSourceContainer ds : dsRegistry.getDataSources()) {
|
||||
if (applicableDrivers.contains(ds.getDriver()) && !ds.isProvided()) {
|
||||
result.add(new WebDataSourceConfig(ds));
|
||||
} else {
|
||||
log.debug("Global datasource '" + ds.getName() + "' ignored - driver is not applicable");
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* DBeaver - Universal Database Manager
|
||||
* Copyright (C) 2010-2020 DBeaver Corp and others
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
package io.cloudbeaver.server;
|
||||
|
||||
import org.jkiss.dbeaver.runtime.ui.console.ConsoleUserInterface;
|
||||
|
||||
/**
|
||||
* The activator class controls the plug-in life cycle
|
||||
*/
|
||||
public class CloudbeaverPlatformUI extends ConsoleUserInterface {
|
||||
|
||||
public static final CloudbeaverPlatformUI INSTANCE = new CloudbeaverPlatformUI();
|
||||
|
||||
}
|
||||
+83
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* DBeaver - Universal Database Manager
|
||||
* Copyright (C) 2010-2020 DBeaver Corp and others
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
package io.cloudbeaver.server;
|
||||
|
||||
import org.eclipse.core.resources.IFile;
|
||||
import org.eclipse.core.resources.IResource;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
import org.jkiss.code.NotNull;
|
||||
import org.jkiss.dbeaver.DBException;
|
||||
import org.jkiss.dbeaver.model.DBPDataSourceContainer;
|
||||
import org.jkiss.dbeaver.model.app.DBPResourceHandler;
|
||||
import org.jkiss.dbeaver.model.navigator.DBNNode;
|
||||
import org.jkiss.dbeaver.model.navigator.DBNResource;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Default resource handler
|
||||
*/
|
||||
public class CloudbeaverResourceHandler implements DBPResourceHandler {
|
||||
|
||||
public static final CloudbeaverResourceHandler INSTANCE = new CloudbeaverResourceHandler();
|
||||
|
||||
@Override
|
||||
public int getFeatures(IResource resource) {
|
||||
if (resource instanceof IFile) {
|
||||
return FEATURE_OPEN | FEATURE_DELETE | FEATURE_RENAME;
|
||||
} else {
|
||||
return FEATURE_DELETE | FEATURE_RENAME | FEATURE_CREATE_FOLDER | FEATURE_MOVE_INTO;
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getTypeName(@NotNull IResource resource) {
|
||||
return "resource"; //$NON-NLS-1$
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getResourceDescription(@NotNull IResource resource) {
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<DBPDataSourceContainer> getAssociatedDataSources(DBNResource resource) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getResourceNodeName(IResource resource) {
|
||||
return resource.toString();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public DBNResource makeNavigatorNode(@NotNull DBNNode parentNode, @NotNull IResource resource) throws CoreException, DBException {
|
||||
DBNResource node = new DBNResource(parentNode, resource, this);
|
||||
return node;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateNavigatorNode(@NotNull DBNResource node, @NotNull IResource resource) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void openResource(@NotNull IResource resource) throws CoreException, DBException {
|
||||
}
|
||||
|
||||
}
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* DBeaver - Universal Database Manager
|
||||
* Copyright (C) 2010-2020 DBeaver Corp and others
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
package io.cloudbeaver.server;
|
||||
|
||||
import org.eclipse.core.resources.IWorkspace;
|
||||
import org.jkiss.code.NotNull;
|
||||
import org.jkiss.dbeaver.model.app.DBPPlatform;
|
||||
import org.jkiss.dbeaver.registry.BaseWorkspaceImpl;
|
||||
|
||||
/**
|
||||
* Web workspace.
|
||||
*
|
||||
* Basically just a wrapper around Eclipse workspace.
|
||||
*/
|
||||
public class CloudbeaverWorkspace extends BaseWorkspaceImpl {
|
||||
|
||||
public CloudbeaverWorkspace(DBPPlatform platform, IWorkspace eclipseWorkspace) {
|
||||
super(platform, eclipseWorkspace);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getWorkspaceId() {
|
||||
return "web-workspace";
|
||||
}
|
||||
|
||||
}
|
||||
+110
@@ -0,0 +1,110 @@
|
||||
/*
|
||||
* DBeaver - Universal Database Manager
|
||||
* Copyright (C) 2010-2020 DBeaver Corp and others
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
package io.cloudbeaver.server;
|
||||
|
||||
import org.eclipse.core.resources.IWorkspace;
|
||||
import org.eclipse.core.resources.ResourcesPlugin;
|
||||
import org.eclipse.core.runtime.Plugin;
|
||||
import org.jkiss.dbeaver.ModelPreferences;
|
||||
import org.jkiss.dbeaver.model.impl.preferences.BundlePreferenceStore;
|
||||
import org.jkiss.dbeaver.model.preferences.DBPPreferenceStore;
|
||||
import org.osgi.framework.Bundle;
|
||||
import org.osgi.framework.BundleContext;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.PrintStream;
|
||||
|
||||
/**
|
||||
* The activator class controls the plug-in life cycle
|
||||
*/
|
||||
public class WebPlatformActivator extends Plugin {
|
||||
|
||||
// The shared instance
|
||||
private static WebPlatformActivator instance;
|
||||
private static File configDir;
|
||||
private PrintStream debugWriter;
|
||||
private DBPPreferenceStore preferences;
|
||||
|
||||
public WebPlatformActivator() {
|
||||
}
|
||||
|
||||
public static WebPlatformActivator getInstance() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start(BundleContext context)
|
||||
throws Exception {
|
||||
super.start(context);
|
||||
|
||||
instance = this;
|
||||
|
||||
Bundle bundle = getBundle();
|
||||
ModelPreferences.setMainBundle(bundle);
|
||||
preferences = new BundlePreferenceStore(bundle);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stop(BundleContext context)
|
||||
throws Exception {
|
||||
this.shutdownPlatform();
|
||||
|
||||
if (debugWriter != null) {
|
||||
debugWriter.close();
|
||||
debugWriter = null;
|
||||
}
|
||||
instance = null;
|
||||
|
||||
super.stop(context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns configuration file
|
||||
*/
|
||||
public static synchronized File getConfigurationFile(String fileName)
|
||||
{
|
||||
if (configDir == null) {
|
||||
configDir = getInstance().getStateLocation().toFile();
|
||||
}
|
||||
return new File(configDir, fileName);
|
||||
}
|
||||
|
||||
public DBPPreferenceStore getPreferences() {
|
||||
return preferences;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the workspace instance.
|
||||
*/
|
||||
public static IWorkspace getWorkspace() {
|
||||
return ResourcesPlugin.getWorkspace();
|
||||
}
|
||||
|
||||
private void shutdownPlatform() {
|
||||
try {
|
||||
// Dispose core
|
||||
if (CloudbeaverPlatform.instance != null) {
|
||||
CloudbeaverPlatform.instance.dispose();
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
System.err.println("Internal error after shutdown process:" + e.getMessage()); //$NON-NLS-1$
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* DBeaver - Universal Database Manager
|
||||
* Copyright (C) 2010-2020 DBeaver Corp and others
|
||||
* Copyright (C) 2017-2018 Alexander Fedorov (alexander.fedorov@jkiss.org)
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package io.cloudbeaver.server;
|
||||
|
||||
import org.eclipse.core.runtime.IAdapterFactory;
|
||||
import org.jkiss.dbeaver.model.app.DBPPlatform;
|
||||
import org.jkiss.dbeaver.runtime.DBWorkbench;
|
||||
import org.jkiss.dbeaver.runtime.ui.DBPPlatformUI;
|
||||
|
||||
public class WebPlatformAdapterFactory implements IAdapterFactory {
|
||||
|
||||
private static final Class<?>[] CLASSES = new Class[] { DBPPlatform.class, DBPPlatformUI.class };
|
||||
|
||||
@Override
|
||||
public <T> T getAdapter(Object adaptableObject, Class<T> adapterType) {
|
||||
if (adaptableObject instanceof DBWorkbench) {
|
||||
if (adapterType == DBPPlatform.class) {
|
||||
return adapterType.cast(CloudbeaverPlatform.getInstance());
|
||||
} else if (adapterType == DBPPlatformUI.class) {
|
||||
return adapterType.cast(CloudbeaverPlatformUI.INSTANCE);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?>[] getAdapterList() {
|
||||
return CLASSES;
|
||||
}
|
||||
|
||||
}
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* DBeaver - Universal Database Manager
|
||||
* Copyright (C) 2010-2020 DBeaver Corp and others
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package io.cloudbeaver.server;
|
||||
|
||||
import org.jkiss.dbeaver.DBException;
|
||||
import org.jkiss.dbeaver.model.DBPDataSourceContainer;
|
||||
import org.jkiss.dbeaver.model.runtime.DBRProgressListener;
|
||||
import org.jkiss.dbeaver.model.runtime.DBRProgressMonitor;
|
||||
import org.jkiss.dbeaver.runtime.DBServiceConnections;
|
||||
|
||||
/**
|
||||
* WebServiceConnectionsImpl
|
||||
*
|
||||
* Needed to instantiate connections thru navigator model.
|
||||
*/
|
||||
public class WebServiceConnectionsImpl implements DBServiceConnections {
|
||||
|
||||
@Override
|
||||
public void initConnection(DBRProgressMonitor monitor, DBPDataSourceContainer dataSourceContainer, DBRProgressListener onFinish) throws DBException {
|
||||
dataSourceContainer.connect(monitor, true, false);
|
||||
}
|
||||
}
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* DBeaver - Universal Database Manager
|
||||
* Copyright (C) 2010-2020 DBeaver Corp and others
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
package io.cloudbeaver.server;
|
||||
|
||||
import org.eclipse.core.runtime.IStatus;
|
||||
import org.eclipse.core.runtime.Status;
|
||||
import org.jkiss.dbeaver.model.runtime.AbstractJob;
|
||||
import org.jkiss.dbeaver.model.runtime.DBRProgressMonitor;
|
||||
|
||||
/**
|
||||
* WebSessionMonitorJob
|
||||
*/
|
||||
class WebSessionMonitorJob extends AbstractJob {
|
||||
private static final int MONITOR_INTERVAL = 10000; // once per 10 seconds
|
||||
|
||||
private final CloudbeaverPlatform platform;
|
||||
|
||||
WebSessionMonitorJob(CloudbeaverPlatform platform) {
|
||||
super("Web session monitor");
|
||||
setUser(false);
|
||||
setSystem(true);
|
||||
this.platform = platform;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected IStatus run(DBRProgressMonitor monitor) {
|
||||
if (platform.isShuttingDown()) {
|
||||
return Status.OK_STATUS;
|
||||
}
|
||||
|
||||
platform.getSessionManager().expireIdleSessions();
|
||||
|
||||
if (!platform.isShuttingDown()) {
|
||||
scheduleMonitor();
|
||||
}
|
||||
return Status.OK_STATUS;
|
||||
}
|
||||
|
||||
void scheduleMonitor() {
|
||||
schedule(MONITOR_INTERVAL);
|
||||
}
|
||||
|
||||
}
|
||||
+78
@@ -0,0 +1,78 @@
|
||||
package io.cloudbeaver.server.graphql;
|
||||
|
||||
public class GraphQLConstants {
|
||||
|
||||
public static final String CONTENT_TYPE_JSON_UTF8 = "application/json;charset=UTF-8";
|
||||
|
||||
public static final String SCHEMA_READ_QUERY = " __schema {\n" +
|
||||
" queryType { name }\n" +
|
||||
" mutationType { name }\n" +
|
||||
" subscriptionType { name }\n" +
|
||||
" types {\n" +
|
||||
" ...FullType\n" +
|
||||
" }\n" +
|
||||
" directives {\n" +
|
||||
" name\n" +
|
||||
" description\n" +
|
||||
" locations\n" +
|
||||
" args {\n" +
|
||||
" ...InputValue\n" +
|
||||
" }\n" +
|
||||
" }\n" +
|
||||
" }\n" +
|
||||
" }\n" +
|
||||
" fragment FullType on __Type {\n" +
|
||||
" kind\n" +
|
||||
" name\n" +
|
||||
" description\n" +
|
||||
" fields(includeDeprecated: true) {\n" +
|
||||
" name\n" +
|
||||
" description\n" +
|
||||
" args {\n" +
|
||||
" ...InputValue\n" +
|
||||
" }\n" +
|
||||
" type {\n" +
|
||||
" ...TypeRef\n" +
|
||||
" }\n" +
|
||||
" isDeprecated\n" +
|
||||
" deprecationReason\n" +
|
||||
" }\n" +
|
||||
" inputFields {\n" +
|
||||
" ...InputValue\n" +
|
||||
" }\n" +
|
||||
" interfaces {\n" +
|
||||
" ...TypeRef\n" +
|
||||
" }\n" +
|
||||
" enumValues(includeDeprecated: true) {\n" +
|
||||
" name\n" +
|
||||
" description\n" +
|
||||
" isDeprecated\n" +
|
||||
" deprecationReason\n" +
|
||||
" }\n" +
|
||||
" possibleTypes {\n" +
|
||||
" ...TypeRef\n" +
|
||||
" }\n" +
|
||||
" }\n" +
|
||||
" fragment InputValue on __InputValue {\n" +
|
||||
" name\n" +
|
||||
" description\n" +
|
||||
" type { ...TypeRef }\n" +
|
||||
" defaultValue\n" +
|
||||
" }\n" +
|
||||
" fragment TypeRef on __Type {\n" +
|
||||
" kind\n" +
|
||||
" name\n" +
|
||||
" ofType {\n" +
|
||||
" kind\n" +
|
||||
" name\n" +
|
||||
" ofType {\n" +
|
||||
" kind\n" +
|
||||
" name\n" +
|
||||
" ofType {\n" +
|
||||
" kind\n" +
|
||||
" name\n" +
|
||||
" }\n" +
|
||||
" }\n" +
|
||||
" }";
|
||||
|
||||
}
|
||||
+294
@@ -0,0 +1,294 @@
|
||||
/*
|
||||
* DBeaver - Universal Database Manager
|
||||
* Copyright (C) 2010-2020 DBeaver Corp and others
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
package io.cloudbeaver.server.graphql;
|
||||
|
||||
import com.google.gson.*;
|
||||
import graphql.*;
|
||||
import graphql.execution.AsyncExecutionStrategy;
|
||||
import graphql.execution.DataFetcherExceptionHandlerResult;
|
||||
import graphql.execution.ExecutionPath;
|
||||
import graphql.execution.instrumentation.SimpleInstrumentation;
|
||||
import graphql.execution.instrumentation.parameters.InstrumentationExecutionParameters;
|
||||
import graphql.execution.instrumentation.parameters.InstrumentationFieldFetchParameters;
|
||||
import graphql.language.SourceLocation;
|
||||
import graphql.schema.DataFetcher;
|
||||
import graphql.schema.GraphQLSchema;
|
||||
import graphql.schema.idl.SchemaGenerator;
|
||||
import graphql.schema.idl.SchemaParser;
|
||||
import graphql.schema.idl.TypeDefinitionRegistry;
|
||||
import io.cloudbeaver.DBWebException;
|
||||
import io.cloudbeaver.WebServiceUtils;
|
||||
import io.cloudbeaver.api.DBWService;
|
||||
import io.cloudbeaver.api.DBWServiceGraphQL;
|
||||
import io.cloudbeaver.server.CloudbeaverApplication;
|
||||
import io.cloudbeaver.server.registry.WebServiceDescriptor;
|
||||
import io.cloudbeaver.server.registry.WebServiceRegistry;
|
||||
import org.jkiss.dbeaver.Log;
|
||||
import org.jkiss.utils.IOUtils;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.Reader;
|
||||
import java.net.URL;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
public class GraphQLEndpoint extends HttpServlet {
|
||||
|
||||
private static final Log log = Log.getLog(GraphQLEndpoint.class);
|
||||
|
||||
private static final String HEADER_ACCESS_CONTROL_ALLOW_ORIGIN = "Access-Control-Allow-Origin";
|
||||
private static final String HEADER_ACCESS_CONTROL_ALLOW_HEADERS = "Access-Control-Allow-Headers";
|
||||
private static final String HEADER_ACCESS_CONTROL_ALLOW_CREDENTIALS = "Access-Control-Allow-Credentials";
|
||||
|
||||
private static final String CORE_SCHEMA_FILE_NAME = "schema/schema.graphqls";
|
||||
|
||||
private final GraphQL graphQL;
|
||||
|
||||
private static Gson gson = new GsonBuilder()
|
||||
.serializeNulls()
|
||||
.setPrettyPrinting()
|
||||
.create();
|
||||
|
||||
public GraphQLEndpoint() {
|
||||
GraphQLSchema schema = buildSchema();
|
||||
|
||||
graphQL = GraphQL
|
||||
.newGraphQL(schema)
|
||||
.instrumentation(new WebInstrumentation())
|
||||
.queryExecutionStrategy(new WebExecutionStrategy())
|
||||
.mutationExecutionStrategy(new WebExecutionStrategy())
|
||||
.build();
|
||||
}
|
||||
|
||||
private GraphQLSchema buildSchema() {
|
||||
SchemaParser schemaParser = new SchemaParser();
|
||||
TypeDefinitionRegistry parsedSchema = new TypeDefinitionRegistry();
|
||||
|
||||
try (InputStream schemaStream = WebServiceUtils.openStaticResource(CORE_SCHEMA_FILE_NAME)) {
|
||||
try (Reader schemaReader = new InputStreamReader(schemaStream)) {
|
||||
parsedSchema.merge(schemaParser.parse(schemaReader));
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("Error reading core schema", e);
|
||||
}
|
||||
|
||||
for (WebServiceDescriptor wsd : WebServiceRegistry.getInstance().getWebServices()) {
|
||||
DBWService instance;
|
||||
try {
|
||||
instance = wsd.getInstance();
|
||||
} catch (Exception e) {
|
||||
log.error(e);
|
||||
continue;
|
||||
}
|
||||
if (instance instanceof DBWServiceGraphQL) {
|
||||
try {
|
||||
TypeDefinitionRegistry typeDefinition = ((DBWServiceGraphQL) instance).getTypeDefinition();
|
||||
if (typeDefinition != null) {
|
||||
log.debug("Adding web service '" + wsd.getId() + "' GQL schema");
|
||||
parsedSchema.merge(typeDefinition);
|
||||
}
|
||||
} catch (DBWebException e) {
|
||||
log.warn("Error obtaining web service '" + wsd.getId() + "' type definitions", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SchemaGenerator schemaGenerator = new SchemaGenerator();
|
||||
GraphQLModel wiring = new GraphQLModel();
|
||||
return schemaGenerator.makeExecutableSchema(parsedSchema, wiring.buildRuntimeWiring());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doOptions(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
|
||||
setDevelHeaders(request, response);
|
||||
}
|
||||
|
||||
private void setDevelHeaders(HttpServletRequest request, HttpServletResponse response) {
|
||||
if (CloudbeaverApplication.getInstance().isDevelMode()) {
|
||||
// response.setHeader(HEADER_ACCESS_CONTROL_ALLOW_ORIGIN, "*");
|
||||
// response.setHeader(HEADER_ACCESS_CONTROL_ALLOW_HEADERS, "*");
|
||||
// response.setHeader(HEADER_ACCESS_CONTROL_ALLOW_CREDENTIALS, "*");
|
||||
|
||||
String referrer = request.getHeader("referer");
|
||||
|
||||
try {
|
||||
URL url = new URL(referrer);
|
||||
String protocol = url.getProtocol();
|
||||
String host = url.getHost();
|
||||
int port = url.getPort();
|
||||
|
||||
String origin;
|
||||
|
||||
// if the port is not explicitly specified in the input, it will be -1.
|
||||
if (port == -1) {
|
||||
origin = String.format("%s://%s", protocol, host);
|
||||
} else {
|
||||
origin = String.format("%s://%s:%d", protocol, host, port);
|
||||
}
|
||||
|
||||
// for local machine must be defined explicitly:
|
||||
response.setHeader(HEADER_ACCESS_CONTROL_ALLOW_ORIGIN, origin);
|
||||
response.setHeader(HEADER_ACCESS_CONTROL_ALLOW_HEADERS, "Set-Cookie, Content-Type");
|
||||
response.setHeader(HEADER_ACCESS_CONTROL_ALLOW_CREDENTIALS, "true");
|
||||
} catch (Throwable t) {}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
|
||||
String postBody = IOUtils.readToString(request.getReader());
|
||||
JsonElement json = gson.fromJson(postBody, JsonElement.class);
|
||||
if (json instanceof JsonArray) {
|
||||
setDevelHeaders(request, response);
|
||||
response.setContentType(GraphQLConstants.CONTENT_TYPE_JSON_UTF8);
|
||||
response.getWriter().print("[\n");
|
||||
|
||||
JsonArray array = (JsonArray)json;
|
||||
int reqCount = 0;
|
||||
for (int i = 0; i < array.size(); i++) {
|
||||
if (reqCount > 0) {
|
||||
response.getWriter().print(",\n");
|
||||
}
|
||||
JsonElement item = array.get(i);
|
||||
if (item instanceof JsonObject) {
|
||||
executeSingleQuery(request, response, (JsonObject) item);
|
||||
reqCount++;
|
||||
}
|
||||
}
|
||||
|
||||
response.getWriter().print("\n]");
|
||||
} else if (json instanceof JsonObject) {
|
||||
JsonObject reqObject = (JsonObject) json;
|
||||
executeSingleQuery(request, response, reqObject);
|
||||
} else {
|
||||
response.sendError(400, "Bad JSON request");
|
||||
}
|
||||
}
|
||||
|
||||
private void executeSingleQuery(HttpServletRequest request, HttpServletResponse response, JsonObject reqObject) throws IOException {
|
||||
JsonElement query = reqObject.get("query");
|
||||
if (query == null) {
|
||||
response.sendError(400, "Query not specified");
|
||||
return;
|
||||
}
|
||||
JsonElement varJSON = reqObject.get("variables");
|
||||
Map<String, Object> variables = varJSON == null ? null : gson.fromJson(varJSON, Map.class);
|
||||
|
||||
JsonElement operNameJSON = reqObject.get("operationName");
|
||||
|
||||
executeQuery(request, response, query.getAsString(), variables, operNameJSON == null || operNameJSON instanceof JsonNull ? null : operNameJSON.getAsString());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
|
||||
String path = request.getPathInfo();
|
||||
if (path == null) {
|
||||
path = request.getServletPath();
|
||||
}
|
||||
boolean develMode = CloudbeaverApplication.getInstance().isDevelMode();
|
||||
|
||||
if (path.contentEquals("/schema.json") && develMode) {
|
||||
executeQuery(request, response, GraphQLConstants.SCHEMA_READ_QUERY, null, null);
|
||||
} else if (path.contentEquals("/console") && develMode) {
|
||||
try (InputStream consolePageStream = WebServiceUtils.openStaticResource("static/graphiql/index.html")) {
|
||||
IOUtils.copyStream(consolePageStream, response.getOutputStream());
|
||||
}
|
||||
} else {
|
||||
String query = request.getParameter("query");
|
||||
if (query != null) {
|
||||
executeQuery(request, response, query, null, request.getParameter("operationName"));
|
||||
} else {
|
||||
response.sendError(400, "Bad GET request");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void executeQuery(HttpServletRequest request, HttpServletResponse response, String query, Map<String, Object> variables, String operationName) throws IOException {
|
||||
GraphQLContext context = new GraphQLContext.Builder()
|
||||
.of("request", request)
|
||||
.of("response", response)
|
||||
.build();
|
||||
ExecutionInput.Builder contextBuilder = ExecutionInput.newExecutionInput()
|
||||
.context(context)
|
||||
.query(query);
|
||||
if (variables != null) {
|
||||
contextBuilder.variables(variables);
|
||||
}
|
||||
if (operationName != null) {
|
||||
contextBuilder.operationName(operationName);
|
||||
}
|
||||
|
||||
ExecutionInput executionInput = contextBuilder.build();
|
||||
ExecutionResult executionResult = graphQL.execute(executionInput);
|
||||
|
||||
Map<String, Object> resJSON = executionResult.toSpecification();
|
||||
String resString = gson.toJson(resJSON);
|
||||
setDevelHeaders(request, response);
|
||||
response.setContentType(GraphQLConstants.CONTENT_TYPE_JSON_UTF8);
|
||||
response.getWriter().print(resString);
|
||||
}
|
||||
|
||||
private class WebInstrumentation extends SimpleInstrumentation {
|
||||
@Override
|
||||
public CompletableFuture<ExecutionResult> instrumentExecutionResult(ExecutionResult executionResult, InstrumentationExecutionParameters parameters) {
|
||||
return super.instrumentExecutionResult(executionResult, parameters);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataFetcher<?> instrumentDataFetcher(DataFetcher<?> dataFetcher, InstrumentationFieldFetchParameters parameters) {
|
||||
return dataFetcher;
|
||||
// return environment -> {
|
||||
// try {
|
||||
// return dataFetcher.get(environment);
|
||||
// } catch (Exception e) {
|
||||
// log.debug(e);
|
||||
// throw e;
|
||||
// }
|
||||
// };
|
||||
}
|
||||
}
|
||||
|
||||
private class WebExecutionStrategy extends AsyncExecutionStrategy {
|
||||
public WebExecutionStrategy() {
|
||||
super(handlerParameters -> {
|
||||
Throwable exception = handlerParameters.getException();
|
||||
log.debug(exception);
|
||||
|
||||
SourceLocation sourceLocation = handlerParameters.getSourceLocation();
|
||||
ExecutionPath path = handlerParameters.getPath();
|
||||
|
||||
DataFetcherExceptionHandlerResult.Builder handlerResult = DataFetcherExceptionHandlerResult.newResult();
|
||||
if (exception instanceof GraphQLError) {
|
||||
if (exception instanceof DBWebException) {
|
||||
((DBWebException) exception).setPath(path.toList());
|
||||
((DBWebException) exception).setLocations(Collections.singletonList(sourceLocation));
|
||||
}
|
||||
return handlerResult.error((GraphQLError) exception).build();
|
||||
} else {
|
||||
return handlerResult.error(new ExceptionWhileDataFetching(path, exception, sourceLocation)).build();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
+204
@@ -0,0 +1,204 @@
|
||||
package io.cloudbeaver.server.graphql;
|
||||
|
||||
import graphql.scalars.ExtendedScalars;
|
||||
import graphql.schema.DataFetchingEnvironment;
|
||||
import graphql.schema.idl.RuntimeWiring;
|
||||
import graphql.schema.idl.TypeRuntimeWiring;
|
||||
import io.cloudbeaver.DBWebException;
|
||||
import io.cloudbeaver.api.DBWModel;
|
||||
import io.cloudbeaver.api.DBWService;
|
||||
import io.cloudbeaver.api.DBWServiceGraphQL;
|
||||
import io.cloudbeaver.api.DBWUtils;
|
||||
import io.cloudbeaver.server.CloudbeaverPlatform;
|
||||
import io.cloudbeaver.server.model.WebDatabaseObjectInfo;
|
||||
import io.cloudbeaver.server.model.WebPropertyFilter;
|
||||
import io.cloudbeaver.server.model.session.WebSessionManager;
|
||||
import io.cloudbeaver.server.model.sql.WebSQLDataFilter;
|
||||
import io.cloudbeaver.server.registry.WebServiceDescriptor;
|
||||
import io.cloudbeaver.server.registry.WebServiceRegistry;
|
||||
import org.jkiss.dbeaver.Log;
|
||||
import org.jkiss.dbeaver.runtime.DBWorkbench;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.util.Map;
|
||||
|
||||
class GraphQLModel implements DBWModel {
|
||||
|
||||
private static final Log log = Log.getLog(GraphQLModel.class);
|
||||
|
||||
private TypeRuntimeWiring.Builder queryType;
|
||||
private TypeRuntimeWiring.Builder mutationType;
|
||||
private WebSessionManager sessionManager;
|
||||
|
||||
GraphQLModel() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public CloudbeaverPlatform getPlatform() {
|
||||
return DBWorkbench.getPlatform(CloudbeaverPlatform.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public WebSessionManager getSessionManager() {
|
||||
return sessionManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeRuntimeWiring.Builder getQueryType() {
|
||||
return queryType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeRuntimeWiring.Builder getMutationType() {
|
||||
return mutationType;
|
||||
}
|
||||
|
||||
RuntimeWiring buildRuntimeWiring() {
|
||||
|
||||
CloudbeaverPlatform webServiceMain = getPlatform();
|
||||
sessionManager = webServiceMain.getSessionManager();
|
||||
|
||||
RuntimeWiring.Builder builder = RuntimeWiring.newRuntimeWiring();
|
||||
builder
|
||||
.scalar(ExtendedScalars.DateTime)
|
||||
.scalar(ExtendedScalars.Object);
|
||||
queryType = TypeRuntimeWiring.newTypeWiring("Query");
|
||||
mutationType = TypeRuntimeWiring.newTypeWiring("Mutation");
|
||||
|
||||
queryType
|
||||
.dataFetcher("serverConfig", env -> webServiceMain.getServerConfig())
|
||||
|
||||
.dataFetcher("driverList", env -> sessionManager.getWebSession(getServletRequest(env)).getDriverList(env.getArgument("id")))
|
||||
.dataFetcher("dataSourceList", env -> webServiceMain.getGlobalDataSources())
|
||||
|
||||
.dataFetcher("sessionState", env -> sessionManager.getWebSession(getServletRequest(env)))
|
||||
|
||||
.dataFetcher("readSessionLog", env -> sessionManager.getWebSession(getServletRequest(env)).readLog(
|
||||
env.getArgument("maxEntries"),
|
||||
env.getArgument("clearEntries")))
|
||||
|
||||
.dataFetcher("navNodeChildren", env -> sessionManager.getWebSession(getServletRequest(env)).getNavigatorNodeChildren(
|
||||
env.getArgument("parentPath"), env.getArgument("offset"), env.getArgument("limit"), env.getArgument("onlyFolders")))
|
||||
.dataFetcher("navNodeInfo", env -> sessionManager.getWebSession(getServletRequest(env)).getNavigatorNodeInfo(
|
||||
env.getArgument("nodePath")))
|
||||
.dataFetcher("navRefreshNode", env -> sessionManager.getWebSession(getServletRequest(env)).refreshNavigatorNode(
|
||||
env.getArgument("nodePath")
|
||||
))
|
||||
|
||||
.dataFetcher("navGetStructContainers", env -> DBWUtils.getSQLProcessor(sessionManager, env).getStructContainers(
|
||||
env.getArgument("catalog")
|
||||
))
|
||||
|
||||
.dataFetcher("sqlDialectInfo", env ->
|
||||
DBWUtils.getSQLProcessor(sessionManager, env).getDialectInfo()
|
||||
)
|
||||
.dataFetcher("sqlCompletionProposals", env ->
|
||||
DBWUtils.getSQLContext(sessionManager, env).getCompletionProposals(
|
||||
env.getArgument("query"),
|
||||
env.getArgument("position"),
|
||||
env.getArgument("maxResults")
|
||||
)
|
||||
)
|
||||
;
|
||||
|
||||
mutationType
|
||||
.dataFetcher("openSession", env -> sessionManager.openSession(getServletRequest(env), false))
|
||||
.dataFetcher("closeSession", env -> sessionManager.closeSession(getServletRequest(env)))
|
||||
.dataFetcher("touchSession", env -> sessionManager.touchSession(getServletRequest(env)))
|
||||
.dataFetcher("changeSessionLanguage", env -> {
|
||||
sessionManager.getWebSession(getServletRequest(env)).setLocale(env.getArgument("locale"));
|
||||
return true;
|
||||
})
|
||||
|
||||
.dataFetcher("openConnection", env -> sessionManager.openConnection(getServletRequest(env), env.getArgument("config")))
|
||||
.dataFetcher("createConnection", env -> sessionManager.createConnection(getServletRequest(env), env.getArgument("config")))
|
||||
.dataFetcher("testConnection", env -> sessionManager.testConnection(getServletRequest(env), env.getArgument("config")))
|
||||
.dataFetcher("closeConnection", env -> sessionManager.closeConnection(getServletRequest(env), env.getArgument("id")))
|
||||
|
||||
.dataFetcher("sqlContextCreate", env -> DBWUtils.getSQLProcessor(sessionManager, env).createContext(env.getArgument("defaultCatalog"), env.getArgument("defaultSchema")))
|
||||
.dataFetcher("sqlContextDestroy", env -> { DBWUtils.getSQLContext(sessionManager, env).destroy(); return true; } )
|
||||
.dataFetcher("sqlContextSetDefaults", env -> { DBWUtils.getSQLContext(sessionManager, env).setDefaults(env.getArgument("defaultCatalog"), env.getArgument("defaultSchema")); return true; })
|
||||
|
||||
.dataFetcher("sqlExecuteQuery", env ->
|
||||
DBWUtils.getSQLContext(sessionManager, env).executeQuery(
|
||||
env.getArgument("sql"), getDataFilter(env)
|
||||
))
|
||||
.dataFetcher("sqlResultClose", env ->
|
||||
DBWUtils.getSQLContext(sessionManager, env).closeResult(env.getArgument("resultId")))
|
||||
|
||||
.dataFetcher("readDataFromContainer", env ->
|
||||
DBWUtils.getSQLProcessor(sessionManager, env).readDataFromContainer(
|
||||
DBWUtils.getSQLContext(sessionManager, env),
|
||||
env.getArgument("containerNodePath"), getDataFilter(env)
|
||||
))
|
||||
.dataFetcher("updateResultsData", env ->
|
||||
DBWUtils.getSQLProcessor(sessionManager, env).updateResultsData(
|
||||
DBWUtils.getSQLContext(sessionManager, env),
|
||||
env.getArgument("resultsId"),
|
||||
env.getArgument("updateRow"),
|
||||
env.getArgument("updateValues")
|
||||
))
|
||||
.dataFetcher("asyncSqlExecuteQuery", env ->
|
||||
DBWUtils.getSQLContext(sessionManager, env).asyncExecuteQuery(
|
||||
env.getArgument("sql"), getDataFilter(env)
|
||||
))
|
||||
.dataFetcher("asyncTaskStatus", env ->
|
||||
sessionManager.getWebSession(getServletRequest(env)).asyncTaskStatus(
|
||||
env.getArgument("id"))
|
||||
)
|
||||
.dataFetcher("asyncTaskCancel", env ->
|
||||
sessionManager.getWebSession(getServletRequest(env)).asyncTaskCancel(
|
||||
env.getArgument("id"))
|
||||
)
|
||||
;
|
||||
|
||||
// Extend queries and mutations
|
||||
for (WebServiceDescriptor wsd : WebServiceRegistry.getInstance().getWebServices()) {
|
||||
DBWService instance;
|
||||
try {
|
||||
instance = wsd.getInstance();
|
||||
} catch (Exception e) {
|
||||
log.error(e);
|
||||
continue;
|
||||
}
|
||||
if (instance instanceof DBWServiceGraphQL) {
|
||||
try {
|
||||
((DBWServiceGraphQL) instance).bindWiring(this);
|
||||
} catch (DBWebException e) {
|
||||
log.warn("Error obtaining web service '" + wsd.getId() + "' type definitions", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
builder.type(queryType);
|
||||
builder.type(mutationType);
|
||||
|
||||
builder.type(TypeRuntimeWiring.newTypeWiring("DatabaseObjectInfo")
|
||||
.dataFetcher("properties", env -> {
|
||||
Map<String, Object> filterProps = env.getArgument("filter");
|
||||
WebPropertyFilter filter = filterProps == null ? null : new WebPropertyFilter(filterProps);
|
||||
return ((WebDatabaseObjectInfo)env.getSource()).filterProperties(filter);
|
||||
})
|
||||
);
|
||||
builder.type(TypeRuntimeWiring.newTypeWiring("AsyncTaskResult").typeResolver(env -> {
|
||||
return env.getObject();
|
||||
})
|
||||
);
|
||||
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
private HttpServletRequest getServletRequest(DataFetchingEnvironment env) {
|
||||
return DBWUtils.getServletRequest(env);
|
||||
}
|
||||
|
||||
///////////////////////////////////////
|
||||
// Helpers
|
||||
|
||||
private static WebSQLDataFilter getDataFilter(DataFetchingEnvironment env) {
|
||||
Map<String, Object> filterProps = env.getArgument("filter");
|
||||
return filterProps == null ? null : new WebSQLDataFilter(filterProps);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
+77
@@ -0,0 +1,77 @@
|
||||
package io.cloudbeaver.server.jetty;
|
||||
|
||||
import org.eclipse.core.runtime.FileLocator;
|
||||
import org.jkiss.dbeaver.Log;
|
||||
import org.jkiss.utils.CommonUtils;
|
||||
import org.jkiss.utils.IOUtils;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URL;
|
||||
|
||||
public class CloudbeaverImageServlet extends HttpServlet {
|
||||
|
||||
private static final Log log = Log.getLog(CloudbeaverImageServlet.class);
|
||||
|
||||
public CloudbeaverImageServlet() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
|
||||
String iconId = request.getPathInfo();
|
||||
while (iconId.startsWith("/")) {
|
||||
iconId = iconId.substring(1);
|
||||
}
|
||||
if (CommonUtils.isEmpty(iconId)) {
|
||||
response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Image ID missing");
|
||||
return;
|
||||
}
|
||||
if (!iconId.startsWith("platform:/plugin")) {
|
||||
response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Bad image ID");
|
||||
return;
|
||||
}
|
||||
int divPos = iconId.lastIndexOf(".");
|
||||
if (divPos == -1) {
|
||||
response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Bad image extension");
|
||||
return;
|
||||
}
|
||||
String iconPath = iconId.substring(0, divPos);
|
||||
String iconExt = iconId.substring(divPos + 1);
|
||||
try {
|
||||
String bigIconPath = iconPath + "@2x." + iconExt;
|
||||
URL iconURL = FileLocator.find(new URL(bigIconPath));
|
||||
if (iconURL == null) {
|
||||
iconURL = FileLocator.find(new URL(iconId));
|
||||
}
|
||||
if (iconURL == null) {
|
||||
response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Image not found");
|
||||
return;
|
||||
}
|
||||
|
||||
response.setContentType("image/" + iconExt);
|
||||
setExpireTime(response, 60 * 60 * 24 * 30); // Month
|
||||
try (InputStream is = new BufferedInputStream(iconURL.openStream())) {
|
||||
IOUtils.copyStream(is, response.getOutputStream());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error(e);
|
||||
response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Error reading image " + iconId + ": " + e.getMessage());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
private void setExpireTime(HttpServletResponse response, long expiresSeconds) {
|
||||
// Http 1.0 header, set a fix expires date.
|
||||
response.setDateHeader("Expires", System.currentTimeMillis() + expiresSeconds * 1000);
|
||||
// Http 1.1 header, set a time after now.
|
||||
response.setHeader("Cache-Control", "public, max-age=" + expiresSeconds);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
+90
@@ -0,0 +1,90 @@
|
||||
package io.cloudbeaver.server.jetty;
|
||||
|
||||
import io.cloudbeaver.server.CloudbeaverApplication;
|
||||
import io.cloudbeaver.server.graphql.GraphQLEndpoint;
|
||||
import org.eclipse.jetty.server.ConnectionFactory;
|
||||
import org.eclipse.jetty.server.Connector;
|
||||
import org.eclipse.jetty.server.HttpConnectionFactory;
|
||||
import org.eclipse.jetty.server.Server;
|
||||
import org.eclipse.jetty.server.session.DefaultSessionCache;
|
||||
import org.eclipse.jetty.server.session.FileSessionDataStore;
|
||||
import org.eclipse.jetty.server.session.SessionHandler;
|
||||
import org.eclipse.jetty.servlet.ErrorPageErrorHandler;
|
||||
import org.eclipse.jetty.servlet.ServletContextHandler;
|
||||
import org.jkiss.dbeaver.Log;
|
||||
import org.jkiss.dbeaver.runtime.DBWorkbench;
|
||||
import org.jkiss.dbeaver.utils.GeneralUtils;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
public class CloudbeaverJettyServer {
|
||||
|
||||
private static final Log log = Log.getLog(CloudbeaverJettyServer.class);
|
||||
private static final String SESSION_CACHE_DIR = ".http-sessions";
|
||||
|
||||
public CloudbeaverJettyServer() {
|
||||
}
|
||||
|
||||
public void runServer() {
|
||||
CloudbeaverApplication application = CloudbeaverApplication.getInstance();
|
||||
try {
|
||||
Server server = new Server(application.getServerPort());
|
||||
|
||||
{
|
||||
// Handler configuration
|
||||
ServletContextHandler servletContextHandler = new ServletContextHandler(ServletContextHandler.SESSIONS);
|
||||
servletContextHandler.setResourceBase(application.getContentRoot());
|
||||
servletContextHandler.setContextPath(application.getRootURI());
|
||||
servletContextHandler.addServlet(CloudbeaverStaticServlet.class, application.getRootURI());
|
||||
servletContextHandler.addServlet(CloudbeaverImageServlet.class, application.getServicesURI() + "images/*");
|
||||
servletContextHandler.addServlet(GraphQLEndpoint.class, application.getServicesURI() + "gql/*");
|
||||
servletContextHandler.addEventListener(new CloudbeaverServerContextListener());
|
||||
initSessionManager(servletContextHandler);
|
||||
|
||||
server.setHandler(servletContextHandler);
|
||||
|
||||
ErrorPageErrorHandler errorHandler = new ErrorPageErrorHandler();
|
||||
//errorHandler.addErrorPage(404, "/missing.html");
|
||||
servletContextHandler.setErrorHandler(errorHandler);
|
||||
}
|
||||
|
||||
{
|
||||
// HTTP config
|
||||
for(Connector y : server.getConnectors()) {
|
||||
for(ConnectionFactory x : y.getConnectionFactories()) {
|
||||
if(x instanceof HttpConnectionFactory) {
|
||||
((HttpConnectionFactory)x).getHttpConfiguration().setSendServerVersion(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
server.start();
|
||||
server.join();
|
||||
} catch (Exception e) {
|
||||
log.error("Error running Jetty server", e);
|
||||
}
|
||||
}
|
||||
|
||||
private void initSessionManager(ServletContextHandler servletContextHandler) {
|
||||
// Init sessions persistence
|
||||
File metadataFolder = GeneralUtils.getMetadataFolder(DBWorkbench.getPlatform().getWorkspace().getAbsolutePath());
|
||||
File sessionCacheFolder = new File(metadataFolder, SESSION_CACHE_DIR);
|
||||
if (!sessionCacheFolder.exists()) {
|
||||
if (!sessionCacheFolder.mkdirs()) {
|
||||
log.error("Can't create http session cache directory '" + sessionCacheFolder.getAbsolutePath() + "'");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
SessionHandler sessionHandler = new SessionHandler();
|
||||
DefaultSessionCache sessionCache = new DefaultSessionCache(sessionHandler);
|
||||
FileSessionDataStore sessionStore = new FileSessionDataStore();
|
||||
|
||||
sessionStore.setStoreDir(sessionCacheFolder);
|
||||
sessionCache.setSessionDataStore(sessionStore);
|
||||
sessionHandler.setSessionCache(sessionCache);
|
||||
servletContextHandler.setSessionHandler(sessionHandler);
|
||||
}
|
||||
|
||||
}
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* DBeaver - Universal Database Manager
|
||||
* Copyright (C) 2010-2020 DBeaver Corp and others
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
package io.cloudbeaver.server.jetty;
|
||||
|
||||
import io.cloudbeaver.server.CloudbeaverApplication;
|
||||
|
||||
import javax.servlet.ServletContextEvent;
|
||||
import javax.servlet.ServletContextListener;
|
||||
import javax.servlet.SessionCookieConfig;
|
||||
|
||||
public class CloudbeaverServerContextListener implements ServletContextListener {
|
||||
|
||||
public static final String DBEAVER_SESSION_COOKIE_NAME = "DBEAVER_SESSION_ID";
|
||||
|
||||
public void contextInitialized(ServletContextEvent sce) {
|
||||
SessionCookieConfig scf = sce.getServletContext().getSessionCookieConfig();
|
||||
|
||||
scf.setComment("Cloudbeaver Session ID");
|
||||
//scf.setDomain(domain);
|
||||
//scf.setHttpOnly(httpOnly);
|
||||
//scf.setMaxAge(maxAge);
|
||||
scf.setPath(CloudbeaverApplication.getInstance().getRootURI());
|
||||
//scf.setSecure(isSecure);
|
||||
scf.setName(DBEAVER_SESSION_COOKIE_NAME);
|
||||
}
|
||||
|
||||
public void contextDestroyed(ServletContextEvent sce) {
|
||||
|
||||
}
|
||||
}
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
package io.cloudbeaver.server.jetty;
|
||||
|
||||
import org.eclipse.jetty.server.ResourceService;
|
||||
import org.eclipse.jetty.servlet.DefaultServlet;
|
||||
|
||||
import javax.servlet.annotation.WebServlet;
|
||||
|
||||
@WebServlet(urlPatterns = "/")
|
||||
public class CloudbeaverStaticServlet extends DefaultServlet {
|
||||
|
||||
public CloudbeaverStaticServlet() {
|
||||
// super(makeResourceService());
|
||||
super();
|
||||
}
|
||||
|
||||
private static ResourceService makeResourceService() {
|
||||
ResourceService resourceService = new ResourceService();
|
||||
return resourceService;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* DBeaver - Universal Database Manager
|
||||
* Copyright (C) 2010-2020 DBeaver Corp and others
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
package io.cloudbeaver.server.launcher;
|
||||
|
||||
import org.eclipse.core.runtime.adaptor.EclipseStarter;
|
||||
import org.jkiss.dbeaver.model.app.DBPPlatform;
|
||||
import org.osgi.framework.BundleContext;
|
||||
import org.osgi.framework.ServiceReference;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* The activator class controls the plug-in life cycle
|
||||
*/
|
||||
public class CloudbeaverLauncher {
|
||||
|
||||
public static DBPPlatform instantiatePlatform() throws Exception {
|
||||
Map<String, String> props = new HashMap<>();
|
||||
|
||||
EclipseStarter.setInitialProperties(props);
|
||||
BundleContext context = EclipseStarter.startup(
|
||||
new String[]{},
|
||||
null);
|
||||
|
||||
ServiceReference<DBPPlatform> platformRef = context.getServiceReference(DBPPlatform.class);
|
||||
return context.getService(platformRef);
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
|
||||
Map<String, String> props = new HashMap<>();
|
||||
|
||||
EclipseStarter.setInitialProperties(props);
|
||||
BundleContext context = EclipseStarter.startup(
|
||||
new String[]{},
|
||||
null);
|
||||
//context.getBundles()
|
||||
}
|
||||
|
||||
}
|
||||
+100
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
* DBeaver - Universal Database Manager
|
||||
* Copyright (C) 2010-2020 DBeaver Corp and others
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
package io.cloudbeaver.server.model;
|
||||
|
||||
import org.jkiss.dbeaver.model.runtime.AbstractJob;
|
||||
|
||||
/**
|
||||
* Web connection info
|
||||
*/
|
||||
public class WebAsyncTaskInfo {
|
||||
|
||||
private String id;
|
||||
private String name;
|
||||
private boolean running;
|
||||
private Object result;
|
||||
private String status;
|
||||
private Throwable jobError;
|
||||
|
||||
private AbstractJob job;
|
||||
|
||||
public WebAsyncTaskInfo(String id, String name) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public boolean isRunning() {
|
||||
return running;
|
||||
}
|
||||
|
||||
public void setRunning(boolean running) {
|
||||
this.running = running;
|
||||
}
|
||||
|
||||
public Object getResult() {
|
||||
return result;
|
||||
}
|
||||
|
||||
public void setResult(Object result) {
|
||||
this.result = result;
|
||||
}
|
||||
|
||||
public String getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public void setStatus(String status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public WebServerError getError() {
|
||||
return jobError == null ? null : new WebServerError(jobError);
|
||||
}
|
||||
|
||||
public Throwable getJobError() {
|
||||
return jobError;
|
||||
}
|
||||
|
||||
public void setJobError(Throwable jobError) {
|
||||
this.jobError = jobError;
|
||||
}
|
||||
|
||||
public AbstractJob getJob() {
|
||||
return job;
|
||||
}
|
||||
|
||||
public void setJob(AbstractJob job) {
|
||||
this.job = job;
|
||||
}
|
||||
|
||||
}
|
||||
+66
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* DBeaver - Universal Database Manager
|
||||
* Copyright (C) 2010-2020 DBeaver Corp and others
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
package io.cloudbeaver.server.model;
|
||||
|
||||
import org.jkiss.dbeaver.model.meta.Property;
|
||||
|
||||
/**
|
||||
* Web connection info
|
||||
*/
|
||||
public class WebBasicObjectInfo {
|
||||
|
||||
private String displayName;
|
||||
private String description;
|
||||
private long id;
|
||||
private String value;
|
||||
|
||||
@Property
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
@Property
|
||||
public String getDisplayName() {
|
||||
return displayName;
|
||||
}
|
||||
|
||||
public void setDisplayName(String displayName) {
|
||||
this.displayName = displayName;
|
||||
}
|
||||
|
||||
@Property
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public void setDescription(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
@Property
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void setValue(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
}
|
||||
+126
@@ -0,0 +1,126 @@
|
||||
/*
|
||||
* DBeaver - Universal Database Manager
|
||||
* Copyright (C) 2010-2020 DBeaver Corp and others
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
package io.cloudbeaver.server.model;
|
||||
|
||||
import org.jkiss.dbeaver.model.data.json.JSONUtils;
|
||||
import org.jkiss.dbeaver.model.meta.Property;
|
||||
import org.jkiss.utils.CommonUtils;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Web connection config
|
||||
*/
|
||||
public class WebConnectionConfig {
|
||||
|
||||
private String dataSourceId;
|
||||
|
||||
private String driverId;
|
||||
private String host;
|
||||
private String port;
|
||||
private String serverName;
|
||||
private String databaseName;
|
||||
private String url;
|
||||
|
||||
private String name;
|
||||
private String description;
|
||||
private Map<String, Object> properties;
|
||||
private String userName;
|
||||
private String userPassword;
|
||||
|
||||
public WebConnectionConfig() {
|
||||
}
|
||||
|
||||
public WebConnectionConfig(Map<String, Object> params) {
|
||||
dataSourceId = CommonUtils.toString(params.get("dataSourceId"));
|
||||
|
||||
driverId = JSONUtils.getString(params, "driverId");
|
||||
host = JSONUtils.getString(params, "host");
|
||||
port = JSONUtils.getString(params, "port");
|
||||
serverName = JSONUtils.getString(params, "serverName");
|
||||
databaseName = JSONUtils.getString(params, "databaseName");
|
||||
url = JSONUtils.getString(params, "url");
|
||||
|
||||
name = JSONUtils.getString(params, "name");
|
||||
description = JSONUtils.getString(params, "description");
|
||||
|
||||
properties = JSONUtils.getObject(params, "properties");
|
||||
userName = JSONUtils.getString(params, "userName");
|
||||
userPassword = JSONUtils.getString(params, "userPassword");
|
||||
}
|
||||
|
||||
@Property
|
||||
public String getDataSourceId() {
|
||||
return dataSourceId;
|
||||
}
|
||||
|
||||
@Property
|
||||
public String getDriverId() {
|
||||
return driverId;
|
||||
}
|
||||
|
||||
@Property
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Property
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
@Property
|
||||
public String getHost() {
|
||||
return host;
|
||||
}
|
||||
|
||||
@Property
|
||||
public String getPort() {
|
||||
return port;
|
||||
}
|
||||
|
||||
@Property
|
||||
public String getServerName() {
|
||||
return serverName;
|
||||
}
|
||||
|
||||
@Property
|
||||
public String getDatabaseName() {
|
||||
return databaseName;
|
||||
}
|
||||
|
||||
@Property
|
||||
public String getUrl() {
|
||||
return url;
|
||||
}
|
||||
|
||||
@Property
|
||||
public Map<String, Object> getProperties() {
|
||||
return properties;
|
||||
}
|
||||
|
||||
@Property
|
||||
public String getUserName() {
|
||||
return userName;
|
||||
}
|
||||
|
||||
@Property
|
||||
public String getUserPassword() {
|
||||
return userPassword;
|
||||
}
|
||||
|
||||
}
|
||||
+138
@@ -0,0 +1,138 @@
|
||||
/*
|
||||
* DBeaver - Universal Database Manager
|
||||
* Copyright (C) 2010-2020 DBeaver Corp and others
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
package io.cloudbeaver.server.model;
|
||||
|
||||
import io.cloudbeaver.DBWebException;
|
||||
import io.cloudbeaver.WebServiceUtils;
|
||||
import io.cloudbeaver.server.CloudbeaverConstants;
|
||||
import io.cloudbeaver.server.model.session.WebSession;
|
||||
import io.cloudbeaver.server.model.sql.WebSQLProcessor;
|
||||
import org.jkiss.dbeaver.DBException;
|
||||
import org.jkiss.dbeaver.model.DBPDataSource;
|
||||
import org.jkiss.dbeaver.model.DBPDataSourceContainer;
|
||||
import org.jkiss.dbeaver.model.meta.Property;
|
||||
|
||||
/**
|
||||
* Web connection info
|
||||
*/
|
||||
public class WebConnectionInfo {
|
||||
|
||||
private final WebSession session;
|
||||
private DBPDataSourceContainer dataSourceContainer;
|
||||
private WebServerError connectError;
|
||||
private WebSQLProcessor sqlProcessor;
|
||||
|
||||
private String connectTime;
|
||||
private String serverVersion;
|
||||
private String clientVersion;
|
||||
|
||||
public WebConnectionInfo(WebSession session, DBPDataSourceContainer ds) {
|
||||
this.session = session;
|
||||
this.dataSourceContainer = ds;
|
||||
}
|
||||
|
||||
public DBPDataSourceContainer getDataSourceContainer() {
|
||||
return dataSourceContainer;
|
||||
}
|
||||
|
||||
public DBPDataSource getDataSource() {
|
||||
return dataSourceContainer.getDataSource();
|
||||
}
|
||||
|
||||
@Property
|
||||
public String getId() {
|
||||
return dataSourceContainer.getId();
|
||||
}
|
||||
|
||||
@Property
|
||||
public String getDriverId() {
|
||||
return WebServiceUtils.makeDriverFullId(dataSourceContainer.getDriver());
|
||||
}
|
||||
|
||||
@Property
|
||||
public String getName() {
|
||||
return dataSourceContainer.getName();
|
||||
}
|
||||
|
||||
@Property
|
||||
public String getDescription() {
|
||||
return dataSourceContainer.getDescription();
|
||||
}
|
||||
|
||||
@Property
|
||||
public String getProperties() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Property
|
||||
public boolean isConnected() {
|
||||
return dataSourceContainer.isConnected();
|
||||
}
|
||||
|
||||
@Property
|
||||
public boolean isProvided() {
|
||||
return dataSourceContainer.isProvided();
|
||||
}
|
||||
|
||||
@Property
|
||||
public String getConnectTime() {
|
||||
return CloudbeaverConstants.ISO_DATE_FORMAT.format(dataSourceContainer.getConnectTime());
|
||||
}
|
||||
|
||||
@Property
|
||||
public WebServerError getConnectError() {
|
||||
return connectError;
|
||||
}
|
||||
|
||||
public void setConnectError(Throwable connectError) {
|
||||
this.connectError = connectError == null ? null : new WebServerError(connectError);
|
||||
}
|
||||
|
||||
public void setConnectTime(String connectTime) {
|
||||
this.connectTime = connectTime;
|
||||
}
|
||||
|
||||
public String getServerVersion() {
|
||||
return serverVersion;
|
||||
}
|
||||
|
||||
public void setServerVersion(String serverVersion) {
|
||||
this.serverVersion = serverVersion;
|
||||
}
|
||||
|
||||
public String getClientVersion() {
|
||||
return clientVersion;
|
||||
}
|
||||
|
||||
public void setClientVersion(String clientVersion) {
|
||||
this.clientVersion = clientVersion;
|
||||
}
|
||||
|
||||
public WebSQLProcessor getSQLProcessor() throws DBWebException {
|
||||
if (getDataSource() == null) {
|
||||
try {
|
||||
dataSourceContainer.connect(session.getProgressMonitor(), true, false);
|
||||
} catch (DBException e) {
|
||||
throw new DBWebException("Error connecting to database", e);
|
||||
}
|
||||
}
|
||||
if (sqlProcessor == null) {
|
||||
sqlProcessor = new WebSQLProcessor(session, this);
|
||||
}
|
||||
return sqlProcessor;
|
||||
}
|
||||
}
|
||||
+93
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* DBeaver - Universal Database Manager
|
||||
* Copyright (C) 2010-2020 DBeaver Corp and others
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
package io.cloudbeaver.server.model;
|
||||
|
||||
import io.cloudbeaver.WebServiceUtils;
|
||||
import org.jkiss.dbeaver.model.DBPDataSourceContainer;
|
||||
import org.jkiss.dbeaver.model.meta.Property;
|
||||
|
||||
/**
|
||||
* Web data source configuration
|
||||
*/
|
||||
public class WebDataSourceConfig {
|
||||
|
||||
private String id;
|
||||
private String driverId;
|
||||
private String name;
|
||||
private String description;
|
||||
|
||||
private String host;
|
||||
private String server;
|
||||
private String port;
|
||||
private String url;
|
||||
private String properties;
|
||||
|
||||
public WebDataSourceConfig(DBPDataSourceContainer ds) {
|
||||
this.id = ds.getId();
|
||||
this.name = ds.getName();
|
||||
this.description = ds.getDescription();
|
||||
this.driverId = WebServiceUtils.makeDriverFullId(ds.getDriver());
|
||||
this.host = ds.getConnectionConfiguration().getHostName();
|
||||
this.port = ds.getConnectionConfiguration().getHostPort();
|
||||
this.url = ds.getConnectionConfiguration().getUrl();
|
||||
}
|
||||
|
||||
@Property
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Property
|
||||
public String getDriverId() {
|
||||
return driverId;
|
||||
}
|
||||
|
||||
@Property
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Property
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
@Property
|
||||
public String getHost() {
|
||||
return host;
|
||||
}
|
||||
|
||||
@Property
|
||||
public String getServer() {
|
||||
return server;
|
||||
}
|
||||
|
||||
@Property
|
||||
public String getPort() {
|
||||
return port;
|
||||
}
|
||||
|
||||
@Property
|
||||
public String getUrl() {
|
||||
return url;
|
||||
}
|
||||
|
||||
@Property
|
||||
public String getProperties() {
|
||||
return properties;
|
||||
}
|
||||
}
|
||||
+175
@@ -0,0 +1,175 @@
|
||||
/*
|
||||
* DBeaver - Universal Database Manager
|
||||
* Copyright (C) 2010-2020 DBeaver Corp and others
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
package io.cloudbeaver.server.model;
|
||||
|
||||
import io.cloudbeaver.DBWebException;
|
||||
import io.cloudbeaver.WebServiceUtils;
|
||||
import io.cloudbeaver.server.model.session.WebSession;
|
||||
import org.jkiss.dbeaver.DBException;
|
||||
import org.jkiss.dbeaver.model.connection.DBPConnectionConfiguration;
|
||||
import org.jkiss.dbeaver.model.connection.DBPDriver;
|
||||
import org.jkiss.dbeaver.model.meta.Property;
|
||||
import org.jkiss.dbeaver.model.preferences.DBPPropertyDescriptor;
|
||||
import org.jkiss.dbeaver.runtime.properties.PropertySourceCustom;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Web driver configuration
|
||||
*/
|
||||
public class WebDatabaseDriverConfig {
|
||||
|
||||
private final WebSession webSession;
|
||||
private final DBPDriver driver;
|
||||
private String id;
|
||||
|
||||
public WebDatabaseDriverConfig(WebSession webSession, DBPDriver driver) {
|
||||
this.webSession = webSession;
|
||||
this.driver = driver;
|
||||
this.id = WebServiceUtils.makeDriverFullId(driver);
|
||||
}
|
||||
|
||||
@Property
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Property
|
||||
public String getName() {
|
||||
return driver.getName();
|
||||
}
|
||||
|
||||
@Property
|
||||
public String getDescription() {
|
||||
return driver.getDescription();
|
||||
}
|
||||
|
||||
@Property
|
||||
public String getIcon() {
|
||||
return WebServiceUtils.makeIconId(driver.getIcon());
|
||||
}
|
||||
|
||||
@Property
|
||||
public String getIconBig() {
|
||||
return WebServiceUtils.makeIconId(driver.getIconBig());
|
||||
}
|
||||
|
||||
@Property
|
||||
public String getProviderId() {
|
||||
return driver.getProviderId();
|
||||
}
|
||||
|
||||
@Property
|
||||
public String getDriverClassName() {
|
||||
return driver.getDriverClassName();
|
||||
}
|
||||
|
||||
@Property
|
||||
public String getDefaultPort() {
|
||||
return driver.getDefaultPort();
|
||||
}
|
||||
|
||||
@Property
|
||||
public String getSampleURL() {
|
||||
return driver.getSampleURL();
|
||||
}
|
||||
|
||||
@Property
|
||||
public String getDriverInfoURL() {
|
||||
return driver.getWebURL();
|
||||
}
|
||||
|
||||
@Property
|
||||
public String getDriverPropertiesURL() {
|
||||
return driver.getPropertiesWebURL();
|
||||
}
|
||||
|
||||
@Property
|
||||
public boolean getEmbedded() {
|
||||
return driver.isEmbedded();
|
||||
}
|
||||
|
||||
@Property
|
||||
public boolean getAnonymousAccess() {
|
||||
return driver.isAnonymousAccess();
|
||||
}
|
||||
|
||||
@Property
|
||||
public boolean getAllowsEmptyPassword() {
|
||||
return driver.isAllowsEmptyPassword();
|
||||
}
|
||||
|
||||
@Property
|
||||
public boolean getLicenseRequired() {
|
||||
return driver.isLicenseRequired();
|
||||
}
|
||||
|
||||
@Property
|
||||
public String getLicense() {
|
||||
return driver.getLicense();
|
||||
}
|
||||
|
||||
@Property
|
||||
public boolean getCustom() {
|
||||
return driver.isCustom();
|
||||
}
|
||||
|
||||
@Property
|
||||
public int getPromotedScore() {
|
||||
return driver.getPromotedScore();
|
||||
}
|
||||
|
||||
@Property
|
||||
public Map<String, Object> getConnectionProperties() {
|
||||
return driver.getConnectionProperties();
|
||||
}
|
||||
|
||||
@Property
|
||||
public Map<String, Object> getDefaultConnectionProperties() {
|
||||
return driver.getDefaultConnectionProperties();
|
||||
}
|
||||
|
||||
@Property
|
||||
public WebPropertyInfo[] getDriverProperties() throws DBWebException {
|
||||
try {
|
||||
DBPConnectionConfiguration cfg = new DBPConnectionConfiguration();
|
||||
cfg.setUrl(driver.getSampleURL());
|
||||
cfg.setHostName("localhost");
|
||||
cfg.setHostPort(driver.getDefaultPort());
|
||||
cfg.setUrl(driver.getDataSourceProvider().getConnectionURL(driver, cfg));
|
||||
DBPPropertyDescriptor[] properties = driver.getDataSourceProvider().getConnectionProperties(webSession.getProgressMonitor(), driver, cfg);
|
||||
|
||||
PropertySourceCustom propertySource = new PropertySourceCustom(
|
||||
properties,
|
||||
cfg.getProperties());
|
||||
|
||||
WebPropertyInfo[] result = new WebPropertyInfo[properties.length];
|
||||
for (int i = 0; i < properties.length; i++) {
|
||||
result[i] = new WebPropertyInfo(webSession, properties[i], propertySource);
|
||||
}
|
||||
return result;
|
||||
} catch (DBException e) {
|
||||
throw new DBWebException("Error reading driver properties", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Property
|
||||
public Map<String, Object> getDriverParameters() {
|
||||
return driver.getDriverParameters();
|
||||
}
|
||||
|
||||
}
|
||||
+147
@@ -0,0 +1,147 @@
|
||||
/*
|
||||
* DBeaver - Universal Database Manager
|
||||
* Copyright (C) 2010-2020 DBeaver Corp and others
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
package io.cloudbeaver.server.model;
|
||||
|
||||
import io.cloudbeaver.server.model.session.WebSession;
|
||||
import org.jkiss.code.Nullable;
|
||||
import org.jkiss.dbeaver.model.*;
|
||||
import org.jkiss.dbeaver.model.meta.Property;
|
||||
import org.jkiss.dbeaver.model.preferences.DBPPropertyDescriptor;
|
||||
import org.jkiss.dbeaver.model.struct.*;
|
||||
import org.jkiss.dbeaver.model.struct.rdb.DBSCatalog;
|
||||
import org.jkiss.dbeaver.model.struct.rdb.DBSSchema;
|
||||
import org.jkiss.dbeaver.runtime.properties.PropertyCollector;
|
||||
import org.jkiss.utils.CommonUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Web connection info
|
||||
*/
|
||||
public class WebDatabaseObjectInfo {
|
||||
|
||||
private final WebSession session;
|
||||
private final DBSObject object;
|
||||
|
||||
public WebDatabaseObjectInfo(WebSession session, DBSObject object) {
|
||||
this.session = session;
|
||||
this.object = object;
|
||||
}
|
||||
|
||||
///////////////////////////////////
|
||||
// General properties
|
||||
///////////////////////////////////
|
||||
|
||||
@Property
|
||||
public String getName() {
|
||||
return object.getName();
|
||||
}
|
||||
|
||||
@Property
|
||||
public String getDescription() {
|
||||
return object.getDescription();
|
||||
}
|
||||
|
||||
@Property
|
||||
public String getType() {
|
||||
return object.getClass().getName();
|
||||
}
|
||||
|
||||
@Property
|
||||
public WebPropertyInfo[] getProperties() {
|
||||
return filterProperties(null);
|
||||
}
|
||||
|
||||
@Property
|
||||
public WebPropertyInfo[] filterProperties(@Nullable WebPropertyFilter filter) {
|
||||
PropertyCollector propertyCollector = new PropertyCollector(object, true);
|
||||
propertyCollector.setLocale(session.getLocale());
|
||||
propertyCollector.collectProperties();
|
||||
List<WebPropertyInfo> webProps = new ArrayList<>();
|
||||
for (DBPPropertyDescriptor prop : propertyCollector.getProperties()) {
|
||||
if (filter != null && !CommonUtils.isEmpty(filter.getIds()) && !filter.getIds().contains(CommonUtils.toString(prop.getId()))) {
|
||||
continue;
|
||||
}
|
||||
WebPropertyInfo webProperty = new WebPropertyInfo(session, prop, propertyCollector);
|
||||
if (filter != null) {
|
||||
if (!CommonUtils.isEmpty(filter.getFeatures()) && !webProperty.hasAnyFeature(filter.getFeatures())) {
|
||||
continue;
|
||||
}
|
||||
if (!CommonUtils.isEmpty(filter.getCategories()) && !filter.getCategories().contains(webProperty.getCategory())) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
webProps.add(webProperty);
|
||||
}
|
||||
return webProps.toArray(new WebPropertyInfo[0]);
|
||||
}
|
||||
|
||||
///////////////////////////////////
|
||||
// Advanced
|
||||
|
||||
@Property
|
||||
public Integer getOrdinalPosition() {
|
||||
return object instanceof DBPOrderedObject ? ((DBPOrderedObject) object).getOrdinalPosition() : null;
|
||||
}
|
||||
|
||||
@Property
|
||||
public String getFullyQualifiedName() {
|
||||
return object instanceof DBPQualifiedObject ? ((DBPQualifiedObject) object).getFullyQualifiedName(DBPEvaluationContext.UI) : getName();
|
||||
}
|
||||
|
||||
@Property
|
||||
public String getOverloadedName() {
|
||||
return object instanceof DBPOverloadedObject ? ((DBPOverloadedObject) object).getOverloadedName() : getName();
|
||||
}
|
||||
|
||||
@Property
|
||||
public String getUniqueName() {
|
||||
return object instanceof DBPUniqueObject ? ((DBPUniqueObject) object).getUniqueName() : getName();
|
||||
}
|
||||
|
||||
@Property
|
||||
public String getState() {
|
||||
if (object instanceof DBPStatefulObject) {
|
||||
DBSObjectState state = ((DBPStatefulObject) object).getObjectState();
|
||||
if (state != null) {
|
||||
return state.getTitle();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Property
|
||||
public String[] getFeatures() {
|
||||
List<String> features = new ArrayList<>();
|
||||
if (object instanceof DBPScriptObject) features.add("script");
|
||||
if (object instanceof DBPScriptObjectExt) features.add("scriptExtended");
|
||||
if (object instanceof DBSDataContainer) features.add("dataContainer");
|
||||
if (object instanceof DBSDataManipulator) features.add("dataManipulator");
|
||||
if (object instanceof DBSEntity) features.add("entity");
|
||||
if (object instanceof DBSSchema) features.add("schema");
|
||||
if (object instanceof DBSCatalog) features.add("catalog");
|
||||
if (object instanceof DBPDataSourceContainer) features.add("dataSource");
|
||||
return features.toArray(new String[0]);
|
||||
}
|
||||
|
||||
@Property
|
||||
public String[] getEditors() {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
+134
@@ -0,0 +1,134 @@
|
||||
/*
|
||||
* DBeaver - Universal Database Manager
|
||||
* Copyright (C) 2010-2020 DBeaver Corp and others
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
package io.cloudbeaver.server.model;
|
||||
|
||||
import io.cloudbeaver.server.model.session.WebSession;
|
||||
import org.jkiss.dbeaver.model.meta.Association;
|
||||
import org.jkiss.dbeaver.model.meta.Property;
|
||||
import org.jkiss.dbeaver.model.navigator.*;
|
||||
import org.jkiss.dbeaver.model.struct.DBSEntity;
|
||||
import org.jkiss.dbeaver.model.struct.DBSObject;
|
||||
import org.jkiss.dbeaver.model.struct.rdb.DBSProcedure;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Web connection info
|
||||
*/
|
||||
public class WebNavigatorNodeInfo {
|
||||
private final WebSession sesion;
|
||||
private final DBNNode node;
|
||||
|
||||
public WebNavigatorNodeInfo(WebSession sesion, DBNNode node) {
|
||||
this.sesion = sesion;
|
||||
this.node = node;
|
||||
}
|
||||
|
||||
public DBNNode getNode() {
|
||||
return node;
|
||||
}
|
||||
|
||||
///////////////////////////////////
|
||||
// General properties
|
||||
///////////////////////////////////
|
||||
|
||||
@Property
|
||||
public String getId() {
|
||||
return node.getNodeItemPath();
|
||||
}
|
||||
|
||||
@Property
|
||||
public String getName() {
|
||||
return node.getLocalizedName(sesion.getLocale());
|
||||
}
|
||||
|
||||
@Property
|
||||
public String getIcon() {
|
||||
return node.getNodeIconDefault().getLocation();
|
||||
}
|
||||
|
||||
@Property
|
||||
public String getDescription() {
|
||||
return node.getNodeDescription();
|
||||
}
|
||||
|
||||
@Property
|
||||
public String getNodeType() {
|
||||
return node.getNodeType();
|
||||
}
|
||||
|
||||
@Property
|
||||
public boolean isFolder() {
|
||||
return node instanceof DBNContainer && !(node instanceof DBNDataSource);
|
||||
}
|
||||
|
||||
@Property
|
||||
public boolean isInline() {
|
||||
return node instanceof DBNDatabaseNode && ((DBNDatabaseNode) node).getMeta().isInline();
|
||||
}
|
||||
|
||||
@Property
|
||||
public boolean isNavigable() {
|
||||
if (node instanceof DBNDatabaseNode) {
|
||||
DBNDatabaseNode databaseNode = (DBNDatabaseNode) this.node;
|
||||
if (!databaseNode.getMeta().isNavigable()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Property
|
||||
public boolean isHasChildren() {
|
||||
return node.hasChildren(true);
|
||||
}
|
||||
|
||||
@Association
|
||||
public String[] getFeatures() {
|
||||
List<String> features = new ArrayList<>();
|
||||
if (node instanceof DBNDatabaseItem) {
|
||||
features.add("item");
|
||||
DBSObject object = ((DBNDatabaseItem) node).getObject();
|
||||
if (object instanceof DBSEntity || object instanceof DBSProcedure) {
|
||||
features.add("leaf");
|
||||
}
|
||||
|
||||
}
|
||||
if (node instanceof DBNContainer) {
|
||||
features.add("container");
|
||||
}
|
||||
return features.toArray(new String[0]);
|
||||
}
|
||||
|
||||
///////////////////////////////////
|
||||
// Objects
|
||||
///////////////////////////////////
|
||||
|
||||
@Property
|
||||
public WebDatabaseObjectInfo getObject() {
|
||||
if (node instanceof DBNDatabaseNode) {
|
||||
return new WebDatabaseObjectInfo(sesion, ((DBNDatabaseNode) node).getObject());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return node.getNodeItemPath();
|
||||
}
|
||||
}
|
||||
+71
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* DBeaver - Universal Database Manager
|
||||
* Copyright (C) 2010-2020 DBeaver Corp and others
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
package io.cloudbeaver.server.model;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Web property filter
|
||||
*/
|
||||
public class WebPropertyFilter {
|
||||
private List<String> ids;
|
||||
private List<String> features;
|
||||
private List<String> categories;
|
||||
private List<String> dataTypes;
|
||||
|
||||
public WebPropertyFilter() {
|
||||
}
|
||||
|
||||
public WebPropertyFilter(Map<String, Object> props) {
|
||||
ids = (List<String>) props.get("ids");
|
||||
features = (List<String>) props.get("features");
|
||||
|
||||
}
|
||||
|
||||
public List<String> getIds() {
|
||||
return ids;
|
||||
}
|
||||
|
||||
public void setIds(List<String> ids) {
|
||||
this.ids = ids;
|
||||
}
|
||||
|
||||
public List<String> getFeatures() {
|
||||
return features;
|
||||
}
|
||||
|
||||
public void setFeatures(List<String> features) {
|
||||
this.features = features;
|
||||
}
|
||||
|
||||
public List<String> getCategories() {
|
||||
return categories;
|
||||
}
|
||||
|
||||
public void setCategories(List<String> categories) {
|
||||
this.categories = categories;
|
||||
}
|
||||
|
||||
public List<String> getDataTypes() {
|
||||
return dataTypes;
|
||||
}
|
||||
|
||||
public void setDataTypes(List<String> dataTypes) {
|
||||
this.dataTypes = dataTypes;
|
||||
}
|
||||
}
|
||||
+237
@@ -0,0 +1,237 @@
|
||||
/*
|
||||
* DBeaver - Universal Database Manager
|
||||
* Copyright (C) 2010-2020 DBeaver Corp and others
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
package io.cloudbeaver.server.model;
|
||||
|
||||
import io.cloudbeaver.server.model.session.WebSession;
|
||||
import org.jkiss.code.NotNull;
|
||||
import org.jkiss.dbeaver.DBException;
|
||||
import org.jkiss.dbeaver.model.*;
|
||||
import org.jkiss.dbeaver.model.meta.IPropertyValueListProvider;
|
||||
import org.jkiss.dbeaver.model.meta.Property;
|
||||
import org.jkiss.dbeaver.model.preferences.DBPPropertyDescriptor;
|
||||
import org.jkiss.dbeaver.model.preferences.DBPPropertySource;
|
||||
import org.jkiss.dbeaver.runtime.properties.ObjectPropertyDescriptor;
|
||||
import org.jkiss.utils.CommonUtils;
|
||||
|
||||
import java.lang.reflect.Array;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Web connection info
|
||||
*/
|
||||
public class WebPropertyInfo {
|
||||
private WebSession session;
|
||||
private DBPPropertyDescriptor property;
|
||||
private DBPPropertySource propertySource;
|
||||
|
||||
public WebPropertyInfo(WebSession session, DBPPropertyDescriptor property, DBPPropertySource propertySource) {
|
||||
this.session = session;
|
||||
this.property = property;
|
||||
this.propertySource = propertySource;
|
||||
}
|
||||
|
||||
///////////////////////////////////
|
||||
// General properties
|
||||
///////////////////////////////////
|
||||
|
||||
@Property
|
||||
public String getId() {
|
||||
return CommonUtils.toString(property.getId());
|
||||
}
|
||||
|
||||
@Property
|
||||
public String getDisplayName() {
|
||||
if (property instanceof DBPNamedObjectLocalized) {
|
||||
return ((DBPNamedObjectLocalized) property).getLocalizedName(session.getLocale());
|
||||
} else {
|
||||
return property.getDisplayName();
|
||||
}
|
||||
}
|
||||
|
||||
@Property
|
||||
public String getDescription() {
|
||||
if (property instanceof DBPObjectWithDescriptionLocalized) {
|
||||
return ((DBPObjectWithDescriptionLocalized) property).getLocalizedDescription(session.getLocale());
|
||||
} else {
|
||||
return property.getDescription();
|
||||
}
|
||||
}
|
||||
|
||||
@Property
|
||||
public String getCategory() {
|
||||
return property.getCategory();
|
||||
}
|
||||
|
||||
@Property
|
||||
public String getType() {
|
||||
return getDataType();
|
||||
}
|
||||
|
||||
@Property
|
||||
public String getDataType() {
|
||||
Class<?> dataType = property.getDataType();
|
||||
return dataType == null ? null : dataType.getSimpleName();
|
||||
}
|
||||
|
||||
@Property
|
||||
public Object getDefaultValue() throws DBException {
|
||||
return getValue();
|
||||
}
|
||||
|
||||
@Property
|
||||
public Object getValue() throws DBException {
|
||||
Object value = propertySource.getPropertyValue(session.getProgressMonitor(), property.getId());
|
||||
return value == null ? null : makePropertyValue(value);
|
||||
}
|
||||
|
||||
@Property
|
||||
public Object[] getValidValues() {
|
||||
if (property instanceof IPropertyValueListProvider) {
|
||||
Object[] possibleValues = ((IPropertyValueListProvider) property).getPossibleValues(propertySource.getEditableValue());
|
||||
if (possibleValues != null) {
|
||||
Object[] validValues = new Object[possibleValues.length];
|
||||
for (int i = 0; i < possibleValues.length; i++) {
|
||||
validValues[i] = makePropertyValue(possibleValues[i]);
|
||||
}
|
||||
return validValues;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Property
|
||||
public String[] getFeatures() {
|
||||
List<String> features = new ArrayList<>();
|
||||
if (property instanceof ObjectPropertyDescriptor) {
|
||||
ObjectPropertyDescriptor opd = (ObjectPropertyDescriptor)property;
|
||||
if (opd.isRequired()) features.add("required");
|
||||
if (opd.isSpecific()) features.add("specific");
|
||||
if (opd.isOptional()) features.add("optional");
|
||||
if (opd.isHidden()) features.add("hidden");
|
||||
if (opd.isRemote()) features.add("remote");
|
||||
|
||||
if (opd.isDateTime()) features.add("datetme");
|
||||
if (opd.isNumeric()) features.add("numeric");
|
||||
if (opd.isNameProperty()) features.add("name");
|
||||
|
||||
if (opd.isMultiLine()) features.add("multiline");
|
||||
if (opd.isExpensive()) features.add("expensive");
|
||||
if (opd.isEditPossible()) features.add("editPossible");
|
||||
if (opd.isLinkPossible()) features.add("linkPossible");
|
||||
if (opd.isViewable()) features.add("viewable");
|
||||
}
|
||||
return features.toArray(new String[0]);
|
||||
}
|
||||
|
||||
public boolean hasFeature(@NotNull String feature) {
|
||||
if (property instanceof ObjectPropertyDescriptor) {
|
||||
switch (feature) {
|
||||
case "required":
|
||||
return property.isRequired();
|
||||
case "specific":
|
||||
return ((ObjectPropertyDescriptor) property).isSpecific();
|
||||
case "optional":
|
||||
return ((ObjectPropertyDescriptor) property).isOptional();
|
||||
case "hidden":
|
||||
return ((ObjectPropertyDescriptor) property).isHidden();
|
||||
case "remote":
|
||||
return property.isRemote();
|
||||
|
||||
case "datetme":
|
||||
return ((ObjectPropertyDescriptor) property).isDateTime();
|
||||
case "numeric":
|
||||
return ((ObjectPropertyDescriptor) property).isNumeric();
|
||||
case "name":
|
||||
return ((ObjectPropertyDescriptor) property).isNameProperty();
|
||||
|
||||
case "multiline":
|
||||
return ((ObjectPropertyDescriptor) property).isMultiLine();
|
||||
case "expensive":
|
||||
return ((ObjectPropertyDescriptor) property).isExpensive();
|
||||
case "editPossible":
|
||||
return ((ObjectPropertyDescriptor) property).isEditPossible();
|
||||
case "linkPossible":
|
||||
return ((ObjectPropertyDescriptor) property).isLinkPossible();
|
||||
case "viewable":
|
||||
return ((ObjectPropertyDescriptor) property).isViewable();
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean hasAnyFeature(@NotNull List<String> features) {
|
||||
for (String feature : features) {
|
||||
if (hasFeature(feature)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return CommonUtils.toString(property.getId());
|
||||
}
|
||||
|
||||
private Object makePropertyValue(Object value) {
|
||||
if (value == null) {
|
||||
return null;
|
||||
// } else if (value instanceof DBSObject) {
|
||||
// return new WebDatabaseObjectInfo(session, (DBSObject) value);
|
||||
} else if (value instanceof DBPObject) {
|
||||
Map<String, Object> basicInfo = new LinkedHashMap<>();
|
||||
//WebBasicObjectInfo objectInfo = new WebBasicObjectInfo();
|
||||
if (value instanceof DBPNamedObject) {
|
||||
basicInfo.put("displayName", ((DBPNamedObject) value).getName());
|
||||
} else {
|
||||
basicInfo.put("value", CommonUtils.toString(value));
|
||||
}
|
||||
if (value instanceof DBPObjectWithDescription) {
|
||||
String description = ((DBPObjectWithDescription) value).getDescription();
|
||||
if (!CommonUtils.isEmpty(description)) {
|
||||
basicInfo.put("description", description);
|
||||
}
|
||||
}
|
||||
if (value instanceof DBPObjectWithLongId) {
|
||||
basicInfo.put("id", ((DBPObjectWithLongId) value).getObjectId());
|
||||
}
|
||||
if (value instanceof DBPQualifiedObject) {
|
||||
basicInfo.put("fullName", ((DBPQualifiedObject) value).getFullyQualifiedName(DBPEvaluationContext.UI));
|
||||
}
|
||||
if (value instanceof DBPUniqueObject) {
|
||||
basicInfo.put("uniqueName", ((DBPUniqueObject) value).getUniqueName());
|
||||
}
|
||||
return basicInfo;
|
||||
} else if (value instanceof Collection) {
|
||||
List<Object> result = new ArrayList<>();
|
||||
for (Object item : (Collection)value) {
|
||||
result.add(makePropertyValue(item));
|
||||
}
|
||||
return result;
|
||||
} else if (value.getClass().isArray()) {
|
||||
List<Object> result = new ArrayList<>();
|
||||
int length = Array.getLength(value);
|
||||
for (int i = 0; i < length; i++) {
|
||||
result.add(Array.get(value, i));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
return CommonUtils.toString(value);
|
||||
}
|
||||
|
||||
}
|
||||
+119
@@ -0,0 +1,119 @@
|
||||
/*
|
||||
* DBeaver - Universal Database Manager
|
||||
* Copyright (C) 2010-2020 DBeaver Corp and others
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
package io.cloudbeaver.server.model;
|
||||
|
||||
import io.cloudbeaver.server.registry.WebServiceDescriptor;
|
||||
import io.cloudbeaver.server.registry.WebServiceRegistry;
|
||||
import org.jkiss.dbeaver.model.meta.Property;
|
||||
import org.jkiss.dbeaver.model.meta.RuntimeAction;
|
||||
import org.jkiss.dbeaver.registry.language.PlatformLanguageDescriptor;
|
||||
import org.jkiss.dbeaver.registry.language.PlatformLanguageRegistry;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Web server configuration
|
||||
*/
|
||||
public class WebServerConfig {
|
||||
|
||||
private String name;
|
||||
private String version;
|
||||
private boolean supportsPredefinedConnections;
|
||||
private boolean supportsCustomConnections;
|
||||
private boolean supportsConnectionBrowser;
|
||||
private boolean supportsWorkspaces;
|
||||
|
||||
public WebServerConfig(String name, String version) {
|
||||
this.name = name;
|
||||
this.version = version;
|
||||
}
|
||||
|
||||
@Property
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Property
|
||||
public String getVersion() {
|
||||
return version;
|
||||
}
|
||||
|
||||
public void setVersion(String version) {
|
||||
this.version = version;
|
||||
}
|
||||
|
||||
@Property
|
||||
public boolean isSupportsPredefinedConnections() {
|
||||
return supportsPredefinedConnections;
|
||||
}
|
||||
|
||||
public void setSupportsPredefinedConnections(boolean supportsPredefinedConnections) {
|
||||
this.supportsPredefinedConnections = supportsPredefinedConnections;
|
||||
}
|
||||
|
||||
@Property
|
||||
public boolean isSupportsCustomConnections() {
|
||||
return supportsCustomConnections;
|
||||
}
|
||||
|
||||
public void setSupportsCustomConnections(boolean supportsCustomConnections) {
|
||||
this.supportsCustomConnections = supportsCustomConnections;
|
||||
}
|
||||
|
||||
@Property
|
||||
public boolean isSupportsConnectionBrowser() {
|
||||
return supportsConnectionBrowser;
|
||||
}
|
||||
|
||||
public void setSupportsConnectionBrowser(boolean supportsConnectionBrowser) {
|
||||
this.supportsConnectionBrowser = supportsConnectionBrowser;
|
||||
}
|
||||
|
||||
@Property
|
||||
public boolean isSupportsWorkspaces() {
|
||||
return supportsWorkspaces;
|
||||
}
|
||||
|
||||
public void setSupportsWorkspaces(boolean supportsWorkspaces) {
|
||||
this.supportsWorkspaces = supportsWorkspaces;
|
||||
}
|
||||
|
||||
@RuntimeAction
|
||||
public WebServerLanguage[] getSupportedLanguages() {
|
||||
List<PlatformLanguageDescriptor> langs = PlatformLanguageRegistry.getInstance().getLanguages();
|
||||
WebServerLanguage[] webLangs = new WebServerLanguage[langs.size()];
|
||||
for (int i = 0; i < webLangs.length; i++) {
|
||||
webLangs[i] = new WebServerLanguage(langs.get(i));
|
||||
}
|
||||
return webLangs;
|
||||
}
|
||||
|
||||
@RuntimeAction
|
||||
public WebServiceConfig[] getServices() {
|
||||
List<WebServiceConfig> services = new ArrayList<>();
|
||||
for (WebServiceDescriptor wsd : WebServiceRegistry.getInstance().getWebServices()) {
|
||||
services.add(new WebServiceConfig(wsd));
|
||||
}
|
||||
return services.toArray(new WebServiceConfig[0]);
|
||||
}
|
||||
|
||||
}
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* DBeaver - Universal Database Manager
|
||||
* Copyright (C) 2010-2020 DBeaver Corp and others
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
package io.cloudbeaver.server.model;
|
||||
|
||||
import org.jkiss.dbeaver.DBException;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
|
||||
/**
|
||||
* Web driver configuration
|
||||
*/
|
||||
public class WebServerError {
|
||||
|
||||
private String message;
|
||||
private String stackTrace;
|
||||
private String errorCode;
|
||||
|
||||
public WebServerError(Throwable ex) {
|
||||
this.message = ex.getMessage();
|
||||
StringWriter buf = new StringWriter();
|
||||
ex.printStackTrace(new PrintWriter(buf, true));
|
||||
this.stackTrace = buf.toString();
|
||||
if (ex instanceof DBException) {
|
||||
errorCode = String.valueOf(((DBException) ex).getErrorCode());
|
||||
}
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
public String getStackTrace() {
|
||||
return stackTrace;
|
||||
}
|
||||
|
||||
public String getErrorCode() {
|
||||
return errorCode;
|
||||
}
|
||||
|
||||
}
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* DBeaver - Universal Database Manager
|
||||
* Copyright (C) 2010-2020 DBeaver Corp and others
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
package io.cloudbeaver.server.model;
|
||||
|
||||
import org.jkiss.dbeaver.registry.language.PlatformLanguageDescriptor;
|
||||
|
||||
/**
|
||||
* Web server message
|
||||
*/
|
||||
public class WebServerLanguage {
|
||||
|
||||
private PlatformLanguageDescriptor languageDescriptor;
|
||||
|
||||
public WebServerLanguage(PlatformLanguageDescriptor languageDescriptor) {
|
||||
this.languageDescriptor = languageDescriptor;
|
||||
}
|
||||
|
||||
public String getIsoCode() {
|
||||
return languageDescriptor.getCode();
|
||||
}
|
||||
|
||||
public String getDisplayName() {
|
||||
return languageDescriptor.getLabel();
|
||||
}
|
||||
|
||||
public String getNativeName() {
|
||||
return languageDescriptor.getLocalizedName(getIsoCode());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getIsoCode();
|
||||
}
|
||||
}
|
||||
+60
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* DBeaver - Universal Database Manager
|
||||
* Copyright (C) 2010-2020 DBeaver Corp and others
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
package io.cloudbeaver.server.model;
|
||||
|
||||
import io.cloudbeaver.server.CloudbeaverConstants;
|
||||
|
||||
/**
|
||||
* Web server message
|
||||
*/
|
||||
public class WebServerMessage {
|
||||
|
||||
|
||||
public enum MessageType {
|
||||
DEBUG,
|
||||
INFO,
|
||||
WARNING,
|
||||
ERROR
|
||||
}
|
||||
|
||||
private final MessageType type;
|
||||
private long time;
|
||||
private String message;
|
||||
|
||||
public WebServerMessage(MessageType type, String message) {
|
||||
this.type = type;
|
||||
this.time = System.currentTimeMillis();
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public MessageType getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public String getTime() {
|
||||
return CloudbeaverConstants.ISO_DATE_FORMAT.format(time);
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
public String getStackTrace() {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
+53
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* DBeaver - Universal Database Manager
|
||||
* Copyright (C) 2010-2020 DBeaver Corp and others
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
package io.cloudbeaver.server.model;
|
||||
|
||||
import io.cloudbeaver.server.registry.WebServiceDescriptor;
|
||||
import org.jkiss.dbeaver.model.meta.Property;
|
||||
|
||||
/**
|
||||
* Web server configuration
|
||||
*/
|
||||
public class WebServiceConfig {
|
||||
|
||||
private final WebServiceDescriptor descriptor;
|
||||
|
||||
public WebServiceConfig(WebServiceDescriptor descriptor) {
|
||||
this.descriptor = descriptor;
|
||||
}
|
||||
|
||||
@Property
|
||||
public String getId() {
|
||||
return descriptor.getId();
|
||||
}
|
||||
|
||||
@Property
|
||||
public String getName() {
|
||||
return descriptor.getLabel();
|
||||
}
|
||||
|
||||
@Property
|
||||
public String getDescription() {
|
||||
return descriptor.getDescription();
|
||||
}
|
||||
|
||||
@Property
|
||||
public String getBundleVersion() {
|
||||
return descriptor.getContributorBundle().getVersion().toString();
|
||||
}
|
||||
|
||||
}
|
||||
+296
@@ -0,0 +1,296 @@
|
||||
/*
|
||||
* DBeaver - Universal Database Manager
|
||||
* Copyright (C) 2010-2020 DBeaver Corp and others
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
package io.cloudbeaver.server.model.resources;
|
||||
|
||||
import org.eclipse.core.resources.*;
|
||||
import org.eclipse.core.runtime.*;
|
||||
import org.eclipse.core.runtime.jobs.ISchedulingRule;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.net.URI;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Web workspace
|
||||
*/
|
||||
public class WebWorkspace implements IWorkspace {
|
||||
|
||||
@Override
|
||||
public void addResourceChangeListener(IResourceChangeListener listener) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addResourceChangeListener(IResourceChangeListener listener, int eventMask) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public ISavedState addSaveParticipant(Plugin plugin, ISaveParticipant participant) throws CoreException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ISavedState addSaveParticipant(String pluginId, ISaveParticipant participant) throws CoreException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void build(int kind, IProgressMonitor monitor) throws CoreException {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void build(IBuildConfiguration[] buildConfigs, int kind, boolean buildReferences, IProgressMonitor monitor) throws CoreException {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkpoint(boolean build) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public IProject[][] computePrerequisiteOrder(IProject[] projects) {
|
||||
return new IProject[0][];
|
||||
}
|
||||
|
||||
@Override
|
||||
public ProjectOrder computeProjectOrder(IProject[] projects) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IStatus copy(IResource[] resources, IPath destination, boolean force, IProgressMonitor monitor) throws CoreException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IStatus copy(IResource[] resources, IPath destination, int updateFlags, IProgressMonitor monitor) throws CoreException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IStatus delete(IResource[] resources, boolean force, IProgressMonitor monitor) throws CoreException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IStatus delete(IResource[] resources, int updateFlags, IProgressMonitor monitor) throws CoreException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteMarkers(IMarker[] markers) throws CoreException {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void forgetSavedTree(String pluginId) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public IFilterMatcherDescriptor[] getFilterMatcherDescriptors() {
|
||||
return new IFilterMatcherDescriptor[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public IFilterMatcherDescriptor getFilterMatcherDescriptor(String filterMatcherId) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IProjectNatureDescriptor[] getNatureDescriptors() {
|
||||
return new IProjectNatureDescriptor[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public IProjectNatureDescriptor getNatureDescriptor(String natureId) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<IProject, IProject[]> getDanglingReferences() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IWorkspaceDescription getDescription() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IWorkspaceRoot getRoot() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IResourceRuleFactory getRuleFactory() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ISynchronizer getSynchronizer() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAutoBuilding() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isTreeLocked() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IProjectDescription loadProjectDescription(IPath projectDescriptionFile) throws CoreException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IProjectDescription loadProjectDescription(InputStream projectDescriptionFile) throws CoreException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IStatus move(IResource[] resources, IPath destination, boolean force, IProgressMonitor monitor) throws CoreException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IStatus move(IResource[] resources, IPath destination, int updateFlags, IProgressMonitor monitor) throws CoreException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBuildConfiguration newBuildConfig(String projectName, String configName) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IProjectDescription newProjectDescription(String projectName) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeResourceChangeListener(IResourceChangeListener listener) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeSaveParticipant(Plugin plugin) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeSaveParticipant(String pluginId) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(ICoreRunnable action, ISchedulingRule rule, int flags, IProgressMonitor monitor) throws CoreException {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(ICoreRunnable action, IProgressMonitor monitor) throws CoreException {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(IWorkspaceRunnable action, ISchedulingRule rule, int flags, IProgressMonitor monitor) throws CoreException {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(IWorkspaceRunnable action, IProgressMonitor monitor) throws CoreException {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public IStatus save(boolean full, IProgressMonitor monitor) throws CoreException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDescription(IWorkspaceDescription description) throws CoreException {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] sortNatureSet(String[] natureIds) {
|
||||
return new String[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public IStatus validateEdit(IFile[] files, Object context) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IStatus validateFiltered(IResource resource) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IStatus validateLinkLocation(IResource resource, IPath location) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IStatus validateLinkLocationURI(IResource resource, URI location) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IStatus validateName(String segment, int typeMask) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IStatus validateNatureSet(String[] natureIds) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IStatus validatePath(String path, int typeMask) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IStatus validateProjectLocation(IProject project, IPath location) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IStatus validateProjectLocationURI(IProject project, URI location) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IPathVariableManager getPathVariableManager() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T getAdapter(Class<T> adapter) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
+548
@@ -0,0 +1,548 @@
|
||||
/*
|
||||
* DBeaver - Universal Database Manager
|
||||
* Copyright (C) 2010-2020 DBeaver Corp and others
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
package io.cloudbeaver.server.model.session;
|
||||
|
||||
import io.cloudbeaver.DBWebException;
|
||||
import io.cloudbeaver.WebServiceUtils;
|
||||
import io.cloudbeaver.server.CloudbeaverConstants;
|
||||
import io.cloudbeaver.server.CloudbeaverPlatform;
|
||||
import io.cloudbeaver.server.model.*;
|
||||
import io.cloudbeaver.server.model.sql.WebSQLProcessor;
|
||||
import org.eclipse.core.runtime.IStatus;
|
||||
import org.eclipse.core.runtime.Status;
|
||||
import org.jkiss.code.NotNull;
|
||||
import org.jkiss.code.Nullable;
|
||||
import org.jkiss.dbeaver.DBException;
|
||||
import org.jkiss.dbeaver.Log;
|
||||
import org.jkiss.dbeaver.model.DBPDataSourceContainer;
|
||||
import org.jkiss.dbeaver.model.app.DBPDataSourceRegistry;
|
||||
import org.jkiss.dbeaver.model.app.DBPPlatform;
|
||||
import org.jkiss.dbeaver.model.app.DBPProject;
|
||||
import org.jkiss.dbeaver.model.connection.DBPConnectionConfiguration;
|
||||
import org.jkiss.dbeaver.model.connection.DBPDriver;
|
||||
import org.jkiss.dbeaver.model.meta.Association;
|
||||
import org.jkiss.dbeaver.model.meta.Property;
|
||||
import org.jkiss.dbeaver.model.navigator.*;
|
||||
import org.jkiss.dbeaver.model.runtime.*;
|
||||
import org.jkiss.dbeaver.registry.DataSourceDescriptor;
|
||||
import org.jkiss.dbeaver.runtime.DBWorkbench;
|
||||
import org.jkiss.dbeaver.runtime.jobs.ConnectionTestJob;
|
||||
import org.jkiss.dbeaver.runtime.jobs.DisconnectJob;
|
||||
import org.jkiss.dbeaver.utils.RuntimeUtils;
|
||||
import org.jkiss.utils.CommonUtils;
|
||||
|
||||
import javax.servlet.http.HttpSession;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
/**
|
||||
* Web session.
|
||||
* Is the main source of data in web application
|
||||
*/
|
||||
public class WebSession {
|
||||
|
||||
private static final Log log = Log.getLog(WebSession.class);
|
||||
|
||||
public static final List<WebNavigatorNodeInfo> EMPTY_NODE_LIST = Collections.emptyList();
|
||||
|
||||
private static final String ATTR_LOCALE = "locale";
|
||||
|
||||
private static final AtomicInteger TASK_ID = new AtomicInteger();
|
||||
|
||||
private String id;
|
||||
private long createTime;
|
||||
private long lastAccessTime;
|
||||
|
||||
private String locale;
|
||||
|
||||
private final List<WebConnectionInfo> connections = new ArrayList<>();
|
||||
private final List<WebServerMessage> progressMessages = new ArrayList<>();
|
||||
|
||||
private final Map<String, WebAsyncTaskInfo> asyncTasks = new HashMap<>();
|
||||
|
||||
private DBNModel navigatorModel;
|
||||
private DBNProjectDatabases databases;
|
||||
private DBRProgressMonitor progressMonitor = new SessionProgressMonitor();
|
||||
|
||||
public WebSession(HttpSession httpSession) {
|
||||
this.id = httpSession.getId();
|
||||
this.createTime = System.currentTimeMillis();
|
||||
|
||||
this.updateInfo(httpSession);
|
||||
|
||||
DBPPlatform platform = DBWorkbench.getPlatform();
|
||||
this.navigatorModel = new DBNModel(platform, false);
|
||||
this.navigatorModel.initialize();
|
||||
|
||||
DBPProject project = platform.getWorkspace().getActiveProject();
|
||||
DBNProject projectNode = this.navigatorModel.getRoot().getProjectNode(project);
|
||||
this.databases = projectNode.getDatabases();
|
||||
this.locale = Locale.getDefault().getLanguage();
|
||||
|
||||
// Add all provided datasources to the session
|
||||
synchronized (connections) {
|
||||
for (DBPDataSourceContainer ds : databases.getDataSourceRegistry().getDataSources()) {
|
||||
if (ds.isProvided()) {
|
||||
WebConnectionInfo connectionInfo = new WebConnectionInfo(this, ds);
|
||||
connections.add(connectionInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Property
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Property
|
||||
public String getCreateTime() {
|
||||
return CloudbeaverConstants.ISO_DATE_FORMAT.format(createTime);
|
||||
}
|
||||
|
||||
@Property
|
||||
public String getLastAccessTime() {
|
||||
return CloudbeaverConstants.ISO_DATE_FORMAT.format(lastAccessTime);
|
||||
}
|
||||
|
||||
public long getLastAccessTimeMillis() {
|
||||
return lastAccessTime;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getLocale() {
|
||||
return locale;
|
||||
}
|
||||
|
||||
public void setLocale(String locale) {
|
||||
this.locale = locale;
|
||||
}
|
||||
|
||||
public DBNModel getNavigatorModel() {
|
||||
return navigatorModel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns and clears progress messages
|
||||
*/
|
||||
@Association
|
||||
public List<WebServerMessage> getProgressMessages() {
|
||||
synchronized (progressMessages) {
|
||||
List<WebServerMessage> copy = new ArrayList<>(progressMessages);
|
||||
progressMessages.clear();
|
||||
return copy;
|
||||
}
|
||||
}
|
||||
|
||||
public void updateInfo(HttpSession httpSession) {
|
||||
this.lastAccessTime = System.currentTimeMillis();
|
||||
this.locale = CommonUtils.toString(httpSession.getAttribute(ATTR_LOCALE), this.locale);
|
||||
}
|
||||
|
||||
@Association
|
||||
public List<WebConnectionInfo> getConnections() {
|
||||
synchronized (connections) {
|
||||
return new ArrayList<>(connections);
|
||||
}
|
||||
}
|
||||
|
||||
public WebConnectionInfo openConnectionFromTemplate(WebConnectionConfig config) throws DBWebException {
|
||||
String dataSourceId = config.getDataSourceId();
|
||||
if (CommonUtils.isEmpty(dataSourceId)) {
|
||||
throw new DBWebException("Only preconfigured data sources are supported yet");
|
||||
}
|
||||
DBPDataSourceRegistry templateRegistry = WebServiceUtils.getDataSourceRegistry();
|
||||
DBPDataSourceContainer dataSourceTemplate = templateRegistry.getDataSource(dataSourceId);
|
||||
if (dataSourceTemplate == null) {
|
||||
throw new DBWebException("Datasource '" + dataSourceId + "' not found");
|
||||
}
|
||||
|
||||
DBPDataSourceRegistry sessionRegistry = databases.getDataSourceRegistry();
|
||||
DBPDataSourceContainer newDataSource = sessionRegistry.createDataSource(dataSourceTemplate);
|
||||
newDataSource.setSavePassword(true);
|
||||
((DataSourceDescriptor)newDataSource).setTemporary(true);
|
||||
|
||||
DBPConnectionConfiguration cfg = newDataSource.getConnectionConfiguration();
|
||||
cfg.setUserName(config.getUserName());
|
||||
cfg.setUserPassword(config.getUserPassword());
|
||||
if (!CommonUtils.isEmpty(config.getName())) {
|
||||
newDataSource.setName(config.getName());
|
||||
}
|
||||
if (!CommonUtils.isEmpty(config.getDescription())) {
|
||||
newDataSource.setDescription(config.getDescription());
|
||||
}
|
||||
try {
|
||||
newDataSource.connect(getProgressMonitor(), true, false);
|
||||
} catch (DBException e) {
|
||||
throw new DBWebException("Error connecting to database", e);
|
||||
}
|
||||
sessionRegistry.addDataSource(newDataSource);
|
||||
|
||||
WebConnectionInfo connectionInfo = new WebConnectionInfo(this, newDataSource);
|
||||
synchronized (connections) {
|
||||
connections.add(connectionInfo);
|
||||
}
|
||||
|
||||
return connectionInfo;
|
||||
}
|
||||
|
||||
public WebConnectionInfo createConnection(WebConnectionConfig config) throws DBWebException {
|
||||
DBPDataSourceRegistry sessionRegistry = databases.getDataSourceRegistry();
|
||||
|
||||
DBPDataSourceContainer newDataSource = makeConnectionInstance(config, sessionRegistry);
|
||||
if (CommonUtils.isEmpty(newDataSource.getName())) {
|
||||
newDataSource.setName(CommonUtils.notNull(config.getName(), "NewConnection"));
|
||||
}
|
||||
((DataSourceDescriptor)newDataSource).setTemporary(true);
|
||||
sessionRegistry.addDataSource(newDataSource);
|
||||
|
||||
WebConnectionInfo connectionInfo = new WebConnectionInfo(this, newDataSource);
|
||||
synchronized (connections) {
|
||||
connections.add(connectionInfo);
|
||||
}
|
||||
|
||||
return connectionInfo;
|
||||
}
|
||||
|
||||
public WebConnectionInfo testConnection(WebConnectionConfig config) throws DBWebException {
|
||||
DBPDataSourceRegistry sessionRegistry = databases.getDataSourceRegistry();
|
||||
|
||||
DBPDataSourceContainer newDataSource = makeConnectionInstance(config, sessionRegistry);
|
||||
try {
|
||||
ConnectionTestJob ct = new ConnectionTestJob(newDataSource, param -> {});
|
||||
ct.run(getProgressMonitor());
|
||||
if (ct.getConnectError() != null) {
|
||||
throw new DBWebException("Connection failed", ct.getConnectError());
|
||||
}
|
||||
WebConnectionInfo connectionInfo = new WebConnectionInfo(this, newDataSource);
|
||||
connectionInfo.setConnectError(ct.getConnectError());
|
||||
connectionInfo.setServerVersion(ct.getServerVersion());
|
||||
connectionInfo.setClientVersion(ct.getClientVersion());
|
||||
connectionInfo.setConnectTime(RuntimeUtils.formatExecutionTime(ct.getConnectTime()));
|
||||
return connectionInfo;
|
||||
} catch (DBException e) {
|
||||
throw new DBWebException("Error connecting to database", e);
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private DBPDataSourceContainer makeConnectionInstance(WebConnectionConfig config, DBPDataSourceRegistry sessionRegistry) throws DBWebException {
|
||||
String driverId = config.getDriverId();
|
||||
if (CommonUtils.isEmpty(driverId)) {
|
||||
throw new DBWebException("Driver not specified");
|
||||
}
|
||||
DBPDriver driver = WebServiceUtils.getDriverById(driverId);
|
||||
|
||||
DBPConnectionConfiguration dsConfig = new DBPConnectionConfiguration();
|
||||
|
||||
DBPDataSourceContainer newDataSource = sessionRegistry.createDataSource(driver, dsConfig);
|
||||
newDataSource.setSavePassword(true);
|
||||
|
||||
if (!CommonUtils.isEmpty(config.getUrl())) {
|
||||
dsConfig.setUrl(config.getUrl());
|
||||
} else {
|
||||
dsConfig.setHostName(config.getHost());
|
||||
dsConfig.setHostPort(config.getPort());
|
||||
dsConfig.setDatabaseName(config.getDatabaseName());
|
||||
dsConfig.setServerName(config.getServerName());
|
||||
dsConfig.setUrl(driver.getDataSourceProvider().getConnectionURL(driver, dsConfig));
|
||||
}
|
||||
if (config.getProperties() != null) {
|
||||
for (Map.Entry<String, Object> pe : config.getProperties().entrySet()) {
|
||||
dsConfig.setProperty(pe.getKey(), CommonUtils.toString(pe.getValue()));
|
||||
}
|
||||
}
|
||||
dsConfig.setUserName(config.getUserName());
|
||||
dsConfig.setUserPassword(config.getUserPassword());
|
||||
newDataSource.setName(config.getName());
|
||||
newDataSource.setDescription(config.getDescription());
|
||||
return newDataSource;
|
||||
}
|
||||
|
||||
public boolean closeConnection(String connectionID) throws DBWebException {
|
||||
|
||||
WebConnectionInfo connectionInfo = getWebConnectionInfo(connectionID);
|
||||
|
||||
boolean disconnected = false;
|
||||
if (connectionInfo.isConnected()) {
|
||||
try {
|
||||
connectionInfo.getDataSourceContainer().disconnect(getProgressMonitor());
|
||||
disconnected = true;
|
||||
} catch (DBException e) {
|
||||
log.error("Error closing connection", e);
|
||||
}
|
||||
// Disconnect in async mode?
|
||||
//new DisconnectJob(connectionInfo.getDataSource()).schedule();
|
||||
}
|
||||
databases.getDataSourceRegistry().removeDataSource(connectionInfo.getDataSourceContainer());
|
||||
|
||||
synchronized (connections) {
|
||||
connections.remove(connectionInfo);
|
||||
}
|
||||
|
||||
return disconnected;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private WebConnectionInfo getWebConnectionInfo(String connectionID) throws DBWebException {
|
||||
WebConnectionInfo connectionInfo = null;
|
||||
synchronized (connections) {
|
||||
for (WebConnectionInfo ci : connections) {
|
||||
if (ci.getId().equals(connectionID)) {
|
||||
connectionInfo = ci;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (connectionInfo == null) {
|
||||
throw new DBWebException("Connection '" + connectionID + "' not found");
|
||||
}
|
||||
return connectionInfo;
|
||||
}
|
||||
|
||||
void close() {
|
||||
try {
|
||||
List<WebConnectionInfo> conCopy;
|
||||
synchronized (this.connections) {
|
||||
conCopy = new ArrayList<>(this.connections);
|
||||
this.connections.clear();
|
||||
}
|
||||
|
||||
for (WebConnectionInfo connectionInfo : conCopy) {
|
||||
if (connectionInfo.isConnected()) {
|
||||
new DisconnectJob(connectionInfo.getDataSourceContainer()).schedule();
|
||||
}
|
||||
}
|
||||
|
||||
if (this.navigatorModel != null) {
|
||||
this.navigatorModel.dispose();
|
||||
this.navigatorModel = null;
|
||||
}
|
||||
this.databases = null;
|
||||
} catch (Throwable e) {
|
||||
log.error(e);
|
||||
}
|
||||
}
|
||||
|
||||
public List<WebNavigatorNodeInfo> getNavigatorNodeChildren(String parentPath, Integer offset, Integer limit, Boolean onlyFolders) throws DBWebException {
|
||||
try {
|
||||
DBRProgressMonitor monitor = getProgressMonitor();
|
||||
|
||||
DBNNode parentNode = CommonUtils.isEmpty(parentPath) || "/".equals(parentPath) ? databases : navigatorModel.getNodeByPath(monitor, parentPath);
|
||||
if (parentNode == null) {
|
||||
throw new DBWebException("Node '" + parentPath + "' not found");
|
||||
}
|
||||
if (!parentNode.hasChildren(true)) {
|
||||
return EMPTY_NODE_LIST;
|
||||
}
|
||||
DBNNode[] nodeChildren = parentNode.getChildren(monitor);
|
||||
if (nodeChildren == null) {
|
||||
return EMPTY_NODE_LIST;
|
||||
}
|
||||
List<WebNavigatorNodeInfo> result = new ArrayList<>();
|
||||
for (DBNNode node : nodeChildren) {
|
||||
if (!CommonUtils.toBoolean(onlyFolders) || node instanceof DBNContainer) {
|
||||
result.add(new WebNavigatorNodeInfo(this, node));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
} catch (DBException e) {
|
||||
throw new DBWebException("Error getting navigator nodes", e);
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public WebNavigatorNodeInfo getNavigatorNodeInfo(String nodePath) throws DBWebException {
|
||||
try {
|
||||
DBRProgressMonitor monitor = getProgressMonitor();
|
||||
|
||||
DBNNode node = navigatorModel.getNodeByPath(monitor, nodePath);
|
||||
if (node == null) {
|
||||
throw new DBWebException("Navigator node '" + nodePath + "' not found");
|
||||
}
|
||||
return new WebNavigatorNodeInfo(this, node);
|
||||
} catch (DBException e) {
|
||||
throw new DBWebException("Error getting navigator node '" + nodePath + "'", e);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean refreshNavigatorNode(String nodePath) throws DBWebException {
|
||||
try {
|
||||
DBRProgressMonitor monitor = getProgressMonitor();
|
||||
|
||||
DBNNode node = navigatorModel.getNodeByPath(monitor, nodePath);
|
||||
if (node == null) {
|
||||
throw new DBWebException("Navigator node '" + nodePath + "' not found");
|
||||
}
|
||||
node.refreshNode(monitor, this);
|
||||
return true;
|
||||
} catch (DBException e) {
|
||||
throw new DBWebException("Error refreshing navigator node '" + nodePath + "'", e);
|
||||
}
|
||||
}
|
||||
|
||||
public DBRProgressMonitor getProgressMonitor() {
|
||||
return progressMonitor;
|
||||
}
|
||||
|
||||
public WebSQLProcessor getSQLProcessor(String connectionId) throws DBWebException {
|
||||
return getWebConnectionInfo(connectionId).getSQLProcessor();
|
||||
}
|
||||
|
||||
public List<WebDatabaseDriverConfig> getDriverList(@Nullable String driverId) {
|
||||
List<WebDatabaseDriverConfig> result = new ArrayList<>();
|
||||
for (DBPDriver driver : CloudbeaverPlatform.getInstance().getApplicableDrivers()) {
|
||||
if (driverId == null || driverId.equals(WebServiceUtils.makeDriverFullId(driver))) {
|
||||
result.add(new WebDatabaseDriverConfig(this, driver));
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////
|
||||
// Async model
|
||||
|
||||
public WebAsyncTaskInfo getAsyncTask(String taskId, String taskName, boolean create) {
|
||||
synchronized (asyncTasks) {
|
||||
WebAsyncTaskInfo taskInfo = asyncTasks.get(taskId);
|
||||
if (taskInfo == null && create) {
|
||||
taskInfo = new WebAsyncTaskInfo(taskId, taskName);
|
||||
asyncTasks.put(taskId, taskInfo);
|
||||
}
|
||||
return taskInfo;
|
||||
}
|
||||
}
|
||||
|
||||
public WebAsyncTaskInfo asyncTaskStatus(String taskId) throws DBWebException {
|
||||
synchronized (asyncTasks) {
|
||||
WebAsyncTaskInfo taskInfo = asyncTasks.get(taskId);
|
||||
if (taskInfo == null) {
|
||||
throw new DBWebException("Task '" + taskId + "' not found");
|
||||
}
|
||||
taskInfo.setRunning(taskInfo.getJob() != null && !taskInfo.getJob().isFinished());
|
||||
if (!taskInfo.isRunning()) {
|
||||
asyncTasks.remove(taskId);
|
||||
}
|
||||
return taskInfo;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean asyncTaskCancel(String taskId) throws DBWebException {
|
||||
WebAsyncTaskInfo taskInfo;
|
||||
synchronized (asyncTasks) {
|
||||
taskInfo = asyncTasks.get(taskId);
|
||||
if (taskInfo == null) {
|
||||
throw new DBWebException("Task '" + taskId + "' not found");
|
||||
}
|
||||
}
|
||||
AbstractJob job = taskInfo.getJob();
|
||||
if (job != null) {
|
||||
job.cancel();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public WebAsyncTaskInfo createAndRunAsyncTask(String taskName, DBRRunnableWithResult runnable) {
|
||||
int taskId = TASK_ID.incrementAndGet();
|
||||
WebAsyncTaskInfo asyncTask = getAsyncTask(String.valueOf(taskId), taskName, true);
|
||||
|
||||
AbstractJob job = new AbstractJob(taskName) {
|
||||
@Override
|
||||
protected IStatus run(DBRProgressMonitor monitor) {
|
||||
TaskProgressMonitor taskMonitor = new TaskProgressMonitor(monitor, asyncTask);
|
||||
try {
|
||||
runnable.run(taskMonitor);
|
||||
asyncTask.setResult(runnable.getResult());
|
||||
asyncTask.setStatus("Finished");
|
||||
asyncTask.setRunning(false);
|
||||
} catch (InvocationTargetException e) {
|
||||
asyncTask.setJobError(e.getTargetException());
|
||||
} catch (InterruptedException e) {
|
||||
asyncTask.setJobError(e);
|
||||
}
|
||||
return Status.OK_STATUS;
|
||||
}
|
||||
};
|
||||
|
||||
asyncTask.setJob(job);
|
||||
asyncTask.setRunning(true);
|
||||
job.schedule();
|
||||
return asyncTask;
|
||||
}
|
||||
|
||||
public List<WebServerMessage> readLog(Integer maxEntries, Boolean clearLog) {
|
||||
synchronized (progressMessages) {
|
||||
List<WebServerMessage> messages = new ArrayList<>();
|
||||
int entryCount = CommonUtils.toInt(maxEntries);
|
||||
if (entryCount == 0 || entryCount >= progressMessages.size()) {
|
||||
messages.addAll(progressMessages);
|
||||
if (CommonUtils.toBoolean(clearLog)) {
|
||||
progressMessages.clear();
|
||||
}
|
||||
} else {
|
||||
messages.addAll(progressMessages.subList(0, maxEntries));
|
||||
if (CommonUtils.toBoolean(clearLog)) {
|
||||
progressMessages.removeAll(messages);
|
||||
}
|
||||
}
|
||||
return messages;
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////
|
||||
// Utils
|
||||
|
||||
private class SessionProgressMonitor extends BaseProgressMonitor {
|
||||
@Override
|
||||
public void beginTask(String name, int totalWork) {
|
||||
synchronized (progressMessages) {
|
||||
progressMessages.add(new WebServerMessage(WebServerMessage.MessageType.INFO, name));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void subTask(String name) {
|
||||
synchronized (progressMessages) {
|
||||
progressMessages.add(new WebServerMessage(WebServerMessage.MessageType.INFO, name));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class TaskProgressMonitor extends ProxyProgressMonitor {
|
||||
|
||||
private final WebAsyncTaskInfo asyncTask;
|
||||
|
||||
public TaskProgressMonitor(DBRProgressMonitor original, WebAsyncTaskInfo asyncTask) {
|
||||
super(original);
|
||||
this.asyncTask = asyncTask;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beginTask(String name, int totalWork) {
|
||||
super.beginTask(name, totalWork);
|
||||
asyncTask.setStatus(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void subTask(String name) {
|
||||
super.subTask(name);
|
||||
asyncTask.setStatus(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
+149
@@ -0,0 +1,149 @@
|
||||
/*
|
||||
* DBeaver - Universal Database Manager
|
||||
* Copyright (C) 2010-2020 DBeaver Corp and others
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
package io.cloudbeaver.server.model.session;
|
||||
|
||||
import io.cloudbeaver.DBWebException;
|
||||
import io.cloudbeaver.server.CloudbeaverPlatform;
|
||||
import io.cloudbeaver.server.model.WebConnectionConfig;
|
||||
import io.cloudbeaver.server.model.WebConnectionInfo;
|
||||
import org.jkiss.code.NotNull;
|
||||
import org.jkiss.dbeaver.Log;
|
||||
import org.jkiss.dbeaver.runtime.DBWorkbench;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpSession;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Various constants
|
||||
*/
|
||||
public class WebSessionManager {
|
||||
|
||||
private static final Log log = Log.getLog(WebSessionManager.class);
|
||||
|
||||
private static WebSessionManager instance;
|
||||
|
||||
public synchronized static WebSessionManager getInstance() {
|
||||
if (instance == null) {
|
||||
instance = new WebSessionManager();
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
private final Map<String, WebSession> sessionMap = new HashMap<>();
|
||||
|
||||
public WebSessionManager() {
|
||||
}
|
||||
|
||||
public WebSession openSession(@NotNull HttpServletRequest request, boolean errorOnNoFound) throws DBWebException {
|
||||
HttpSession session = getOrCreateHttpSession(request);
|
||||
return getWebSession(session, errorOnNoFound);
|
||||
}
|
||||
|
||||
public boolean closeSession(@NotNull HttpServletRequest request) {
|
||||
HttpSession session = request.getSession();
|
||||
if (session != null) {
|
||||
WebSession webSession;
|
||||
synchronized (sessionMap) {
|
||||
webSession = sessionMap.remove(session.getId());
|
||||
}
|
||||
if (webSession != null) {
|
||||
log.debug("> Close session '" + session.getId() + "'");
|
||||
webSession.close();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean touchSession(@NotNull HttpServletRequest request) throws DBWebException {
|
||||
WebSession webSession = openSession(request, false);
|
||||
webSession.updateInfo(request.getSession());
|
||||
return true;
|
||||
}
|
||||
|
||||
public WebSession getWebSession(@NotNull HttpServletRequest request) throws DBWebException {
|
||||
return openSession(request, true);
|
||||
}
|
||||
|
||||
private HttpSession getOrCreateHttpSession(@NotNull HttpServletRequest request) {
|
||||
HttpSession session = request.getSession();
|
||||
if (session == null) {
|
||||
session = request.getSession(true);
|
||||
log.debug("New session: " + session.getId());
|
||||
}
|
||||
return session;
|
||||
}
|
||||
|
||||
public WebSession getWebSession(HttpSession httpSession, boolean errorOnNoFound) throws DBWebException {
|
||||
String sessionId = httpSession.getId();
|
||||
WebSession webSession;
|
||||
synchronized (sessionMap) {
|
||||
webSession = sessionMap.get(sessionId);
|
||||
if (webSession == null) {
|
||||
webSession = new WebSession(httpSession);
|
||||
sessionMap.put(sessionId, webSession);
|
||||
|
||||
if (!httpSession.isNew() && errorOnNoFound) {
|
||||
throw new DBWebException("Session has expired", DBWebException.ERROR_CODE_SESSION_EXPIRED);
|
||||
}
|
||||
|
||||
log.debug("> New web session '" + webSession.getId() + "'");
|
||||
} else {
|
||||
webSession.updateInfo(httpSession);
|
||||
}
|
||||
}
|
||||
return webSession;
|
||||
}
|
||||
|
||||
public WebConnectionInfo openConnection(HttpServletRequest servletRequest, Map<String, Object> config) throws DBWebException {
|
||||
return getWebSession(servletRequest).openConnectionFromTemplate(new WebConnectionConfig(config));
|
||||
}
|
||||
|
||||
public WebConnectionInfo createConnection(HttpServletRequest servletRequest, Map<String, Object> config) throws DBWebException {
|
||||
return getWebSession(servletRequest).createConnection(new WebConnectionConfig(config));
|
||||
}
|
||||
|
||||
public WebConnectionInfo testConnection(HttpServletRequest servletRequest, Map<String, Object> config) throws DBWebException {
|
||||
return getWebSession(servletRequest).testConnection(new WebConnectionConfig(config));
|
||||
}
|
||||
|
||||
public boolean closeConnection(HttpServletRequest servletRequest, String connectionId) throws DBWebException {
|
||||
return getWebSession(servletRequest).closeConnection(connectionId);
|
||||
}
|
||||
|
||||
public void expireIdleSessions() {
|
||||
long maxSessionIdleTime = DBWorkbench.getPlatform(CloudbeaverPlatform.class).getApplication().getMaxSessionIdleTime();
|
||||
|
||||
List<WebSession> expiredList = new ArrayList<>();
|
||||
synchronized (sessionMap) {
|
||||
for (Iterator<WebSession> iterator = sessionMap.values().iterator(); iterator.hasNext(); ) {
|
||||
WebSession session = iterator.next();
|
||||
long idleMillis = System.currentTimeMillis() - session.getLastAccessTimeMillis();
|
||||
if (idleMillis >= maxSessionIdleTime) {
|
||||
iterator.remove();
|
||||
expiredList.add(session);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (WebSession session : expiredList) {
|
||||
log.debug("> Expire session '" + session.getId() + "'");
|
||||
session.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* DBeaver - Universal Database Manager
|
||||
* Copyright (C) 2010-2020 DBeaver Corp and others
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
package io.cloudbeaver.server.model.sql;
|
||||
|
||||
import org.jkiss.dbeaver.model.exec.DBCExecutionContext;
|
||||
import org.jkiss.dbeaver.model.impl.AbstractExecutionSource;
|
||||
import org.jkiss.dbeaver.model.struct.DBSDataContainer;
|
||||
|
||||
class WebExecutionSource extends AbstractExecutionSource {
|
||||
public WebExecutionSource(DBSDataContainer dataContainer, DBCExecutionContext executionContext, Object controller) {
|
||||
super(dataContainer, executionContext, controller);
|
||||
}
|
||||
}
|
||||
+115
@@ -0,0 +1,115 @@
|
||||
/*
|
||||
* DBeaver - Universal Database Manager
|
||||
* Copyright (C) 2010-2020 DBeaver Corp and others
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
package io.cloudbeaver.server.model.sql;
|
||||
|
||||
import org.jkiss.code.NotNull;
|
||||
import org.jkiss.code.Nullable;
|
||||
import org.jkiss.dbeaver.Log;
|
||||
import org.jkiss.dbeaver.model.*;
|
||||
import org.jkiss.dbeaver.model.exec.DBCExecutionContext;
|
||||
import org.jkiss.dbeaver.model.sql.SQLSyntaxManager;
|
||||
import org.jkiss.dbeaver.model.sql.completion.SQLCompletionContext;
|
||||
import org.jkiss.dbeaver.model.sql.completion.SQLCompletionProposalBase;
|
||||
import org.jkiss.dbeaver.model.sql.completion.SQLCompletionRequest;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Web SQL dialect.
|
||||
*/
|
||||
public class WebSQLCompletionContext implements SQLCompletionContext {
|
||||
|
||||
private static final Log log = Log.getLog(WebSQLCompletionContext.class);
|
||||
|
||||
private final WebSQLContextInfo sqlContext;
|
||||
|
||||
public WebSQLCompletionContext(WebSQLContextInfo context) {
|
||||
this.sqlContext = context;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DBPDataSource getDataSource() {
|
||||
return sqlContext.getProcessor().getConnection().getDataSource();
|
||||
}
|
||||
|
||||
@Override
|
||||
public DBCExecutionContext getExecutionContext() {
|
||||
return DBUtils.getDefaultContext(
|
||||
sqlContext.getProcessor().getConnection().getDataSource(),
|
||||
false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SQLSyntaxManager getSyntaxManager() {
|
||||
return sqlContext.getProcessor().getSyntaxManager();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isUseFQNames() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isReplaceWords() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isShowServerHelp() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isUseShortNames() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getInsertCase() {
|
||||
return PROPOSAL_CASE_DEFAULT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSearchProcedures() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSearchInsideNames() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSortAlphabetically() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSearchGlobally() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isHideDuplicates() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SQLCompletionProposalBase createProposal(@NotNull SQLCompletionRequest request, @NotNull String displayString, @NotNull String replacementString, int cursorPosition, @Nullable DBPImage image, @NotNull DBPKeywordType proposalType, @Nullable String description, @Nullable DBPNamedObject object, @NotNull Map<String, Object> params) {
|
||||
return new SQLCompletionProposalBase(this, request.getWordDetector(), displayString, replacementString, cursorPosition, image, proposalType, description, object, params);
|
||||
}
|
||||
}
|
||||
+69
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* DBeaver - Universal Database Manager
|
||||
* Copyright (C) 2010-2020 DBeaver Corp and others
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
package io.cloudbeaver.server.model.sql;
|
||||
|
||||
import org.jkiss.dbeaver.Log;
|
||||
import org.jkiss.dbeaver.model.DBPImage;
|
||||
import org.jkiss.dbeaver.model.sql.completion.SQLCompletionProposalBase;
|
||||
|
||||
/**
|
||||
* Web SQL dialect.
|
||||
*/
|
||||
public class WebSQLCompletionProposal {
|
||||
|
||||
private static final Log log = Log.getLog(WebSQLCompletionProposal.class);
|
||||
|
||||
private SQLCompletionProposalBase proposal;
|
||||
|
||||
public WebSQLCompletionProposal(SQLCompletionProposalBase proposal) {
|
||||
this.proposal = proposal;
|
||||
}
|
||||
|
||||
public String getDisplayString() {
|
||||
return proposal.getDisplayString();
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
return proposal.getProposalType().name();
|
||||
}
|
||||
|
||||
public String getReplacementString() {
|
||||
return proposal.getReplacementString();
|
||||
}
|
||||
|
||||
public int getReplacementOffset() {
|
||||
return proposal.getReplacementOffset();
|
||||
}
|
||||
|
||||
public int getReplacementLength() {
|
||||
return proposal.getReplacementLength();
|
||||
}
|
||||
|
||||
public int getScore() {
|
||||
return proposal.getProposalScore();
|
||||
}
|
||||
|
||||
public String getIcon() {
|
||||
DBPImage image = proposal.getObjectImage();
|
||||
return image == null ? null : image.getLocation();
|
||||
}
|
||||
|
||||
public String getNodePath() {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
+255
@@ -0,0 +1,255 @@
|
||||
/*
|
||||
* DBeaver - Universal Database Manager
|
||||
* Copyright (C) 2010-2020 DBeaver Corp and others
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
package io.cloudbeaver.server.model.sql;
|
||||
|
||||
import io.cloudbeaver.DBWebException;
|
||||
import io.cloudbeaver.server.model.WebAsyncTaskInfo;
|
||||
import org.eclipse.jface.text.Document;
|
||||
import org.jkiss.code.NotNull;
|
||||
import org.jkiss.code.Nullable;
|
||||
import org.jkiss.dbeaver.DBException;
|
||||
import org.jkiss.dbeaver.Log;
|
||||
import org.jkiss.dbeaver.model.DBPDataSource;
|
||||
import org.jkiss.dbeaver.model.DBUtils;
|
||||
import org.jkiss.dbeaver.model.data.DBDAttributeBinding;
|
||||
import org.jkiss.dbeaver.model.exec.DBCExecutionContext;
|
||||
import org.jkiss.dbeaver.model.exec.DBExecUtils;
|
||||
import org.jkiss.dbeaver.model.impl.struct.ContextDefaultObjectsReader;
|
||||
import org.jkiss.dbeaver.model.meta.RuntimeAction;
|
||||
import org.jkiss.dbeaver.model.runtime.DBRProgressMonitor;
|
||||
import org.jkiss.dbeaver.model.runtime.DBRRunnableWithResult;
|
||||
import org.jkiss.dbeaver.model.sql.SQLQuery;
|
||||
import org.jkiss.dbeaver.model.sql.SQLScriptElement;
|
||||
import org.jkiss.dbeaver.model.sql.completion.SQLCompletionAnalyzer;
|
||||
import org.jkiss.dbeaver.model.sql.completion.SQLCompletionProposalBase;
|
||||
import org.jkiss.dbeaver.model.sql.completion.SQLCompletionRequest;
|
||||
import org.jkiss.dbeaver.model.struct.DBSDataContainer;
|
||||
import org.jkiss.dbeaver.model.struct.DBSObject;
|
||||
import org.jkiss.dbeaver.model.struct.DBSObjectContainer;
|
||||
import org.jkiss.dbeaver.model.struct.rdb.DBSCatalog;
|
||||
import org.jkiss.dbeaver.model.struct.rdb.DBSSchema;
|
||||
import org.jkiss.utils.CommonUtils;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
/**
|
||||
* WebSQLContextInfo.
|
||||
*/
|
||||
public class WebSQLContextInfo {
|
||||
|
||||
private static final Log log = Log.getLog(WebSQLContextInfo.class);
|
||||
|
||||
private WebSQLProcessor processor;
|
||||
private String id;
|
||||
private DBSCatalog defaultCatalog;
|
||||
private String defaultSchema;
|
||||
private Map<String, WebSQLResultsInfo> resultInfoMap = new HashMap<>();
|
||||
|
||||
private AtomicInteger resultId = new AtomicInteger();
|
||||
|
||||
public WebSQLContextInfo(WebSQLProcessor processor, String id, String catalogName, String schemaName) {
|
||||
this.processor = processor;
|
||||
this.id = id;
|
||||
|
||||
setContextDefaults(catalogName, schemaName);
|
||||
}
|
||||
|
||||
private void setContextDefaults(String catalogName, String schemaName) {
|
||||
DBPDataSource dataSource = this.processor.getConnection().getDataSource();
|
||||
|
||||
DBSObject defaultObject = null;
|
||||
if (CommonUtils.isEmpty(catalogName) && CommonUtils.isEmpty(schemaName)) {
|
||||
ContextDefaultObjectsReader defaultObjectsReader = new ContextDefaultObjectsReader(
|
||||
dataSource,
|
||||
DBUtils.getDefaultContext(dataSource, false)
|
||||
);
|
||||
defaultObjectsReader.setReadNodes(false);
|
||||
try {
|
||||
defaultObjectsReader.run(this.processor.getWebSession().getProgressMonitor());
|
||||
} catch (InvocationTargetException e) {
|
||||
log.error("Error reading context defaults", e.getTargetException());
|
||||
} catch (InterruptedException e) {
|
||||
// ignore
|
||||
}
|
||||
|
||||
catalogName = defaultObjectsReader.getDefaultCatalogName();
|
||||
defaultObject = defaultObjectsReader.getDefaultObject();
|
||||
}
|
||||
|
||||
if (defaultObject instanceof DBSCatalog) {
|
||||
this.defaultCatalog = (DBSCatalog) defaultObject;
|
||||
} else if (defaultObject instanceof DBSSchema) {
|
||||
this.defaultCatalog = DBUtils.getParentOfType(DBSCatalog.class, defaultObject);
|
||||
this.defaultSchema = defaultObject.getName();
|
||||
} else {
|
||||
if (defaultObject == null && (!CommonUtils.isEmpty(catalogName) || !CommonUtils.isEmpty(schemaName))) {
|
||||
String childObjectName = CommonUtils.toString(catalogName, schemaName);
|
||||
DBSObjectContainer objectContainer = DBUtils.getAdapter(DBSObjectContainer.class, dataSource);
|
||||
if (objectContainer != null) {
|
||||
try {
|
||||
DBSObject childObject = objectContainer.getChild(this.processor.getWebSession().getProgressMonitor(), childObjectName);
|
||||
if (childObject == null) {
|
||||
log.debug("Can't find child '" + childObjectName + "'");
|
||||
} else if (childObject instanceof DBSCatalog) {
|
||||
defaultCatalog = (DBSCatalog) childObject;
|
||||
} else if (childObject instanceof DBSSchema) {
|
||||
this.defaultCatalog = DBUtils.getParentOfType(DBSCatalog.class, childObject);
|
||||
this.defaultSchema = childObject.getName();
|
||||
}
|
||||
} catch (DBException e) {
|
||||
log.error("Error reading default object '" + childObjectName + "'", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (defaultSchema == null && schemaName != null) {
|
||||
defaultSchema = schemaName;
|
||||
}
|
||||
}
|
||||
|
||||
public WebSQLProcessor getProcessor() {
|
||||
return processor;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public String getDefaultCatalog() {
|
||||
return defaultCatalog == null ? null : defaultCatalog.getName();
|
||||
}
|
||||
|
||||
public void setDefaults(String catalogName, String schemaName) throws DBWebException {
|
||||
String oldCatalogName = defaultCatalog == null ? null : defaultCatalog.getName();
|
||||
setContextDefaults(catalogName, schemaName);
|
||||
try {
|
||||
DBExecUtils.setExecutionContextDefaults(
|
||||
processor.getWebSession().getProgressMonitor(),
|
||||
processor.getConnection().getDataSource(),
|
||||
processor.getExecutionContext(),
|
||||
defaultCatalog == null ? null : defaultCatalog.getName(),
|
||||
oldCatalogName,
|
||||
schemaName);
|
||||
} catch (DBException e) {
|
||||
throw new DBWebException("Error ", e);
|
||||
}
|
||||
}
|
||||
|
||||
@RuntimeAction
|
||||
public String getDefaultSchema() {
|
||||
if (defaultSchema == null) {
|
||||
DBCExecutionContext defaultContext = DBUtils.getDefaultContext(
|
||||
defaultCatalog != null ? defaultCatalog : processor.getConnection().getDataSource(), false);
|
||||
DBSObject ao = DBUtils.getActiveInstanceObject(defaultContext);
|
||||
if (ao instanceof DBSSchema) {
|
||||
defaultSchema = ao.getName();
|
||||
} else {
|
||||
defaultSchema = "";
|
||||
}
|
||||
}
|
||||
return CommonUtils.isEmpty(defaultSchema) ? null : defaultSchema;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public WebSQLExecuteInfo executeQuery(@NotNull String sql, @Nullable WebSQLDataFilter filter) throws DBException {
|
||||
return processor.executeQuery(this, sql, filter);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public WebSQLResultsInfo saveResult(@NotNull DBSDataContainer dataContainer, @NotNull DBDAttributeBinding[] attributes) {
|
||||
WebSQLResultsInfo resultInfo = new WebSQLResultsInfo(
|
||||
dataContainer,
|
||||
String.valueOf(resultId.incrementAndGet())
|
||||
);
|
||||
resultInfo.setAttributes(attributes);
|
||||
resultInfoMap.put(resultInfo.getId(), resultInfo);
|
||||
return resultInfo;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public WebSQLResultsInfo getResults(@NotNull String resultId) throws DBWebException {
|
||||
WebSQLResultsInfo resultsInfo = resultInfoMap.get(resultId);
|
||||
if (resultsInfo == null) {
|
||||
throw new DBWebException("Results '" + resultId + "' not found in context '" + getId() + "'@'" + processor.getConnection().getId() + "'");
|
||||
}
|
||||
return resultsInfo;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Boolean closeResult(@NotNull String resultId) {
|
||||
return resultInfoMap.remove(resultId) != null;
|
||||
}
|
||||
|
||||
public @NotNull WebSQLCompletionProposal[] getCompletionProposals(@NotNull String query, Integer position, Integer maxResults) throws DBWebException {
|
||||
try {
|
||||
DBPDataSource dataSource = processor.getConnection().getDataSourceContainer().getDataSource();
|
||||
Document document = new Document();
|
||||
document.set(query);
|
||||
SQLScriptElement activeQuery = new SQLQuery(dataSource, query);
|
||||
SQLCompletionRequest request = new SQLCompletionRequest(
|
||||
new WebSQLCompletionContext(this),
|
||||
document,
|
||||
position == null ? 0 : position,
|
||||
activeQuery,
|
||||
false
|
||||
);
|
||||
SQLCompletionAnalyzer analyzer = new SQLCompletionAnalyzer(request);
|
||||
analyzer.runAnalyzer(processor.getWebSession().getProgressMonitor());
|
||||
List<SQLCompletionProposalBase> proposals = analyzer.getProposals();
|
||||
if (maxResults == null) maxResults = 200;
|
||||
if (proposals.size() > maxResults) {
|
||||
proposals = proposals.subList(0, maxResults);
|
||||
}
|
||||
|
||||
WebSQLCompletionProposal[] result = new WebSQLCompletionProposal[proposals.size()];
|
||||
for (int i = 0; i < proposals.size(); i++) {
|
||||
result[i] = new WebSQLCompletionProposal(proposals.get(i));
|
||||
}
|
||||
return result;
|
||||
} catch (DBException e) {
|
||||
throw new DBWebException("Error processing SQL proposals", e);
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////
|
||||
// Async model
|
||||
|
||||
@NotNull
|
||||
public WebAsyncTaskInfo asyncExecuteQuery(@NotNull String sql, @Nullable WebSQLDataFilter filter) throws DBException {
|
||||
DBRRunnableWithResult<WebSQLExecuteInfo> runnable = new DBRRunnableWithResult<WebSQLExecuteInfo>() {
|
||||
@Override
|
||||
public void run(DBRProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
|
||||
try {
|
||||
result = processor.processQuery(monitor, WebSQLContextInfo.this, sql, filter);
|
||||
} catch (Throwable e) {
|
||||
throw new InvocationTargetException(e);
|
||||
}
|
||||
}
|
||||
};
|
||||
return processor.getWebSession().createAndRunAsyncTask("SQL execute", runnable);
|
||||
}
|
||||
|
||||
public void destroy() {
|
||||
resultInfoMap.clear();
|
||||
}
|
||||
|
||||
}
|
||||
+114
@@ -0,0 +1,114 @@
|
||||
/*
|
||||
* DBeaver - Universal Database Manager
|
||||
* Copyright (C) 2010-2020 DBeaver Corp and others
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
package io.cloudbeaver.server.model.sql;
|
||||
|
||||
import org.jkiss.dbeaver.model.data.DBDAttributeConstraint;
|
||||
import org.jkiss.dbeaver.model.data.DBDDataFilter;
|
||||
import org.jkiss.dbeaver.model.exec.DBCLogicalOperator;
|
||||
import org.jkiss.utils.CommonUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Web SQL data filter.
|
||||
*/
|
||||
public class WebSQLDataFilter {
|
||||
|
||||
private static final int DEFAULT_ROWS_NUMBER = 200;
|
||||
private static final int MAX_ROWS_NUMBER = 100000;
|
||||
|
||||
|
||||
private int offset;
|
||||
private int limit ;
|
||||
private String where;
|
||||
private List<WebSQLDataFilterConstraint> constraints = new ArrayList<>();
|
||||
|
||||
public WebSQLDataFilter() {
|
||||
this.offset = 0;
|
||||
this.limit = DEFAULT_ROWS_NUMBER;
|
||||
}
|
||||
|
||||
public WebSQLDataFilter(Map<String, Object> filterProps) {
|
||||
this.offset = CommonUtils.toInt(filterProps.get("offset"));
|
||||
this.limit = CommonUtils.toInt(filterProps.get("limit"));
|
||||
if (this.limit <= 0) {
|
||||
this.limit = DEFAULT_ROWS_NUMBER;
|
||||
} else if (this.limit > MAX_ROWS_NUMBER) {
|
||||
this.limit = MAX_ROWS_NUMBER;
|
||||
}
|
||||
this.where = CommonUtils.toString(filterProps.get("where"), null);
|
||||
Object constraints = filterProps.get("constraints");
|
||||
if (constraints instanceof Collection) {
|
||||
for (Object constrItem : (Collection)constraints) {
|
||||
if (constrItem instanceof Map) {
|
||||
this.constraints.add(
|
||||
new WebSQLDataFilterConstraint((Map<String, Object>)constrItem));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int getOffset() {
|
||||
return offset;
|
||||
}
|
||||
|
||||
public void setOffset(int offset) {
|
||||
this.offset = offset;
|
||||
}
|
||||
|
||||
public int getLimit() {
|
||||
return limit;
|
||||
}
|
||||
|
||||
public void setLimit(int limit) {
|
||||
this.limit = limit;
|
||||
}
|
||||
|
||||
public List<WebSQLDataFilterConstraint> getConstraints() {
|
||||
return constraints;
|
||||
}
|
||||
|
||||
public DBDDataFilter makeDataFilter() {
|
||||
DBDDataFilter dataFilter = new DBDDataFilter();
|
||||
dataFilter.setWhere(where);
|
||||
if (!CommonUtils.isEmpty(constraints)) {
|
||||
List<DBDAttributeConstraint> dbdConstraints = new ArrayList<>();
|
||||
for (WebSQLDataFilterConstraint webConstr : constraints) {
|
||||
DBDAttributeConstraint dbConstraint = new DBDAttributeConstraint(webConstr.getAttribute(), -1);
|
||||
if (webConstr.getOrderPosition() != null) {
|
||||
dbConstraint.setOrderPosition(webConstr.getOrderPosition());
|
||||
}
|
||||
if (webConstr.getOrderAsc() != null) {
|
||||
dbConstraint.setOrderDescending(!webConstr.getOrderAsc());
|
||||
}
|
||||
dbConstraint.setCriteria(webConstr.getCriteria());
|
||||
if (webConstr.getOperator() != null) {
|
||||
dbConstraint.setOperator(CommonUtils.valueOf(DBCLogicalOperator.class, webConstr.getOperator()));
|
||||
}
|
||||
if (webConstr.getValue() != null) {
|
||||
dbConstraint.setValue(webConstr.getValue());
|
||||
}
|
||||
dbdConstraints.add(dbConstraint);
|
||||
}
|
||||
dataFilter.addConstraints(dbdConstraints);
|
||||
}
|
||||
return dataFilter;
|
||||
}
|
||||
}
|
||||
+71
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* DBeaver - Universal Database Manager
|
||||
* Copyright (C) 2010-2020 DBeaver Corp and others
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
package io.cloudbeaver.server.model.sql;
|
||||
|
||||
import org.jkiss.utils.CommonUtils;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Web SQL data filter constraint.
|
||||
*/
|
||||
public class WebSQLDataFilterConstraint {
|
||||
|
||||
private String attribute;
|
||||
private Integer orderPosition;
|
||||
private Boolean orderAsc;
|
||||
|
||||
private String criteria;
|
||||
private String operator;
|
||||
private Object value;
|
||||
|
||||
public WebSQLDataFilterConstraint(Map<String, Object> map) {
|
||||
this.attribute = CommonUtils.toString(map.get("attribute"));
|
||||
this.orderPosition = map.containsKey("orderPosition") ?
|
||||
CommonUtils.toInt(map.get("orderPosition")) + 1 : // Use position + 1 because 0 means no ordering (because of legacy compatibility)
|
||||
null;
|
||||
this.orderAsc = map.containsKey("orderAsc") ? CommonUtils.toBoolean(map.get("orderAsc")) : null;
|
||||
|
||||
this.criteria = CommonUtils.toString(map.get("criteria"), null);
|
||||
this.operator = CommonUtils.toString(map.get("operator"), null);
|
||||
this.value = CommonUtils.toString(map.get("value"), null);
|
||||
}
|
||||
|
||||
public String getAttribute() {
|
||||
return attribute;
|
||||
}
|
||||
|
||||
public Integer getOrderPosition() {
|
||||
return orderPosition;
|
||||
}
|
||||
|
||||
public Boolean getOrderAsc() {
|
||||
return orderAsc;
|
||||
}
|
||||
|
||||
public String getCriteria() {
|
||||
return criteria;
|
||||
}
|
||||
|
||||
public String getOperator() {
|
||||
return operator;
|
||||
}
|
||||
|
||||
public Object getValue() {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
+83
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* DBeaver - Universal Database Manager
|
||||
* Copyright (C) 2010-2020 DBeaver Corp and others
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
package io.cloudbeaver.server.model.sql;
|
||||
|
||||
import org.jkiss.dbeaver.Log;
|
||||
import org.jkiss.dbeaver.model.DBPDataSource;
|
||||
import org.jkiss.dbeaver.model.sql.SQLDialect;
|
||||
import org.jkiss.utils.Pair;
|
||||
|
||||
/**
|
||||
* Web SQL dialect.
|
||||
*/
|
||||
public class WebSQLDialectInfo {
|
||||
|
||||
private static final Log log = Log.getLog(WebSQLDialectInfo.class);
|
||||
|
||||
private final DBPDataSource dataSource;
|
||||
private final SQLDialect dialect;
|
||||
|
||||
public WebSQLDialectInfo(DBPDataSource dataSource, SQLDialect dialect) {
|
||||
this.dataSource = dataSource;
|
||||
this.dialect = dialect;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return dialect.getDialectName();
|
||||
}
|
||||
|
||||
public String[] getDataTypes() {
|
||||
return dialect.getDataTypes(dataSource).toArray(new String[0]);
|
||||
}
|
||||
|
||||
public String[] getFunctions() {
|
||||
return dialect.getFunctions(dataSource).toArray(new String[0]);
|
||||
}
|
||||
|
||||
public String[] getReservedWords() {
|
||||
return dialect.getReservedWords().toArray(new String[0]);
|
||||
}
|
||||
|
||||
public String[][] getQuoteStrings() {
|
||||
return dialect.getIdentifierQuoteStrings();
|
||||
}
|
||||
|
||||
public String[] getSingleLineComments() {
|
||||
return dialect.getSingleLineComments();
|
||||
}
|
||||
|
||||
public String[][] getMultiLineComments() {
|
||||
Pair<String, String> mlComments = dialect.getMultiLineComments();
|
||||
if (mlComments == null) {
|
||||
return new String[0][];
|
||||
}
|
||||
return new String[][] { { mlComments.getFirst(), mlComments.getSecond() } };
|
||||
}
|
||||
|
||||
public String getCatalogSeparator() {
|
||||
return dialect.getCatalogSeparator();
|
||||
}
|
||||
|
||||
public String getStructSeparator() {
|
||||
return String.valueOf(dialect.getStructSeparator());
|
||||
}
|
||||
|
||||
public String getScriptDelimiter() {
|
||||
return dialect.getScriptDelimiter();
|
||||
}
|
||||
|
||||
}
|
||||
+59
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* DBeaver - Universal Database Manager
|
||||
* Copyright (C) 2010-2020 DBeaver Corp and others
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
package io.cloudbeaver.server.model.sql;
|
||||
|
||||
import org.jkiss.dbeaver.Log;
|
||||
import org.jkiss.dbeaver.model.meta.Property;
|
||||
|
||||
/**
|
||||
* WebSQLExecuteInfo.
|
||||
*/
|
||||
public class WebSQLExecuteInfo {
|
||||
|
||||
private static final Log log = Log.getLog(WebSQLExecuteInfo.class);
|
||||
|
||||
private String statusMessage;
|
||||
private long duration;
|
||||
private WebSQLQueryResults[] results;
|
||||
|
||||
@Property
|
||||
public String getStatusMessage() {
|
||||
return statusMessage;
|
||||
}
|
||||
|
||||
public void setStatusMessage(String statusMessage) {
|
||||
this.statusMessage = statusMessage;
|
||||
}
|
||||
|
||||
@Property
|
||||
public long getDuration() {
|
||||
return duration;
|
||||
}
|
||||
|
||||
public void setDuration(long duration) {
|
||||
this.duration = duration;
|
||||
}
|
||||
|
||||
@Property
|
||||
public WebSQLQueryResults[] getResults() {
|
||||
return results;
|
||||
}
|
||||
|
||||
public void setResults(WebSQLQueryResults[] results) {
|
||||
this.results = results;
|
||||
}
|
||||
}
|
||||
+488
@@ -0,0 +1,488 @@
|
||||
/*
|
||||
* DBeaver - Universal Database Manager
|
||||
* Copyright (C) 2010-2020 DBeaver Corp and others
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
package io.cloudbeaver.server.model.sql;
|
||||
|
||||
import io.cloudbeaver.DBWebException;
|
||||
import io.cloudbeaver.server.model.WebConnectionInfo;
|
||||
import io.cloudbeaver.server.model.WebDatabaseObjectInfo;
|
||||
import io.cloudbeaver.server.model.session.WebSession;
|
||||
import org.jkiss.code.NotNull;
|
||||
import org.jkiss.code.Nullable;
|
||||
import org.jkiss.dbeaver.DBException;
|
||||
import org.jkiss.dbeaver.Log;
|
||||
import org.jkiss.dbeaver.model.DBPDataSource;
|
||||
import org.jkiss.dbeaver.model.DBUtils;
|
||||
import org.jkiss.dbeaver.model.data.*;
|
||||
import org.jkiss.dbeaver.model.exec.*;
|
||||
import org.jkiss.dbeaver.model.impl.data.DBDValueError;
|
||||
import org.jkiss.dbeaver.model.impl.struct.ContextDefaultObjectsReader;
|
||||
import org.jkiss.dbeaver.model.meta.RuntimeAction;
|
||||
import org.jkiss.dbeaver.model.navigator.DBNDatabaseItem;
|
||||
import org.jkiss.dbeaver.model.navigator.DBNNode;
|
||||
import org.jkiss.dbeaver.model.runtime.DBRProgressMonitor;
|
||||
import org.jkiss.dbeaver.model.sql.SQLDialect;
|
||||
import org.jkiss.dbeaver.model.sql.SQLSyntaxManager;
|
||||
import org.jkiss.dbeaver.model.sql.SQLUtils;
|
||||
import org.jkiss.dbeaver.model.struct.DBSDataContainer;
|
||||
import org.jkiss.dbeaver.model.struct.DBSDataManipulator;
|
||||
import org.jkiss.dbeaver.model.struct.DBSEntity;
|
||||
import org.jkiss.dbeaver.model.struct.DBSObject;
|
||||
import org.jkiss.dbeaver.model.struct.rdb.DBSCatalog;
|
||||
import org.jkiss.utils.CommonUtils;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
/**
|
||||
* Web SQL processor.
|
||||
*/
|
||||
public class WebSQLProcessor {
|
||||
|
||||
private static final Log log = Log.getLog(WebSQLProcessor.class);
|
||||
|
||||
private static final int MAX_RESULTS_COUNT = 100;
|
||||
|
||||
private final WebSession webSession;
|
||||
private final WebConnectionInfo connection;
|
||||
private final SQLSyntaxManager syntaxManager;
|
||||
private final Map<String, WebSQLContextInfo> contexts = new LinkedHashMap<>();
|
||||
|
||||
private AtomicInteger contextId = new AtomicInteger();
|
||||
|
||||
public WebSQLProcessor(@NotNull WebSession webSession, @NotNull WebConnectionInfo connection) {
|
||||
this.webSession = webSession;
|
||||
this.connection = connection;
|
||||
|
||||
syntaxManager = new SQLSyntaxManager();
|
||||
syntaxManager.init(connection.getDataSource());
|
||||
}
|
||||
|
||||
public WebConnectionInfo getConnection() {
|
||||
return connection;
|
||||
}
|
||||
|
||||
WebSession getWebSession() {
|
||||
return webSession;
|
||||
}
|
||||
|
||||
SQLSyntaxManager getSyntaxManager() {
|
||||
return syntaxManager;
|
||||
}
|
||||
|
||||
DBCExecutionContext getExecutionContext() {
|
||||
return DBUtils.getDefaultContext(connection.getDataSource(), false);
|
||||
}
|
||||
|
||||
private DBCExecutionContext getExecutionContext(@NotNull DBSDataContainer dataContainer) {
|
||||
return DBUtils.getDefaultContext(dataContainer, false);
|
||||
}
|
||||
|
||||
@RuntimeAction
|
||||
@NotNull
|
||||
public WebSQLDialectInfo getDialectInfo() throws DBWebException {
|
||||
DBPDataSource dataSource = connection.getDataSourceContainer().getDataSource();
|
||||
SQLDialect dialect = SQLUtils.getDialectFromDataSource(dataSource);
|
||||
return new WebSQLDialectInfo(dataSource, dialect);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public WebSQLContextInfo createContext(String defaultCatalog, String defaultSchema) {
|
||||
String contextId = String.valueOf(this.contextId.incrementAndGet());
|
||||
WebSQLContextInfo contextInfo = new WebSQLContextInfo(this, contextId, defaultCatalog, defaultSchema);
|
||||
synchronized (contexts) {
|
||||
contexts.put(contextId, contextInfo);
|
||||
}
|
||||
return contextInfo;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public WebSQLContextInfo getContext(@NotNull String contextId) {
|
||||
synchronized (contexts) {
|
||||
return contexts.get(contextId);
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public WebSQLContextInfo[] getContexts() {
|
||||
synchronized (contexts) {
|
||||
return contexts.values().toArray(new WebSQLContextInfo[0]);
|
||||
}
|
||||
}
|
||||
|
||||
public void destroyContext(@NotNull String contextId) {
|
||||
WebSQLContextInfo contextInfo;
|
||||
synchronized (contexts) {
|
||||
contextInfo = contexts.get(contextId);
|
||||
}
|
||||
if (contextInfo != null) {
|
||||
contextInfo.destroy();
|
||||
}
|
||||
}
|
||||
|
||||
@RuntimeAction
|
||||
@NotNull
|
||||
public WebSQLExecuteInfo executeQuery(WebSQLContextInfo contextInfo, @NotNull String sql, @Nullable WebSQLDataFilter filter) throws DBWebException {
|
||||
return processQuery(webSession.getProgressMonitor(), contextInfo, sql, filter);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
WebSQLExecuteInfo processQuery(DBRProgressMonitor monitor, WebSQLContextInfo contextInfo, @NotNull String sql, @Nullable WebSQLDataFilter filter) throws DBWebException {
|
||||
if (filter == null) {
|
||||
// Use default filter
|
||||
filter = new WebSQLDataFilter();
|
||||
}
|
||||
long startTime = System.currentTimeMillis();
|
||||
WebSQLExecuteInfo executeInfo = new WebSQLExecuteInfo();
|
||||
|
||||
DBSDataContainer dataContainer = new WebSQLQueryDataContainer(connection.getDataSource(), sql);
|
||||
|
||||
DBCExecutionContext context = getExecutionContext(dataContainer);
|
||||
|
||||
{
|
||||
DBDDataFilter dataFilter = filter.makeDataFilter();
|
||||
if (dataFilter.hasFilters()) {
|
||||
sql = context.getDataSource().getSQLDialect().addFiltersToQuery(
|
||||
context.getDataSource(), sql, dataFilter);
|
||||
}
|
||||
}
|
||||
|
||||
final WebSQLDataFilter dataFilter = filter;
|
||||
final String sqlQuery = sql;
|
||||
|
||||
try {
|
||||
DBExecUtils.tryExecuteRecover(monitor, connection.getDataSource(), param -> {
|
||||
try (DBCSession session = context.openSession(monitor, DBCExecutionPurpose.USER, "Execute SQL")) {
|
||||
try (DBCStatement dbStat = session.prepareStatement(DBCStatementType.SCRIPT, sqlQuery, false, false, false)) {
|
||||
dbStat.setLimit(dataFilter.getOffset(), dataFilter.getLimit());
|
||||
boolean hasResultSet = dbStat.executeStatement();
|
||||
fillQueryResults(contextInfo, dataContainer, dbStat, hasResultSet, executeInfo, dataFilter);
|
||||
} catch (DBCException e) {
|
||||
throw new InvocationTargetException(e);
|
||||
}
|
||||
}
|
||||
});
|
||||
} catch (DBException e) {
|
||||
throw new DBWebException("Error executing query", e);
|
||||
}
|
||||
executeInfo.setDuration(System.currentTimeMillis() - startTime);
|
||||
if (executeInfo.getResults().length == 0) {
|
||||
executeInfo.setStatusMessage("No Data");
|
||||
} else {
|
||||
executeInfo.setStatusMessage("Success");
|
||||
}
|
||||
|
||||
return executeInfo;
|
||||
}
|
||||
|
||||
@RuntimeAction
|
||||
@NotNull
|
||||
public WebSQLExecuteInfo readDataFromContainer(@NotNull WebSQLContextInfo contextInfo, @NotNull String containerPath, @Nullable WebSQLDataFilter filter) throws DBWebException {
|
||||
try {
|
||||
DBRProgressMonitor monitor = webSession.getProgressMonitor();
|
||||
|
||||
DBSDataContainer dataContainer = getDataContainerByNodePath(monitor, containerPath, DBSDataContainer.class);
|
||||
|
||||
if (filter == null) {
|
||||
// Use default filter
|
||||
filter = new WebSQLDataFilter();
|
||||
}
|
||||
|
||||
return readDataFromContainer(contextInfo, monitor, dataContainer, filter);
|
||||
} catch (DBException e) {
|
||||
if (e instanceof DBWebException) throw (DBWebException) e;
|
||||
throw new DBWebException("Error reading data from '" + containerPath + "'", e);
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private WebSQLExecuteInfo readDataFromContainer(@NotNull WebSQLContextInfo contextInfo, @NotNull DBRProgressMonitor monitor, @NotNull DBSDataContainer dataContainer, @NotNull WebSQLDataFilter filter) throws DBException {
|
||||
|
||||
WebSQLExecuteInfo executeInfo = new WebSQLExecuteInfo();
|
||||
|
||||
DBCExecutionContext executionContext = getExecutionContext(dataContainer);
|
||||
DBDDataFilter dataFilter = filter.makeDataFilter();
|
||||
DBExecUtils.tryExecuteRecover(monitor, connection.getDataSource(), param -> {
|
||||
try (DBCSession session = executionContext.openSession(monitor, DBCExecutionPurpose.USER, "Read data from container")) {
|
||||
try (WebDataReceiver dataReceiver = new WebDataReceiver(contextInfo, dataContainer)) {
|
||||
DBCStatistics statistics = dataContainer.readData(
|
||||
new WebExecutionSource(dataContainer, executionContext, this),
|
||||
session,
|
||||
dataReceiver,
|
||||
dataFilter,
|
||||
filter.getOffset(),
|
||||
filter.getLimit(),
|
||||
DBSDataContainer.FLAG_NONE,
|
||||
filter.getLimit());
|
||||
executeInfo.setDuration(statistics.getTotalTime());
|
||||
|
||||
WebSQLQueryResults results = new WebSQLQueryResults();
|
||||
results.setResultSet(dataReceiver.getResultSet());
|
||||
executeInfo.setResults(new WebSQLQueryResults[]{results});
|
||||
|
||||
executeInfo.setStatusMessage(dataReceiver.getResultSet().getRows().length + " row(s) fetched");
|
||||
} catch (DBCException e) {
|
||||
throw new InvocationTargetException(e);
|
||||
}
|
||||
}
|
||||
});
|
||||
return executeInfo;
|
||||
}
|
||||
|
||||
@RuntimeAction
|
||||
public WebSQLExecuteInfo updateResultsData(
|
||||
@NotNull WebSQLContextInfo contextInfo,
|
||||
@NotNull String resultsId,
|
||||
@NotNull List<Object> updateRow,
|
||||
@NotNull Map<String, Object> updateValues) throws DBWebException
|
||||
{
|
||||
WebSQLResultsInfo resultsInfo = contextInfo.getResults(resultsId);
|
||||
|
||||
DBDRowIdentifier rowIdentifier = resultsInfo.getDefaultRowIdentifier();
|
||||
if (rowIdentifier == null) {
|
||||
throw new DBWebException("Can't detect row identifier for results '" + resultsId + "'");
|
||||
}
|
||||
DBSEntity dataContainer = rowIdentifier.getEntity();
|
||||
if (!(dataContainer instanceof DBSDataManipulator)) {
|
||||
throw new DBWebException("Data container '" + dataContainer.getName() + "' is not editable");
|
||||
}
|
||||
DBSDataManipulator dataManipulator = (DBSDataManipulator) dataContainer;
|
||||
|
||||
DBRProgressMonitor monitor = webSession.getProgressMonitor();
|
||||
WebSQLExecuteInfo result = new WebSQLExecuteInfo();
|
||||
|
||||
try {
|
||||
DBExecUtils.tryExecuteRecover(monitor, connection.getDataSource(), param -> {
|
||||
try {
|
||||
DBCExecutionContext executionContext = getExecutionContext(dataManipulator);
|
||||
try (DBCSession session = executionContext.openSession(monitor, DBCExecutionPurpose.USER, "Update data in container")) {
|
||||
WebExecutionSource executionSource = new WebExecutionSource(dataManipulator, executionContext, this);
|
||||
|
||||
DBDAttributeBinding[] allAttributes = resultsInfo.getAttributes();
|
||||
DBDAttributeBinding[] keyAttributes = rowIdentifier.getAttributes().toArray(new DBDAttributeBinding[0]);
|
||||
DBDAttributeBinding[] updateAttributes = new DBDAttributeBinding[updateValues.size()];
|
||||
// Final row is what we return back
|
||||
Object[] finalRow = updateRow.toArray();
|
||||
|
||||
int index = 0;
|
||||
for (String indexStr : updateValues.keySet()) {
|
||||
int attrIndex = CommonUtils.toInt(indexStr, -1);
|
||||
updateAttributes[index++] = allAttributes[attrIndex];
|
||||
}
|
||||
|
||||
Object[] rowValues = new Object[updateAttributes.length + keyAttributes.length];
|
||||
for (int i = 0; i < updateAttributes.length; i++) {
|
||||
DBDAttributeBinding updateAttribute = updateAttributes[i];
|
||||
Object cellRawValue = updateValues.get(String.valueOf(updateAttribute.getOrdinalPosition()));
|
||||
Object realCellValue = updateAttribute.getValueHandler().getValueFromObject(session, updateAttribute, cellRawValue, false, true);
|
||||
rowValues[i] = realCellValue;
|
||||
finalRow[updateAttribute.getOrdinalPosition()] = WebSQLUtils.makeWebCellValue(monitor, null, realCellValue);
|
||||
}
|
||||
for (int i = 0; i < keyAttributes.length; i++) {
|
||||
DBDAttributeBinding keyAttribute = keyAttributes[i];
|
||||
Object cellValueRaw = updateRow.get(keyAttribute.getOrdinalPosition());
|
||||
rowValues[updateAttributes.length + i] = keyAttribute.getValueHandler().getValueFromObject(session, keyAttribute, cellValueRaw, false, true);
|
||||
}
|
||||
|
||||
DBSDataManipulator.ExecuteBatch updateBatch = dataManipulator.updateData(session, updateAttributes, keyAttributes, null, executionSource);
|
||||
updateBatch.add(rowValues);
|
||||
DBCStatistics statistics = updateBatch.execute(session);
|
||||
|
||||
// Returns fake resultset with updated row values
|
||||
WebSQLQueryResultSet updatedResultSet = new WebSQLQueryResultSet();
|
||||
updatedResultSet.setResultsInfo(resultsInfo);
|
||||
updatedResultSet.setColumns(resultsInfo.getAttributes());
|
||||
updatedResultSet.setRows(new Object[][]{finalRow});
|
||||
|
||||
WebSQLQueryResults updateResults = new WebSQLQueryResults();
|
||||
updateResults.setUpdateRowCount((int) statistics.getRowsUpdated());
|
||||
updateResults.setResultSet(updatedResultSet);
|
||||
result.setDuration(statistics.getExecuteTime());
|
||||
result.setResults(new WebSQLQueryResults[]{updateResults});
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new InvocationTargetException(e);
|
||||
}
|
||||
});
|
||||
} catch (DBException e) {
|
||||
throw new DBWebException("Error updating data", e);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private <T> T getDataContainerByNodePath(DBRProgressMonitor monitor, @NotNull String containerPath, Class<T> type) throws DBException {
|
||||
DBNNode node = webSession.getNavigatorModel().getNodeByPath(monitor, containerPath);
|
||||
if (node == null) {
|
||||
throw new DBWebException("Container node '" + containerPath + "' not found");
|
||||
}
|
||||
if (!(node instanceof DBNDatabaseItem)) {
|
||||
throw new DBWebException("Container node '" + containerPath + "' is not a database item");
|
||||
}
|
||||
DBSObject object = ((DBNDatabaseItem) node).getObject();
|
||||
if (!type.isInstance(object)) {
|
||||
throw new DBWebException("Container node '" + containerPath + "' doesn't implement " + type.getName());
|
||||
}
|
||||
return type.cast(object);
|
||||
}
|
||||
|
||||
|
||||
private void fillQueryResults(WebSQLContextInfo contextInfo, @NotNull DBSDataContainer dataContainer, @NotNull DBCStatement dbStat, boolean hasResultSet, @NotNull WebSQLExecuteInfo executeInfo, @NotNull WebSQLDataFilter filter) throws DBCException {
|
||||
|
||||
List<WebSQLQueryResults> resultList = new ArrayList<>();
|
||||
for (int i = 0; i < MAX_RESULTS_COUNT; i++) {
|
||||
WebSQLQueryResults results = new WebSQLQueryResults();
|
||||
if (hasResultSet) {
|
||||
DBCResultSet resultSet = dbStat.openResultSet();
|
||||
if (resultSet == null) {
|
||||
break;
|
||||
}
|
||||
try (WebDataReceiver dataReceiver = new WebDataReceiver(contextInfo, dataContainer)) {
|
||||
readResultSet(dbStat.getSession(), resultSet, filter, dataReceiver);
|
||||
results.setResultSet(dataReceiver.getResultSet());
|
||||
}
|
||||
} else {
|
||||
int updateRowCount = dbStat.getUpdateRowCount();
|
||||
if (updateRowCount >= 0) {
|
||||
results.setUpdateRowCount(updateRowCount);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
resultList.add(results);
|
||||
hasResultSet = dbStat.nextResults();
|
||||
}
|
||||
|
||||
executeInfo.setResults(resultList.toArray(new WebSQLQueryResults[0]));
|
||||
}
|
||||
|
||||
private void readResultSet(@NotNull DBCSession session, @NotNull DBCResultSet dbResult, @NotNull WebSQLDataFilter filter, @NotNull WebDataReceiver dataReceiver) throws DBCException {
|
||||
dataReceiver.fetchStart(session, dbResult, filter.getOffset(), filter.getLimit());
|
||||
int rowCount = 0;
|
||||
while (dbResult.nextRow()) {
|
||||
if (rowCount > filter.getLimit()) {
|
||||
break;
|
||||
}
|
||||
|
||||
dataReceiver.fetchRow(session, dbResult);
|
||||
rowCount++;
|
||||
}
|
||||
dataReceiver.fetchEnd(session, dbResult);
|
||||
}
|
||||
|
||||
public WebStructContainers getStructContainers(String catalog) throws DBWebException {
|
||||
DBPDataSource dataSource = connection.getDataSource();
|
||||
ContextDefaultObjectsReader reader = new ContextDefaultObjectsReader(dataSource, getExecutionContext());
|
||||
reader.setReadNodes(false);
|
||||
try {
|
||||
reader.run(webSession.getProgressMonitor());
|
||||
} catch (InvocationTargetException e) {
|
||||
throw new DBWebException("Error reading context defaults", e.getTargetException());
|
||||
} catch (InterruptedException e) {
|
||||
// ignore
|
||||
}
|
||||
WebStructContainers structContainers = new WebStructContainers();
|
||||
for (DBSObject node : reader.getObjectList()) {
|
||||
if (!dataSource.getContainer().getNavigatorSettings().isShowSystemObjects() && DBUtils.isSystemObject(node)) {
|
||||
continue;
|
||||
}
|
||||
List<WebDatabaseObjectInfo> objectInfos = node instanceof DBSCatalog ? structContainers.getCatalogList() : structContainers.getSchemaList();
|
||||
objectInfos.add(new WebDatabaseObjectInfo(webSession, node));
|
||||
}
|
||||
return structContainers;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////
|
||||
// Utils
|
||||
|
||||
private class WebDataReceiver implements DBDDataReceiver {
|
||||
private final WebSQLContextInfo contextInfo;
|
||||
private DBSDataContainer dataContainer;
|
||||
private WebSQLQueryResultSet webResultSet = new WebSQLQueryResultSet();
|
||||
|
||||
private DBDAttributeBindingMeta[] bindings;
|
||||
private List<Object[]> rows = new ArrayList<>();
|
||||
|
||||
public WebDataReceiver(WebSQLContextInfo contextInfo, DBSDataContainer dataContainer) {
|
||||
this.contextInfo = contextInfo;
|
||||
this.dataContainer = dataContainer;
|
||||
}
|
||||
|
||||
public WebSQLQueryResultSet getResultSet() {
|
||||
return webResultSet;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fetchStart(DBCSession session, DBCResultSet dbResult, long offset, long maxRows) throws DBCException {
|
||||
DBCResultSetMetaData meta = dbResult.getMeta();
|
||||
List<DBCAttributeMetaData> attributes = meta.getAttributes();
|
||||
bindings = new DBDAttributeBindingMeta[attributes.size()];
|
||||
for (int i = 0; i < attributes.size(); i++) {
|
||||
DBCAttributeMetaData attrMeta = attributes.get(i);
|
||||
bindings[i] = new DBDAttributeBindingMeta(dataContainer, dbResult.getSession(), attrMeta);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fetchRow(DBCSession session, DBCResultSet resultSet) throws DBCException {
|
||||
Object[] row = new Object[bindings.length];
|
||||
|
||||
for (int i = 0; i < bindings.length; i++) {
|
||||
DBDAttributeBindingMeta binding = bindings[i];
|
||||
try {
|
||||
Object cellValue = binding.getValueHandler().fetchValueObject(
|
||||
resultSet.getSession(),
|
||||
resultSet,
|
||||
binding.getMetaAttribute(),
|
||||
i);
|
||||
row[i] = WebSQLUtils.makeWebCellValue(session.getProgressMonitor(), binding, cellValue);
|
||||
} catch (Throwable e) {
|
||||
row[i] = new DBDValueError(e);
|
||||
}
|
||||
}
|
||||
|
||||
rows.add(row);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fetchEnd(DBCSession session, DBCResultSet resultSet) throws DBCException {
|
||||
webResultSet.setRows(rows.toArray(new Object[0][]));
|
||||
|
||||
DBSEntity entity = dataContainer instanceof DBSEntity ? (DBSEntity) dataContainer : null;
|
||||
|
||||
try {
|
||||
DBExecUtils.bindAttributes(session, entity, resultSet, bindings, rows);
|
||||
} catch (DBException e) {
|
||||
log.error("Error binding attributes", e);
|
||||
}
|
||||
|
||||
webResultSet.setColumns(bindings);
|
||||
|
||||
WebSQLResultsInfo resultsInfo = contextInfo.saveResult(dataContainer, bindings);
|
||||
webResultSet.setResultsInfo(resultsInfo);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
rows.clear();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+91
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* DBeaver - Universal Database Manager
|
||||
* Copyright (C) 2010-2020 DBeaver Corp and others
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
package io.cloudbeaver.server.model.sql;
|
||||
|
||||
import org.jkiss.code.NotNull;
|
||||
import org.jkiss.code.Nullable;
|
||||
import org.jkiss.dbeaver.Log;
|
||||
import org.jkiss.dbeaver.model.DBPDataSource;
|
||||
import org.jkiss.dbeaver.model.data.DBDDataFilter;
|
||||
import org.jkiss.dbeaver.model.data.DBDDataReceiver;
|
||||
import org.jkiss.dbeaver.model.exec.DBCException;
|
||||
import org.jkiss.dbeaver.model.exec.DBCExecutionSource;
|
||||
import org.jkiss.dbeaver.model.exec.DBCSession;
|
||||
import org.jkiss.dbeaver.model.exec.DBCStatistics;
|
||||
import org.jkiss.dbeaver.model.struct.DBSDataContainer;
|
||||
import org.jkiss.dbeaver.model.struct.DBSObject;
|
||||
|
||||
/**
|
||||
* Web SQL query data container.
|
||||
*/
|
||||
public class WebSQLQueryDataContainer implements DBSDataContainer {
|
||||
|
||||
private static final Log log = Log.getLog(WebSQLQueryDataContainer.class);
|
||||
|
||||
private DBPDataSource dataSource;
|
||||
private String query;
|
||||
|
||||
public WebSQLQueryDataContainer(DBPDataSource dataSource, String query) {
|
||||
this.dataSource = dataSource;
|
||||
this.query = query;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public DBSObject getParentObject() {
|
||||
return dataSource;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getName() {
|
||||
return query;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPersisted() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public DBPDataSource getDataSource() {
|
||||
return dataSource;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSupportedFeatures() {
|
||||
return DATA_SELECT | DATA_FILTER | DATA_COUNT;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public DBCStatistics readData(@NotNull DBCExecutionSource source, @NotNull DBCSession session, @NotNull DBDDataReceiver dataReceiver, @Nullable DBDDataFilter dataFilter, long firstRow, long maxRows, long flags, int fetchSize) throws DBCException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long countData(@NotNull DBCExecutionSource source, @NotNull DBCSession session, @Nullable DBDDataFilter dataFilter, long flags) throws DBCException {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
+92
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* DBeaver - Universal Database Manager
|
||||
* Copyright (C) 2010-2020 DBeaver Corp and others
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
package io.cloudbeaver.server.model.sql;
|
||||
|
||||
import org.jkiss.dbeaver.Log;
|
||||
import org.jkiss.dbeaver.model.DBValueFormatting;
|
||||
import org.jkiss.dbeaver.model.data.DBDAttributeBinding;
|
||||
import org.jkiss.dbeaver.model.meta.Property;
|
||||
|
||||
/**
|
||||
* Web SQL query resultset.
|
||||
*/
|
||||
public class WebSQLQueryResultColumn {
|
||||
|
||||
private static final Log log = Log.getLog(WebSQLQueryResultColumn.class);
|
||||
|
||||
private final DBDAttributeBinding attrMeta;
|
||||
|
||||
public WebSQLQueryResultColumn(DBDAttributeBinding attrMeta) {
|
||||
this.attrMeta = attrMeta;
|
||||
}
|
||||
|
||||
@Property
|
||||
public Integer getPosition() {
|
||||
return attrMeta.getOrdinalPosition();
|
||||
}
|
||||
|
||||
@Property
|
||||
public String getName() {
|
||||
return attrMeta.getName();
|
||||
}
|
||||
|
||||
@Property
|
||||
public String getLabel() {
|
||||
return attrMeta.getLabel();
|
||||
}
|
||||
|
||||
@Property
|
||||
public String getIcon() {
|
||||
return DBValueFormatting.getObjectImage(attrMeta).getLocation();
|
||||
}
|
||||
|
||||
@Property
|
||||
public String getEntityName() {
|
||||
return attrMeta.getMetaAttribute().getEntityName();
|
||||
}
|
||||
|
||||
@Property
|
||||
public String getDataKind() {
|
||||
return attrMeta.getDataKind().name();
|
||||
}
|
||||
|
||||
@Property
|
||||
public String getTypeName() {
|
||||
return attrMeta.getTypeName();
|
||||
}
|
||||
|
||||
@Property
|
||||
public String getFullTypeName() {
|
||||
return attrMeta.getFullTypeName();
|
||||
}
|
||||
|
||||
@Property
|
||||
public long getMaxLength() {
|
||||
return attrMeta.getMaxLength();
|
||||
}
|
||||
|
||||
@Property
|
||||
public Integer getScale() {
|
||||
return attrMeta.getScale();
|
||||
}
|
||||
|
||||
@Property
|
||||
public Integer getPrecision() {
|
||||
return attrMeta.getPrecision();
|
||||
}
|
||||
|
||||
}
|
||||
+82
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* DBeaver - Universal Database Manager
|
||||
* Copyright (C) 2010-2020 DBeaver Corp and others
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
package io.cloudbeaver.server.model.sql;
|
||||
|
||||
import org.jkiss.dbeaver.Log;
|
||||
import org.jkiss.dbeaver.model.data.DBDAttributeBinding;
|
||||
import org.jkiss.dbeaver.model.meta.Property;
|
||||
|
||||
/**
|
||||
* Web SQL query resultset.
|
||||
*/
|
||||
public class WebSQLQueryResultSet {
|
||||
|
||||
private static final Log log = Log.getLog(WebSQLQueryResultSet.class);
|
||||
|
||||
private WebSQLQueryResultColumn[] columns;
|
||||
private Object[][] rows;
|
||||
private boolean hasMoreData;
|
||||
private WebSQLResultsInfo resultsInfo;
|
||||
|
||||
@Property
|
||||
public String getId() {
|
||||
return resultsInfo == null ? null : resultsInfo.getId();
|
||||
}
|
||||
|
||||
@Property
|
||||
public WebSQLQueryResultColumn[] getColumns() {
|
||||
return columns;
|
||||
}
|
||||
|
||||
public void setColumns(WebSQLQueryResultColumn[] columns) {
|
||||
this.columns = columns;
|
||||
}
|
||||
|
||||
public void setColumns(DBDAttributeBinding[] bindings) {
|
||||
WebSQLQueryResultColumn[] columns = new WebSQLQueryResultColumn[bindings.length];
|
||||
for (int i = 0; i < bindings.length; i++) {
|
||||
columns[i] = new WebSQLQueryResultColumn(bindings[i]);
|
||||
}
|
||||
this.columns = columns;
|
||||
}
|
||||
|
||||
@Property
|
||||
public Object[][] getRows() {
|
||||
return rows;
|
||||
}
|
||||
|
||||
public void setRows(Object[][] rows) {
|
||||
this.rows = rows;
|
||||
}
|
||||
|
||||
@Property
|
||||
public boolean isHasMoreData() {
|
||||
return hasMoreData;
|
||||
}
|
||||
|
||||
public void setHasMoreData(boolean hasMoreData) {
|
||||
this.hasMoreData = hasMoreData;
|
||||
}
|
||||
|
||||
public void setResultsInfo(WebSQLResultsInfo resultsInfo) {
|
||||
this.resultsInfo = resultsInfo;
|
||||
}
|
||||
|
||||
public WebSQLResultsInfo getResultsInfo() {
|
||||
return resultsInfo;
|
||||
}
|
||||
}
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* DBeaver - Universal Database Manager
|
||||
* Copyright (C) 2010-2020 DBeaver Corp and others
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
package io.cloudbeaver.server.model.sql;
|
||||
|
||||
import org.jkiss.dbeaver.model.meta.Property;
|
||||
|
||||
/**
|
||||
* Web SQL query results.
|
||||
*/
|
||||
public class WebSQLQueryResults {
|
||||
|
||||
private Integer updateRowCount;
|
||||
private WebSQLQueryResultSet resultSet;
|
||||
|
||||
@Property
|
||||
public Integer getUpdateRowCount() {
|
||||
return updateRowCount;
|
||||
}
|
||||
|
||||
public void setUpdateRowCount(int updateRowCount) {
|
||||
this.updateRowCount = updateRowCount;
|
||||
}
|
||||
|
||||
@Property
|
||||
public WebSQLQueryResultSet getResultSet() {
|
||||
return resultSet;
|
||||
}
|
||||
|
||||
public void setResultSet(WebSQLQueryResultSet resultSet) {
|
||||
this.resultSet = resultSet;
|
||||
}
|
||||
}
|
||||
+70
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* DBeaver - Universal Database Manager
|
||||
* Copyright (C) 2010-2020 DBeaver Corp and others
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
package io.cloudbeaver.server.model.sql;
|
||||
|
||||
import org.jkiss.code.NotNull;
|
||||
import org.jkiss.code.Nullable;
|
||||
import org.jkiss.dbeaver.model.data.DBDAttributeBinding;
|
||||
import org.jkiss.dbeaver.model.data.DBDRowIdentifier;
|
||||
import org.jkiss.dbeaver.model.struct.DBSDataContainer;
|
||||
|
||||
/**
|
||||
* Web query results info.
|
||||
*/
|
||||
public class WebSQLResultsInfo {
|
||||
|
||||
@NotNull
|
||||
private final DBSDataContainer dataContainer;
|
||||
@NotNull
|
||||
private final String id;
|
||||
private DBDAttributeBinding[] attributes;
|
||||
|
||||
public WebSQLResultsInfo(@NotNull DBSDataContainer dataContainer, @NotNull String id) {
|
||||
this.dataContainer = dataContainer;
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public DBSDataContainer getDataContainer() {
|
||||
return dataContainer;
|
||||
}
|
||||
|
||||
public DBDAttributeBinding[] getAttributes() {
|
||||
return attributes;
|
||||
}
|
||||
|
||||
public void setAttributes(DBDAttributeBinding[] attributes) {
|
||||
this.attributes = attributes;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public DBDRowIdentifier getDefaultRowIdentifier() {
|
||||
for (DBDAttributeBinding column : attributes) {
|
||||
DBDRowIdentifier rowIdentifier = column.getRowIdentifier();
|
||||
if (rowIdentifier != null) {
|
||||
return rowIdentifier;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
+94
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
* DBeaver - Universal Database Manager
|
||||
* Copyright (C) 2010-2020 DBeaver Corp and others
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
package io.cloudbeaver.server.model.sql;
|
||||
|
||||
import io.cloudbeaver.server.CloudbeaverConstants;
|
||||
import org.jkiss.dbeaver.Log;
|
||||
import org.jkiss.dbeaver.model.data.*;
|
||||
import org.jkiss.dbeaver.model.exec.DBCException;
|
||||
import org.jkiss.dbeaver.model.gis.DBGeometry;
|
||||
import org.jkiss.dbeaver.model.runtime.DBRProgressMonitor;
|
||||
import org.jkiss.dbeaver.model.struct.DBSAttributeBase;
|
||||
import org.jkiss.dbeaver.model.struct.DBSTypedObject;
|
||||
import org.jkiss.dbeaver.utils.ContentUtils;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Web SQL utils.
|
||||
*/
|
||||
public class WebSQLUtils {
|
||||
|
||||
private static final Log log = Log.getLog(WebSQLUtils.class);
|
||||
|
||||
public static Object makeWebCellValue(DBRProgressMonitor monitor, DBSTypedObject type, Object cellValue) throws DBCException {
|
||||
if (cellValue instanceof Date) {
|
||||
return CloudbeaverConstants.ISO_DATE_FORMAT.format(cellValue);
|
||||
}
|
||||
if (cellValue instanceof DBDValue) {
|
||||
DBDValue dbValue = (DBDValue) cellValue;
|
||||
if (dbValue.isNull()) {
|
||||
return null;
|
||||
}
|
||||
if (dbValue instanceof DBDComplexValue) {
|
||||
return serializeComplexValue(monitor, (DBDComplexValue)dbValue);
|
||||
} else if (dbValue instanceof DBGeometry) {
|
||||
return serializeGeometryValue((DBGeometry)dbValue);
|
||||
} else if (dbValue instanceof DBDContent) {
|
||||
return serializeContentValue(monitor, (DBDContent)dbValue);
|
||||
} else if (dbValue instanceof DBDDocument) {
|
||||
return serializeDocumentValue((DBDDocument)dbValue);
|
||||
}
|
||||
}
|
||||
return cellValue;
|
||||
}
|
||||
|
||||
private static Object serializeComplexValue(DBRProgressMonitor monitor, DBDComplexValue value) throws DBCException {
|
||||
if (value instanceof DBDCollection) {
|
||||
DBDCollection collection = (DBDCollection) value;
|
||||
int size = collection.getItemCount();
|
||||
Object[] items = new Object[size];
|
||||
for (int i = 0; i < size; i++) {
|
||||
items[i] = makeWebCellValue(monitor, collection.getComponentType(), collection.getItem(i));
|
||||
}
|
||||
return items;
|
||||
} else if (value instanceof DBDComposite) {
|
||||
DBDComposite composite = (DBDComposite)value;
|
||||
Map<String, Object> map = new LinkedHashMap<>();
|
||||
for (DBSAttributeBase attr : composite.getAttributes()) {
|
||||
map.put(attr.getName(), makeWebCellValue(monitor, attr, composite.getAttributeValue(attr)));
|
||||
}
|
||||
return map;
|
||||
}
|
||||
return value.toString();
|
||||
}
|
||||
|
||||
private static Object serializeContentValue(DBRProgressMonitor monitor, DBDContent value) throws DBCException {
|
||||
return ContentUtils.getContentStringValue(monitor, value);
|
||||
}
|
||||
|
||||
private static Object serializeDocumentValue(DBDDocument value) {
|
||||
return value;
|
||||
}
|
||||
|
||||
private static Object serializeGeometryValue(DBGeometry value) {
|
||||
return value.toString();
|
||||
}
|
||||
|
||||
}
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* DBeaver - Universal Database Manager
|
||||
* Copyright (C) 2010-2020 DBeaver Corp and others
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
package io.cloudbeaver.server.model.sql;
|
||||
|
||||
import io.cloudbeaver.server.model.WebDatabaseObjectInfo;
|
||||
import org.jkiss.dbeaver.Log;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* WebStructContainers
|
||||
*/
|
||||
public class WebStructContainers {
|
||||
|
||||
private static final Log log = Log.getLog(WebStructContainers.class);
|
||||
|
||||
private List<WebDatabaseObjectInfo> catalogList = new ArrayList<>();
|
||||
private List<WebDatabaseObjectInfo> schemaList = new ArrayList<>();
|
||||
|
||||
public List<WebDatabaseObjectInfo> getCatalogList() {
|
||||
return catalogList;
|
||||
}
|
||||
|
||||
public void setCatalogList(List<WebDatabaseObjectInfo> catalogList) {
|
||||
this.catalogList = catalogList;
|
||||
}
|
||||
|
||||
public List<WebDatabaseObjectInfo> getSchemaList() {
|
||||
return schemaList;
|
||||
}
|
||||
|
||||
public void setSchemaList(List<WebDatabaseObjectInfo> schemaList) {
|
||||
this.schemaList = schemaList;
|
||||
}
|
||||
}
|
||||
+67
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* DBeaver - Universal Database Manager
|
||||
* Copyright (C) 2010-2020 DBeaver Corp and others
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
package io.cloudbeaver.server.registry;
|
||||
|
||||
import io.cloudbeaver.WebServiceUtils;
|
||||
import org.eclipse.core.runtime.IConfigurationElement;
|
||||
import org.eclipse.core.runtime.IExtensionRegistry;
|
||||
import org.eclipse.core.runtime.Platform;
|
||||
import org.jkiss.dbeaver.Log;
|
||||
import org.jkiss.dbeaver.model.connection.DBPDriver;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
public class WebDriverRegistry {
|
||||
|
||||
private static final Log log = Log.getLog(WebDriverRegistry.class);
|
||||
|
||||
private static final String EXTENSION_ID = "io.cloudbeaver.driver"; //$NON-NLS-1$
|
||||
private static final String TAG_DRIVER = "driver"; //$NON-NLS-1$
|
||||
|
||||
private static WebDriverRegistry instance = null;
|
||||
|
||||
public synchronized static WebDriverRegistry getInstance() {
|
||||
if (instance == null) {
|
||||
instance = new WebDriverRegistry();
|
||||
instance.loadExtensions(Platform.getExtensionRegistry());
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
private final Set<String> webDrivers = new HashSet<>();
|
||||
|
||||
private WebDriverRegistry() {
|
||||
}
|
||||
|
||||
private void loadExtensions(IExtensionRegistry registry) {
|
||||
{
|
||||
IConfigurationElement[] extConfigs = registry.getConfigurationElementsFor(EXTENSION_ID);
|
||||
for (IConfigurationElement ext : extConfigs) {
|
||||
// Load webServices
|
||||
if (TAG_DRIVER.equals(ext.getName())) {
|
||||
this.webDrivers.add(ext.getAttribute("id"));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isDriverEnabled(DBPDriver driver) {
|
||||
return webDrivers.contains(WebServiceUtils.makeDriverFullId(driver));
|
||||
}
|
||||
|
||||
}
|
||||
+69
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* DBeaver - Universal Database Manager
|
||||
* Copyright (C) 2010-2020 DBeaver Corp and others
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package io.cloudbeaver.server.registry;
|
||||
|
||||
import io.cloudbeaver.api.DBWService;
|
||||
import org.eclipse.core.runtime.IConfigurationElement;
|
||||
import org.jkiss.dbeaver.DBException;
|
||||
import org.jkiss.dbeaver.model.impl.AbstractContextDescriptor;
|
||||
|
||||
/**
|
||||
* WebServiceDescriptor
|
||||
*/
|
||||
public class WebServiceDescriptor extends AbstractContextDescriptor {
|
||||
|
||||
public static final String EXTENSION_ID = "io.cloudbeaver.service"; //$NON-NLS-1$
|
||||
|
||||
private final String id;
|
||||
private final String label;
|
||||
private final String description;
|
||||
private final ObjectType implClass;
|
||||
|
||||
private DBWService instance;
|
||||
|
||||
public WebServiceDescriptor(IConfigurationElement config)
|
||||
{
|
||||
super(config);
|
||||
this.id = config.getAttribute("id");
|
||||
this.label = config.getAttribute("label");
|
||||
this.description = config.getAttribute("description");
|
||||
this.implClass = new ObjectType(config.getAttribute("class"));
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public String getLabel() {
|
||||
return label;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public DBWService getInstance()
|
||||
throws DBException
|
||||
{
|
||||
if (instance == null) {
|
||||
instance = implClass.createInstance(DBWService.class);
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
}
|
||||
+80
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
* DBeaver - Universal Database Manager
|
||||
* Copyright (C) 2010-2020 DBeaver Corp and others
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
package io.cloudbeaver.server.registry;
|
||||
|
||||
import io.cloudbeaver.api.DBWService;
|
||||
import org.eclipse.core.runtime.IConfigurationElement;
|
||||
import org.eclipse.core.runtime.IExtensionRegistry;
|
||||
import org.eclipse.core.runtime.Platform;
|
||||
import org.jkiss.dbeaver.Log;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class WebServiceRegistry {
|
||||
|
||||
private static final Log log = Log.getLog(WebServiceRegistry.class);
|
||||
|
||||
private static final String TAG_SERVICE = "service"; //$NON-NLS-1$
|
||||
|
||||
private static WebServiceRegistry instance = null;
|
||||
|
||||
public synchronized static WebServiceRegistry getInstance() {
|
||||
if (instance == null) {
|
||||
instance = new WebServiceRegistry();
|
||||
instance.loadExtensions(Platform.getExtensionRegistry());
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
private final List<WebServiceDescriptor> webServices = new ArrayList<>();
|
||||
private DBWService[] webServiceInstances;
|
||||
|
||||
private WebServiceRegistry() {
|
||||
}
|
||||
|
||||
private void loadExtensions(IExtensionRegistry registry) {
|
||||
{
|
||||
IConfigurationElement[] extConfigs = registry.getConfigurationElementsFor(WebServiceDescriptor.EXTENSION_ID);
|
||||
for (IConfigurationElement ext : extConfigs) {
|
||||
// Load webServices
|
||||
if (TAG_SERVICE.equals(ext.getName())) {
|
||||
this.webServices.add(
|
||||
new WebServiceDescriptor(ext));
|
||||
}
|
||||
}
|
||||
}
|
||||
List<DBWService> instances = new ArrayList<>();
|
||||
for (WebServiceDescriptor wsd : webServices) {
|
||||
try {
|
||||
DBWService instance = wsd.getInstance();
|
||||
instances.add(instance);
|
||||
} catch (Exception e) {
|
||||
log.error("Error instantiating web service '" + wsd.getId() + "'", e);
|
||||
}
|
||||
}
|
||||
webServiceInstances = instances.toArray(new DBWService[0]);
|
||||
}
|
||||
|
||||
public List<WebServiceDescriptor> getWebServices() {
|
||||
return webServices;
|
||||
}
|
||||
|
||||
public DBWService[] getWebServiceInstances() {
|
||||
return webServiceInstances;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,140 @@
|
||||
<!--
|
||||
* Copyright (c) Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
-->
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<style>
|
||||
body {
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
#graphiql {
|
||||
height: 100vh;
|
||||
}
|
||||
</style>
|
||||
|
||||
<!--
|
||||
This GraphiQL example depends on Promise and fetch, which are available in
|
||||
modern browsers, but can be "polyfilled" for older browsers.
|
||||
GraphiQL itself depends on React DOM.
|
||||
If you do not want to rely on a CDN, you can host these files locally or
|
||||
include them directly in your favored resource bunder.
|
||||
-->
|
||||
<script src="//cdn.jsdelivr.net/es6-promise/4.0.5/es6-promise.auto.min.js"></script>
|
||||
<script src="//cdn.jsdelivr.net/fetch/0.9.0/fetch.min.js"></script>
|
||||
<script src="//cdn.jsdelivr.net/react/15.4.2/react.min.js"></script>
|
||||
<script src="//cdn.jsdelivr.net/react/15.4.2/react-dom.min.js"></script>
|
||||
|
||||
<!--
|
||||
These two files can be found in the npm module, however you may wish to
|
||||
copy them directly into your environment, or perhaps include them in your
|
||||
favored resource bundler.
|
||||
-->
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/graphiql@0.11.2/graphiql.css" />
|
||||
<script src="https://cdn.jsdelivr.net/npm/graphiql@0.11.2/graphiql.js"></script>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<div id="graphiql">Loading...</div>
|
||||
<script>
|
||||
/**
|
||||
* This GraphiQL example illustrates how to use some of GraphiQL's props
|
||||
* in order to enable reading and updating the URL parameters, making
|
||||
* link sharing of queries a little bit easier.
|
||||
*
|
||||
* This is only one example of this kind of feature, GraphiQL exposes
|
||||
* various React params to enable interesting integrations.
|
||||
*/
|
||||
// Parse the search string to get url parameters.
|
||||
var search = window.location.search;
|
||||
var parameters = {};
|
||||
search.substr(1).split('&').forEach(function (entry) {
|
||||
var eq = entry.indexOf('=');
|
||||
if (eq >= 0) {
|
||||
parameters[decodeURIComponent(entry.slice(0, eq))] =
|
||||
decodeURIComponent(entry.slice(eq + 1));
|
||||
}
|
||||
});
|
||||
// if variables was provided, try to format it.
|
||||
if (parameters.variables) {
|
||||
try {
|
||||
parameters.variables =
|
||||
JSON.stringify(JSON.parse(parameters.variables), null, 2);
|
||||
} catch (e) {
|
||||
// Do nothing, we want to display the invalid JSON as a string, rather
|
||||
// than present an error.
|
||||
}
|
||||
}
|
||||
// When the query and variables string is edited, update the URL bar so
|
||||
// that it can be easily shared
|
||||
function onEditQuery(newQuery) {
|
||||
parameters.query = newQuery;
|
||||
updateURL();
|
||||
}
|
||||
function onEditVariables(newVariables) {
|
||||
parameters.variables = newVariables;
|
||||
updateURL();
|
||||
}
|
||||
function onEditOperationName(newOperationName) {
|
||||
parameters.operationName = newOperationName;
|
||||
updateURL();
|
||||
}
|
||||
function updateURL() {
|
||||
var newSearch = '?' + Object.keys(parameters).filter(function (key) {
|
||||
return Boolean(parameters[key]);
|
||||
}).map(function (key) {
|
||||
return encodeURIComponent(key) + '=' +
|
||||
encodeURIComponent(parameters[key]);
|
||||
}).join('&');
|
||||
history.replaceState(null, null, newSearch);
|
||||
}
|
||||
// Defines a GraphQL fetcher using the fetch API. You're not required to
|
||||
// use fetch, and could instead implement graphQLFetcher however you like,
|
||||
// as long as it returns a Promise or Observable.
|
||||
function graphQLFetcher(graphQLParams) {
|
||||
// This example expects a GraphQL server at the path /graphql.
|
||||
// Change this to point wherever you host your GraphQL server.
|
||||
return fetch('/dbeaver/gql', {
|
||||
method: 'post',
|
||||
headers: {
|
||||
'Accept': 'application/json',
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify(graphQLParams),
|
||||
credentials: 'include',
|
||||
}).then(function (response) {
|
||||
return response.text();
|
||||
}).then(function (responseBody) {
|
||||
try {
|
||||
return JSON.parse(responseBody);
|
||||
} catch (error) {
|
||||
return responseBody;
|
||||
}
|
||||
});
|
||||
}
|
||||
// Render <GraphiQL /> into the body.
|
||||
// See the README in the top level of this module to learn more about
|
||||
// how you can customize GraphiQL by providing different values or
|
||||
// additional child elements.
|
||||
ReactDOM.render(
|
||||
React.createElement(GraphiQL, {
|
||||
fetcher: graphQLFetcher,
|
||||
query: parameters.query,
|
||||
variables: parameters.variables,
|
||||
operationName: parameters.operationName,
|
||||
onEditQuery: onEditQuery,
|
||||
onEditVariables: onEditVariables,
|
||||
onEditOperationName: onEditOperationName
|
||||
}),
|
||||
document.getElementById('graphiql')
|
||||
);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,23 @@
|
||||
Manifest-Version: 1.0
|
||||
Bundle-ManifestVersion: 2
|
||||
Bundle-Vendor: %Bundle-Vendor
|
||||
Bundle-Name: %Bundle-Name
|
||||
Bundle-SymbolicName: io.cloudbeaver.service.metadata;singleton:=true
|
||||
Bundle-Version: 1.0.3.qualifier
|
||||
Bundle-Release-Date: 20200420
|
||||
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
|
||||
Bundle-ActivationPolicy: lazy
|
||||
Bundle-ClassPath: .
|
||||
Require-Bundle: org.eclipse.core.runtime,
|
||||
org.eclipse.core.expressions,
|
||||
org.apache.commons.logging,
|
||||
org.eclipse.core.commands,
|
||||
org.eclipse.core.resources,
|
||||
io.cloudbeaver.server,
|
||||
com.google.gson,
|
||||
javax.servlet,
|
||||
org.jkiss.bundle.graphql.java,
|
||||
org.jkiss.dbeaver.model,
|
||||
org.jkiss.dbeaver.model.sql
|
||||
Bundle-Localization: OSGI-INF/l10n/bundle
|
||||
Automatic-Module-Name: io.cloudbeaver.service.metadata
|
||||
@@ -0,0 +1,2 @@
|
||||
Bundle-Vendor = DBeaver Corp
|
||||
Bundle-Name = Cloudbeaver Web Service - Metadata
|
||||
@@ -0,0 +1,7 @@
|
||||
source.. = src/
|
||||
output.. = target/classes/
|
||||
bin.includes = .,\
|
||||
META-INF/,\
|
||||
OSGI-INF/,\
|
||||
schema/,\
|
||||
plugin.xml
|
||||
@@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<?eclipse version="3.2"?>
|
||||
|
||||
<plugin>
|
||||
|
||||
<extension point="io.cloudbeaver.service">
|
||||
<service id="metadata" label="Metadata management " description="Metadata management services" class="io.cloudbeaver.service.metadata.WebServiceMetadata">
|
||||
|
||||
</service>
|
||||
</extension>
|
||||
|
||||
</plugin>
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user