Browse Source

HUE-1808 [dbquery] Pull out rdbms config to librdbms app

- Move config to librdbms section.
- Move server selection to librdbms app.
Abraham Elmahrek 12 năm trước cách đây
mục cha
commit
55515756e1
35 tập tin đã thay đổi với 824 bổ sung và 240 xóa
  1. 4 6
      apps/beeswax/src/beeswax/models.py
  2. 4 3
      apps/rdbms/src/rdbms/api.py
  3. 0 86
      apps/rdbms/src/rdbms/conf.py
  4. 4 5
      apps/rdbms/src/rdbms/tests.py
  5. 4 4
      apps/rdbms/src/rdbms/views.py
  6. 1 0
      apps/sqoop/src/sqoop/api/__init__.py
  7. 2 1
      desktop/Makefile
  8. 54 54
      desktop/conf.dist/hue.ini
  9. 54 54
      desktop/conf/pseudo-distributed.ini.tmpl
  10. 36 0
      desktop/libs/librdbms/Makefile
  11. 1 0
      desktop/libs/librdbms/babel.cfg
  12. 30 0
      desktop/libs/librdbms/setup.py
  13. 15 0
      desktop/libs/librdbms/src/librdbms/__init__.py
  14. 100 0
      desktop/libs/librdbms/src/librdbms/conf.py
  15. 0 0
      desktop/libs/librdbms/src/librdbms/design.py
  16. 44 0
      desktop/libs/librdbms/src/librdbms/locale/de/LC_MESSAGES/django.po
  17. 42 0
      desktop/libs/librdbms/src/librdbms/locale/en/LC_MESSAGES/django.po
  18. 41 0
      desktop/libs/librdbms/src/librdbms/locale/en_US.pot
  19. 44 0
      desktop/libs/librdbms/src/librdbms/locale/es/LC_MESSAGES/django.po
  20. 44 0
      desktop/libs/librdbms/src/librdbms/locale/fr/LC_MESSAGES/django.po
  21. 44 0
      desktop/libs/librdbms/src/librdbms/locale/ja/LC_MESSAGES/django.po
  22. 44 0
      desktop/libs/librdbms/src/librdbms/locale/ko/LC_MESSAGES/django.po
  23. 44 0
      desktop/libs/librdbms/src/librdbms/locale/pt/LC_MESSAGES/django.po
  24. 44 0
      desktop/libs/librdbms/src/librdbms/locale/pt_BR/LC_MESSAGES/django.po
  25. 44 0
      desktop/libs/librdbms/src/librdbms/locale/zh_CN/LC_MESSAGES/django.po
  26. 16 0
      desktop/libs/librdbms/src/librdbms/models.py
  27. 0 0
      desktop/libs/librdbms/src/librdbms/server/__init__.py
  28. 27 20
      desktop/libs/librdbms/src/librdbms/server/dbms.py
  29. 1 1
      desktop/libs/librdbms/src/librdbms/server/mysql_lib.py
  30. 1 1
      desktop/libs/librdbms/src/librdbms/server/oracle_lib.py
  31. 1 1
      desktop/libs/librdbms/src/librdbms/server/postgresql_lib.py
  32. 1 3
      desktop/libs/librdbms/src/librdbms/server/rdbms_base_lib.py
  33. 1 1
      desktop/libs/librdbms/src/librdbms/server/sqlite_lib.py
  34. 16 0
      desktop/libs/librdbms/src/librdbms/tests.py
  35. 16 0
      desktop/libs/librdbms/src/librdbms/urls.py

+ 4 - 6
apps/beeswax/src/beeswax/models.py

@@ -28,6 +28,8 @@ from django.utils.translation import ugettext as _, ugettext_lazy as _t
 
 
 from enum import Enum
 from enum import Enum
 
 
+from librdbms.server import dbms as librdbms_dbms
+
 from desktop.lib.exceptions_renderable import PopupException
 from desktop.lib.exceptions_renderable import PopupException
 from desktop.models import Document
 from desktop.models import Document
 
 
@@ -44,10 +46,6 @@ QUERY_SUBMISSION_TIMEOUT = datetime.timedelta(0, 60 * 60)               # 1 hour
 # Constants for DB fields, hue ini
 # Constants for DB fields, hue ini
 BEESWAX = 'beeswax'
 BEESWAX = 'beeswax'
 HIVE_SERVER2 = 'hiveserver2'
 HIVE_SERVER2 = 'hiveserver2'
-MYSQL = 'mysql'
-POSTGRESQL = 'postgresql'
-SQLITE = 'sqlite'
-ORACLE = 'oracle'
 QUERY_TYPES = (HQL, IMPALA, RDBMS, SPARK) = range(4)
 QUERY_TYPES = (HQL, IMPALA, RDBMS, SPARK) = range(4)
 
 
 
 
@@ -57,8 +55,8 @@ class QueryHistory(models.Model):
   """
   """
   STATE = Enum('submitted', 'running', 'available', 'failed', 'expired')
   STATE = Enum('submitted', 'running', 'available', 'failed', 'expired')
   SERVER_TYPE = ((BEESWAX, 'Beeswax'), (HIVE_SERVER2, 'Hive Server 2'),
   SERVER_TYPE = ((BEESWAX, 'Beeswax'), (HIVE_SERVER2, 'Hive Server 2'),
-                 (MYSQL, 'MySQL'), (POSTGRESQL, 'PostgreSQL'),
-                 (SQLITE, 'sqlite'), (ORACLE, 'oracle'))
+                 (librdbms_dbms.MYSQL, 'MySQL'), (librdbms_dbms.POSTGRESQL, 'PostgreSQL'),
+                 (librdbms_dbms.SQLITE, 'sqlite'), (librdbms_dbms.ORACLE, 'oracle'))
 
 
   owner = models.ForeignKey(User, db_index=True)
   owner = models.ForeignKey(User, db_index=True)
   query = models.TextField()
   query = models.TextField()

+ 4 - 3
apps/rdbms/src/rdbms/api.py

@@ -24,14 +24,15 @@ from django.utils.translation import ugettext as _
 
 
 from desktop.context_processors import get_app_name
 from desktop.context_processors import get_app_name
 
 
+from librdbms import conf
+from librdbms.server import dbms
+from librdbms.design import SQLdesign
+
 from beeswax import models as beeswax_models
 from beeswax import models as beeswax_models
 from beeswax.forms import SaveForm
 from beeswax.forms import SaveForm
 from beeswax.views import authorized_get_history, safe_get_design
 from beeswax.views import authorized_get_history, safe_get_design
 
 
-from rdbms import conf
 from rdbms.forms import SQLForm
 from rdbms.forms import SQLForm
-from rdbms.design import SQLdesign
-from rdbms.server import dbms
 from rdbms.views import save_design
 from rdbms.views import save_design
 
 
 
 

