# Path: pydal/_compat.py
# PY2 = sys.version_info[0] == 2
#     def implements_bool(cls):
#     def implements_iterator(cls):
#     def to_bytes(obj, charset="utf-8", errors="strict"):
#     def to_native(obj, charset="utf8", errors="strict"):
#     def to_bytes(obj, charset="utf-8", errors="strict"):
#     def to_native(obj, charset="utf8", errors="strict"):
# def with_metaclass(meta, *bases):
#         def __new__(cls, name, this_bases, d):
# def to_unicode(obj, charset="utf-8", errors="strict"):
#     class metaclass(meta):
# 
# Path: pydal/helpers/regex.py
# REGEX_CREDENTIALS = r"(?<=//)[\w.-]+([:/][^@]*)?(?=@)"
# 
# REGEX_UNPACK = r"(?<!\|)\|(?!\|)"
# 
# REGEX_CONST_STRING = '("[^"]*")|' "('[^']*')"
# 
# REGEX_W = re.compile(r"^\w+$")
# 
# Path: pydal/helpers/classes.py
# class SQLCustomType(object):
#     """
#     Allows defining of custom SQL types
# 
#     Args:
#         type: the web2py type (default = 'string')
#         native: the backend type
#         encoder: how to encode the value to store it in the backend
#         decoder: how to decode the value retrieved from the backend
#         validator: what validators to use ( default = None, will use the
#             default validator for type)
# 
#     Example::
#         Define as:
# 
#             decimal = SQLCustomType(
#                 type ='double',
#                 native ='integer',
#                 encoder =(lambda x: int(float(x) * 100)),
#                 decoder = (lambda x: Decimal("0.00") + Decimal(str(float(x)/100)) )
#                 )
# 
#             db.define_table(
#                 'example',
#                 Field('value', type=decimal)
#                 )
# 
#     """
# 
#     def __init__(
#         self,
#         type="string",
#         native=None,
#         encoder=None,
#         decoder=None,
#         validator=None,
#         _class=None,
#         widget=None,
#         represent=None,
#     ):
#         self.type = type
#         self.native = native
#         self.encoder = encoder or (lambda x: x)
#         self.decoder = decoder or (lambda x: x)
#         self.validator = validator
#         self._class = _class or type
#         self.widget = widget
#         self.represent = represent
# 
#     def startswith(self, text=None):
#         try:
#             return self.type.startswith(self, text)
#         except TypeError:
#             return False
# 
#     def endswith(self, text=None):
#         try:
#             return self.type.endswith(self, text)
#         except TypeError:
#             return False
# 
#     def __getslice__(self, a=0, b=100):
#         return None
# 
#     def __getitem__(self, i):
#         return None
# 
#     def __str__(self):
#         return self._class


import os
import re
import uuid
from .._compat import (
    PY2,
    BytesIO,
    iteritems,
    integer_types,
    string_types,
    to_bytes,
    pjoin,
    exists,
    text_type,
)
from .regex import REGEX_CREDENTIALS, REGEX_UNPACK, REGEX_CONST_STRING, REGEX_W
from .classes import SQLCustomType
    from ..objects import Field, Table
        fields = table.fields
    fields = [
        f
        for f in fields
        if table[f].type == "upload"
        and table[f].uploadfield == True
        and table[f].autodelete
    ]
    if not fields:
        return False
    for record in dbset.select(*[table[f] for f in fields]):
        for fieldname in fields:
            field = table[fieldname]
            oldname = record.get(fieldname, None)
            if not oldname:
                continue
            if (
                upload_fields
                and fieldname in upload_fields
                and oldname == upload_fields[fieldname]
            ):
                continue
            if field.custom_delete:
                field.custom_delete(oldname)
            else:
                uploadfolder = field.uploadfolder
                if not uploadfolder:
                    uploadfolder = pjoin(dbset.db._adapter.folder, "..", "uploads")
                if field.uploadseparate:
                    items = oldname.split(".")

