浏览代码

[librdbms] Basic implementation of JDBC api

Romain Rigaux 10 年之前
父节点
当前提交
5a537dbddc

+ 81 - 0
desktop/libs/librdbms/src/librdbms/jdbc.py

@@ -0,0 +1,81 @@
+#!/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.
+
+import logging
+import sys
+
+
+LOG = logging.getLogger(__name__)
+
+try:
+  from py4j.java_gateway import JavaGateway
+except ImportError, e:
+  LOG.exception('Failed to import py4j')
+
+
+class Jdbc():
+
+  def __init__(self, driver_name, url, username, password):
+    if 'py4j' not in sys.modules:
+      raise Exception('Required py4j module is not imported.')
+
+    self.gateway = JavaGateway()
+
+    self.jdbc_driver = driver_name
+    self.db_url = url
+    self.username = username
+    self.password = password
+
+    self.conn = None
+
+  def connect(self):
+    if self.conn is None:
+      self.conn = self.gateway.jvm.java.sql.DriverManager.getConnection(self.db_url, self.username, self.password)
+
+  def execute(self, statement):
+    stmt = self.conn.createStatement()
+
+    try:
+      rs = stmt.executeQuery(statement)
+
+      try:
+        md = rs.getMetaData()
+
+        rs_meta = [{
+            'name': md.getColumnName(i + 1),
+            'type': md.getColumnTypeName(i + 1),
+            'length': md.getColumnDisplaySize(i + 1),
+            'precision': md.getPrecision(i + 1),
+          } for i in xrange(md.getColumnCount())]
+
+        res = []
+        while rs.next():
+          row = []
+          for c in xrange(md.getColumnCount()):
+            row.append(rs.getString(c + 1))
+          res.append(row)
+
+        return res, rs_meta
+      finally:
+        rs.close()
+    finally:
+      stmt.close()
+
+  def disconnect(self):
+    if self.conn is not None:
+      self.conn.close()
+      self.conn = None

+ 17 - 31
desktop/libs/notebook/src/notebook/connectors/jdbc.py

@@ -17,10 +17,11 @@
 
 import logging
 import re
-import sys
+
 
 from desktop.lib.exceptions_renderable import PopupException
 from desktop.lib.i18n import force_unicode
+from librdbms.jdbc import Jdbc
 from django.utils.translation import ugettext as _
 
 from notebook.connectors.base import Api, QueryError
@@ -28,11 +29,6 @@ from notebook.connectors.base import Api, QueryError
 
 LOG = logging.getLogger(__name__)
 
-try:
-  import jaydebeapi
-except ImportError, e:
-  LOG.exception('Failed to import jaydebeapi')
-
 
 def query_error_handler(func):
   def decorator(*args, **kwargs):
@@ -54,45 +50,35 @@ class JDBCApi(Api):
   # impersonation / prompting for username/password
   @query_error_handler
   def execute(self, notebook, snippet):
-    if 'jaydebeapi' not in sys.modules:
-      raise Exception('Required jaydebeapi module is not imported.')
-
     user = 'root'
     password = 'root'
-    
+
     host = 'localhost'
     port = 3306
     database = 'test'
-    
-    autocommit = True
+
+
     jclassname = "com.mysql.jdbc.Driver"
     url = "jdbc:mysql://{host}:{port}/{database}".format(host=host, port=port, database=database)
-    driver_args = [url, user, password]
-    jars = None
-    libs = None
-
-    db = jaydebeapi.connect(jclassname, driver_args, jars=jars, libs=libs)
-    db.jconn.setAutoCommit(autocommit)
-    
-    curs = db.cursor()
-    curs.execute(snippet['statement'])
-
-    data = curs.fetchmany(100)
-    description = curs.description
-    
-    curs.close()
-    db.close()
-    
+
+    db = Jdbc(jclassname, url, user, password)
+    db.connect()
+
+
+    data, meta = db.execute(snippet['statement'])
+
+    db.disconnect()
+
     return {
       'sync': True,
       'result': {
         'has_more': False,
         'data': list(data),
         'meta': [{
-          'name': column[0],
-          'type': 'TODO',
+          'name': column['name'],
+          'type': column['type'],
           'comment': ''
-        } for column in description],
+        } for column in meta],
         'type': 'table'
       }
     }

+ 0 - 1
desktop/libs/notebook/src/notebook/static/notebook/js/notebook.ko.js

@@ -123,7 +123,6 @@ var getDefaultSnippetProperties = function (snippetType) {
     properties['files'] = [];
   }
   else if (snippetType == 'pig') {
-    properties['script'] = '';
     properties['parameters'] = [];
     properties['hadoopProperties'] = [];
     properties['resources'] = [];