+ 0 - 86
apps/rdbms/src/rdbms/conf.py

@@ -14,89 +14,3 @@
 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 # See the License for the specific language governing permissions and
 # See the License for the specific language governing permissions and
 # limitations under the License.
 # limitations under the License.
-
-from django.utils.translation import ugettext_lazy as _t, ugettext as _
-from desktop.lib.conf import Config, UnspecifiedConfigSection,\
-                             ConfigSection, coerce_json_dict
-from desktop.conf import coerce_database
-
-from rdbms.settings import NICE_NAME
-
-
-RDBMS = UnspecifiedConfigSection(
-  key="databases",
-  help=_t("RDBMS server configurations."),
-  each=ConfigSection(
-    help=_t("RDBMS server configuration."),
-    members=dict(
-      NICE_NAME=Config(
-        key='nice_name',
-        help=_t('Nice name of server.'),
-        type=str,
-        default=None,
-      ),
-      NAME=Config(
-        key='name',
-        help=_t('Database name or path to database file. If provided, then choosing other databases will not be permitted.'),
-        type=str,
-        default='',
-      ),
-      ENGINE=Config(
-        key='engine',
-        help=_t('Database engine, such as postgresql_psycopg2, mysql, or sqlite3.'),
-        type=coerce_database,
-        default='django.db.backends.sqlite3',
-      ),
-      USER=Config(
-        key='user',
-        help=_t('Database username.'),
-        type=str,
-        default='',
-      ),
-      PASSWORD=Config(
-        key='password',
-        help=_t('Database password.'),
-        type=str,
-        default='',
-      ),
-      HOST=Config(
-        key='host',
-        help=_t('Database host.'),
-        type=str,
-        default='',
-      ),
-      PORT=Config(
-        key='port',
-        help=_t('Database port.'),
-        type=int,
-        default=0,
-      ),
-      OPTIONS=Config(
-        key='options',
-        help=_t('Database options to send to the server when connecting.'),
-        type=coerce_json_dict,
-        default='{}'
-      )
-    )
-  )
-)
-
-
-def config_validator(user):
-  res = []
-
-  for server in RDBMS:
-    if not RDBMS[server].NAME.get():
-      engine = RDBMS[server].ENGINE.get().split('.')[-1]
-      if engine in ('sqlite', 'sqlite3'):
-        res.append((RDBMS[server].NAME, _("Database name should not be empty for the SQLite backend. The %s may not work correctly.") % NICE_NAME))
-      if engine == 'oracle':
-        res.append((RDBMS[server].NAME, _("Database name should not be empty for the Oracle backend. It should be the SID of your database. The %s may not work correctly.") % NICE_NAME))
-      if engine in ('postgresql_psycopg2', 'postgresql'):
-        res.append((RDBMS[server].NAME, _("Database name should not be empty for the PostgreSQL backend. The %s may not work correctly.") % NICE_NAME))
-
-  return res
-
-
-def get_server_choices():
-  return [(alias, RDBMS[alias].NICE_NAME.get() or alias) for alias in RDBMS]

+ 4 - 5
apps/rdbms/src/rdbms/tests.py

@@ -24,8 +24,7 @@ from nose.tools import assert_true, assert_equal
 
 
 from desktop.lib.django_test_util import make_logged_in_client
 from desktop.lib.django_test_util import make_logged_in_client
 
 
-from rdbms import conf as rdbms_conf
-from rdbms.server import dbms
+from librdbms import conf as rdbms_conf, dbms
 
 
 
 
 class MockRdbms:
 class MockRdbms:
@@ -53,7 +52,7 @@ class TestMockedRdbms:
     assert_true('DB Query' in response.content, response.content)
     assert_true('DB Query' in response.content, response.content)
 
 
   def test_config_error(self):
   def test_config_error(self):
-    self.finish = rdbms_conf.RDBMS.set_for_testing({})
+    self.finish = rdbms_conf.DATABASES.set_for_testing({})
 
 
     response = self.client.get("/rdbms/")
     response = self.client.get("/rdbms/")
     assert_true('There are currently no databases configured.' in response.content)
     assert_true('There are currently no databases configured.' in response.content)
@@ -76,7 +75,7 @@ class TestSQLiteRdbmsBase(object):
 
 
   def setUp(self):
   def setUp(self):
     self.client = make_logged_in_client()
     self.client = make_logged_in_client()
