# Path: spanner_orm/api.py
# class SpannerRetryableApi(abc.ABC):
# class SpannerReadApi(SpannerRetryableApi):
# class SpannerWriteApi(SpannerRetryableApi):
# class SpannerConnection:
# class SpannerApi(SpannerReadApi, SpannerWriteApi):
#   def _ensure_session(self, api_method, *args, **kwargs):
#   def _connection(self) -> spanner_database.Database:
#   def run_read_only(self, method: Callable[..., CallableReturn], *args: Any,
#                     **kwargs: Any) -> CallableReturn:
#   def _run_read_only(self, method, *args, **kwargs):
#   def _connection(self) -> spanner_database.Database:
#   def run_write(self, method: Callable[..., CallableReturn], *args: Any,
#                 **kwargs: Any) -> CallableReturn:
#   def __init__(
#       self,
#       instance: str,
#       database: str,
#       project: Optional[str] = None,
#       credentials: Optional[auth_credentials.Credentials] = None,
#       pool: Optional[spanner_pool.AbstractSessionPool] = None,
#       create_ddl: Optional[Iterable[str]] = None,
#       *,
#       client_options: Union[api_client_options.ClientOptions, Dict[Any, Any],
#                             None] = None,
#   ):
#   def connect(self):
#   def __init__(self, connection: SpannerConnection):
#   def spanner_connection(self) -> SpannerConnection:
#   def _connection(self):
# def connect(
#     instance: str,
#     database: str,
#     project: Optional[str] = None,
#     credentials: Optional[auth_credentials.Credentials] = None,
#     pool: Optional[spanner_pool.AbstractSessionPool] = None) -> SpannerApi:
# def from_connection(connection: SpannerConnection) -> SpannerApi:
# def hangup() -> None:
# def spanner_api() -> SpannerApi:


from typing import Callable, TypeVar
from spanner_orm import api

def transactional_write(func: Callable[..., T]) -> Callable[..., T]:
  """Injects a write transaction object as first argument to given function.

    For example:

    @transactional_write
    def save_book(book_id, transaction=None):
      ...

    Client would then call this by skipping the 'transaction' argument:
    book_reader.save_book(123)

    To call a decorated function if you already have a transaction:

    @transactional_write
    def save_books(book_ids, transaction=None):
      for book_id in book_ids:
        save_book(book_id, transaction=transaction)

    save_books method would call save_book method using same transaction

  Args:
    func: Callable which will be called with write transaction and original
      arguments. Decorated `func` can also be passed an optional 'transaction'
      kwarg to use a given transaction, instead of creating a new one.

  Returns:
    decorated function
  """

# Path: spanner_orm/api.py
# class SpannerRetryableApi(abc.ABC):
# class SpannerReadApi(SpannerRetryableApi):
# class SpannerWriteApi(SpannerRetryableApi):
# class SpannerConnection:
# class SpannerApi(SpannerReadApi, SpannerWriteApi):
#   def _ensure_session(self, api_method, *args, **kwargs):
#   def _connection(self) -> spanner_database.Database:
#   def run_read_only(self, method: Callable[..., CallableReturn], *args: Any,
#                     **kwargs: Any) -> CallableReturn:
#   def _run_read_only(self, method, *args, **kwargs):
#   def _connection(self) -> spanner_database.Database:
#   def run_write(self, method: Callable[..., CallableReturn], *args: Any,
#                 **kwargs: Any) -> CallableReturn:
#   def __init__(
#       self,
#       instance: str,
#       database: str,
#       project: Optional[str] = None,
#       credentials: Optional[auth_credentials.Credentials] = None,
#       pool: Optional[spanner_pool.AbstractSessionPool] = None,
#       create_ddl: Optional[Iterable[str]] = None,
#       *,
#       client_options: Union[api_client_options.ClientOptions, Dict[Any, Any],
#                             None] = None,
#   ):
#   def connect(self):
#   def __init__(self, connection: SpannerConnection):
#   def spanner_connection(self) -> SpannerConnection:
#   def _connection(self):
# def connect(
#     instance: str,
#     database: str,
#     project: Optional[str] = None,
#     credentials: Optional[auth_credentials.Credentials] = None,
#     pool: Optional[spanner_pool.AbstractSessionPool] = None) -> SpannerApi:
# def from_connection(connection: SpannerConnection) -> SpannerApi:
# def hangup() -> None:
# def spanner_api() -> SpannerApi:


# Path: spanner_orm/decorator.py
from typing import Callable, TypeVar
from spanner_orm import api


def transactional_write(func: Callable[..., T]) -> Callable[..., T]:
  """Injects a write transaction object as first argument to given function.

    For example:

    @transactional_write
    def save_book(book_id, transaction=None):
      ...

    Client would then call this by skipping the 'transaction' argument:
    book_reader.save_book(123)

    To call a decorated function if you already have a transaction:

    @transactional_write
    def save_books(book_ids, transaction=None):
      for book_id in book_ids:
        save_book(book_id, transaction=transaction)

    save_books method would call save_book method using same transaction

  Args:
    func: Callable which will be called with write transaction and original
      arguments. Decorated `func` can also be passed an optional 'transaction'
      kwarg to use a given transaction, instead of creating a new one.

  Returns:
    decorated function
  """

  api_method_lambda = lambda: api.spanner_api().run_write