# Path: django_sharding_library/sql.py

# 
# Path: django_sharding_library/exceptions.py
# class DjangoShardingException(Exception):
#     pass


from django.db import connections, DatabaseError, transaction
from django.conf import settings
from django_sharding_library.sql import postgres_shard_id_function_sql
from django.db.models import signals
from django_sharding_library.exceptions import DjangoShardingException



def create_postgres_global_sequence(sequence_name, db_alias, reset_sequence=False):
    cursor = connections[db_alias].cursor()
    sid = transaction.savepoint(db_alias)
    create_sequence_if_not_exists_sql = """DO
$$
BEGIN
        CREATE SEQUENCE %s;
EXCEPTION WHEN duplicate_table THEN
        -- do nothing, it's already there
END
$$ LANGUAGE plpgsql;"""
    try:
        cursor.execute(create_sequence_if_not_exists_sql % sequence_name)
    except DatabaseError:
        transaction.savepoint_rollback(sid, using=db_alias)
    else:
        transaction.savepoint_commit(sid, using=db_alias)
    if reset_sequence:
        cursor.execute("SELECT setval('%s', 1, false)" % (sequence_name,))
    cursor.close()


def create_postgres_shard_id_function(sequence_name, db_alias, shard_id):
    cursor = connections[db_alias].cursor()

# Path: django_sharding_library/sql.py

# 
# Path: django_sharding_library/exceptions.py
# class DjangoShardingException(Exception):
#     pass


# Path: django_sharding_library/utils.py
from django.db import connections, DatabaseError, transaction
from django.conf import settings
from django_sharding_library.sql import postgres_shard_id_function_sql
from django.db.models import signals
from django_sharding_library.exceptions import DjangoShardingException




def create_postgres_global_sequence(sequence_name, db_alias, reset_sequence=False):
    cursor = connections[db_alias].cursor()
    sid = transaction.savepoint(db_alias)
    create_sequence_if_not_exists_sql = """DO
$$
BEGIN
        CREATE SEQUENCE %s;
EXCEPTION WHEN duplicate_table THEN
        -- do nothing, it's already there
END
$$ LANGUAGE plpgsql;"""
    try:
        cursor.execute(create_sequence_if_not_exists_sql % sequence_name)
    except DatabaseError:
        transaction.savepoint_rollback(sid, using=db_alias)
    else:
        transaction.savepoint_commit(sid, using=db_alias)
    if reset_sequence:
        cursor.execute("SELECT setval('%s', 1, false)" % (sequence_name,))
    cursor.close()


def create_postgres_shard_id_function(sequence_name, db_alias, shard_id):
    cursor = connections[db_alias].cursor()

    cursor.execute(postgres_shard_id_function_sql % {'shard_epoch': settings.SHARD_EPOCH,