Updated from latest web2py master
This commit is contained in:
1 parent
b20b81b8f5
commit
947dcbc226
6 files changed
+46
-20
No files matched your search
@@ -64,7 +64,7 @@ class BaseAdapter(ConnectionPool):
|
|||||||
|
|
||||||
__metaclass__ = AdapterMeta
|
__metaclass__ = AdapterMeta
|
||||||
|
|
||||||
native_json = False
|
driver_auto_json = False
|
||||||
driver = None
|
driver = None
|
||||||
driver_name = None
|
driver_name = None
|
||||||
drivers = () # list of drivers from which to pick
|
drivers = () # list of drivers from which to pick
|
||||||
@@ -1113,13 +1113,20 @@ class BaseAdapter(ConnectionPool):
|
|||||||
query = self.common_filter(query,tablenames_for_common_filters)
|
query = self.common_filter(query,tablenames_for_common_filters)
|
||||||
sql_w = ' WHERE ' + self.expand(query) if query else ''
|
sql_w = ' WHERE ' + self.expand(query) if query else ''
|
||||||
|
|
||||||
|
JOIN = ' CROSS JOIN '
|
||||||
|
|
||||||
if inner_join and not left:
|
if inner_join and not left:
|
||||||
sql_t = ', '.join([self.table_alias(t) for t in iexcluded + \
|
# Wrap table references with parenthesis (approach 1)
|
||||||
itables_to_merge.keys()])
|
# sql_t = ', '.join([self.table_alias(t) for t in iexcluded + \
|
||||||
|
# itables_to_merge.keys()])
|
||||||
|
# sql_t = '(%s)' % sql_t
|
||||||
|
# or approach 2: Use 'JOIN' instead comma:
|
||||||
|
sql_t = JOIN.join([self.table_alias(t)
|
||||||
|
for t in iexcluded + itables_to_merge.keys()])
|
||||||
for t in ijoinon:
|
for t in ijoinon:
|
||||||
sql_t += ' %s %s' % (icommand, t)
|
sql_t += ' %s %s' % (icommand, t)
|
||||||
elif not inner_join and left:
|
elif not inner_join and left:
|
||||||
sql_t = ', '.join([self.table_alias(t) for t in excluded + \
|
sql_t = JOIN.join([self.table_alias(t) for t in excluded + \
|
||||||
tables_to_merge.keys()])
|
tables_to_merge.keys()])
|
||||||
if joint:
|
if joint:
|
||||||
sql_t += ' %s %s' % (command,
|
sql_t += ' %s %s' % (command,
|
||||||
@@ -1133,7 +1140,7 @@ class BaseAdapter(ConnectionPool):
|
|||||||
tables_in_joinon = set(joinont + ijoinont)
|
tables_in_joinon = set(joinont + ijoinont)
|
||||||
tables_not_in_joinon = \
|
tables_not_in_joinon = \
|
||||||
all_tables_in_query.difference(tables_in_joinon)
|
all_tables_in_query.difference(tables_in_joinon)
|
||||||
sql_t = ','.join([self.table_alias(t) for t in tables_not_in_joinon])
|
sql_t = JOIN.join([self.table_alias(t) for t in tables_not_in_joinon])
|
||||||
for t in ijoinon:
|
for t in ijoinon:
|
||||||
sql_t += ' %s %s' % (icommand, t)
|
sql_t += ' %s %s' % (icommand, t)
|
||||||
if joint:
|
if joint:
|
||||||
@@ -1386,7 +1393,8 @@ class BaseAdapter(ConnectionPool):
|
|||||||
else:
|
else:
|
||||||
obj = str(obj)
|
obj = str(obj)
|
||||||
elif fieldtype == 'json':
|
elif fieldtype == 'json':
|
||||||
if not self.native_json:
|
if not 'dumps' in self.driver_auto_json:
|
||||||
|
# always pass a string JSON string
|
||||||
if have_serializers:
|
if have_serializers:
|
||||||
obj = serializers.json(obj)
|
obj = serializers.json(obj)
|
||||||
elif simplejson:
|
elif simplejson:
|
||||||
@@ -1524,7 +1532,7 @@ class BaseAdapter(ConnectionPool):
|
|||||||
return float(value)
|
return float(value)
|
||||||
|
|
||||||
def parse_json(self, value, field_type):
|
def parse_json(self, value, field_type):
|
||||||
if not self.native_json:
|
if not 'loads' in self.driver_auto_json:
|
||||||
if not isinstance(value, basestring):
|
if not isinstance(value, basestring):
|
||||||
raise RuntimeError('json data not a string')
|
raise RuntimeError('json data not a string')
|
||||||
if isinstance(value, unicode):
|
if isinstance(value, unicode):
|
||||||
|
|||||||
@@ -5,7 +5,8 @@ import re
|
|||||||
from .._compat import pjoin
|
from .._compat import pjoin
|
||||||
from .._globals import IDENTITY, LOGGER, THREAD_LOCAL
|
from .._globals import IDENTITY, LOGGER, THREAD_LOCAL
|
||||||
from .._load import classobj, gae, ndb, NDBDecimalProperty, GAEDecimalProperty, \
|
from .._load import classobj, gae, ndb, NDBDecimalProperty, GAEDecimalProperty, \
|
||||||
namespace_manager, Key, NDBPolyModel, PolyModel, rdbms
|
namespace_manager, Key, NDBPolyModel, PolyModel, rdbms, have_serializers, \
|
||||||
|
serializers, simplejson
|
||||||
from ..objects import Table, Field, Expression, Query
|
from ..objects import Table, Field, Expression, Query
|
||||||
from ..helpers.classes import SQLCustomType, SQLALL, Reference, UseDatabaseStoredFile
|
from ..helpers.classes import SQLCustomType, SQLALL, Reference, UseDatabaseStoredFile
|
||||||
from ..helpers.methods import use_common_filters, xorify
|
from ..helpers.methods import use_common_filters, xorify
|
||||||
@@ -173,6 +174,17 @@ class GoogleDatastoreAdapter(NoSQLAdapter):
|
|||||||
def parse_id(self, value, field_type):
|
def parse_id(self, value, field_type):
|
||||||
return value
|
return value
|
||||||
|
|
||||||
|
def represent(self, obj, fieldtype):
|
||||||
|
if fieldtype == "json":
|
||||||
|
if have_serializers:
|
||||||
|
return serializers.json(obj)
|
||||||
|
elif simplejson:
|
||||||
|
return simplejson.dumps(obj)
|
||||||
|
else:
|
||||||
|
raise Exception("Could not dump json object (missing json library)")
|
||||||
|
else:
|
||||||
|
return NoSQLAdapter.represent(self, obj, fieldtype)
|
||||||
|
|
||||||
def create_table(self,table,migrate=True,fake_migrate=False, polymodel=None):
|
def create_table(self,table,migrate=True,fake_migrate=False, polymodel=None):
|
||||||
myfields = {}
|
myfields = {}
|
||||||
for field in table:
|
for field in table:
|
||||||
|
|||||||
@@ -10,8 +10,8 @@ from ..helpers.methods import xorify
|
|||||||
from .base import NoSQLAdapter
|
from .base import NoSQLAdapter
|
||||||
|
|
||||||
class MongoDBAdapter(NoSQLAdapter):
|
class MongoDBAdapter(NoSQLAdapter):
|
||||||
native_json = True
|
|
||||||
drivers = ('pymongo',)
|
drivers = ('pymongo',)
|
||||||
|
driver_auto_json = ['loads','dumps']
|
||||||
|
|
||||||
uploads_in_blob = False
|
uploads_in_blob = False
|
||||||
|
|
||||||
|
|||||||
@@ -175,16 +175,21 @@ class PostgreSQLAdapter(BaseAdapter):
|
|||||||
# (to be added to after_connection)
|
# (to be added to after_connection)
|
||||||
if self.driver_name == "pg8000":
|
if self.driver_name == "pg8000":
|
||||||
supports_json = self.connection.server_version >= "9.2.0"
|
supports_json = self.connection.server_version >= "9.2.0"
|
||||||
elif (self.driver_name == "psycopg2") and \
|
elif (self.driver_name == "psycopg2" and
|
||||||
(self.driver.__version__ >= "2.0.12"):
|
self.driver.__version__ >= "2.0.12"):
|
||||||
supports_json = self.connection.server_version >= 90200
|
supports_json = self.connection.server_version >= 90200
|
||||||
elif self.driver_name == "zxJDBC":
|
elif self.driver_name == "zxJDBC":
|
||||||
supports_json = self.connection.dbversion >= "9.2.0"
|
supports_json = self.connection.dbversion >= "9.2.0"
|
||||||
else: supports_json = None
|
else:
|
||||||
|
supports_json = None
|
||||||
if supports_json:
|
if supports_json:
|
||||||
self.types["json"] = "JSON"
|
self.types["json"] = "JSON"
|
||||||
self.native_json = True
|
if (self.driver_name == "psycopg2" and
|
||||||
else: LOGGER.debug("Your database version does not support the JSON data type (using TEXT instead)")
|
self.driver.__version__ >= '2.5.0'):
|
||||||
|
self.driver_auto_json = ['loads']
|
||||||
|
else:
|
||||||
|
LOGGER.debug("Your database version does not support the JSON"
|
||||||
|
" data type (using TEXT instead)")
|
||||||
|
|
||||||
def LIKE(self,first,second):
|
def LIKE(self,first,second):
|
||||||
args = (self.expand(first), self.expand(second,'string'))
|
args = (self.expand(first), self.expand(second,'string'))
|
||||||
|
|||||||
@@ -192,7 +192,7 @@ def smart_query(fields,text):
|
|||||||
elif op == 'notbelongs': new_query = ~field.belongs(value.split(','))
|
elif op == 'notbelongs': new_query = ~field.belongs(value.split(','))
|
||||||
elif field.type in ('text', 'string', 'json'):
|
elif field.type in ('text', 'string', 'json'):
|
||||||
if op == 'contains': new_query = field.contains(value)
|
if op == 'contains': new_query = field.contains(value)
|
||||||
elif op == 'like': new_query = field.like(value)
|
elif op == 'like': new_query = field.ilike(value)
|
||||||
elif op == 'startswith': new_query = field.startswith(value)
|
elif op == 'startswith': new_query = field.startswith(value)
|
||||||
elif op == 'endswith': new_query = field.endswith(value)
|
elif op == 'endswith': new_query = field.endswith(value)
|
||||||
else: raise RuntimeError("Invalid operation")
|
else: raise RuntimeError("Invalid operation")
|
||||||
@@ -246,7 +246,7 @@ def sqlhtml_validators(field):
|
|||||||
if field_type in (('string', 'text', 'password')):
|
if field_type in (('string', 'text', 'password')):
|
||||||
requires.append(validators.IS_LENGTH(field_length))
|
requires.append(validators.IS_LENGTH(field_length))
|
||||||
elif field_type == 'json':
|
elif field_type == 'json':
|
||||||
requires.append(validators.IS_EMPTY_OR(validators.IS_JSON(native_json=field.db._adapter.native_json)))
|
requires.append(validators.IS_EMPTY_OR(validators.IS_JSON()))
|
||||||
elif field_type == 'double' or field_type == 'float':
|
elif field_type == 'double' or field_type == 'float':
|
||||||
requires.append(validators.IS_FLOAT_IN_RANGE(-1e100, 1e100))
|
requires.append(validators.IS_FLOAT_IN_RANGE(-1e100, 1e100))
|
||||||
elif field_type == 'integer':
|
elif field_type == 'integer':
|
||||||
|
|||||||
@@ -1207,6 +1207,9 @@ class Expression(object):
|
|||||||
op = case_sensitive and db._adapter.LIKE or db._adapter.ILIKE
|
op = case_sensitive and db._adapter.LIKE or db._adapter.ILIKE
|
||||||
return Query(db, op, self, value)
|
return Query(db, op, self, value)
|
||||||
|
|
||||||
|
def ilike(self, value):
|
||||||
|
return self.like(case_sensitive=False)
|
||||||
|
|
||||||
def regexp(self, value):
|
def regexp(self, value):
|
||||||
db = self.db
|
db = self.db
|
||||||
return Query(db, db._adapter.REGEXP, self, value)
|
return Query(db, db._adapter.REGEXP, self, value)
|
||||||
@@ -1254,14 +1257,12 @@ class Expression(object):
|
|||||||
|
|
||||||
def contains(self, value, all=False, case_sensitive=False):
|
def contains(self, value, all=False, case_sensitive=False):
|
||||||
"""
|
"""
|
||||||
The case_sensitive parameters is only useful for PostgreSQL
|
|
||||||
For other RDMBs it is ignored and contains is always case insensitive
|
|
||||||
For MongoDB and GAE contains is always case sensitive
|
For MongoDB and GAE contains is always case sensitive
|
||||||
"""
|
"""
|
||||||
db = self.db
|
db = self.db
|
||||||
if isinstance(value,(list, tuple)):
|
if isinstance(value,(list, tuple)):
|
||||||
subqueries = [self.contains(str(v).strip(),case_sensitive=case_sensitive)
|
subqueries = [self.contains(str(v),case_sensitive=case_sensitive)
|
||||||
for v in value if str(v).strip()]
|
for v in value if str(v)]
|
||||||
if not subqueries:
|
if not subqueries:
|
||||||
return self.contains('')
|
return self.contains('')
|
||||||
else:
|
else:
|
||||||
|
|||||||
Reference in new issue
Block a user