# Path: pydal/_compat.py
# PY2 = sys.version_info[0] == 2
#     def implements_bool(cls):
#     def implements_iterator(cls):
#     def to_bytes(obj, charset="utf-8", errors="strict"):
#     def to_native(obj, charset="utf8", errors="strict"):
#     def to_bytes(obj, charset="utf-8", errors="strict"):
#     def to_native(obj, charset="utf8", errors="strict"):
# def with_metaclass(meta, *bases):
#         def __new__(cls, name, this_bases, d):
# def to_unicode(obj, charset="utf-8", errors="strict"):
#     class metaclass(meta):
# 
# Path: pydal/helpers/regex.py
# REGEX_CREDENTIALS = r"(?<=//)[\w.-]+([:/][^@]*)?(?=@)"
# 
# REGEX_UNPACK = r"(?<!\|)\|(?!\|)"
# 
# REGEX_CONST_STRING = '("[^"]*")|' "('[^']*')"
# 
# REGEX_W = re.compile(r"^\w+$")
# 
# Path: pydal/helpers/classes.py
# class SQLCustomType(object):
#     """
#     Allows defining of custom SQL types
# 
#     Args:
#         type: the web2py type (default = 'string')
#         native: the backend type
#         encoder: how to encode the value to store it in the backend
#         decoder: how to decode the value retrieved from the backend
#         validator: what validators to use ( default = None, will use the
#             default validator for type)
# 
#     Example::
#         Define as:
# 
#             decimal = SQLCustomType(
#                 type ='double',
#                 native ='integer',
#                 encoder =(lambda x: int(float(x) * 100)),
#                 decoder = (lambda x: Decimal("0.00") + Decimal(str(float(x)/100)) )
#                 )
# 
#             db.define_table(
#                 'example',
#                 Field('value', type=decimal)
#                 )
# 
#     """
# 
#     def __init__(
#         self,
#         type="string",
#         native=None,
#         encoder=None,
#         decoder=None,
#         validator=None,
#         _class=None,
#         widget=None,
#         represent=None,
#     ):
#         self.type = type
#         self.native = native
#         self.encoder = encoder or (lambda x: x)
#         self.decoder = decoder or (lambda x: x)
#         self.validator = validator
#         self._class = _class or type
#         self.widget = widget
#         self.represent = represent
# 
#     def startswith(self, text=None):
#         try:
#             return self.type.startswith(self, text)
#         except TypeError:
#             return False
# 
#     def endswith(self, text=None):
#         try:
#             return self.type.endswith(self, text)
#         except TypeError:
#             return False
# 
#     def __getslice__(self, a=0, b=100):
#         return None
# 
#     def __getitem__(self, i):
#         return None
# 
#     def __str__(self):
#         return self._class


# Path: pydal/helpers/methods.py
import os
import re
import uuid
from .._compat import (
    PY2,
    BytesIO,
    iteritems,
    integer_types,
    string_types,
    to_bytes,
    pjoin,
    exists,
    text_type,
)
from .regex import REGEX_CREDENTIALS, REGEX_UNPACK, REGEX_CONST_STRING, REGEX_W
from .classes import SQLCustomType
    from ..objects import Field, Table

        fields = table.fields
    fields = [
        f
        for f in fields
        if table[f].type == "upload"
        and table[f].uploadfield == True
        and table[f].autodelete
    ]
    if not fields:
        return False
    for record in dbset.select(*[table[f] for f in fields]):
        for fieldname in fields:
            field = table[fieldname]
            oldname = record.get(fieldname, None)
            if not oldname:
                continue
            if (
                upload_fields
                and fieldname in upload_fields
                and oldname == upload_fields[fieldname]
            ):
                continue
            if field.custom_delete:
                field.custom_delete(oldname)
            else:
                uploadfolder = field.uploadfolder
                if not uploadfolder:
                    uploadfolder = pjoin(dbset.db._adapter.folder, "..", "uploads")
                if field.uploadseparate:
                    items = oldname.split(".")

                    uploadfolder = pjoin(