Cloudbeaver 1.0 initial

This commit is contained in:
serge-rider
2020-04-16 13:06:54 +03:00
commit aed5db2cfa
654 changed files with 52417 additions and 0 deletions
@@ -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>
@@ -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.
@@ -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.
@@ -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.
@@ -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.
@@ -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.
*/
@@ -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;
}
}
@@ -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;
}
}
@@ -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;
}
@@ -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;
}
}
@@ -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();
}
@@ -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 {
}
}
@@ -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";
}
}
@@ -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$
}
}
}
@@ -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;
}
}
@@ -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);
}
}
@@ -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);
}
}
@@ -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" +
" }";
}
@@ -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();
}
});
}
}
}
@@ -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);
}
}
@@ -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);
}
}
@@ -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);
}
}
@@ -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) {
}
}
@@ -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;
}
}
@@ -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()
}
}
@@ -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;
}
}
@@ -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;
}
}
@@ -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;
}
}
@@ -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;
}
}
@@ -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;
}
}
@@ -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();
}
}
@@ -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;
}
}
@@ -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();
}
}
@@ -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;
}
}
@@ -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);
}
}
@@ -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]);
}
}
@@ -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;
}
}
@@ -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();
}
}
@@ -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;
}
}
@@ -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();
}
}
@@ -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;
}
}
@@ -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);
}
}
}
@@ -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();
}
}
}
@@ -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);
}
}
@@ -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);
}
}
@@ -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;
}
}
@@ -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();
}
}
@@ -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;
}
}
@@ -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;
}
}
@@ -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();
}
}
@@ -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;
}
}
@@ -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();
}
}
}
@@ -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;
}
}
@@ -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();
}
}
@@ -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;
}
}
@@ -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;
}
}
@@ -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;
}
}
@@ -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();
}
}
@@ -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;
}
}
@@ -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));
}
}
@@ -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;
}
}
@@ -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