Created
December 30, 2018 05:14
-
-
Save shininglion/2f04c752b55a0aa40203f09db2d5655d to your computer and use it in GitHub Desktop.
Create a user-defined type family that allow composition
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from enum import Enum | |
class DatabaseType(Enum): | |
INTEGER = 'INTEGER' | |
REAL = 'REAL' | |
TEXT = 'TEXT' | |
LIST = 'LIST' | |
MAP = 'MAP' | |
class TypeInterface: | |
def __init__(self): | |
raise TypeError("Try to create an object with forbid type") | |
def __str__(self): | |
raise NotImplementedError("Method '__str__' has no implementation") | |
def __repr__(self): | |
raise NotImplementedError("Method '__repr__' has no implementation") | |
def type(self): | |
raise NotImplementedError("Method 'type' has no implementation") | |
def to_str(self, type2str = None): | |
raise NotImplementedError("Method 'to_str' has no implementation") | |
class IntegerType(TypeInterface): | |
def __init__(self): | |
self.__type = DatabaseType.INTEGER | |
def __str__(self): | |
return self.__type.value | |
def __repr__(self): | |
return self.__type.name | |
def type(self): | |
return self.__type | |
def to_str(self, type2str = None): | |
if type2str is None: | |
return self.__str__() | |
else: | |
return type2str[self.__type] | |
class RealType(TypeInterface): | |
def __init__(self): | |
self.__type = DatabaseType.REAL | |
def __str__(self): | |
return self.__type.value | |
def __repr__(self): | |
return self.__type.name | |
def type(self): | |
return self.__type | |
def to_str(self, type2str = None): | |
if type2str is None: | |
return self.__str__() | |
else: | |
return type2str[self.__type] | |
class TextType(TypeInterface): | |
def __init__(self): | |
self.__type = DatabaseType.TEXT | |
def __str__(self): | |
return self.__type.value | |
def __repr__(self): | |
return self.__type.name | |
def type(self): | |
return self.__type | |
def to_str(self, type2str = None): | |
if type2str is None: | |
return self.__str__() | |
else: | |
return type2str[self.__type] | |
class ListType(TypeInterface): | |
def __init__(self, elem_type : DatabaseType): | |
# exclude collection types | |
if (elem_type == DatabaseType.LIST) or (elem_type == DatabaseType.MAP): | |
raise TypeError("Element type of type '{}' cannot be collection types".format(DatabaseType.LIST.name)) | |
# initialize | |
self.__type = DatabaseType.LIST | |
self.__elem_type = elem_type | |
def __str__(self): | |
return "{}<{}>".format(self.__type.value, self.__elem_type.value) | |
def __repr__(self): | |
return self.__type.name | |
def type(self): | |
return self.__type | |
def to_str(self, type2str = None): | |
if type2str is None: | |
return self.__str__() | |
else: | |
return "{}<{}>".format(self.__type.value, type2str[self.__elem_type]) | |
class MapType(TypeInterface): | |
def __init__(self, key_type : DatabaseType, val_type : DatabaseType): | |
# exclude collection types | |
if (key_type == DatabaseType.LIST) or (key_type == DatabaseType.MAP): | |
raise TypeError("Key type of type '{}' cannot be collection types".format(DatabaseType.MAP.name)) | |
if (val_type == DatabaseType.LIST) or (val_type == DatabaseType.MAP): | |
raise TypeError("Value type of type '{}' cannot be collection types".format(DatabaseType.MAP.name)) | |
# initialize | |
self.__type = DatabaseType.MAP | |
self.__key_type = key_type | |
self.__val_type = val_type | |
def __str__(self): | |
return "{}<{},{}>".format(self.__type.value, self.__key_type.value, self.__val_type.value) | |
def __repr__(self): | |
return self.__type.name | |
def type(self): | |
return self.__type | |
def to_str(self, type2str = None): | |
if type2str is None: | |
return self.__str__() | |
else: | |
return "{}<{},{}>".format(self.__type.value, type2str[self.__key_type], type2str[self.__val_type]) | |
# test: correct | |
type2str = { DatabaseType.INTEGER: 'bigint', DatabaseType.REAL: 'double', DatabaseType.TEXT: 'string' } | |
int_type = IntegerType() | |
real_type = RealType() | |
text_type = TextType() | |
print("integer: {}\t{}".format(int_type.to_str(), int_type.to_str(type2str))) | |
print("real: {}\t{}".format(real_type.to_str(), real_type.to_str(type2str))) | |
print("text: {}\t{}".format(text_type.to_str(), text_type.to_str(type2str))) | |
print("direct use: {}\t{}".format(IntegerType().to_str(), RealType().to_str(type2str))) | |
list_t1 = ListType(DatabaseType.INTEGER) | |
list_t2 = ListType(DatabaseType.REAL) | |
list_t3 = ListType(DatabaseType.TEXT) | |
print("list: {}\t{}".format(list_t1.to_str(), list_t1.to_str(type2str))) | |
print("list: {}\t{}".format(list_t2.to_str(), list_t2.to_str(type2str))) | |
print("list: {}\t{}".format(list_t3.to_str(), list_t3.to_str(type2str))) | |
map_t1 = MapType(DatabaseType.INTEGER, DatabaseType.INTEGER) | |
map_t2 = MapType(DatabaseType.REAL, DatabaseType.REAL) | |
map_t3 = MapType(DatabaseType.TEXT, DatabaseType.TEXT) | |
map_t4 = MapType(DatabaseType.INTEGER, DatabaseType.REAL) | |
map_t5 = MapType(DatabaseType.INTEGER, DatabaseType.TEXT) | |
map_t6 = MapType(DatabaseType.REAL, DatabaseType.TEXT) | |
print("map: {}\t{}".format(map_t1.to_str(), map_t1.to_str(type2str))) | |
print("map: {}\t{}".format(map_t2.to_str(), map_t2.to_str(type2str))) | |
print("map: {}\t{}".format(map_t3.to_str(), map_t3.to_str(type2str))) | |
print("map: {}\t{}".format(map_t4.to_str(), map_t4.to_str(type2str))) | |
print("map: {}\t{}".format(map_t5.to_str(), map_t5.to_str(type2str))) | |
print("map: {}\t{}".format(map_t6.to_str(), map_t6.to_str(type2str))) | |
# test: exception | |
#new_type = TypeInterface() | |
#new_type = ListType(DatabaseType.LIST) | |
#new_type = ListType(DatabaseType.MAP) | |
#new_type = MapType(DatabaseType.LIST, DatabaseType.LIST) | |
#new_type = MapType(DatabaseType.MAP, DatabaseType.MAP) | |
#new_type = MapType(DatabaseType.LIST, DatabaseType.INTEGER) | |
#new_type = MapType(DatabaseType.REAL, DatabaseType.MAP) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment