summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
l---------[-rwxr-xr-x]contrib/ast-db-manage/cdr/env.py75
l---------[-rwxr-xr-x]contrib/ast-db-manage/config/env.py75
-rwxr-xr-xcontrib/ast-db-manage/env.py140
l---------[-rwxr-xr-x]contrib/ast-db-manage/voicemail/env.py75
-rw-r--r--include/asterisk/vector.h48
-rw-r--r--res/res_pjsip_config_wizard.c4
6 files changed, 193 insertions, 224 deletions
diff --git a/contrib/ast-db-manage/cdr/env.py b/contrib/ast-db-manage/cdr/env.py
index 6740d5906..74b15c930 100755..120000
--- a/contrib/ast-db-manage/cdr/env.py
+++ b/contrib/ast-db-manage/cdr/env.py
@@ -1,74 +1 @@
-from __future__ import with_statement
-from alembic import context
-from sqlalchemy import engine_from_config, pool
-from logging.config import fileConfig
-
-# this is the Alembic Config object, which provides
-# access to the values within the .ini file in use.
-config = context.config
-
-# Interpret the config file for Python logging.
-# This line sets up loggers basically.
-try:
- fileConfig(config.config_file_name)
-except:
- pass
-
-# add your model's MetaData object here
-# for 'autogenerate' support
-# from myapp import mymodel
-# target_metadata = mymodel.Base.metadata
-target_metadata = None
-
-# other values from the config, defined by the needs of env.py,
-# can be acquired:
-# my_important_option = config.get_main_option("my_important_option")
-# ... etc.
-
-def run_migrations_offline():
- """Run migrations in 'offline' mode.
-
- This configures the context with just a URL
- and not an Engine, though an Engine is acceptable
- here as well. By skipping the Engine creation
- we don't even need a DBAPI to be available.
-
- Calls to context.execute() here emit the given string to the
- script output.
-
- """
- url = config.get_main_option("sqlalchemy.url")
- context.configure(url=url)
-
- with context.begin_transaction():
- context.run_migrations()
-
-def run_migrations_online():
- """Run migrations in 'online' mode.
-
- In this scenario we need to create an Engine
- and associate a connection with the context.
-
- """
- engine = engine_from_config(
- config.get_section(config.config_ini_section),
- prefix='sqlalchemy.',
- poolclass=pool.NullPool)
-
- connection = engine.connect()
- context.configure(
- connection=connection,
- target_metadata=target_metadata
- )
-
- try:
- with context.begin_transaction():
- context.run_migrations()
- finally:
- connection.close()
-
-if context.is_offline_mode():
- run_migrations_offline()
-else:
- run_migrations_online()
-
+../env.py \ No newline at end of file
diff --git a/contrib/ast-db-manage/config/env.py b/contrib/ast-db-manage/config/env.py
index 6740d5906..74b15c930 100755..120000
--- a/contrib/ast-db-manage/config/env.py
+++ b/contrib/ast-db-manage/config/env.py
@@ -1,74 +1 @@
-from __future__ import with_statement
-from alembic import context
-from sqlalchemy import engine_from_config, pool
-from logging.config import fileConfig
-
-# this is the Alembic Config object, which provides
-# access to the values within the .ini file in use.
-config = context.config
-
-# Interpret the config file for Python logging.
-# This line sets up loggers basically.
-try:
- fileConfig(config.config_file_name)
-except:
- pass
-
-# add your model's MetaData object here
-# for 'autogenerate' support
-# from myapp import mymodel
-# target_metadata = mymodel.Base.metadata
-target_metadata = None
-
-# other values from the config, defined by the needs of env.py,
-# can be acquired:
-# my_important_option = config.get_main_option("my_important_option")
-# ... etc.
-
-def run_migrations_offline():
- """Run migrations in 'offline' mode.
-
- This configures the context with just a URL
- and not an Engine, though an Engine is acceptable
- here as well. By skipping the Engine creation
- we don't even need a DBAPI to be available.
-
- Calls to context.execute() here emit the given string to the
- script output.
-
- """
- url = config.get_main_option("sqlalchemy.url")
- context.configure(url=url)
-
- with context.begin_transaction():
- context.run_migrations()
-
-def run_migrations_online():
- """Run migrations in 'online' mode.
-
- In this scenario we need to create an Engine
- and associate a connection with the context.
-
- """
- engine = engine_from_config(
- config.get_section(config.config_ini_section),
- prefix='sqlalchemy.',
- poolclass=pool.NullPool)
-
- connection = engine.connect()
- context.configure(
- connection=connection,
- target_metadata=target_metadata
- )
-
- try:
- with context.begin_transaction():
- context.run_migrations()
- finally:
- connection.close()
-
-if context.is_offline_mode():
- run_migrations_offline()
-else:
- run_migrations_online()
-
+../env.py \ No newline at end of file
diff --git a/contrib/ast-db-manage/env.py b/contrib/ast-db-manage/env.py
new file mode 100755
index 000000000..a903451b4
--- /dev/null
+++ b/contrib/ast-db-manage/env.py
@@ -0,0 +1,140 @@
+from __future__ import with_statement
+from alembic import context
+from alembic.script import ScriptDirectory
+from alembic.operations import Operations
+from sqlalchemy import engine_from_config, pool
+from logging.config import fileConfig
+import logging
+
+# this is the Alembic Config object, which provides
+# access to the values within the .ini file in use.
+config = context.config
+
+# Interpret the config file for Python logging.
+# This line sets up loggers basically.
+try:
+ fileConfig(config.config_file_name)
+except:
+ pass
+
+logger = logging.getLogger('alembic.runtime.setup')
+# add your model's MetaData object here
+# for 'autogenerate' support
+# from myapp import mymodel
+# target_metadata = mymodel.Base.metadata
+target_metadata = None
+
+# other values from the config, defined by the needs of env.py,
+# can be acquired:
+# my_important_option = config.get_main_option("my_important_option")
+# ... etc.
+
+def run_migrations_offline():
+ """Run migrations in 'offline' mode.
+
+ This configures the context with just a URL
+ and not an Engine, though an Engine is acceptable
+ here as well. By skipping the Engine creation
+ we don't even need a DBAPI to be available.
+
+ Calls to context.execute() here emit the given string to the
+ script output.
+
+ """
+ url = config.get_main_option("sqlalchemy.url")
+ context.configure(url=url)
+
+ with context.begin_transaction():
+ context.run_migrations()
+
+def run_migrations_online():
+ """Run migrations in 'online' mode.
+
+ In this scenario we need to create an Engine
+ and associate a connection with the context.
+
+ """
+ engine = engine_from_config(
+ config.get_section(config.config_ini_section),
+ prefix='sqlalchemy.',
+ poolclass=pool.NullPool)
+
+ logger.info('Testing for an old alembic_version table.')
+
+ connection = engine.connect()
+ context.configure(
+ connection=connection,
+ target_metadata=target_metadata,
+ version_table='alembic_version'
+ )
+
+ script_location = config.get_main_option('script_location')
+ found = False
+ mc = context.get_context()
+ current_db_revision = mc.get_current_revision()
+ script = ScriptDirectory.from_config(config)
+ """ If there was an existing alembic_version table, we need to
+ check that it's current revision is in the history for the tree
+ we're working with.
+ """
+ for x in script.iterate_revisions('head', 'base'):
+ if x.revision == current_db_revision:
+ """ An alembic_versions table was found and it belongs to
+ this alembic tree
+ """
+ logger.info(
+ ('An old alembic_version table at revision %s was '
+ 'found for %s. Renaming to alembic_version_%s.'),
+ current_db_revision, script_location,
+ script_location)
+ op = Operations(mc)
+ try:
+ with context.begin_transaction():
+ op.rename_table(
+ 'alembic_version', 'alembic_version_%s'
+ % script_location)
+ found = True
+ except:
+ logger.error(('Unable to rename alembic_version to '
+ 'alembic_version_%s.'),
+ script_location)
+ connection.close()
+ return
+
+ break
+
+ if not found:
+ logger.info('Didn\'t find an old alembic_version table.')
+ logger.info('Trying alembic_version_%s.' % script_location)
+
+ """ We MAY have an alembic_version table that doesn't belong to
+ this tree but if we still don't have an alembic_version_<tree>
+ table, alembic will create it.
+ """
+ context.configure(
+ connection=connection,
+ target_metadata=target_metadata,
+ version_table='alembic_version_' + script_location
+ )
+ mc = context.get_context()
+ current_db_revision = mc.get_current_revision()
+ if current_db_revision:
+ logger.info(
+ 'Using the alembic_version_%s table at revision %s.',
+ script_location, current_db_revision)
+ else:
+ logger.info('Creating new alembic_version_%s table.',
+ script_location)
+
+ try:
+ with context.begin_transaction():
+ context.run_migrations()
+ finally:
+ connection.close()
+
+
+if context.is_offline_mode():
+ run_migrations_offline()
+else:
+ run_migrations_online()
+
diff --git a/contrib/ast-db-manage/voicemail/env.py b/contrib/ast-db-manage/voicemail/env.py
index 6740d5906..74b15c930 100755..120000
--- a/contrib/ast-db-manage/voicemail/env.py
+++ b/contrib/ast-db-manage/voicemail/env.py
@@ -1,74 +1 @@
-from __future__ import with_statement
-from alembic import context
-from sqlalchemy import engine_from_config, pool
-from logging.config import fileConfig
-
-# this is the Alembic Config object, which provides
-# access to the values within the .ini file in use.
-config = context.config
-
-# Interpret the config file for Python logging.
-# This line sets up loggers basically.
-try:
- fileConfig(config.config_file_name)
-except:
- pass
-
-# add your model's MetaData object here
-# for 'autogenerate' support
-# from myapp import mymodel
-# target_metadata = mymodel.Base.metadata
-target_metadata = None
-
-# other values from the config, defined by the needs of env.py,
-# can be acquired:
-# my_important_option = config.get_main_option("my_important_option")
-# ... etc.
-
-def run_migrations_offline():
- """Run migrations in 'offline' mode.
-
- This configures the context with just a URL
- and not an Engine, though an Engine is acceptable
- here as well. By skipping the Engine creation
- we don't even need a DBAPI to be available.
-
- Calls to context.execute() here emit the given string to the
- script output.
-
- """
- url = config.get_main_option("sqlalchemy.url")
- context.configure(url=url)
-
- with context.begin_transaction():
- context.run_migrations()
-
-def run_migrations_online():
- """Run migrations in 'online' mode.
-
- In this scenario we need to create an Engine
- and associate a connection with the context.
-
- """
- engine = engine_from_config(
- config.get_section(config.config_ini_section),
- prefix='sqlalchemy.',
- poolclass=pool.NullPool)
-
- connection = engine.connect()
- context.configure(
- connection=connection,
- target_metadata=target_metadata
- )
-
- try:
- with context.begin_transaction():
- context.run_migrations()
- finally:
- connection.close()
-
-if context.is_offline_mode():
- run_migrations_offline()
-else:
- run_migrations_online()
-
+../env.py \ No newline at end of file
diff --git a/include/asterisk/vector.h b/include/asterisk/vector.h
index 0a13c560b..ef6104d57 100644
--- a/include/asterisk/vector.h
+++ b/include/asterisk/vector.h
@@ -354,6 +354,30 @@
AST_VECTOR_REMOVE(vec, idx, 1)
/*!
+ * \brief Remove all elements from a vector that matches the given comparison
+ *
+ * \param vec Vector to remove from.
+ * \param value Value to pass into comparator.
+ * \param cmp Comparator function/macros (called as \c cmp(elem, value))
+ * \param cleanup How to cleanup a removed element macro/function.
+ *
+ * \return the number of deleted elements.
+ */
+#define AST_VECTOR_REMOVE_ALL_CMP_UNORDERED(vec, value, cmp, cleanup) ({ \
+ int count = 0; \
+ size_t idx; \
+ typeof(value) __value = (value); \
+ for (idx = 0; idx < (vec)->current; ++idx) { \
+ if (cmp((vec)->elems[idx], __value)) { \
+ cleanup((vec)->elems[idx]); \
+ AST_VECTOR_REMOVE_UNORDERED((vec), idx); \
+ ++count; \
+ } \
+ } \
+ count; \
+})
+
+/*!
* \brief Remove an element from a vector that matches the given comparison
*
* \param vec Vector to remove from.
@@ -380,6 +404,30 @@
})
/*!
+ * \brief Remove all elements from a vector that matches the given comparison while maintaining order
+ *
+ * \param vec Vector to remove from.
+ * \param value Value to pass into comparator.
+ * \param cmp Comparator function/macros (called as \c cmp(elem, value))
+ * \param cleanup How to cleanup a removed element macro/function.
+ *
+ * \return the number of deleted elements.
+ */
+#define AST_VECTOR_REMOVE_ALL_CMP_ORDERED(vec, value, cmp, cleanup) ({ \
+ int count = 0; \
+ size_t idx; \
+ typeof(value) __value = (value); \
+ for (idx = 0; idx < (vec)->current; ++idx) { \
+ if (cmp((vec)->elems[idx], __value)) { \
+ cleanup((vec)->elems[idx]); \
+ AST_VECTOR_REMOVE_ORDERED((vec), idx); \
+ ++count; \
+ } \
+ } \
+ oount; \
+})
+
+/*!
* \brief Remove an element from a vector that matches the given comparison while maintaining order
*
* \param vec Vector to remove from.
diff --git a/res/res_pjsip_config_wizard.c b/res/res_pjsip_config_wizard.c
index e263437d7..1967d87ab 100644
--- a/res/res_pjsip_config_wizard.c
+++ b/res/res_pjsip_config_wizard.c
@@ -989,7 +989,7 @@ static int wizard_apply_handler(const struct ast_sorcery *sorcery, struct object
rc = handle_registrations(sorcery, otw, wiz, &remote_hosts_vector);
}
- AST_VECTOR_REMOVE_CMP_UNORDERED(&remote_hosts_vector, NULL, NOT_EQUALS, ast_free);
+ AST_VECTOR_REMOVE_ALL_CMP_UNORDERED(&remote_hosts_vector, NULL, NOT_EQUALS, ast_free);
AST_VECTOR_FREE(&remote_hosts_vector);
ast_debug(4, "%s handler complete. rc: %d\n", otw->object_type, rc);
@@ -1293,7 +1293,7 @@ static int unload_module(void)
{
ast_cli_unregister_multiple(config_wizard_cli, ARRAY_LEN(config_wizard_cli));
ast_sorcery_global_observer_remove(&global_observer);
- AST_VECTOR_REMOVE_CMP_UNORDERED(&object_type_wizards, NULL, NOT_EQUALS, OTW_DELETE_CB);
+ AST_VECTOR_REMOVE_ALL_CMP_UNORDERED(&object_type_wizards, NULL, NOT_EQUALS, OTW_DELETE_CB);
AST_VECTOR_RW_FREE(&object_type_wizards);
return 0;