-    self.finish = rdbms_conf.RDBMS.set_for_testing({
+    self.finish = rdbms_conf.DATABASES.set_for_testing({
       'sqlitee': {
       'sqlitee': {
         'name': self.database,
         'name': self.database,
         'engine': 'sqlite'
         'engine': 'sqlite'
@@ -132,7 +131,7 @@ class TestAPI(TestSQLiteRdbmsBase):
     assert_equal(1, len(response_dict['results']['rows']), response_dict)
     assert_equal(1, len(response_dict['results']['rows']), response_dict)
 
 
   def test_options(self):
   def test_options(self):
-    finish = rdbms_conf.RDBMS['sqlitee'].OPTIONS.set_for_testing({'nonsensical': None})
+    finish = rdbms_conf.DATABASES['sqlitee'].OPTIONS.set_for_testing({'nonsensical': None})
     try:
     try:
       self.client.get(reverse('rdbms:api_tables', args=['sqlitee', self.database]))
       self.client.get(reverse('rdbms:api_tables', args=['sqlitee', self.database]))
     except TypeError, e:
     except TypeError, e:

+ 4 - 4
apps/rdbms/src/rdbms/views.py

@@ -25,12 +25,12 @@ from desktop.context_processors import get_app_name
 from desktop.models import Document
 from desktop.models import Document
 from desktop.lib.django_util import render
 from desktop.lib.django_util import render
 
 
+from librdbms import conf
+from librdbms.design import SQLdesign
+
 from beeswax import models as beeswax_models
 from beeswax import models as beeswax_models
 from beeswax.views import safe_get_design
 from beeswax.views import safe_get_design
 
 
-from rdbms import conf
-from rdbms.design import SQLdesign
-
 
 
 LOG = logging.getLogger(__name__)
 LOG = logging.getLogger(__name__)
 
 
@@ -48,7 +48,7 @@ Decorators
 """
 """
 def ensure_configuration(view_func):
 def ensure_configuration(view_func):
   def _decorator(*args, **kwargs):
   def _decorator(*args, **kwargs):
-    if conf.RDBMS.get():
+    if conf.DATABASES.get():
       return view_func(*args, **kwargs)
       return view_func(*args, **kwargs)
     else:
     else:
       return configuration_error(*args, **kwargs)
       return configuration_error(*args, **kwargs)

+ 1 - 0
apps/sqoop/src/sqoop/api/__init__.py

@@ -15,6 +15,7 @@
 # See the License for the specific language governing permissions and
 # See the License for the specific language governing permissions and
 # limitations under the License.
 # limitations under the License.
 
 
+from autocomplete import autocomplete
 from connection import get_connections, create_connection, update_connection,\
 from connection import get_connections, create_connection, update_connection,\
                        connection, connections, connection_clone, connection_delete
                        connection, connections, connection_clone, connection_delete
 from connector import get_connectors, connectors, connector
 from connector import get_connectors, connectors, connector

+ 2 - 1
desktop/Makefile

@@ -42,7 +42,8 @@ include $(ROOT)/Makefile.vars.priv
 APPS := core \
 APPS := core \
 	libs/hadoop \
 	libs/hadoop \
 	libs/liboozie \
 	libs/liboozie \
-	libs/libsaml
+	libs/libsaml \
+	libs/librdbms
 
 
 .PHONY: default
 .PHONY: default
 default:: hue syncdb
 default:: hue syncdb

+ 54 - 54
desktop/conf.dist/hue.ini

@@ -307,6 +307,60 @@
   ## logout_enabled=true
   ## logout_enabled=true
 
 
 
 
+###########################################################################
+# Settings for the RDBMS application
+###########################################################################
+
+[librdbms]
+  # The RDBMS app can have any number of databases configured in the databases
+  # section. A database is known by its section name
+  # (IE sqlite, mysql, psql, and oracle in the list below).
+
+  [[databases]]
+    # sqlite configuration.
+    ## [[[sqlite]]]
+      # Name to show in the UI.
+      ## nice_name=SQLite
+
+      # For SQLite, name defines the path to the database.
+      ## name=/tmp/sqlite.db
+
+      # Database backend to use.
+      ## engine=sqlite
+
+    # mysql, oracle, or postgresql configuration.
+    ## [[[mysql]]]
+      # Name to show in the UI.
+      ## nice_name="My SQL DB"
+
+      # For MySQL and PostgreSQL, name is the name of the database.
+      # For Oracle, Name is instance of the Oracle server. For express edition
+      # this is 'xe' by default.
+      ## name=mysqldb
+
+      # Database backend to use. This can be:
+      # 1. mysql
+      # 2. postgresql
+      # 3. oracle
+      ## engine=mysql
+
+      # IP or hostname of the database to connect to.
+      ## host=localhost
+
+      # Port the database server is listening to. Defaults are:
+      # 1. MySQL: 3306
+      # 2. PostgreSQL: 5432
+      # 3. Oracle Express Edition: 1521
+      ## port=3306
+
+      # Username to authenticate with when connecting to the database.
+      ## user=example
+
+      # Password matching the username to authenticate with when
+      # connecting to the database.
+      ## password=example
+
+
 ###########################################################################
 ###########################################################################
 # Settings to configure your Hadoop cluster.
 # Settings to configure your Hadoop cluster.
 ###########################################################################
 ###########################################################################
@@ -606,57 +660,3 @@
 [useradmin]
 [useradmin]
   # The name of the default user group that users will be a member of
   # The name of the default user group that users will be a member of
   ## default_user_group=default
   ## default_user_group=default
-
-
-###########################################################################
-# Settings for the RDBMS application
-###########################################################################
-
-[rdbms]
-  # The RDBMS app can have any number of databases configured in the databases
-  # section. A database is known by its section name
-  # (IE sqlite, mysql, psql, and oracle in the list below).
-
-  [[databases]]
-    # sqlite configuration.
-    ## [[[sqlite]]]
-      # Name to show in the UI.
-      ## nice_name=SQLite
-
-      # For SQLite, name defines the path to the database.
-      ## name=/tmp/sqlite.db
-
-      # Database backend to use.
-      ## engine=sqlite
-
-    # mysql, oracle, or postgresql configuration.
-    ## [[[mysql]]]
-      # Name to show in the UI.
-      ## nice_name="My SQL DB"
-
-      # For MySQL and PostgreSQL, name is the name of the database.
-      # For Oracle, Name is instance of the Oracle server. For express edition
-      # this is 'xe' by default.
-      ## name=mysqldb
-
-      # Database backend to use. This can be:
-      # 1. mysql
-      # 2. postgresql
-      # 3. oracle
-      ## engine=mysql
-
-      # IP or hostname of the database to connect to.
-      ## host=localhost
-
-      # Port the database server is listening to. Defaults are:
-      # 1. MySQL: 3306
-      # 2. PostgreSQL: 5432
-      # 3. Oracle Express Edition: 1521
-      ## port=3306
-
-      # Username to authenticate with when connecting to the database.
-      ## user=example
-
-      # Password matching the username to authenticate with when
-      # connecting to the database.
-      ## password=example

+ 54 - 54
desktop/conf/pseudo-distributed.ini.tmpl

@@ -312,6 +312,60 @@
   ## logout_enabled=true
   ## logout_enabled=true
 
 
 
 
+###########################################################################
+# Settings for the RDBMS application
+###########################################################################
+
+[librdbms]
+  # The RDBMS app can have any number of databases configured in the databases
+  # section. A database is known by its section name
+  # (IE sqlite, mysql, psql, and oracle in the list below).
+
+  [[databases]]
+    # sqlite configuration.
+    ## [[[sqlite]]]
+      # Name to show in the UI.
+      ## nice_name=SQLite
+
+      # For SQLite, name defines the path to the database.
+      ## name=/tmp/sqlite.db
+
+      # Database backend to use.
+      ## engine=sqlite
+
+    # mysql, oracle, or postgresql configuration.
+    ## [[[mysql]]]
+      # Name to show in the UI.
+      ## nice_name="My SQL DB"
+
+      # For MySQL and PostgreSQL, name is the name of the database.
+      # For Oracle, Name is instance of the Oracle server. For express edition
+      # this is 'xe' by default.
+      ## name=mysqldb
+
+      # Database backend to use. This can be:
+      # 1. mysql
+      # 2. postgresql
+      # 3. oracle
+      ## engine=mysql
+
+      # IP or hostname of the database to connect to.
+      ## host=localhost
+
+      # Port the database server is listening to. Defaults are:
+      # 1. MySQL: 3306
+      # 2. PostgreSQL: 5432
+      # 3. Oracle Express Edition: 1521
+      ## port=3306
+
+      # Username to authenticate with when connecting to the database.
+      ## user=example
+
+      # Password matching the username to authenticate with when
+      # connecting to the database.
+      ## password=example
+
+
 ###########################################################################
 ###########################################################################
 # Settings to configure your Hadoop cluster.
 # Settings to configure your Hadoop cluster.
 ###########################################################################
 ###########################################################################
@@ -647,57 +701,3 @@
 [useradmin]
 [useradmin]
   # The name of the default user group that users will be a member of
   # The name of the default user group that users will be a member of
   ## default_user_group=default
   ## default_user_group=default
-
-
-###########################################################################
-# Settings for the RDBMS application
-###########################################################################
-
-[rdbms]
-  # The RDBMS app can have any number of databases configured in the databases
-  # section. A database is known by its section name
-  # (IE sqlite, mysql, psql, and oracle in the list below).
-
-  [[databases]]
-    # sqlite configuration.
-    ## [[[sqlite]]]
-      # Name to show in the UI.
-      ## nice_name=SQLite
-
-      # For SQLite, name defines the path to the database.
-      ## name=/tmp/sqlite.db
-
-      # Database backend to use.
-      ## engine=sqlite
-
-    # mysql, oracle, or postgresql configuration.
-    ## [[[mysql]]]
-      # Name to show in the UI.
-      ## nice_name="My SQL DB"
-
-      # For MySQL and PostgreSQL, name is the name of the database.
-      # For Oracle, Name is instance of the Oracle server. For express edition
-      # this is 'xe' by default.
-      ## name=mysqldb
-
-      # Database backend to use. This can be:
-      # 1. mysql
-      # 2. postgresql
-      # 3. oracle
-      ## engine=mysql
-
-      # IP or hostname of the database to connect to.
-      ## host=localhost
-
-      # Port the database server is listening to. Defaults are:
-      # 1. MySQL: 3306
-      # 2. PostgreSQL: 5432
-      # 3. Oracle Express Edition: 1521
-      ## port=3306
-
-      # Username to authenticate with when connecting to the database.
-      ## user=example
-
-      # Password matching the username to authenticate with when
-      # connecting to the database.
-      ## password=example

+ 36 - 0
desktop/libs/librdbms/Makefile

@@ -0,0 +1,36 @@
+#
+# Licensed to Cloudera, Inc. under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  Cloudera, Inc. licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+
+ifeq ($(ROOT),)
+  $(error "Error: Expect the environment variable $$ROOT to point to the Desktop installation")
+endif
+
+include $(ROOT)/Makefile.sdk
+
+default::
+	@echo '  env-install    : Install into virtual-env'
+
+#
+# env-install
+#   Install app into the virtual environment.
+#
+.PHONY: env-install
+env-install: compile ext-env-install
+	@echo '--- Installing $(APP_NAME) into virtual-env'
+	@$(ENV_PYTHON) setup.py develop -N -q

+ 1 - 0
desktop/libs/librdbms/babel.cfg

@@ -0,0 +1 @@
+[python: src/librdbms/**.py]

+ 30 - 0
desktop/libs/librdbms/setup.py

@@ -0,0 +1,30 @@
+# Licensed to Cloudera, Inc. under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  Cloudera, Inc. licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+from setuptools import setup, find_packages
+
+setup(
+      name = "librdbms",
+      version = "3.5.0",
+      url = 'http://github.com/cloudera/hue',
+      description = "RDBMS Libraries",
+      packages = find_packages('src'),
+      package_dir = {'': 'src' },
+      install_requires = ['setuptools', 'desktop'],
+      # Even libraries need to be registered as desktop_apps,
+      # if they have configuration, like this one.
+      entry_points = { 'desktop.sdk.lib': 'librdbms=librdbms' },
+)

+ 15 - 0
desktop/libs/librdbms/src/librdbms/__init__.py

@@ -0,0 +1,15 @@
+# Licensed to Cloudera, Inc. under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  Cloudera, Inc. licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.

+ 100 - 0
desktop/libs/librdbms/src/librdbms/conf.py

@@ -0,0 +1,100 @@
+#!/usr/bin/env python
+# Licensed to Cloudera, Inc. under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  Cloudera, Inc. licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+from django.utils.translation import ugettext_lazy as _t, ugettext as _
+from desktop.lib.conf import Config, UnspecifiedConfigSection,\
+                             ConfigSection, coerce_json_dict
+from desktop.conf import coerce_database
+
+
+DATABASES = UnspecifiedConfigSection(
+  key="databases",
+  help=_t("RDBMS server configurations."),
+  each=ConfigSection(
+    help=_t("RDBMS server configuration."),
+    members=dict(
+      NICE_NAME=Config(
+        key='nice_name',
+        help=_t('Nice name of server.'),
+        type=str,
+        default=None,
+      ),
+      NAME=Config(
+        key='name',
+        help=_t('Database name or path to database file. If provided, then choosing other databases will not be permitted.'),
+        type=str,
+        default='',
+      ),
+      ENGINE=Config(
+        key='engine',
+        help=_t('Database engine, such as postgresql_psycopg2, mysql, or sqlite3.'),
+        type=coerce_database,
+        default='django.db.backends.sqlite3',
+      ),
+      USER=Config(
+        key='user',
+        help=_t('Database username.'),
+        type=str,
+        default='',
+      ),
+      PASSWORD=Config(
+        key='password',
+        help=_t('Database password.'),
+        type=str,
+        default='',
+      ),
+      HOST=Config(
+        key='host',
+        help=_t('Database host.'),
+        type=str,
+        default='',
+      ),
+      PORT=Config(
+        key='port',
+        help=_t('Database port.'),
+        type=int,
+        default=0,
+      ),
+      OPTIONS=Config(
+        key='options',
+        help=_t('Database options to send to the server when connecting.'),
+        type=coerce_json_dict,
+        default='{}'
+      )
+    )
+  )
+)
+
+
+def config_validator(user):
+  res = []
+
+  for server in DATABASES:
+    if not DATABASES[server].NAME.get():
+      engine = DATABASES[server].ENGINE.get().split('.')[-1]
+      if engine in ('sqlite', 'sqlite3'):
+        res.append((DATABASES[server].NAME, _("Database name should not be empty for the SQLite backend.")))
+      if engine == 'oracle':
+        res.append((DATABASES[server].NAME, _("Database name should not be empty for the Oracle backend. It should be the SID of your database.")))
+      if engine in ('postgresql_psycopg2', 'postgresql'):
+        res.append((DATABASES[server].NAME, _("Database name should not be empty for the PostgreSQL backend.")))
+
+  return res
+
+
+def get_server_choices():
+  return [(alias, DATABASES[alias].NICE_NAME.get() or alias) for alias in DATABASES]

+ 0 - 0
apps/rdbms/src/rdbms/design.py → desktop/libs/librdbms/src/librdbms/design.py


+ 44 - 0
desktop/libs/librdbms/src/librdbms/locale/de/LC_MESSAGES/django.po

@@ -0,0 +1,44 @@
+# German translations for Hue.
+# Copyright (C) 2012 Cloudera
+# This file is distributed under the same license as the Hue project.
+# FIRST AUTHOR <EMAIL@ADDRESS>, 2012.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: PROJECT VERSION\n"
+"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
+"POT-Creation-Date: 2013-08-02 20:43-0700\n"
+"PO-Revision-Date: 2012-07-30 18:50-0700\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: de <LL@li.org>\n"
+"Plural-Forms: nplurals=2; plural=(n != 1)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Generated-By: Babel 0.9.6\n"
+
+#: src/impala/conf.py:29
+msgid "Host of the Impala Server."
+msgstr "Host des Impala-Servers."
+
+#: src/impala/conf.py:34
+msgid "Port of the Impala Server."
+msgstr "Port des Impala-Servers."
+
+#: src/impala/conf.py:40
+#, fuzzy
+msgid "Beeswax or Hive Server 2 Thrift API used. Choices are: 'beeswax' or 'hiveserver2'."
+msgstr "Beeswax- oder Hive Server 2-Thrift-API verwendet. Zur Auswahl stehen: \"beeswax\" oder \"hiveserver2\"."
+
+#: src/impala/conf.py:45
+msgid "Kerberos principal name for Impala. Typically 'impala/hostname.foo.com'."
+msgstr "Kerberos-Hauptname für Impala. Typischerweise 'impala/hostname.foo.com'."
+
+#: src/impala/conf.py:63
+msgid "No available Impalad to send queries to."
+msgstr "Kein Impalad zum Senden von Abfragen verfügbar."
+
+#: src/impala/views.py:35
+msgid "A POST request is required."
+msgstr "Eine POST-Anforderung ist erforderlich."
+

+ 42 - 0
desktop/libs/librdbms/src/librdbms/locale/en/LC_MESSAGES/django.po

@@ -0,0 +1,42 @@
+# English translations for Hue.
+# Copyright (C) 2013 Cloudera, Inc
+# This file is distributed under the same license as the Hue project.
+# FIRST AUTHOR <EMAIL@ADDRESS>, 2013.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: Hue VERSION\n"
+"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
+"POT-Creation-Date: 2013-05-10 11:59-0700\n"
+"PO-Revision-Date: 2013-10-28 10:31-0700\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: en <LL@li.org>\n"
+"Plural-Forms: nplurals=2; plural=(n != 1)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Generated-By: Babel 0.9.6\n"
+
+#: src/impala/conf.py:26
+msgid "Host of the Impala Server."
+msgstr ""
+
+#: src/impala/conf.py:31
+msgid "Port of the Impala Server."
+msgstr ""
+
+#: src/impala/conf.py:37
+msgid ""
+"Beeswax or Hive Server 2 Thrift API used. Choices are: 'beeswax' or "
+"'hiveserver2'."
+msgstr ""
+
+#: src/impala/conf.py:42
+msgid "Kerberos principal name for Impala. Typically 'impala/hostname.foo.com'."
+msgstr ""
+
+#: src/impala/views.py:35
+msgid "A POST request is required."
+msgstr ""
+

+ 41 - 0
desktop/libs/librdbms/src/librdbms/locale/en_US.pot

@@ -0,0 +1,41 @@
+# Translations template for Hue.
+# Copyright (C) 2013 Cloudera, Inc
+# This file is distributed under the same license as the Hue project.
+# FIRST AUTHOR <EMAIL@ADDRESS>, 2013.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: Hue VERSION\n"
+"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
+"POT-Creation-Date: 2013-05-10 11:59-0700\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Generated-By: Babel 0.9.6\n"
+
+#: src/impala/conf.py:26
+msgid "Host of the Impala Server."
+msgstr ""
+
+#: src/impala/conf.py:31
+msgid "Port of the Impala Server."
+msgstr ""
+
+#: src/impala/conf.py:37
+msgid ""
+"Beeswax or Hive Server 2 Thrift API used. Choices are: 'beeswax' or "
+"'hiveserver2'."
+msgstr ""
+
+#: src/impala/conf.py:42
+msgid "Kerberos principal name for Impala. Typically 'impala/hostname.foo.com'."
+msgstr ""
+
+#: src/impala/views.py:35
+msgid "A POST request is required."
+msgstr ""
+

+ 44 - 0
desktop/libs/librdbms/src/librdbms/locale/es/LC_MESSAGES/django.po

@@ -0,0 +1,44 @@
+# Spanish translations for Hue.
+# Copyright (C) 2012 Cloudera
+# This file is distributed under the same license as the Hue project.
+# FIRST AUTHOR <EMAIL@ADDRESS>, 2012.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: PROJECT VERSION\n"
+"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
+"POT-Creation-Date: 2013-08-02 20:43-0700\n"
+"PO-Revision-Date: 2012-07-30 18:50-0700\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: es <LL@li.org>\n"
+"Plural-Forms: nplurals=2; plural=(n != 1)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Generated-By: Babel 0.9.6\n"
+
+#: src/impala/conf.py:29
+msgid "Host of the Impala Server."
+msgstr "Host del servidor Impala."
+
+#: src/impala/conf.py:34
+msgid "Port of the Impala Server."
+msgstr "Puerto del servidor Impala."
+
+#: src/impala/conf.py:40
+#, fuzzy
+msgid "Beeswax or Hive Server 2 Thrift API used. Choices are: 'beeswax' or 'hiveserver2'."
+msgstr "Se utiliza la API Thrift de Beeswax o de Hive Server 2. Las opciones son: 'beeswax' o 'hiveserver2'."
+
+#: src/impala/conf.py:45
+msgid "Kerberos principal name for Impala. Typically 'impala/hostname.foo.com'."
+msgstr "Nombre de la entidad de seguridad de Kerberos para Hue. Normalmente 'hue/hostname.foo.com'."
+
+#: src/impala/conf.py:63
+msgid "No available Impalad to send queries to."
+msgstr "No hay ningún Impalad disponible al que enviar las consultas."
+
+#: src/impala/views.py:35
+msgid "A POST request is required."
+msgstr "Se necesita una solicitud POST."
+

+ 44 - 0
desktop/libs/librdbms/src/librdbms/locale/fr/LC_MESSAGES/django.po

@@ -0,0 +1,44 @@
+# French translations for Hue.
+# Copyright (C) 2012 Cloudera
+# This file is distributed under the same license as the Hue project.
+# FIRST AUTHOR <EMAIL@ADDRESS>, 2012.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: PROJECT VERSION\n"
+"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
+"POT-Creation-Date: 2013-08-02 20:43-0700\n"
+"PO-Revision-Date: 2012-07-30 18:50-0700\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: fr <LL@li.org>\n"
+"Plural-Forms: nplurals=2; plural=(n > 1)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Generated-By: Babel 0.9.6\n"
+
+#: src/impala/conf.py:29
+msgid "Host of the Impala Server."
+msgstr "Hôte du serveur Impala."
+
+#: src/impala/conf.py:34
+msgid "Port of the Impala Server."
+msgstr "Port du serveur Impala."
+
+#: src/impala/conf.py:40
+#, fuzzy
+msgid "Beeswax or Hive Server 2 Thrift API used. Choices are: 'beeswax' or 'hiveserver2'."
+msgstr "API Thrift de Beeswax ou Hive Server 2 utilisée. Les choix possibles sont : \"beeswax\" ou \"hiveserver2\"."
+
+#: src/impala/conf.py:45
+msgid "Kerberos principal name for Impala. Typically 'impala/hostname.foo.com'."
+msgstr "Nom Kerberos principal pour Impala. En général 'impala/nomhôte.foo.com'."
+
+#: src/impala/conf.py:63
+msgid "No available Impalad to send queries to."
+msgstr "Aucun Impalad disponible pour l'envoi de requêtes."
+
+#: src/impala/views.py:35
+msgid "A POST request is required."
+msgstr "Requête POST requise."
+

+ 44 - 0
desktop/libs/librdbms/src/librdbms/locale/ja/LC_MESSAGES/django.po

@@ -0,0 +1,44 @@
+# Japanese translations for Hue.
+# Copyright (C) 2012 Cloudera
+# This file is distributed under the same license as the Hue project.
+# FIRST AUTHOR <EMAIL@ADDRESS>, 2012.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: PROJECT VERSION\n"
+"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
+"POT-Creation-Date: 2013-08-02 20:43-0700\n"
+"PO-Revision-Date: 2012-07-30 18:50-0700\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: ja <LL@li.org>\n"
+"Plural-Forms: nplurals=1; plural=0\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Generated-By: Babel 0.9.6\n"
+
+#: src/impala/conf.py:29
+msgid "Host of the Impala Server."
+msgstr "Impala Server のホストです。"
+
+#: src/impala/conf.py:34
+msgid "Port of the Impala Server."
+msgstr "Impala Server のポートです。"
+
+#: src/impala/conf.py:40
+#, fuzzy
+msgid "Beeswax or Hive Server 2 Thrift API used. Choices are: 'beeswax' or 'hiveserver2'."
+msgstr "Beeswax または Hive Server 2 Thrift API を使用します。選択肢には 'beeswax' と 'hiveserver2' があります。"
+
+#: src/impala/conf.py:45
+msgid "Kerberos principal name for Impala. Typically 'impala/hostname.foo.com'."
+msgstr "Impala の Kerberos プリンシパル名。普通は 'impala/hostname.foo.com' です。"
+
+#: src/impala/conf.py:63
+msgid "No available Impalad to send queries to."
+msgstr "クエリ送信先に利用できる Impalad はありません。"
+
+#: src/impala/views.py:35
+msgid "A POST request is required."
+msgstr "POST 要求が必要です。"
+

+ 44 - 0
desktop/libs/librdbms/src/librdbms/locale/ko/LC_MESSAGES/django.po

@@ -0,0 +1,44 @@
+# Korean translations for Hue.
+# Copyright (C) 2012 Cloudera
+# This file is distributed under the same license as the Hue project.
+# FIRST AUTHOR <EMAIL@ADDRESS>, 2012.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: PROJECT VERSION\n"
+"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
+"POT-Creation-Date: 2013-08-02 20:43-0700\n"
+"PO-Revision-Date: 2012-07-30 18:50-0700\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: ko <LL@li.org>\n"
+"Plural-Forms: nplurals=1; plural=0\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Generated-By: Babel 0.9.6\n"
+
+#: src/impala/conf.py:29
+msgid "Host of the Impala Server."
+msgstr "Impala 서버의 호스트입니다."
+
+#: src/impala/conf.py:34
+msgid "Port of the Impala Server."
+msgstr "Impala 서버의 포트입니다."
+
+#: src/impala/conf.py:40
+#, fuzzy
+msgid "Beeswax or Hive Server 2 Thrift API used. Choices are: 'beeswax' or 'hiveserver2'."
+msgstr "Beeswax 또는 Hive Server 2 Thrift API를 사용 중입니다. 'beeswax' 또는 'hiveserver2' 중에서 선택할 수 있습니다."
+
+#: src/impala/conf.py:45
+msgid "Kerberos principal name for Impala. Typically 'impala/hostname.foo.com'."
+msgstr "Impala의 Kerberos 원칙 이름입니다. 일반적으로 'impala/hostname.foo.com'입니다."
+
+#: src/impala/conf.py:63
+msgid "No available Impalad to send queries to."
+msgstr "쿼리를 전송할 사용 가능한 Impalad가 없습니다."
+
+#: src/impala/views.py:35
+msgid "A POST request is required."
+msgstr "POST 요청이 필요합니다."
+

+ 44 - 0
desktop/libs/librdbms/src/librdbms/locale/pt/LC_MESSAGES/django.po

@@ -0,0 +1,44 @@
+# Portuguese translations for Hue.
+# Copyright (C) 2012 Cloudera
+# This file is distributed under the same license as the Hue project.
+# FIRST AUTHOR <EMAIL@ADDRESS>, 2012.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: PROJECT VERSION\n"
+"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
+"POT-Creation-Date: 2013-08-02 20:43-0700\n"
+"PO-Revision-Date: 2012-07-30 18:50-0700\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: pt <LL@li.org>\n"
+"Plural-Forms: nplurals=2; plural=(n != 1)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Generated-By: Babel 0.9.6\n"
+
+#: src/impala/conf.py:29
+msgid "Host of the Impala Server."
+msgstr "Anfitrião do Impala Server."
+
+#: src/impala/conf.py:34
+msgid "Port of the Impala Server."
+msgstr "Porta do servidor Impala."
+
+#: src/impala/conf.py:40
+#, fuzzy
+msgid "Beeswax or Hive Server 2 Thrift API used. Choices are: 'beeswax' or 'hiveserver2'."
+msgstr "Beeswax ou Hive Server 2 Thrift API utilizado. As opções são: \"beeswax\" ou \"hiveserver2\"."
+
+#: src/impala/conf.py:45
+msgid "Kerberos principal name for Impala. Typically 'impala/hostname.foo.com'."
+msgstr "Nome principal do Kerberos para o Impala. Normalmente \"impala/hostname.foo.com\"."
+
+#: src/impala/conf.py:63
+msgid "No available Impalad to send queries to."
+msgstr "Sem Impala disponível para enviar consultas."
+
+#: src/impala/views.py:35
+msgid "A POST request is required."
+msgstr "É necessário um pedido POST."
+

+ 44 - 0
desktop/libs/librdbms/src/librdbms/locale/pt_BR/LC_MESSAGES/django.po

@@ -0,0 +1,44 @@
+# Portuguese (Brazil) translations for Hue.
+# Copyright (C) 2012 Cloudera
+# This file is distributed under the same license as the Hue project.
+# FIRST AUTHOR <EMAIL@ADDRESS>, 2012.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: PROJECT VERSION\n"
+"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
+"POT-Creation-Date: 2013-08-02 20:43-0700\n"
+"PO-Revision-Date: 2012-07-30 18:50-0700\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: pt_BR <LL@li.org>\n"
+"Plural-Forms: nplurals=2; plural=(n > 1)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Generated-By: Babel 0.9.6\n"
+
+#: src/impala/conf.py:29
+msgid "Host of the Impala Server."
+msgstr "Host do servidor Impala."
+
+#: src/impala/conf.py:34
+msgid "Port of the Impala Server."
+msgstr "Porta do servidor Impala."
+
+#: src/impala/conf.py:40
+#, fuzzy
+msgid "Beeswax or Hive Server 2 Thrift API used. Choices are: 'beeswax' or 'hiveserver2'."
+msgstr "API Thrift do Beeswax ou Hive Server 2 usada. As opções são: 'beeswax' ou 'hiveserver2'."
+
+#: src/impala/conf.py:45
+msgid "Kerberos principal name for Impala. Typically 'impala/hostname.foo.com'."
+msgstr "Nome principal do Kerberos para o Impala. Normalmente, 'hue/hostname.foo.com'."
+
+#: src/impala/conf.py:63
+msgid "No available Impalad to send queries to."
+msgstr "Nenhum Impala disponível para o qual enviar consultas."
+
+#: src/impala/views.py:35
+msgid "A POST request is required."
+msgstr "É necessária uma solicitação POST."
+

+ 44 - 0
desktop/libs/librdbms/src/librdbms/locale/zh_CN/LC_MESSAGES/django.po

@@ -0,0 +1,44 @@
+# Chinese (China) translations for Hue.
+# Copyright (C) 2012 Cloudera
+# This file is distributed under the same license as the Hue project.
+# FIRST AUTHOR <EMAIL@ADDRESS>, 2012.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: PROJECT VERSION\n"
+"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
+"POT-Creation-Date: 2013-08-02 20:43-0700\n"
+"PO-Revision-Date: 2012-07-30 18:50-0700\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: zh_CN <LL@li.org>\n"
+"Plural-Forms: nplurals=1; plural=0\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Generated-By: Babel 0.9.6\n"
+
+#: src/impala/conf.py:29
+msgid "Host of the Impala Server."
+msgstr "Impala 服务器主机。"
+
+#: src/impala/conf.py:34
+msgid "Port of the Impala Server."
+msgstr "Impala 服务器端口。"
+
+#: src/impala/conf.py:40
+#, fuzzy
+msgid "Beeswax or Hive Server 2 Thrift API used. Choices are: 'beeswax' or 'hiveserver2'."
+msgstr "已使用 Beeswax 或 Hive Server 2 Thrift API。选择是:'beeswax' 或 'hiveserver2'。"
+
+#: src/impala/conf.py:45
+msgid "Kerberos principal name for Impala. Typically 'impala/hostname.foo.com'."
+msgstr "Impala 的 Kerberos 主体名称。通常为“impala/hostname.foo.com”。"
+
+#: src/impala/conf.py:63
+msgid "No available Impalad to send queries to."
+msgstr "没有可向其发送查询的 Impalad。"
+
+#: src/impala/views.py:35
+msgid "A POST request is required."
+msgstr "需要 POST 请求。"
+

+ 16 - 0
desktop/libs/librdbms/src/librdbms/models.py

@@ -0,0 +1,16 @@
+#!/usr/bin/env python
+# Licensed to Cloudera, Inc. under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  Cloudera, Inc. licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.

+ 0 - 0
apps/rdbms/src/rdbms/server/__init__.py → desktop/libs/librdbms/src/librdbms/server/__init__.py


+ 27 - 20
apps/rdbms/src/rdbms/server/dbms.py → desktop/libs/librdbms/src/librdbms/server/dbms.py

@@ -18,12 +18,17 @@
 import logging
 import logging
 
 
 from desktop.lib.i18n import smart_str
 from desktop.lib.i18n import smart_str
-from beeswax.models import QueryHistory
-from rdbms.conf import RDBMS
+
+from librdbms.conf import DATABASES
 
 
 
 
 LOG = logging.getLogger(__name__)
 LOG = logging.getLogger(__name__)
 
 
+MYSQL = 'mysql'
+POSTGRESQL = 'postgresql'
+SQLITE = 'sqlite'
+ORACLE = 'oracle'
+
 
 
 def force_dict_to_strings(dictionary):
 def force_dict_to_strings(dictionary):
   if not dictionary:
   if not dictionary:
@@ -50,43 +55,43 @@ def get(user, query_server=None):
     query_server = get_query_server_config()
     query_server = get_query_server_config()
 
 
   if query_server['server_name'] == 'mysql':
   if query_server['server_name'] == 'mysql':
-    from rdbms.server.mysql_lib import MySQLClient
+    from librdbms.server.mysql_lib import MySQLClient
 
 
-    return Rdbms(MySQLClient(query_server, user), QueryHistory.SERVER_TYPE[2][0])
+    return Rdbms(MySQLClient(query_server, user), MYSQL)
   elif query_server['server_name'] in ('postgresql', 'postgresql_psycopg2'):
   elif query_server['server_name'] in ('postgresql', 'postgresql_psycopg2'):
-    from rdbms.server.postgresql_lib import PostgreSQLClient
+    from librdbms.server.postgresql_lib import PostgreSQLClient
 
 
-    return Rdbms(PostgreSQLClient(query_server, user), QueryHistory.SERVER_TYPE[2][0])
+    return Rdbms(PostgreSQLClient(query_server, user), POSTGRESQL)
   elif query_server['server_name'] in ('sqlite', 'sqlite3'):
   elif query_server['server_name'] in ('sqlite', 'sqlite3'):
-    from rdbms.server.sqlite_lib import SQLiteClient
+    from librdbms.server.sqlite_lib import SQLiteClient
 
 
-    return Rdbms(SQLiteClient(query_server, user), QueryHistory.SERVER_TYPE[2][0])
+    return Rdbms(SQLiteClient(query_server, user), SQLITE)
   elif query_server['server_name'] == 'oracle':
   elif query_server['server_name'] == 'oracle':
-    from rdbms.server.oracle_lib import OracleClient
+    from librdbms.server.oracle_lib import OracleClient
 
 
-    return Rdbms(OracleClient(query_server, user), QueryHistory.SERVER_TYPE[2][0])
+    return Rdbms(OracleClient(query_server, user), ORACLE)
 
 
 
 
 def get_query_server_config(server=None):
 def get_query_server_config(server=None):
-  if not server or server not in RDBMS:
-    keys = RDBMS.keys()
+  if not server or server not in DATABASES:
+    keys = DATABASES.keys()
     name = keys and keys[0] or None
     name = keys and keys[0] or None
   else:
   else:
     name = server
     name = server
 
 
   if name:
   if name:
     query_server = {
     query_server = {
-      'server_name': RDBMS[name].ENGINE.get().split('.')[-1],
-      'server_host': RDBMS[name].HOST.get(),
-      'server_port': RDBMS[name].PORT.get(),
-      'username': RDBMS[name].USER.get(),
-      'password': RDBMS[name].PASSWORD.get(),
-      'options': force_dict_to_strings(RDBMS[name].OPTIONS.get()),
+      'server_name': DATABASES[name].ENGINE.get().split('.')[-1],
+      'server_host': DATABASES[name].HOST.get(),
+      'server_port': DATABASES[name].PORT.get(),
+      'username': DATABASES[name].USER.get(),
+      'password': DATABASES[name].PASSWORD.get(),
+      'options': force_dict_to_strings(DATABASES[name].OPTIONS.get()),
       'alias': name
       'alias': name
     }
     }
 
 
-    if RDBMS[name].NAME.get():
-      query_server['name'] = RDBMS[name].NAME.get()
+    if DATABASES[name].NAME.get():
+      query_server['name'] = DATABASES[name].NAME.get()
   else:
   else:
     query_server = {}
     query_server = {}
 
 
@@ -113,6 +118,8 @@ class Rdbms(object):
     return self.client.get_columns(database, table_name)
     return self.client.get_columns(database, table_name)
 
 
   def execute_query(self, query, design):
   def execute_query(self, query, design):
+    from beeswax.models import QueryHistory
+
     sql_query = query.sql_query
     sql_query = query.sql_query
     query_history = QueryHistory.build(
     query_history = QueryHistory.build(
       owner=self.client.user,
       owner=self.client.user,

+ 1 - 1
apps/rdbms/src/rdbms/server/mysql_lib.py → desktop/libs/librdbms/src/librdbms/server/mysql_lib.py

@@ -32,7 +32,7 @@ if (version < (1,2,1) or (version[:3] == (1, 2, 1) and
     from django.core.exceptions import ImproperlyConfigured
     from django.core.exceptions import ImproperlyConfigured
     raise ImproperlyConfigured("MySQLdb-1.2.1p2 or newer is required; you have %s" % Database.__version__)
     raise ImproperlyConfigured("MySQLdb-1.2.1p2 or newer is required; you have %s" % Database.__version__)
 
 
-from rdbms.server.rdbms_base_lib import BaseRDBMSDataTable, BaseRDBMSResult, BaseRDMSClient
+from librdbms.server.rdbms_base_lib import BaseRDBMSDataTable, BaseRDBMSResult, BaseRDMSClient
 
 
 
 
 LOG = logging.getLogger(__name__)
 LOG = logging.getLogger(__name__)

+ 1 - 1
apps/rdbms/src/rdbms/server/oracle_lib.py → desktop/libs/librdbms/src/librdbms/server/oracle_lib.py

@@ -23,7 +23,7 @@ except ImportError, e:
   from django.core.exceptions import ImproperlyConfigured
   from django.core.exceptions import ImproperlyConfigured
   raise ImproperlyConfigured("Error loading cx_Oracle module: %s" % e)
   raise ImproperlyConfigured("Error loading cx_Oracle module: %s" % e)
 
 
-from rdbms.server.rdbms_base_lib import BaseRDBMSDataTable, BaseRDBMSResult, BaseRDMSClient
+from librdbms.server.rdbms_base_lib import BaseRDBMSDataTable, BaseRDBMSResult, BaseRDMSClient
 
 
 
 
 LOG = logging.getLogger(__name__)
 LOG = logging.getLogger(__name__)

+ 1 - 1
apps/rdbms/src/rdbms/server/postgresql_lib.py → desktop/libs/librdbms/src/librdbms/server/postgresql_lib.py

@@ -23,7 +23,7 @@ except ImportError, e:
     from django.core.exceptions import ImproperlyConfigured
     from django.core.exceptions import ImproperlyConfigured
     raise ImproperlyConfigured("Error loading psycopg2 module: %s" % e)
     raise ImproperlyConfigured("Error loading psycopg2 module: %s" % e)
 
 
-from rdbms.server.rdbms_base_lib import BaseRDBMSDataTable, BaseRDBMSResult, BaseRDMSClient
+from librdbms.server.rdbms_base_lib import BaseRDBMSDataTable, BaseRDBMSResult, BaseRDMSClient
 
 
 
 
 LOG = logging.getLogger(__name__)
 LOG = logging.getLogger(__name__)

+ 1 - 3
apps/rdbms/src/rdbms/server/rdbms_base_lib.py → desktop/libs/librdbms/src/librdbms/server/rdbms_base_lib.py

@@ -17,13 +17,11 @@
 
 
 import logging
 import logging
 
 
-from beeswax.server.dbms import DataTable
-
 
 
 LOG = logging.getLogger(__name__)
 LOG = logging.getLogger(__name__)
 
 
 
 
-class BaseRDBMSDataTable(DataTable):
+class BaseRDBMSDataTable(object):
   def __init__(self, cursor, columns, fetch_size=1000):
   def __init__(self, cursor, columns, fetch_size=1000):
     self.cursor = cursor
     self.cursor = cursor
     self.columns = columns
     self.columns = columns

+ 1 - 1
apps/rdbms/src/rdbms/server/sqlite_lib.py → desktop/libs/librdbms/src/librdbms/server/sqlite_lib.py

@@ -26,7 +26,7 @@ except ImportError, exc:
   from django.core.exceptions import ImproperlyConfigured
   from django.core.exceptions import ImproperlyConfigured
   raise ImproperlyConfigured("Error loading either pysqlite2 or sqlite3 modules (tried in that order): %s" % exc)
   raise ImproperlyConfigured("Error loading either pysqlite2 or sqlite3 modules (tried in that order): %s" % exc)
 
 
-from rdbms.server.rdbms_base_lib import BaseRDBMSDataTable, BaseRDBMSResult, BaseRDMSClient
+from librdbms.server.rdbms_base_lib import BaseRDBMSDataTable, BaseRDBMSResult, BaseRDMSClient
 
 
 
 
 LOG = logging.getLogger(__name__)
 LOG = logging.getLogger(__name__)

+ 16 - 0
desktop/libs/librdbms/src/librdbms/tests.py

@@ -0,0 +1,16 @@
+#!/usr/bin/env python
+# Licensed to Cloudera, Inc. under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  Cloudera, Inc. licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.

+ 16 - 0
desktop/libs/librdbms/src/librdbms/urls.py

@@ -0,0 +1,16 @@
+#!/usr/bin/env python
+# Licensed to Cloudera, Inc. under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  Cloudera, Inc. licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.