# Path: spanner_orm/error.py
# class SpannerError(Exception):
# class ValidationError(Exception):
# 
# Path: spanner_orm/field.py
# class FieldType(abc.ABC):
# class Field(object):
# class Boolean(FieldType):
# class Integer(FieldType):
# class Float(FieldType):
# class String(FieldType):
# class StringArray(FieldType):
# class Timestamp(FieldType):
# class BytesBase64(FieldType):
#   def ddl() -> str:
#   def grpc_type() -> type_pb2.Type:
#   def validate_type(value: Any) -> None:
#   def __init__(self,
#                field_type: Type[FieldType],
#                nullable: bool = False,
#                primary_key: bool = False):
#   def ddl(self) -> str:
#   def field_type(self) -> Type[FieldType]:
#   def grpc_type(self) -> str:
#   def nullable(self) -> bool:
#   def primary_key(self) -> bool:
#   def validate(self, value) -> None:
#   def ddl() -> str:
#   def grpc_type() -> type_pb2.Type:
#   def validate_type(value: Any) -> None:
#   def ddl() -> str:
#   def grpc_type() -> type_pb2.Type:
#   def validate_type(value: Any) -> None:
#   def ddl() -> str:
#   def grpc_type() -> type_pb2.Type:
#   def validate_type(value: Any) -> None:
#   def ddl() -> str:
#   def grpc_type() -> type_pb2.Type:
#   def validate_type(value) -> None:
#   def ddl() -> str:
#   def grpc_type() -> type_pb2.Type:
#   def validate_type(value: Any) -> None:
#   def ddl() -> str:
#   def grpc_type() -> type_pb2.Type:
#   def validate_type(value: Any) -> None:
#   def ddl() -> str:
#   def grpc_type() -> type_pb2.Type:
#   def validate_type(value) -> None:
# ALL_TYPES = [
#     Boolean, Integer, Float, String, StringArray, Timestamp, BytesBase64
# ]
# 
# Path: spanner_orm/foreign_key_relationship.py
# class ForeignKeyRelationshipConstraint:
# class ForeignKeyRelationship(object):
#   def __init__(self, referenced_table_name: str, columns: Mapping[str, str]):
#   def constraint(self) -> ForeignKeyRelationshipConstraint:
#   def ddl(self) -> str:
#   def _parse_constraint(self) -> ForeignKeyRelationshipConstraint:
#   def single(self) -> bool:
# 
# Path: spanner_orm/index.py
# class Index(object):
#   PRIMARY_INDEX = 'PRIMARY_KEY'
#   def __init__(self,
#                columns: List[str],
#                parent: Optional[str] = None,
#                null_filtered: bool = False,
#                unique: bool = False,
#                storing_columns: Optional[List[str]] = None):
#   def primary(self) -> bool:
# 
# Path: spanner_orm/relationship.py
# class RelationshipConstraint:
# class Relationship(object):
#   def __init__(self,
#                destination_handle: Union[Type[Any], str],
#                constraints: Dict[str, str],
#                is_parent: bool = False,
#                single: bool = False):
#   def constraints(self) -> List[RelationshipConstraint]:
#   def destination(self) -> Type[Any]:
#   def single(self) -> bool:
#   def _parse_constraints(self) -> List[RelationshipConstraint]:


import abc
import base64
import dataclasses
import datetime
import decimal
import enum
import string
import immutabledict
from typing import Any, Dict, Iterable, List, Mapping, Optional, Sequence, Tuple, Type, TypeVar, Union
from spanner_orm import error
from spanner_orm import field
from spanner_orm import foreign_key_relationship
from spanner_orm import index
from spanner_orm import relationship
from google.api_core import datetime_helpers
from google.cloud.spanner_v1.proto import type_pb2
class _IndexCondition(Condition):
  """Base class for conditions based on an Index."""

  def __init__(self, index_or_name: Union[index.Index, str]):
    super().__init__()
    if isinstance(index_or_name, index.Index):
      self.name = index_or_name.name
      self.index = index_or_name
    else:
      self.name = index_or_name
      self.index = None

  def bind(self, model_class: Type[Any]) -> None:
    super().bind(model_class)
    self.index = self.model_class.indexes[self.name]

  def _validate(self, model_class: Type[Any]) -> None:
    if self.name not in model_class.indexes:
      raise error.ValidationError('{} is not an index on {}'.format(
          self.name, model_class.table))
    if self.index and self.index != model_class.indexes[self.name]:
      raise error.ValidationError('{} does not belong to {}'.format(
          self.index.name, model_class.table))


