Ticket #421: mysql.patch

File mysql.patch, 9.6 KB (added by Danilo Tomasoni, 11 years ago)

mysql branch against master. Conflicts fixed.

  • mediagoblin/db/sql/extratypes.py

    From 355d4db5c07135d94883294bdc0623b97eabf1d2 Mon Sep 17 00:00:00 2001
    From: David Thompson <dthompson@member.fsf.org>
    Date: Wed, 11 Apr 2012 12:46:12 -0400
    Subject: [PATCH 1/3] Added experimental MySQL support. Migration from MongoDB
     is untested but starting anew with MySQL works.
    
    ---
     mediagoblin/db/sql/extratypes.py |   34 +++++++++++++++++++++++++++++++---
     mediagoblin/db/sql/models.py     |   25 ++++++++++++++++---------
     mediagoblin/db/sql/models_v0.py  |   12 ++++++------
     3 files changed, 53 insertions(+), 18 deletions(-)
    
    diff --git a/mediagoblin/db/sql/extratypes.py b/mediagoblin/db/sql/extratypes.py
    index 8e078f1..d7249c3 100644
    a b  
    1515# along with this program.  If not, see <http://www.gnu.org/licenses/>.
    1616
    1717
    18 from sqlalchemy.types import TypeDecorator, Unicode, VARCHAR
     18from sqlalchemy.types import TypeDecorator, Unicode, VARCHAR, TEXT
    1919import json
    2020
    2121
    2222class PathTupleWithSlashes(TypeDecorator):
    2323    "Represents a Tuple of strings as a slash separated string."
    2424
    25     impl = Unicode
     25    impl = Unicode().with_variant(TEXT(), 'mysql')
    2626
    2727    def process_bind_param(self, value, dialect):
    2828        if value is not None:
    class PathTupleWithSlashes(TypeDecorator):  
    5050class JSONEncoded(TypeDecorator):
    5151    "Represents an immutable structure as a json-encoded string."
    5252
    53     impl = VARCHAR
     53    impl = VARCHAR().with_variant(TEXT(), 'mysql')
    5454
    5555    def process_bind_param(self, value, dialect):
    5656        if value is not None:
    class JSONEncoded(TypeDecorator):  
    6161        if value is not None:
    6262            value = json.loads(value)
    6363        return value
     64
     65class Unicode(TypeDecorator):
     66    """
     67    Represents a string of unicode characters.
     68
     69    SQLite and PostgreSQL do not require a length to be specified for
     70    VARCHAR types. However, MySQL does require it. Thus, we need a
     71    Unicode class that includes a with_variant decorator to use a TEXT
     72    type for MySQL.
     73    """
     74
     75    impl = VARCHAR().with_variant(TEXT(), 'mysql')
     76
     77class UnicodeKey(TypeDecorator):
     78    """
     79    Represents a string of unicode characters, with a MySQL variant
     80    that limits the length to 255.
     81
     82    Database keys to have a set length. The Unicode class falls
     83    back to TEXT for MySQL, but TEXT cannot be used for keys. So, a
     84    VARCHAR of length 255 is used instead.
     85    """
     86
     87    impl = VARCHAR().with_variant(VARCHAR(length=255), 'mysql')
     88
     89def unicodeOptLen(length=255):
     90    return Unicode().with_variant(VARCHAR(length=length), 'mysql')
     91
  • mediagoblin/db/sql/models.py

    diff --git a/mediagoblin/db/sql/models.py b/mediagoblin/db/sql/models.py
    index e87aadd..d6cd209 100644
    a b import datetime  
    2323import sys
    2424
    2525from sqlalchemy import (
    26     Column, Integer, Unicode, UnicodeText, DateTime, Boolean, ForeignKey,
     26    Column, Integer, UnicodeText, DateTime, Boolean, ForeignKey,
    2727    UniqueConstraint, PrimaryKeyConstraint, SmallInteger)
    2828from sqlalchemy.orm import relationship
    2929from sqlalchemy.orm.collections import attribute_mapped_collection
    from sqlalchemy.sql.expression import desc  
    3131from sqlalchemy.ext.associationproxy import association_proxy
    3232from sqlalchemy.util import memoized_property
    3333
    34 from mediagoblin.db.sql.extratypes import PathTupleWithSlashes, JSONEncoded
     34from sqlalchemy.dialects import mysql
     35
     36from mediagoblin.db.sql.extratypes import PathTupleWithSlashes, JSONEncoded, Unicode, UnicodeKey
    3537from mediagoblin.db.sql.base import Base, DictReadAttrProxy
    3638from mediagoblin.db.mixin import UserMixin, MediaEntryMixin, MediaCommentMixin
    3739from mediagoblin.db.sql.base import Session
    from mediagoblin.db.sql.base import Session  
    4345# this import-based meddling...
    4446from migrate import changeset
    4547
    46 
    4748class SimpleFieldAlias(object):
    4849    """An alias for any field"""
    4950    def __init__(self, fieldname):
    class User(Base, UserMixin):  
    6465    __tablename__ = "core__users"
    6566
    6667    id = Column(Integer, primary_key=True)
    67     username = Column(Unicode, nullable=False, unique=True)
     68    username = Column(UnicodeKey, nullable=False, unique=True)
    6869    email = Column(Unicode, nullable=False)
    6970    created = Column(DateTime, nullable=False, default=datetime.datetime.now)
    7071    pw_hash = Column(Unicode, nullable=False)
    class MediaEntry(Base, MediaEntryMixin):  
    9293    id = Column(Integer, primary_key=True)
    9394    uploader = Column(Integer, ForeignKey(User.id), nullable=False, index=True)
    9495    title = Column(Unicode, nullable=False)
    95     slug = Column(Unicode)
     96    slug = Column(UnicodeKey)
    9697    created = Column(DateTime, nullable=False, default=datetime.datetime.now,
    9798        index=True)
    9899    description = Column(UnicodeText) # ??
    class FileKeynames(Base):  
    214215    """
    215216    __tablename__ = "core__file_keynames"
    216217    id = Column(Integer, primary_key=True)
    217     name = Column(Unicode, unique=True)
     218    name = Column(UnicodeKey, unique=True)
    218219
    219220    def __repr__(self):
    220221        return "<FileKeyname %r: %r>" % (self.id, self.name)
    class MediaFile(Base):  
    234235    """
    235236    __tablename__ = "core__mediafiles"
    236237
     238    # Use SmallInteger for name_id, but add a variant for MySQL to use
     239    # a regular INTEGER or else the table creation will fail. MySQL
     240    # seems to expect that the FOREIGN KEY type matches the type that
     241        # it references.
     242    smallint = SmallInteger().with_variant(mysql.INTEGER(), 'mysql')
     243
    237244    media_entry = Column(
    238245        Integer, ForeignKey(MediaEntry.id),
    239246        nullable=False)
    240     name_id = Column(SmallInteger, ForeignKey(FileKeynames.id), nullable=False)
     247    name_id = Column(smallint, ForeignKey(FileKeynames.id), nullable=False)
    241248    file_path = Column(PathTupleWithSlashes)
    242249
    243250    __table_args__ = (
    class Tag(Base):  
    274281    __tablename__ = "core__tags"
    275282
    276283    id = Column(Integer, primary_key=True)
    277     slug = Column(Unicode, nullable=False, unique=True)
     284    slug = Column(UnicodeKey, nullable=False, unique=True)
    278285
    279286    def __repr__(self):
    280287        return "<Tag %r: %r>" % (self.id, self.slug)
    MODELS = [  
    350357class MigrationData(Base):
    351358    __tablename__ = "core__migrations"
    352359
    353     name = Column(Unicode, primary_key=True)
     360    name = Column(UnicodeKey, primary_key=True)
    354361    version = Column(Integer, nullable=False, default=0)
    355362
    356363######################################################
  • mediagoblin/db/sql/models_v0.py

    diff --git a/mediagoblin/db/sql/models_v0.py b/mediagoblin/db/sql/models_v0.py
    index 5dd6b38..47e5ece 100644
    a b import datetime  
    2323import sys
    2424
    2525from sqlalchemy import (
    26     Column, Integer, Unicode, UnicodeText, DateTime, Boolean, ForeignKey,
     26    Column, Integer, UnicodeText, DateTime, Boolean, ForeignKey,
    2727    UniqueConstraint, PrimaryKeyConstraint, SmallInteger, Float)
    2828from sqlalchemy.ext.declarative import declarative_base
    2929from sqlalchemy.orm import relationship, backref
    from sqlalchemy.orm.collections import attribute_mapped_collection  
    3131from sqlalchemy.ext.associationproxy import association_proxy
    3232from sqlalchemy.util import memoized_property
    3333
    34 from mediagoblin.db.sql.extratypes import PathTupleWithSlashes, JSONEncoded
     34from mediagoblin.db.sql.extratypes import PathTupleWithSlashes, JSONEncoded, Unicode, UnicodeKey
    3535from mediagoblin.db.sql.base import GMGTableBase
    3636from mediagoblin.db.sql.base import Session
    3737
    class User(Base_v0):  
    4747    __tablename__ = "core__users"
    4848
    4949    id = Column(Integer, primary_key=True)
    50     username = Column(Unicode, nullable=False, unique=True)
     50    username = Column(UnicodeKey, nullable=False, unique=True)
    5151    email = Column(Unicode, nullable=False)
    5252    created = Column(DateTime, nullable=False, default=datetime.datetime.now)
    5353    pw_hash = Column(Unicode, nullable=False)
    class FileKeynames(Base_v0):  
    144144    """
    145145    __tablename__ = "core__file_keynames"
    146146    id = Column(Integer, primary_key=True)
    147     name = Column(Unicode, unique=True)
     147    name = Column(UnicodeKey, unique=True)
    148148
    149149    def __repr__(self):
    150150        return "<FileKeyname %r: %r>" % (self.id, self.name)
    class Tag(Base_v0):  
    199199    __tablename__ = "core__tags"
    200200
    201201    id = Column(Integer, primary_key=True)
    202     slug = Column(Unicode, nullable=False, unique=True)
     202    slug = Column(UnicodeKey, nullable=False, unique=True)
    203203
    204204    def __repr__(self):
    205205        return "<Tag %r: %r>" % (self.id, self.slug)
    class VideoData(Base_v0):  
    294294class MigrationData(Base_v0):
    295295    __tablename__ = "core__migrations"
    296296
    297     name = Column(Unicode, primary_key=True)
     297    name = Column(UnicodeKey, primary_key=True)
    298298    version = Column(Integer, nullable=False, default=0)
    299299
    300300######################################################
  • mediagoblin/db/sql/extratypes.py

    -- 
    1.7.10.4
    
    
    From 23ae959996afe0d1d816e05db4e77cb391dadfcb Mon Sep 17 00:00:00 2001
    From: David Thompson <dthompson@member.fsf.org>
    Date: Wed, 11 Apr 2012 12:53:48 -0400
    Subject: [PATCH 2/3] Left some changes out of last commit. Updating
     extratypes.py
    
    ---
     mediagoblin/db/sql/extratypes.py |    5 +++++
     1 file changed, 5 insertions(+)
    
    diff --git a/mediagoblin/db/sql/extratypes.py b/mediagoblin/db/sql/extratypes.py
    index d7249c3..7f563c3 100644
    a b class UnicodeKey(TypeDecorator):  
    8787    impl = VARCHAR().with_variant(VARCHAR(length=255), 'mysql')
    8888
    8989def unicodeOptLen(length=255):
     90    """
     91    Returns a Unicode instance with a MySQL variant of VARCHAR with a
     92    specific length.
     93    """
     94
    9095    return Unicode().with_variant(VARCHAR(length=length), 'mysql')
    9196