 
 import Foundation
 
-/// A type that may be serialized to and from a database.
+/// A type that may be serialized to and deserialized from a database.
+///
+/// This is a more generic method for database storage than `ParameterBindable` and `ColumnConvertible`
+/// because it allows types to customize behavior based on the database data type.
 ///
 /// For example, the implementation for `NSNull` is:
 ///
 /// ```swift
-/// extension NSNull: DatabaseValueConvertible {
-///     public func databaseValue() -> DatabaseValue {
-///         return DatabaseValue.null
+/// extension NSNull: DatabaseSerializable {
+///     public func serialized() -> DatabaseValue {
+///         return .null
 ///     }
 ///
-///     public static func from(databaseValue value: DatabaseValue) throws -> Self {
+///     public static func deserialize(from value: DatabaseValue) throws -> Self {
 ///         switch value {
 ///         case .null:
 ///             return self.init()
 ///         default:
-///             throw DatabaseError.dataFormatError("DatabaseValue \"\(value)\" is not null")
+///             throw DatabaseError.dataFormatError("\(value) is not null")
 ///         }
 ///     }
 /// }
 /// ```
-public protocol DatabaseValueConvertible: ParameterBindable {
-	/// Returns the value of `self` as a serializable value.
+public protocol DatabaseSerializable: ParameterBindable {
+	/// Returns a serialized value of `self`.
 	///
-	/// - returns: A serializable instance representing `self`
-	func databaseValue() -> DatabaseValue
+	/// - returns: A serialized value representing `self`
+	func serialized() -> DatabaseValue
 
-	/// Returns the value of `value` as the type of `Self`.
+	/// Deserializes and returns `value` as `Self`.
 	///
-	/// - parameter value: The serializable value to convert
+	/// - parameter value: A serialized value of `Self`
 	/// - returns: An instance of `Self`
 	///
 	/// - throws: An error if `value` contains an illegal value for `Self`
-	static func from(databaseValue value: DatabaseValue) throws -> Self
+	static func deserialize(from value: DatabaseValue) throws -> Self
 }
 
-extension DatabaseValueConvertible {
+extension DatabaseSerializable {
 	public func bind(to stmt: SQLitePreparedStatement, parameter idx: Int32) throws {
-		try databaseValue().bind(to: stmt, parameter: idx)
+		try serialized().bind(to: stmt, parameter: idx)
+	}
+}
+
+extension DatabaseSerializable where Self: NSCoding {
+	public func serialized() -> DatabaseValue {
+		return .blob(NSKeyedArchiver.archivedData(withRootObject: self))
+	}
+
+	public static func deserialize(from value: DatabaseValue) throws -> Self {
+		switch value {
+		case .blob(let b):
+			guard let result = NSKeyedUnarchiver.unarchiveObject(with: b) as? Self else {
+				throw DatabaseError.dataFormatError("\(value) is not a valid type")
+			}
+			return result
+		default:
+			throw DatabaseError.dataFormatError("\(value) is not a blob")
+		}
 	}
 }
 

		}
	}

	public static func from(databaseValue value: DatabaseValue) throws -> Self {
		switch value {
		case .integer(let i):
			return self.init(value: i)

	}
}

extension NSNull: DatabaseSerializable {
	public func serialized() -> DatabaseValue {
		return .null
	}

	public static func deserialize(from value: DatabaseValue) throws -> Self {
		switch value {
		case .null:
			return self.init()