class ForceIndexCondition(_IndexCondition):
  """Used to indicate which index should be used in a Spanner query."""

  def __init__(
      self,

# Path: spanner_orm/error.py
# class SpannerError(Exception):
# class ValidationError(Exception):
# 
# Path: spanner_orm/field.py
# class FieldType(abc.ABC):
# class Field(object):
# class Boolean(FieldType):
# class Integer(FieldType):
# class Float(FieldType):
# class String(FieldType):
# class StringArray(FieldType):
# class Timestamp(FieldType):
# class BytesBase64(FieldType):
#   def ddl() -> str:
#   def grpc_type() -> type_pb2.Type:
#   def validate_type(value: Any) -> None:
#   def __init__(self,
#                field_type: Type[FieldType],
#                nullable: bool = False,
#                primary_key: bool = False):
#   def ddl(self) -> str:
#   def field_type(self) -> Type[FieldType]:
#   def grpc_type(self) -> str:
#   def nullable(self) -> bool:
#   def primary_key(self) -> bool:
#   def validate(self, value) -> None:
#   def ddl() -> str:
#   def grpc_type() -> type_pb2.Type:
#   def validate_type(value: Any) -> None:
#   def ddl() -> str:
#   def grpc_type() -> type_pb2.Type:
#   def validate_type(value: Any) -> None:
#   def ddl() -> str:
#   def grpc_type() -> type_pb2.Type:
#   def validate_type(value: Any) -> None:
#   def ddl() -> str:
#   def grpc_type() -> type_pb2.Type:
#   def validate_type(value) -> None:
#   def ddl() -> str:
#   def grpc_type() -> type_pb2.Type:
#   def validate_type(value: Any) -> None:
#   def ddl() -> str:
#   def grpc_type() -> type_pb2.Type:
#   def validate_type(value: Any) -> None:
#   def ddl() -> str:
#   def grpc_type() -> type_pb2.Type:
#   def validate_type(value) -> None:
# ALL_TYPES = [
#     Boolean, Integer, Float, String, StringArray, Timestamp, BytesBase64
# ]
# 
# Path: spanner_orm/foreign_key_relationship.py
# class ForeignKeyRelationshipConstraint:
# class ForeignKeyRelationship(object):
#   def __init__(self, referenced_table_name: str, columns: Mapping[str, str]):
#   def constraint(self) -> ForeignKeyRelationshipConstraint:
#   def ddl(self) -> str:
#   def _parse_constraint(self) -> ForeignKeyRelationshipConstraint:
#   def single(self) -> bool:
# 
# Path: spanner_orm/index.py
# class Index(object):
#   PRIMARY_INDEX = 'PRIMARY_KEY'
#   def __init__(self,
#                columns: List[str],
#                parent: Optional[str] = None,
#                null_filtered: bool = False,
#                unique: bool = False,
#                storing_columns: Optional[List[str]] = None):
#   def primary(self) -> bool:
# 
# Path: spanner_orm/relationship.py
# class RelationshipConstraint:
# class Relationship(object):
#   def __init__(self,
#                destination_handle: Union[Type[Any], str],
#                constraints: Dict[str, str],
#                is_parent: bool = False,
#                single: bool = False):
#   def constraints(self) -> List[RelationshipConstraint]:
#   def destination(self) -> Type[Any]:
#   def single(self) -> bool:
#   def _parse_constraints(self) -> List[RelationshipConstraint]:


# Path: spanner_orm/condition.py
import abc
import base64
import dataclasses
import datetime
import decimal
import enum
import string
import immutabledict
from typing import Any, Dict, Iterable, List, Mapping, Optional, Sequence, Tuple, Type, TypeVar, Union
from spanner_orm import error
from spanner_orm import field
from spanner_orm import foreign_key_relationship
from spanner_orm import index
from spanner_orm import relationship
from google.api_core import datetime_helpers
from google.cloud.spanner_v1.proto import type_pb2

class _IndexCondition(Condition):
  """Base class for conditions based on an Index."""

  def __init__(self, index_or_name: Union[index.Index, str]):
    super().__init__()
    if isinstance(index_or_name, index.Index):
      self.name = index_or_name.name
      self.index = index_or_name
    else:
      self.name = index_or_name
      self.index = None

  def bind(self, model_class: Type[Any]) -> None:
    super().bind(model_class)
    self.index = self.model_class.indexes[self.name]

  def _validate(self, model_class: Type[Any]) -> None:
    if self.name not in model_class.indexes:
      raise error.ValidationError('{} is not an index on {}'.format(
          self.name, model_class.table))
    if self.index and self.index != model_class.indexes[self.name]:
      raise error.ValidationError('{} does not belong to {}'.format(
          self.index.name, model_class.table))


class ForceIndexCondition(_IndexCondition):
  """Used to indicate which index should be used in a Spanner query."""

  def __init__(
      self,

      index_or_name: Union[index.Index, str],