├── .flake8
├── .github
└── workflows
│ ├── publish.yml
│ └── test.yml
├── .gitignore
├── CHANGELOG.rst
├── DEVELOPMENT.rst
├── LICENSE
├── MANIFEST.in
├── README.rst
├── check.sh
├── mbdata
├── __init__.py
├── api
│ ├── __init__.py
│ ├── commonsettings.py
│ ├── data.py
│ ├── errors.py
│ ├── includes.py
│ └── serialize.py
├── config.py
├── data
│ ├── __init__.py
│ ├── artist.py
│ ├── label.py
│ ├── recording.py
│ └── release_group.py
├── models.py
├── sample_data.py
├── search.py
├── sql
│ ├── CalculateRelatedTags.sql
│ ├── CreateCollateIndexes.sql
│ ├── CreateCollations.sql
│ ├── CreateConstraints.sql
│ ├── CreateFKConstraints.sql
│ ├── CreateFunctions.sql
│ ├── CreateIndexes.sql
│ ├── CreateMirrorIndexes.sql
│ ├── CreateMirrorOnlyFunctions.sql
│ ├── CreateMirrorOnlyTriggers.sql
│ ├── CreatePrimaryKeys.sql
│ ├── CreateReplicationTriggers.sql
│ ├── CreateReplicationTriggers2.sql
│ ├── CreateSearchConfiguration.sql
│ ├── CreateSearchIndexes.sql
│ ├── CreateTables.sql
│ ├── CreateTriggers.sql
│ ├── CreateTypes.sql
│ ├── CreateViews.sql
│ ├── DisableLastUpdatedTriggers.sql
│ ├── DropAll.sql
│ ├── DropCollateIndexes.sql
│ ├── DropCollations.sql
│ ├── DropFKConstraints.sql
│ ├── DropFunctions.sql
│ ├── DropIndexes.sql
│ ├── DropMirrorOnlyFunctions.sql
│ ├── DropMirrorOnlyTriggers.sql
│ ├── DropPrimaryKeys.sql
│ ├── DropReplicationTriggers.sql
│ ├── DropReplicationTriggers2.sql
│ ├── DropSearchIndexes.sql
│ ├── DropTables.sql
│ ├── DropTriggers.sql
│ ├── DropTypes.sql
│ ├── DropViews.sql
│ ├── EnableLastUpdatedTriggers.sql
│ ├── Extensions.sql
│ ├── InsertDefaultRows.sql
│ ├── InsertTestData.sql
│ ├── ReplicationSetup.sql
│ ├── SetSequences.sql
│ ├── TruncateTables.sql
│ ├── caa
│ │ ├── CreateEditFKConstraints.sql
│ │ ├── CreateFKConstraints.sql
│ │ ├── CreateFunctions.sql
│ │ ├── CreateIndexes.sql
│ │ ├── CreatePrimaryKeys.sql
│ │ ├── CreateReplicationTriggers.sql
│ │ ├── CreateReplicationTriggers2.sql
│ │ ├── CreateTables.sql
│ │ ├── CreateTriggers.sql
│ │ ├── CreateViews.sql
│ │ ├── DropFKConstraints.sql
│ │ ├── DropFunctions.sql
│ │ ├── DropIndexes.sql
│ │ ├── DropPrimaryKeys.sql
│ │ ├── DropReplicationTriggers.sql
│ │ ├── DropReplicationTriggers2.sql
│ │ ├── DropTables.sql
│ │ ├── DropTriggers.sql
│ │ ├── DropViews.sql
│ │ ├── SetSequences.sql
│ │ └── TruncateTables.sql
│ ├── dbmirror2
│ │ ├── MasterSetup.sql
│ │ ├── README
│ │ ├── RefreshColumnInfo.sql
│ │ └── ReplicationSetup.sql
│ ├── documentation
│ │ ├── CreateFKConstraints.sql
│ │ ├── CreatePrimaryKeys.sql
│ │ ├── CreateReplicationTriggers.sql
│ │ ├── CreateReplicationTriggers2.sql
│ │ ├── CreateTables.sql
│ │ ├── DropFKConstraints.sql
│ │ ├── DropFunctions.sql
│ │ ├── DropIndexes.sql
│ │ ├── DropPrimaryKeys.sql
│ │ ├── DropReplicationTriggers.sql
│ │ ├── DropReplicationTriggers2.sql
│ │ ├── DropSearchIndexes.sql
│ │ ├── DropTables.sql
│ │ ├── DropTriggers.sql
│ │ ├── DropViews.sql
│ │ ├── SetSequences.sql
│ │ └── TruncateTables.sql
│ ├── eaa
│ │ ├── CreateEditFKConstraints.sql
│ │ ├── CreateFKConstraints.sql
│ │ ├── CreateFunctions.sql
│ │ ├── CreateIndexes.sql
│ │ ├── CreatePrimaryKeys.sql
│ │ ├── CreateReplicationTriggers.sql
│ │ ├── CreateReplicationTriggers2.sql
│ │ ├── CreateTables.sql
│ │ ├── CreateTriggers.sql
│ │ ├── CreateViews.sql
│ │ ├── DropFKConstraints.sql
│ │ ├── DropFunctions.sql
│ │ ├── DropIndexes.sql
│ │ ├── DropPrimaryKeys.sql
│ │ ├── DropReplicationTriggers.sql
│ │ ├── DropReplicationTriggers2.sql
│ │ ├── DropTables.sql
│ │ ├── DropTriggers.sql
│ │ ├── DropViews.sql
│ │ ├── SetSequences.sql
│ │ └── TruncateTables.sql
│ ├── json_dump
│ │ ├── CreateIndexes.sql
│ │ ├── CreatePrimaryKeys.sql
│ │ ├── CreateTables.sql
│ │ ├── DropFKConstraints.sql
│ │ ├── DropIndexes.sql
│ │ ├── DropPrimaryKeys.sql
│ │ ├── DropTables.sql
│ │ └── TruncateTables.sql
│ ├── report
│ │ ├── CreateTables.sql
│ │ └── TruncateTables.sql
│ ├── sitemaps
│ │ ├── CreateFKConstraints.sql
│ │ ├── CreateIndexes.sql
│ │ ├── CreateTables.sql
│ │ ├── DropFKConstraints.sql
│ │ ├── DropIndexes.sql
│ │ ├── DropTables.sql
│ │ └── TruncateTables.sql
│ ├── statistics
│ │ ├── CreateIndexes.sql
│ │ ├── CreatePrimaryKeys.sql
│ │ ├── CreateReplicationTriggers.sql
│ │ ├── CreateReplicationTriggers2.sql
│ │ ├── CreateTables.sql
│ │ ├── DropIndexes.sql
│ │ ├── DropPrimaryKeys.sql
│ │ ├── DropReplicationTriggers.sql
│ │ ├── DropReplicationTriggers2.sql
│ │ ├── DropTables.sql
│ │ ├── SetSequences.sql
│ │ └── TruncateTables.sql
│ └── wikidocs
│ │ ├── CreatePrimaryKeys.sql
│ │ ├── CreateReplicationTriggers.sql
│ │ ├── CreateReplicationTriggers2.sql
│ │ ├── CreateTables.sql
│ │ ├── DropPrimaryKeys.sql
│ │ ├── DropReplicationTriggers.sql
│ │ ├── DropReplicationTriggers2.sql
│ │ ├── DropTables.sql
│ │ └── TruncateTables.sql
├── tests
│ ├── __init__.py
│ ├── test_tools_genmodels.py
│ └── test_utils_sql.py
├── tools
│ ├── __init__.py
│ ├── dump_sample_data.py
│ └── genmodels.py
├── types.py
└── utils
│ ├── __init__.py
│ ├── models.py
│ └── sql.py
├── poetry.lock
├── pyproject.toml
├── scripts
├── create_sample_db.py
├── create_solr_home.py
├── dump_sample_data.sh
├── export_solr_triggers.py
├── update_models.sh
├── update_sql.sh
└── upload_to_pypi.sh
└── settings.py.sample
/.flake8:
--------------------------------------------------------------------------------
1 | [flake8]
2 | ignore = F401,E501,W391,F405,E128,W291,E126,E121,F403
3 | per-file-ignores =
4 | mbdata/sample_data.py:E501
5 | mbdata/models.py:E501
6 | mbdata/api/tests/__init__.py:E402
7 | max-line-length = 160
8 |
--------------------------------------------------------------------------------
/.github/workflows/publish.yml:
--------------------------------------------------------------------------------
1 | name: Continuous Delivery
2 |
3 | on:
4 | release:
5 | types: [published]
6 |
7 | jobs:
8 | deploy:
9 | runs-on: ubuntu-latest
10 | environment:
11 | name: pypi
12 | url: https://pypi.org/p/mbdata
13 | permissions:
14 | id-token: write
15 | steps:
16 | - uses: actions/checkout@v4
17 | - uses: actions/setup-python@v5
18 | with:
19 | python-version: '3.12'
20 | - uses: snok/install-poetry@v1
21 | with:
22 | plugins: |
23 | poetry-dynamic-versioning[plugin]
24 | - run: poetry build
25 | - uses: pypa/gh-action-pypi-publish@release/v1
26 |
--------------------------------------------------------------------------------
/.github/workflows/test.yml:
--------------------------------------------------------------------------------
1 | name: Test
2 |
3 | on:
4 | push:
5 | branches: [ main ]
6 | pull_request:
7 |
8 | jobs:
9 | test:
10 | runs-on: ubuntu-latest
11 | strategy:
12 | matrix:
13 | python_version: [ '3.9', '3.10', '3.11', '3.12', '3.13' ]
14 | steps:
15 | - uses: actions/checkout@v4
16 | - name: Install Python
17 | uses: actions/setup-python@v5
18 | with:
19 | python-version: ${{ matrix.python_version }}
20 | - name: Install Poetry
21 | uses: snok/install-poetry@v1
22 | - name: Install application dependencies
23 | run: poetry install
24 | - name: Run tests
25 | run: ./check.sh
26 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *.pyc
2 | *.swp
3 | *.db
4 | /e/
5 | /.tox/
6 | /.mypy_cache/
7 | /dist/
8 | mbdata.egg-info/
9 | settings.py
10 | venv/
11 |
--------------------------------------------------------------------------------
/CHANGELOG.rst:
--------------------------------------------------------------------------------
1 | Version 30.0.0
2 | ==============
3 |
4 | - Schema change 30.
5 | - Allow selecting MBS tag or branch from which to update SQL
6 | - Delete useless /updates SQL folder after update
7 | - Drop support for Python 3.8, add support for 3.13
8 | - Move the repository maintenance under MetaBrainz umbrella
9 |
10 | Version 29.0.0
11 | ==============
12 |
13 | - Schema change 29.
14 |
15 | Version 27.1.0
16 | ==============
17 |
18 | - Added `mbslave init` command.
19 |
20 | Version 27.0.0
21 | ==============
22 |
23 | - Schema change 27.
24 |
25 | Version 26.0.1
26 | ==============
27 |
28 | - Added ``Recording.tracks`` relationship to the SQLAlchemy models.
29 |
30 | Version 26.0.0
31 | ==============
32 |
33 | - Support for MusicBrainz database schema 26.
34 |
35 | Version 25.0.4
36 | ==============
37 |
38 | - Fixed reading of MusicBrainz API token from ``mbslave.conf``.
39 |
40 | Version 25.0.3
41 | ==============
42 |
43 | - Fixed a bug in locating ``mbslave.conf``.
44 |
45 | Version 25.0.2
46 | ==============
47 |
48 | - Fixed database connection in ``mbslave``.
49 |
50 | Version 25.0.1
51 | ==============
52 |
53 | - Added ``mbdata.__version__``.
54 | - Fixed ``mbslave psql`` with custom PostgreSQL port number.
55 | - By default, the ``mbslave`` script will read its config file from either
56 | ``$PWD/mbslave.conf`` or ``/etc/mbslave.conf``. Previously, it was only ``$PWD/mbslave.conf``.
57 | - Documentation clarifications.
58 |
59 | Version 25.0.0
60 | ==============
61 |
62 | - Changed versioning with the Musicbrainz database schema as the major version.
63 | - Support for MusicBrainz database schema 25.
64 | - Added MusicBrainz replication (mbslave was merged into this project).
65 | - Docker image with mbslave.
66 | - Python 3 support.
67 |
68 | Version 2017.06.02
69 | ==================
70 |
71 | - Remove old_editor_name mapping.
72 |
73 | Version 2017.06.01
74 | ==================
75 |
76 | - Updated to MusicBrainz database schema 24.
77 |
78 | Version 2017.01.18
79 | ==================
80 |
81 | - Added index definitions to models.
82 | - Support for SQLAlchemy 1.1.
83 |
84 | Version 2016.07.17
85 | ==================
86 |
87 | - Updated to MusicBrainz database schema 23.
88 | - Python 3 support.
89 |
90 | Version 2016.02.11
91 | ==================
92 |
93 | - New function ``mbdata.config.configure()`` that makes sure that the
94 | models have not been imported yet.
95 | - Support for schema re-mapping in ``mbdata.config``.
96 | - Enum types are now correctly assigned to the schema. Previously they
97 | were schema-less.
98 | - New module ``mbdata.sample_data`` with a tiny sample of the
99 | MusicBrainz database useful for testing.
100 |
101 | Version 2015.06.20
102 | ==================
103 |
104 | - Added ``mbdata.config`` for configuring the SQLAlchemy base/metadata
105 | to be used in the models.
106 |
107 | Version 2015.01.10
108 | ==================
109 |
110 | - Initial release.
111 |
--------------------------------------------------------------------------------
/DEVELOPMENT.rst:
--------------------------------------------------------------------------------
1 | #################
2 | Development Guide
3 | #################
4 |
5 | Development Setup
6 | =================
7 |
8 | Clone the repository and setup virtualenv::
9 |
10 | git clone git@github.com:metabrainz/mbdata.git
11 | cd mbdata/
12 | virtualenv -p python3 venv
13 | source venv/bin/activate
14 | pip install poetry
15 | poetry install
16 | poetry self add 'poetry-dynamic-versioning[plugin]'
17 |
18 | Updating SQL files and models
19 | =============================
20 |
21 | Run these scripts to update SQL files and rebuild SQLAlchemy models from them::
22 |
23 | ./scripts/update_sql.sh $desired_git_branch_or_tag
24 | ./scripts/update_models.sh
25 |
26 | Release a new version
27 | =====================
28 |
29 | 1. Add notes to ``CHANGELOG.rst``
30 |
31 | 2. Create a new Github release.
32 |
33 | 3. The publish workflow will build a new package distribution and upload it to pypi.
34 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2013 Lukas Lalinsky
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy
4 | of this software and associated documentation files (the "Software"), to deal
5 | in the Software without restriction, including without limitation the rights
6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 | copies of the Software, and to permit persons to whom the Software is
8 | furnished to do so, subject to the following conditions:
9 |
10 | The above copyright notice and this permission notice shall be included in
11 | all copies or substantial portions of the Software.
12 |
13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 | THE SOFTWARE.
20 |
21 |
--------------------------------------------------------------------------------
/MANIFEST.in:
--------------------------------------------------------------------------------
1 | recursive-include mbdata/web/static *
2 | recursive-include mbdata/sql *
3 |
--------------------------------------------------------------------------------
/README.rst:
--------------------------------------------------------------------------------
1 | #############################
2 | MusicBrainz SQLAlchemy Models
3 | #############################
4 |
5 | |pypi badge|
6 |
7 | .. |pypi badge| image:: https://badge.fury.io/py/mbdata.svg
8 | :target: https://badge.fury.io/py/mbdata
9 |
10 | If you are developing a Python application that needs access to the
11 | `MusicBrainz `__
12 | `data `__, you can use
13 | the ``mbdata.models`` module to get
14 | `SQLAlchemy `__ models mapped to the
15 | MusicBrainz database tables.
16 |
17 | All tables from the MusicBrainz database are mapped, all foreign keys
18 | have one-way relationships set up and some models, where it's essential
19 | to access their related models, have two-way relationships (collections)
20 | set up.
21 |
22 | In order to work with the relationships efficiently, you should use the
23 | appropriate kind of `eager
24 | loading `__.
25 |
26 | Example usage of the models:
27 |
28 | .. code:: python
29 |
30 | >>> from sqlalchemy import create_engine
31 | >>> from sqlalchemy.orm import sessionmaker
32 | >>> from mbdata.models import Artist
33 | >>> engine = create_engine('postgresql://musicbrainz:musicbrainz@127.0.0.1/musicbrainz', echo=True)
34 | >>> Session = sessionmaker(bind=engine)
35 | >>> session = Session()
36 | >>> artist = session.query(Artist).filter_by(gid='8970d868-0723-483b-a75b-51088913d3d4').first()
37 | >>> print artist.name
38 |
39 | If you use the models in your own application and want to define foreign
40 | keys from your own models to the MusicBrainz schema, you will need to
41 | let ``mbdata`` know which metadata object to add the MusicBrainz tables
42 | to:
43 |
44 | .. code:: python
45 |
46 | from sqlalchemy.ext.declarative import declarative_base
47 | Base = declarative_base()
48 |
49 | # this should be the first place where you import anything from mbdata
50 | import mbdata.config
51 | mbdata.config.configure(base_class=Base)
52 |
53 | # now you can import and use the mbdata models
54 | import mbdata.models
55 |
56 | You can also use ``mbdata.config`` to re-map the MusicBrainz schema
57 | names, if your database doesn't follow the original structure:
58 |
59 | .. code:: python
60 |
61 | import mbdata.config
62 | mbdata.config.configure(schema='my_own_mb_schema')
63 |
64 | If you need sample MusicBrainz data for your tests, you can use
65 | ``mbdata.sample_data``:
66 |
67 | .. code:: python
68 |
69 | from mbdata.sample_data import create_sample_data
70 | create_sample_data(session)
71 |
72 | ***********
73 | Development
74 | ***********
75 |
76 | Normally you should work against a regular PostgreSQL database with
77 | MusicBrainz data, but for testing purposes, you can use a SQLite
78 | database with small data sub-set used in unit tests. You can create the
79 | database using:
80 |
81 | .. code:: sh
82 |
83 | ./bin/create_sample_db.py sample.db
84 |
85 | Then you can change your configuration:
86 |
87 | .. code:: sh
88 |
89 | DATABASE_URI = 'sqlite:///sample.db'
90 |
91 | Running tests:
92 |
93 | .. code:: sh
94 |
95 | pytest -v
96 |
97 | If you want to see the SQL queries from a failed test, you can use the
98 | following:
99 |
100 | .. code:: sh
101 |
102 | MBDATA_DATABASE_ECHO=1 pytest -v
103 |
104 | GitHub Actions workflow that automatically runs the tests after each commit is
105 | `here `__.
106 |
--------------------------------------------------------------------------------
/check.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | set -eux
4 |
5 | # poetry run isort --check mbdata/
6 | # poetry run black --check mbdata/
7 |
8 | poetry run flake8 mbdata
9 | poetry run pytest -v
10 |
--------------------------------------------------------------------------------
/mbdata/__init__.py:
--------------------------------------------------------------------------------
1 | # Copyright (C) 2013 Lukas Lalinsky
2 | # Distributed under the MIT license, see the LICENSE file for details.
3 |
4 | # automatically filled in and updated by poetry-dynamic-versioning plugin
5 | # in distributions
6 | __version__ = "0.0.0"
7 |
--------------------------------------------------------------------------------
/mbdata/api/__init__.py:
--------------------------------------------------------------------------------
1 | # Copyright (C) 2013 Lukas Lalinsky
2 | # Distributed under the MIT license, see the LICENSE file for details.
3 |
4 |
--------------------------------------------------------------------------------
/mbdata/api/commonsettings.py:
--------------------------------------------------------------------------------
1 | # Copyright (C) 2013 Lukas Lalinsky
2 | # Distributed under the MIT license, see the LICENSE file for details.
3 |
4 | DATABASE_URI = ''
5 | DATABASE_ECHO = False
6 |
7 | SOLR_URI = 'http://127.0.0.1:8983/solr/musicbrainz'
8 |
9 | DEBUG = False
10 |
11 |
--------------------------------------------------------------------------------
/mbdata/api/errors.py:
--------------------------------------------------------------------------------
1 | # Copyright (C) 2013 Lukas Lalinsky
2 | # Distributed under the MIT license, see the LICENSE file for details.
3 |
4 | SUCCESS = 0
5 | INVALID_FORMAT_ERROR = 1
6 | MISSING_PARAMETER_ERROR = 2
7 | NOT_FOUND_ERROR = 3
8 | INCLUDE_DEPENDENCY_ERROR = 4
9 | INVALID_PARAMETER_ERROR = 5
10 |
11 | ERROR_STATUS_CODES = {
12 | SUCCESS: 200,
13 | NOT_FOUND_ERROR: 404,
14 | }
15 |
16 | ERROR_DEFAULT_STATUS_CODE = 400
17 |
--------------------------------------------------------------------------------
/mbdata/api/includes.py:
--------------------------------------------------------------------------------
1 | # Copyright (C) 2013 Lukas Lalinsky
2 | # Distributed under the MIT license, see the LICENSE file for details.
3 |
4 | import re
5 | import itertools
6 | from six import string_types
7 | from mbdata.utils.models import ENTITY_TYPES
8 | from typing import Set, Dict, Type
9 |
10 |
11 | def _iter_includes(tokens):
12 | if isinstance(tokens, string_types):
13 | yield tokens
14 | return
15 |
16 | includes = ['']
17 | for token in tokens:
18 | if token == ',':
19 | for include in includes:
20 | yield include
21 | includes = ['']
22 | else:
23 | new_includes = []
24 | for prefix, suffix in itertools.product(includes, _iter_includes(token)):
25 | new_includes.append(prefix + suffix)
26 | includes = new_includes
27 |
28 | if includes != ['']:
29 | for include in includes:
30 | yield include
31 |
32 |
33 | def expand_includes(input):
34 | tokens = re.split(r'([,()])', input)
35 |
36 | groups = [[]]
37 | for token in tokens:
38 | if token == '(':
39 | groups.append([])
40 | elif token == ')':
41 | group = groups.pop()
42 | groups[-1].append(group)
43 | elif token:
44 | groups[-1].append(token)
45 | grouped_tokens = groups.pop()
46 |
47 | return _iter_includes(grouped_tokens)
48 |
49 |
50 | def expand_includes_multi(inputs):
51 | return itertools.chain.from_iterable(map(expand_includes, inputs))
52 |
53 |
54 | class Includes(object):
55 | INCLUDES = set([]) # type: Set[str]
56 | SUB_INCLUDES = {} # type: Dict[str, Type[Includes]]
57 |
58 | def __init__(self, includes=None, itself=True):
59 | self.includes = dict(includes or {})
60 | for name in self.SUB_INCLUDES:
61 | if name in self.includes and not isinstance(self.includes[name], Includes):
62 | self.includes[name] = self.SUB_INCLUDES[name]()
63 | self.itself = itself
64 |
65 | def check(self, name):
66 | try:
67 | return getattr(self, name)
68 | except AttributeError:
69 | return False
70 |
71 | def __bool__(self):
72 | return self.itself
73 |
74 | __nonzero__ = __bool__
75 |
76 | def __getattr__(self, name):
77 | if name not in self.INCLUDES and name not in self.SUB_INCLUDES:
78 | raise AttributeError(name)
79 |
80 | if name not in self.includes and name in self.SUB_INCLUDES:
81 | self.includes[name] = self.SUB_INCLUDES[name](itself=False)
82 |
83 | return self.includes.get(name, False)
84 |
85 | @classmethod
86 | def parse(cls, params, prefix=''):
87 | includes = {}
88 | sub_includes = {}
89 |
90 | for include in expand_includes_multi(params):
91 | if '.' in include:
92 | include, sub_include = include.split('.', 1)
93 | else:
94 | sub_include = None
95 |
96 | if include not in cls.INCLUDES and include not in cls.SUB_INCLUDES:
97 | raise ValueError('unknown include {0}{1}'.format(prefix, include))
98 |
99 | includes[include] = True
100 |
101 | if sub_include is not None:
102 | if include not in cls.SUB_INCLUDES:
103 | raise ValueError("unknown include {0}{1}.{2}".format(prefix, include, sub_include))
104 | sub_includes.setdefault(include, []).append(sub_include)
105 |
106 | for include, sub_params in sub_includes.items():
107 | includes[include] = cls.SUB_INCLUDES[include].parse(sub_params, '{0}.'.format(include))
108 |
109 | return cls(includes)
110 |
111 |
112 | class RelationshipsIncludes(Includes):
113 | INCLUDES = set(ENTITY_TYPES.keys())
114 |
115 |
116 | class AreaIncludes(Includes):
117 | INCLUDES = set([
118 | 'part_of',
119 | 'iso_3166',
120 | 'type',
121 | ])
122 |
123 |
124 | class ArtistIncludes(Includes):
125 | INCLUDES = set([
126 | 'ipi',
127 | 'isni',
128 | ])
129 |
130 | SUB_INCLUDES = {
131 | 'areas': AreaIncludes,
132 | 'relationships': RelationshipsIncludes,
133 | }
134 |
135 |
136 | class LabelIncludes(Includes):
137 | INCLUDES = set([
138 | 'ipi',
139 | 'isni',
140 | ])
141 |
142 | SUB_INCLUDES = {
143 | 'area': AreaIncludes,
144 | 'relationships': RelationshipsIncludes,
145 | }
146 |
147 |
148 | class RecordingIncludes(Includes):
149 | INCLUDES = set([
150 | 'artist',
151 | 'artists',
152 | 'isrc',
153 | ])
154 |
155 | SUB_INCLUDES = {
156 | 'relationships': RelationshipsIncludes,
157 | }
158 |
159 |
160 | class TrackIncludes(Includes):
161 | INCLUDES = set([
162 | 'artist',
163 | 'artists',
164 | ])
165 |
166 | SUB_INCLUDES = {
167 | 'recording': RecordingIncludes,
168 | }
169 |
170 |
171 | class MediumIncludes(Includes):
172 | INCLUDES = set([]) # type: Set[str]
173 |
174 | SUB_INCLUDES = {
175 | 'tracks': TrackIncludes,
176 | }
177 |
178 |
179 | class ReleaseGroupIncludes(Includes):
180 | INCLUDES = set([
181 | 'artist',
182 | 'artists',
183 | ])
184 |
185 | SUB_INCLUDES = {
186 | 'relationships': RelationshipsIncludes,
187 | }
188 |
189 |
190 | class ReleaseIncludes(Includes):
191 | INCLUDES = set([
192 | 'artist',
193 | 'artists',
194 | ])
195 |
196 | SUB_INCLUDES = {
197 | 'mediums': MediumIncludes,
198 | 'release_group': ReleaseGroupIncludes,
199 | 'relationships': RelationshipsIncludes,
200 | }
201 |
202 |
203 | class WorkIncludes(Includes):
204 | INCLUDES = set([
205 | 'iswc',
206 | ])
207 |
208 | SUB_INCLUDES = {
209 | 'relationships': RelationshipsIncludes,
210 | }
211 |
212 |
213 | class PlaceIncludes(Includes):
214 | INCLUDES = set([]) # type: Set[str]
215 |
216 | SUB_INCLUDES = {
217 | 'area': AreaIncludes,
218 | 'relationships': RelationshipsIncludes,
219 | }
220 |
221 |
222 | class URLIncludes(Includes):
223 | INCLUDES = set([]) # type: Set[str]
224 |
225 | SUB_INCLUDES = {
226 | 'relationships': RelationshipsIncludes,
227 | }
228 |
229 |
230 | # this can't be defined directly in the class because of circular dependency
231 | RelationshipsIncludes.SUB_INCLUDES = {
232 | 'artist': ArtistIncludes,
233 | 'label': LabelIncludes,
234 | 'place': PlaceIncludes,
235 | 'recording': RecordingIncludes,
236 | 'release': ReleaseIncludes,
237 | 'release_group': ReleaseGroupIncludes,
238 | 'url': URLIncludes,
239 | 'work': WorkIncludes,
240 | }
241 |
242 |
--------------------------------------------------------------------------------
/mbdata/config.py:
--------------------------------------------------------------------------------
1 | import sys
2 | from typing import Dict
3 |
4 | # Override this if you want mbdata models to be based on your own base class
5 | Base = None
6 |
7 | # Override this if you want mbdata to create its own base class, but linked to your metadata object
8 | metadata = None
9 |
10 | # Override this if you want customize the schema names that mbdata uses
11 | schemas = {} # type: Dict[str, str]
12 |
13 | use_cube = True
14 |
15 | _is_frozen = False
16 | _unset = object()
17 |
18 |
19 | def configure(base_class=_unset, metadata=_unset, schema=_unset, schemas=_unset, use_cube=_unset):
20 | if _is_frozen:
21 | raise RuntimeError("mbdata.models was already imported, you can't configure it anymore")
22 | if base_class is not _unset:
23 | sys.modules[__name__].Base = base_class
24 | if metadata is not _unset:
25 | sys.modules[__name__].metadata = metadata
26 | if schemas is not _unset:
27 | sys.modules[__name__].schemas = schemas
28 | elif schema is not _unset:
29 | sys.modules[__name__].schemas = {
30 | 'musicbrainz': schema,
31 | 'cover_art_archive': schema,
32 | 'wikidocs': schema,
33 | 'statistics': schema,
34 | 'documentation': schema,
35 | }
36 | if use_cube is not _unset:
37 | sys.modules[__name__].use_cube = use_cube
38 |
39 |
40 | def freeze():
41 | global _is_frozen
42 | _is_frozen = True
43 |
--------------------------------------------------------------------------------
/mbdata/data/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/metabrainz/mbdata/648c34e19327fbc12ccfec6f363f456315da1024/mbdata/data/__init__.py
--------------------------------------------------------------------------------
/mbdata/data/artist.py:
--------------------------------------------------------------------------------
1 | # Copyright (C) 2013 Lukas Lalinsky
2 | # Distributed under the MIT license, see the LICENSE file for details.
3 |
4 | from sqlalchemy.orm import joinedload, subqueryload, defer
5 | from mbdata.models import (
6 | Artist,
7 | )
8 | from mbdata.api.data import (
9 | query_artist,
10 | load_areas,
11 | load_links,
12 | )
13 | from mbdata.api.serialize import (
14 | serialize_artist,
15 | )
16 |
17 |
18 | def get_artists_by_ids(db, ids, include):
19 | if not ids:
20 | return {}
21 |
22 | artists = query_artist(db, include).filter(Artist.id.in_(ids)).all()
23 |
24 | if include.areas:
25 | load_areas(db, artists, include.areas)
26 |
27 | if include.relationships:
28 | load_links(db, artists, include.relationships)
29 |
30 | results = {}
31 | for artist in artists:
32 | results[artist.id] = serialize_artist(artist, include)
33 | return results
34 |
35 |
--------------------------------------------------------------------------------
/mbdata/data/label.py:
--------------------------------------------------------------------------------
1 | # Copyright (C) 2013 Lukas Lalinsky
2 | # Distributed under the MIT license, see the LICENSE file for details.
3 |
4 | from sqlalchemy.orm import joinedload, subqueryload, subqueryload_all, defer
5 | from mbdata.models import (
6 | Label,
7 | )
8 | from mbdata.api.data import (
9 | query_label,
10 | load_areas,
11 | load_links,
12 | )
13 | from mbdata.api.serialize import (
14 | serialize_label,
15 | )
16 |
17 |
18 | def get_labels_by_ids(db, ids, include):
19 | if not ids:
20 | return {}
21 |
22 | labels = query_label(db, include).filter(Label.id.in_(ids)).all()
23 |
24 | if include.relationships:
25 | load_links(db, labels, include.relationships)
26 |
27 | results = {}
28 | for label in labels:
29 | results[label.id] = serialize_label(label, include)
30 | return results
31 |
32 |
--------------------------------------------------------------------------------
/mbdata/data/recording.py:
--------------------------------------------------------------------------------
1 | # Copyright (C) 2013 Lukas Lalinsky
2 | # Distributed under the MIT license, see the LICENSE file for details.
3 |
4 | from sqlalchemy.orm import joinedload, subqueryload, defer
5 | from mbdata.models import (
6 | Recording,
7 | )
8 | from mbdata.api.data import (
9 | query_recording,
10 | load_links,
11 | )
12 | from mbdata.api.serialize import (
13 | serialize_recording,
14 | )
15 |
16 |
17 | def get_recordings_by_ids(db, ids, include):
18 | if not ids:
19 | return {}
20 |
21 | recordings = query_recording(db, include).filter(Recording.id.in_(ids)).all()
22 |
23 | if include.relationships:
24 | load_links(db, recordings, include.relationships)
25 |
26 | results = {}
27 | for recording in recordings:
28 | results[recording.id] = serialize_recording(recording, include)
29 | return results
30 |
31 |
--------------------------------------------------------------------------------
/mbdata/data/release_group.py:
--------------------------------------------------------------------------------
1 | # Copyright (C) 2013 Lukas Lalinsky
2 | # Distributed under the MIT license, see the LICENSE file for details.
3 |
4 | from sqlalchemy.orm import joinedload, subqueryload, defer
5 | from mbdata.models import (
6 | ReleaseGroup,
7 | )
8 | from mbdata.api.data import (
9 | query_release_group,
10 | load_links,
11 | )
12 | from mbdata.api.serialize import (
13 | serialize_release_group,
14 | )
15 |
16 |
17 | def get_release_groups_by_ids(db, ids, include):
18 | if not ids:
19 | return {}
20 |
21 | release_groups = query_release_group(db, include).filter(ReleaseGroup.id.in_(ids)).all()
22 |
23 | if include.relationships:
24 | load_links(db, release_groups, include.relationships)
25 |
26 | results = {}
27 | for release_group in release_groups:
28 | results[release_group.id] = serialize_release_group(release_group, include)
29 | return results
30 |
31 |
--------------------------------------------------------------------------------
/mbdata/sql/CalculateRelatedTags.sql:
--------------------------------------------------------------------------------
1 | \set ON_ERROR_STOP 1
2 |
3 | BEGIN;
4 |
5 | ----------------------------------------
6 | -- Calculate maximum tag count for each entity, this is used
7 | -- later to weight relations between common tags.
8 | ----------------------------------------
9 |
10 | CREATE TEMPORARY TABLE tmp_artist_tag_count
11 | (
12 | id INTEGER NOT NULL,
13 | max_count INTEGER NOT NULL
14 | );
15 |
16 | CREATE TEMPORARY TABLE tmp_release_tag_count
17 | (
18 | id INTEGER NOT NULL,
19 | max_count INTEGER NOT NULL
20 | );
21 |
22 | CREATE TEMPORARY TABLE tmp_label_tag_count
23 | (
24 | id INTEGER NOT NULL,
25 | max_count INTEGER NOT NULL
26 | );
27 |
28 | CREATE TEMPORARY TABLE tmp_recording_tag_count
29 | (
30 | id INTEGER NOT NULL,
31 | max_count INTEGER NOT NULL
32 | );
33 |
34 |
35 | INSERT INTO tmp_artist_tag_count SELECT
36 | a.id, MAX(t.count) AS max_count
37 | FROM
38 | artist a
39 | JOIN artist_tag t ON t.artist = a.id
40 | GROUP BY a.id;
41 |
42 |
43 | INSERT INTO tmp_release_tag_count SELECT
44 | r.id, MAX(t.count) AS max_count
45 | FROM
46 | release r
47 | JOIN release_tag t ON t.release = r.id
48 | GROUP BY r.id;
49 |
50 |
51 | INSERT INTO tmp_label_tag_count SELECT
52 | a.id, MAX(t.count) AS max_count
53 | FROM
54 | label a
55 | JOIN label_tag t ON t.label = a.id
56 | GROUP BY a.id;
57 |
58 |
59 | INSERT INTO tmp_recording_tag_count SELECT
60 | a.id, MAX(t.count) AS max_count
61 | FROM
62 | recording a
63 | JOIN recording_tag t ON t.recording = a.id
64 | GROUP BY a.id;
65 |
66 |
67 | CREATE UNIQUE INDEX tmp_artist_tag_count_id_idx ON tmp_artist_tag_count (id);
68 | CREATE UNIQUE INDEX tmp_release_tag_count_id_idx ON tmp_release_tag_count (id);
69 | CREATE UNIQUE INDEX tmp_label_tag_count_id_idx ON tmp_label_tag_count (id);
70 | CREATE UNIQUE INDEX tmp_recording_tag_count_id_idx ON tmp_recording_tag_count (id);
71 |
72 |
73 | ----------------------------------------
74 | -- Calculate weighted relations between tags from common tags on entities.
75 | ----------------------------------------
76 |
77 |
78 | CREATE TEMPORARY TABLE tmp_artist_tag_relation
79 | (
80 | tag1 INTEGER NOT NULL,
81 | tag2 INTEGER NOT NULL,
82 | weight FLOAT NOT NULL
83 | );
84 |
85 | CREATE TEMPORARY TABLE tmp_release_tag_relation
86 | (
87 | tag1 INTEGER NOT NULL,
88 | tag2 INTEGER NOT NULL,
89 | weight FLOAT NOT NULL
90 | );
91 |
92 | CREATE TEMPORARY TABLE tmp_label_tag_relation
93 | (
94 | tag1 INTEGER NOT NULL,
95 | tag2 INTEGER NOT NULL,
96 | weight FLOAT NOT NULL
97 | );
98 |
99 | CREATE TEMPORARY TABLE tmp_recording_tag_relation
100 | (
101 | tag1 INTEGER NOT NULL,
102 | tag2 INTEGER NOT NULL,
103 | weight FLOAT NOT NULL
104 | );
105 |
106 | CREATE TEMPORARY TABLE tmp_area_tag_relation
107 | (
108 | tag1 INTEGER NOT NULL,
109 | tag2 INTEGER NOT NULL,
110 | weight FLOAT NOT NULL
111 | );
112 |
113 | CREATE TEMPORARY TABLE tmp_instrument_tag_relation
114 | (
115 | tag1 INTEGER NOT NULL,
116 | tag2 INTEGER NOT NULL,
117 | weight FLOAT NOT NULL
118 | );
119 |
120 | CREATE TEMPORARY TABLE tmp_series_tag_relation
121 | (
122 | tag1 INTEGER NOT NULL,
123 | tag2 INTEGER NOT NULL,
124 | weight FLOAT NOT NULL
125 | );
126 |
127 |
128 | INSERT INTO tmp_artist_tag_relation SELECT
129 | t1.tag, t2.tag,
130 | SUM(((t1.count + t2.count) / 2.0) / tc.max_count) AS weight
131 | FROM
132 | artist a
133 | JOIN artist_tag t1 ON t1.artist = a.id
134 | JOIN artist_tag t2 ON t2.artist = a.id
135 | LEFT JOIN tmp_artist_tag_count tc ON a.id = tc.id
136 | WHERE t1.tag < t2.tag
137 | GROUP BY t1.tag, t2.tag
138 | HAVING COUNT(*) >= 3;
139 |
140 |
141 | INSERT INTO tmp_release_tag_relation SELECT
142 | t1.tag, t2.tag,
143 | SUM(((t1.count + t2.count) / 2.0) / tc.max_count) AS weight
144 | FROM
145 | release a
146 | JOIN release_tag t1 ON t1.release = a.id
147 | JOIN release_tag t2 ON t2.release = a.id
148 | LEFT JOIN tmp_release_tag_count tc ON a.id = tc.id
149 | WHERE t1.tag < t2.tag
150 | GROUP BY t1.tag, t2.tag
151 | HAVING COUNT(*) >= 3;
152 |
153 |
154 | INSERT INTO tmp_label_tag_relation SELECT
155 | t1.tag, t2.tag,
156 | SUM(((t1.count + t2.count) / 2.0) / tc.max_count) AS weight
157 | FROM
158 | label a
159 | JOIN label_tag t1 ON t1.label = a.id
160 | JOIN label_tag t2 ON t2.label = a.id
161 | LEFT JOIN tmp_label_tag_count tc ON a.id = tc.id
162 | WHERE t1.tag < t2.tag
163 | GROUP BY t1.tag, t2.tag
164 | HAVING COUNT(*) >= 3;
165 |
166 |
167 | INSERT INTO tmp_recording_tag_relation SELECT
168 | t1.tag, t2.tag,
169 | SUM(((t1.count + t2.count) / 2.0) / tc.max_count) AS weight
170 | FROM
171 | recording a
172 | JOIN recording_tag t1 ON t1.recording = a.id
173 | JOIN recording_tag t2 ON t2.recording = a.id
174 | LEFT JOIN tmp_recording_tag_count tc ON a.id = tc.id
175 | WHERE t1.tag < t2.tag
176 | GROUP BY t1.tag, t2.tag
177 | HAVING COUNT(*) >= 3;
178 |
179 |
180 | INSERT INTO tmp_area_tag_relation SELECT
181 | t1.tag, t2.tag,
182 | SUM(((t1.count + t2.count) / 2.0) / tc.max_count) AS weight
183 | FROM
184 | area a
185 | JOIN area_tag t1 ON t1.area = a.id
186 | JOIN area_tag t2 ON t2.area = a.id
187 | LEFT JOIN tmp_area_tag_count tc ON a.id = tc.id
188 | WHERE t1.tag < t2.tag
189 | GROUP BY t1.tag, t2.tag
190 | HAVING COUNT(*) >= 3;
191 |
192 |
193 | INSERT INTO tmp_instrument_tag_relation SELECT
194 | t1.tag, t2.tag,
195 | SUM(((t1.count + t2.count) / 2.0) / tc.max_count) AS weight
196 | FROM
197 | instrument a
198 | JOIN instrument_tag t1 ON t1.instrument = a.id
199 | JOIN instrument_tag t2 ON t2.instrument = a.id
200 | LEFT JOIN tmp_instrument_tag_count tc ON a.id = tc.id
201 | WHERE t1.tag < t2.tag
202 | GROUP BY t1.tag, t2.tag
203 | HAVING COUNT(*) >= 3;
204 |
205 |
206 | INSERT INTO tmp_series_tag_relation SELECT
207 | t1.tag, t2.tag,
208 | SUM(((t1.count + t2.count) / 2.0) / tc.max_count) AS weight
209 | FROM
210 | series a
211 | JOIN series_tag t1 ON t1.series = a.id
212 | JOIN series_tag t2 ON t2.series = a.id
213 | LEFT JOIN tmp_series_tag_count tc ON a.id = tc.id
214 | WHERE t1.tag < t2.tag
215 | GROUP BY t1.tag, t2.tag
216 | HAVING COUNT(*) >= 3;
217 |
218 |
219 | CREATE INDEX tmp_artist_tag_relation_tag1 ON tmp_artist_tag_relation (tag1);
220 | CREATE INDEX tmp_artist_tag_relation_tag2 ON tmp_artist_tag_relation (tag2);
221 |
222 | CREATE INDEX tmp_release_tag_relation_tag1 ON tmp_release_tag_relation (tag1);
223 | CREATE INDEX tmp_release_tag_relation_tag2 ON tmp_release_tag_relation (tag2);
224 |
225 | CREATE INDEX tmp_label_tag_relation_tag1 ON tmp_label_tag_relation (tag1);
226 | CREATE INDEX tmp_label_tag_relation_tag2 ON tmp_label_tag_relation (tag2);
227 |
228 | CREATE INDEX tmp_recording_tag_relation_tag1 ON tmp_recording_tag_relation (tag1);
229 | CREATE INDEX tmp_recording_tag_relation_tag2 ON tmp_recording_tag_relation (tag2);
230 |
231 | CREATE INDEX tmp_series_tag_relation_tag1 ON tmp_series_tag_relation (tag1);
232 | CREATE INDEX tmp_series_tag_relation_tag2 ON tmp_series_tag_relation (tag2);
233 |
234 | CREATE INDEX tmp_area_tag_relation_tag1 ON tmp_area_tag_relation (tag1);
235 | CREATE INDEX tmp_area_tag_relation_tag2 ON tmp_area_tag_relation (tag2);
236 |
237 | CREATE INDEX tmp_instrument_tag_relation_tag1 ON tmp_instrument_tag_relation (tag1);
238 | CREATE INDEX tmp_instrument_tag_relation_tag2 ON tmp_instrument_tag_relation (tag2);
239 |
240 | ----------------------------------------
241 | -- Join the temporary table and calculate the final weights.
242 | ----------------------------------------
243 |
244 | TRUNCATE tag_relation;
245 |
246 | INSERT INTO tag_relation SELECT
247 | COALESCE(r1.tag1, r2.tag1, r3.tag1, r4.tag1) AS tag1,
248 | COALESCE(r1.tag2, r2.tag2, r3.tag2, r4.tag2) AS tag2,
249 | COALESCE(r1.weight, 0) + COALESCE(r2.weight, 0) + COALESCE(r3.weight, 0) + COALESCE(r4.weight, 0) AS weight
250 | FROM
251 | tmp_artist_tag_relation r1
252 | FULL OUTER JOIN tmp_release_tag_relation r2
253 | ON (r2.tag1 = r1.tag1 AND r2.tag2 = r1.tag2)
254 | FULL OUTER JOIN tmp_label_tag_relation r3
255 | ON (r3.tag1 = COALESCE(r1.tag1, r2.tag1) AND r3.tag2 = COALESCE(r1.tag2, r2.tag2))
256 | FULL OUTER JOIN tmp_recording_tag_relation r4
257 | ON (r4.tag1 = COALESCE(r1.tag1, r2.tag1, r3.tag1) AND r4.tag2 = COALESCE(r1.tag2, r2.tag2, r3.tag2));
258 |
259 | /*
260 |
261 | Usage:
262 |
263 | SELECT
264 | t1.name, t2.name, tr.weight
265 | FROM
266 | tag t1
267 | JOIN tag_relation tr ON t1.id = tr.tag1 OR t1.id = tr.tag2
268 | JOIN tag t2 ON t1.id != t2.id AND (t2.id = tr.tag1 OR t2.id = tr.tag2)
269 | WHERE
270 | t1.name = 'jazz'
271 | ORDER BY tr.weight DESC;
272 |
273 | */
274 |
275 | COMMIT;
276 |
277 | VACUUM ANALYZE tag_relation;
278 |
--------------------------------------------------------------------------------
/mbdata/sql/CreateCollateIndexes.sql:
--------------------------------------------------------------------------------
1 | \set ON_ERROR_STOP 1
2 | BEGIN;
3 | CREATE INDEX release_idx_musicbrainz_collate ON release (name COLLATE musicbrainz.musicbrainz);
4 | CREATE INDEX release_group_idx_musicbrainz_collate ON release_group (name COLLATE musicbrainz.musicbrainz);
5 | CREATE INDEX artist_idx_musicbrainz_collate ON artist (name COLLATE musicbrainz.musicbrainz);
6 | CREATE INDEX artist_credit_idx_musicbrainz_collate ON artist_credit (name COLLATE musicbrainz.musicbrainz);
7 | CREATE INDEX artist_credit_name_idx_musicbrainz_collate ON artist_credit_name (name COLLATE musicbrainz.musicbrainz);
8 | CREATE INDEX label_idx_musicbrainz_collate ON label (name COLLATE musicbrainz.musicbrainz);
9 | CREATE INDEX recording_idx_musicbrainz_collate ON recording (name COLLATE musicbrainz.musicbrainz);
10 | CREATE INDEX work_idx_musicbrainz_collate ON work (name COLLATE musicbrainz.musicbrainz);
11 | COMMIT;
12 |
--------------------------------------------------------------------------------
/mbdata/sql/CreateCollations.sql:
--------------------------------------------------------------------------------
1 | \set ON_ERROR_STOP 1
2 |
3 | SET search_path = musicbrainz, public;
4 |
5 | BEGIN;
6 |
7 | CREATE COLLATION musicbrainz (
8 | provider = icu,
9 | locale = '@colCaseFirst=lower;colNumeric=yes'
10 | );
11 |
12 | COMMIT;
13 |
--------------------------------------------------------------------------------
/mbdata/sql/CreateMirrorIndexes.sql:
--------------------------------------------------------------------------------
1 | \set ON_ERROR_STOP 1
2 | BEGIN;
3 |
4 | CREATE INDEX medium_idx_release_position ON medium (release, position);
5 |
6 | CREATE INDEX track_idx_medium_position ON track (medium, position);
7 |
8 | COMMIT;
9 |
--------------------------------------------------------------------------------
/mbdata/sql/CreateMirrorOnlyFunctions.sql:
--------------------------------------------------------------------------------
1 | \set ON_ERROR_STOP 1
2 |
3 | BEGIN;
4 |
5 | CREATE OR REPLACE FUNCTION a_ins_release_mirror()
6 | RETURNS trigger AS $$
7 | BEGIN
8 | INSERT INTO artist_release_pending_update VALUES (NEW.id);
9 | INSERT INTO artist_release_group_pending_update VALUES (NEW.release_group);
10 | RETURN NULL;
11 | END;
12 | $$ LANGUAGE 'plpgsql';
13 |
14 | CREATE OR REPLACE FUNCTION a_upd_release_mirror()
15 | RETURNS trigger AS $$
16 | BEGIN
17 | IF (
18 | NEW.status IS DISTINCT FROM OLD.status OR
19 | NEW.release_group != OLD.release_group OR
20 | NEW.artist_credit != OLD.artist_credit
21 | ) THEN
22 | INSERT INTO artist_release_group_pending_update
23 | VALUES (NEW.release_group), (OLD.release_group);
24 | END IF;
25 | IF (
26 | NEW.barcode IS DISTINCT FROM OLD.barcode OR
27 | NEW.name != OLD.name OR
28 | NEW.artist_credit != OLD.artist_credit
29 | ) THEN
30 | INSERT INTO artist_release_pending_update VALUES (OLD.id);
31 | END IF;
32 | RETURN NULL;
33 | END;
34 | $$ LANGUAGE 'plpgsql';
35 |
36 | CREATE OR REPLACE FUNCTION a_del_release_mirror()
37 | RETURNS trigger AS $$
38 | BEGIN
39 | INSERT INTO artist_release_pending_update VALUES (OLD.id);
40 | INSERT INTO artist_release_group_pending_update VALUES (OLD.release_group);
41 | RETURN NULL;
42 | END;
43 | $$ LANGUAGE 'plpgsql';
44 |
45 | CREATE OR REPLACE FUNCTION a_ins_release_event_mirror()
46 | RETURNS trigger AS $$
47 | BEGIN
48 | PERFORM set_release_first_release_date(NEW.release);
49 | PERFORM set_releases_recordings_first_release_dates(ARRAY[NEW.release]);
50 | IF TG_TABLE_NAME = 'release_country' THEN
51 | INSERT INTO artist_release_pending_update VALUES (NEW.release);
52 | END IF;
53 | RETURN NULL;
54 | END;
55 | $$ LANGUAGE 'plpgsql';
56 |
57 | CREATE OR REPLACE FUNCTION a_upd_release_event_mirror()
58 | RETURNS trigger AS $$
59 | BEGIN
60 | PERFORM set_release_first_release_date(OLD.release);
61 | PERFORM set_release_first_release_date(NEW.release);
62 | PERFORM set_releases_recordings_first_release_dates(ARRAY[NEW.release, OLD.release]);
63 | IF TG_TABLE_NAME = 'release_country' THEN
64 | IF NEW.country != OLD.country THEN
65 | INSERT INTO artist_release_pending_update VALUES (OLD.release);
66 | END IF;
67 | END IF;
68 | RETURN NULL;
69 | END;
70 | $$ LANGUAGE 'plpgsql';
71 |
72 | CREATE OR REPLACE FUNCTION a_del_release_event_mirror()
73 | RETURNS trigger AS $$
74 | BEGIN
75 | PERFORM set_release_first_release_date(OLD.release);
76 | PERFORM set_releases_recordings_first_release_dates(ARRAY[OLD.release]);
77 | IF TG_TABLE_NAME = 'release_country' THEN
78 | INSERT INTO artist_release_pending_update VALUES (OLD.release);
79 | END IF;
80 | RETURN NULL;
81 | END;
82 | $$ LANGUAGE 'plpgsql';
83 |
84 | CREATE OR REPLACE FUNCTION a_ins_release_group_mirror()
85 | RETURNS trigger AS $$
86 | BEGIN
87 | INSERT INTO artist_release_group_pending_update VALUES (NEW.id);
88 | RETURN NULL;
89 | END;
90 | $$ LANGUAGE 'plpgsql';
91 |
92 | CREATE OR REPLACE FUNCTION a_upd_release_group_mirror()
93 | RETURNS trigger AS $$
94 | BEGIN
95 | IF (
96 | NEW.name != OLD.name OR
97 | NEW.artist_credit != OLD.artist_credit OR
98 | NEW.type IS DISTINCT FROM OLD.type
99 | ) THEN
100 | INSERT INTO artist_release_group_pending_update VALUES (OLD.id);
101 | END IF;
102 | RETURN NULL;
103 | END;
104 | $$ LANGUAGE 'plpgsql';
105 |
106 | CREATE OR REPLACE FUNCTION a_del_release_group_mirror()
107 | RETURNS trigger AS $$
108 | BEGIN
109 | INSERT INTO artist_release_group_pending_update VALUES (OLD.id);
110 | RETURN NULL;
111 | END;
112 | $$ LANGUAGE 'plpgsql';
113 |
114 | CREATE OR REPLACE FUNCTION a_upd_release_group_meta_mirror()
115 | RETURNS trigger AS $$
116 | BEGIN
117 | IF (
118 | (NEW.first_release_date_year IS DISTINCT FROM OLD.first_release_date_year) OR
119 | (NEW.first_release_date_month IS DISTINCT FROM OLD.first_release_date_month) OR
120 | (NEW.first_release_date_day IS DISTINCT FROM OLD.first_release_date_day)
121 | ) THEN
122 | INSERT INTO artist_release_group_pending_update VALUES (OLD.id);
123 | END IF;
124 | RETURN NULL;
125 | END;
126 | $$ LANGUAGE 'plpgsql';
127 |
128 | CREATE OR REPLACE FUNCTION a_ins_release_group_secondary_type_join_mirror()
129 | RETURNS trigger AS $$
130 | BEGIN
131 | INSERT INTO artist_release_group_pending_update VALUES (NEW.release_group);
132 | RETURN NULL;
133 | END;
134 | $$ LANGUAGE 'plpgsql';
135 |
136 | CREATE OR REPLACE FUNCTION a_del_release_group_secondary_type_join_mirror()
137 | RETURNS trigger AS $$
138 | BEGIN
139 | INSERT INTO artist_release_group_pending_update VALUES (OLD.release_group);
140 | RETURN NULL;
141 | END;
142 | $$ LANGUAGE 'plpgsql';
143 |
144 | CREATE OR REPLACE FUNCTION a_ins_release_label_mirror()
145 | RETURNS trigger AS $$
146 | BEGIN
147 | INSERT INTO artist_release_pending_update VALUES (NEW.release);
148 | RETURN NULL;
149 | END;
150 | $$ LANGUAGE 'plpgsql';
151 |
152 | CREATE OR REPLACE FUNCTION a_upd_release_label_mirror()
153 | RETURNS trigger AS $$
154 | BEGIN
155 | IF NEW.catalog_number IS DISTINCT FROM OLD.catalog_number THEN
156 | INSERT INTO artist_release_pending_update VALUES (OLD.release);
157 | END IF;
158 | RETURN NULL;
159 | END;
160 | $$ LANGUAGE 'plpgsql';
161 |
162 | CREATE OR REPLACE FUNCTION a_del_release_label_mirror()
163 | RETURNS trigger AS $$
164 | BEGIN
165 | INSERT INTO artist_release_pending_update VALUES (OLD.release);
166 | RETURN NULL;
167 | END;
168 | $$ LANGUAGE 'plpgsql';
169 |
170 | CREATE OR REPLACE FUNCTION a_ins_track_mirror()
171 | RETURNS trigger AS $$
172 | BEGIN
173 | PERFORM set_recordings_first_release_dates(ARRAY[NEW.recording]);
174 | INSERT INTO artist_release_pending_update (
175 | SELECT release FROM medium
176 | WHERE id = NEW.medium
177 | );
178 | INSERT INTO artist_release_group_pending_update (
179 | SELECT release_group FROM release
180 | JOIN medium ON medium.release = release.id
181 | WHERE medium.id = NEW.medium
182 | );
183 | RETURN NULL;
184 | END;
185 | $$ LANGUAGE 'plpgsql';
186 |
187 | CREATE OR REPLACE FUNCTION a_upd_track_mirror()
188 | RETURNS trigger AS $$
189 | BEGIN
190 | IF NEW.artist_credit != OLD.artist_credit THEN
191 | INSERT INTO artist_release_pending_update (
192 | SELECT release FROM medium
193 | WHERE id = OLD.medium
194 | );
195 | INSERT INTO artist_release_group_pending_update (
196 | SELECT release_group FROM release
197 | JOIN medium ON medium.release = release.id
198 | WHERE medium.id = OLD.medium
199 | );
200 | END IF;
201 | IF OLD.recording <> NEW.recording THEN
202 | PERFORM set_recordings_first_release_dates(ARRAY[OLD.recording, NEW.recording]);
203 | END IF;
204 | RETURN NULL;
205 | END;
206 | $$ LANGUAGE 'plpgsql';
207 |
208 | CREATE OR REPLACE FUNCTION a_del_track_mirror()
209 | RETURNS trigger AS $$
210 | BEGIN
211 | PERFORM set_recordings_first_release_dates(ARRAY[OLD.recording]);
212 | INSERT INTO artist_release_pending_update (
213 | SELECT release FROM medium
214 | WHERE id = OLD.medium
215 | );
216 | INSERT INTO artist_release_group_pending_update (
217 | SELECT release_group FROM release
218 | JOIN medium ON medium.release = release.id
219 | WHERE medium.id = OLD.medium
220 | );
221 | RETURN NULL;
222 | END;
223 | $$ LANGUAGE 'plpgsql';
224 |
225 | COMMIT;
226 |
--------------------------------------------------------------------------------
/mbdata/sql/CreateMirrorOnlyTriggers.sql:
--------------------------------------------------------------------------------
1 | \set ON_ERROR_STOP 1
2 |
3 | -- This file contains triggers that are necessary (and safe) to create
4 | -- on mirror databases. These are NOT created on master/standalone
5 | -- databases.
6 | --
7 | -- The primary use case is to allow materialized tables to be kept
8 | -- up-to-date on mirrors without having to replicate that information.
9 | -- Since the materialized information can be fully derived from primary
10 | -- table data, we avoid packet bloat this way.
11 | --
12 | -- Any functions these call should NEVER modify a replicated table! As
13 | -- a convention, functions that are safe to call here generally end in
14 | -- `_mirror`.
15 |
16 | BEGIN;
17 |
18 | CREATE TRIGGER a_ins_l_area_area_mirror AFTER INSERT ON l_area_area
19 | FOR EACH ROW EXECUTE PROCEDURE a_ins_l_area_area_mirror();
20 |
21 | CREATE TRIGGER a_upd_l_area_area_mirror AFTER UPDATE ON l_area_area
22 | FOR EACH ROW EXECUTE PROCEDURE a_upd_l_area_area_mirror();
23 |
24 | CREATE TRIGGER a_del_l_area_area_mirror AFTER DELETE ON l_area_area
25 | FOR EACH ROW EXECUTE PROCEDURE a_del_l_area_area_mirror();
26 |
27 | CREATE TRIGGER a_upd_medium AFTER UPDATE ON medium
28 | FOR EACH ROW EXECUTE PROCEDURE a_upd_medium_mirror();
29 |
30 | CREATE TRIGGER a_ins_release_mirror AFTER INSERT ON release
31 | FOR EACH ROW EXECUTE PROCEDURE a_ins_release_mirror();
32 |
33 | CREATE TRIGGER a_upd_release_mirror AFTER UPDATE ON release
34 | FOR EACH ROW EXECUTE PROCEDURE a_upd_release_mirror();
35 |
36 | CREATE TRIGGER a_del_release_mirror AFTER DELETE ON release
37 | FOR EACH ROW EXECUTE PROCEDURE a_del_release_mirror();
38 |
39 | CREATE TRIGGER a_ins_release_event_mirror AFTER INSERT ON release_country
40 | FOR EACH ROW EXECUTE PROCEDURE a_ins_release_event_mirror();
41 |
42 | CREATE TRIGGER a_upd_release_event_mirror AFTER UPDATE ON release_country
43 | FOR EACH ROW EXECUTE PROCEDURE a_upd_release_event_mirror();
44 |
45 | CREATE TRIGGER a_del_release_event_mirror AFTER DELETE ON release_country
46 | FOR EACH ROW EXECUTE PROCEDURE a_del_release_event_mirror();
47 |
48 | CREATE TRIGGER a_ins_release_event_mirror AFTER INSERT ON release_unknown_country
49 | FOR EACH ROW EXECUTE PROCEDURE a_ins_release_event_mirror();
50 |
51 | CREATE TRIGGER a_upd_release_event_mirror AFTER UPDATE ON release_unknown_country
52 | FOR EACH ROW EXECUTE PROCEDURE a_upd_release_event_mirror();
53 |
54 | CREATE TRIGGER a_del_release_event_mirror AFTER DELETE ON release_unknown_country
55 | FOR EACH ROW EXECUTE PROCEDURE a_del_release_event_mirror();
56 |
57 | CREATE TRIGGER a_ins_release_group_mirror AFTER INSERT ON release_group
58 | FOR EACH ROW EXECUTE PROCEDURE a_ins_release_group_mirror();
59 |
60 | CREATE TRIGGER a_upd_release_group_mirror AFTER UPDATE ON release_group
61 | FOR EACH ROW EXECUTE PROCEDURE a_upd_release_group_mirror();
62 |
63 | CREATE TRIGGER a_del_release_group_mirror AFTER DELETE ON release_group
64 | FOR EACH ROW EXECUTE PROCEDURE a_del_release_group_mirror();
65 |
66 | CREATE TRIGGER a_upd_release_group_meta_mirror AFTER UPDATE ON release_group_meta
67 | FOR EACH ROW EXECUTE PROCEDURE a_upd_release_group_meta_mirror();
68 |
69 | CREATE TRIGGER a_upd_release_group_primary_type_mirror AFTER UPDATE ON release_group_primary_type
70 | FOR EACH ROW EXECUTE PROCEDURE a_upd_release_group_primary_type_mirror();
71 |
72 | CREATE TRIGGER a_upd_release_group_secondary_type_mirror AFTER UPDATE ON release_group_secondary_type
73 | FOR EACH ROW EXECUTE PROCEDURE a_upd_release_group_secondary_type_mirror();
74 |
75 | CREATE TRIGGER a_ins_release_group_secondary_type_join_mirror AFTER INSERT ON release_group_secondary_type_join
76 | FOR EACH ROW EXECUTE PROCEDURE a_ins_release_group_secondary_type_join_mirror();
77 |
78 | CREATE TRIGGER a_del_release_group_secondary_type_join_mirror AFTER DELETE ON release_group_secondary_type_join
79 | FOR EACH ROW EXECUTE PROCEDURE a_del_release_group_secondary_type_join_mirror();
80 |
81 | CREATE TRIGGER a_ins_release_label_mirror AFTER INSERT ON release_label
82 | FOR EACH ROW EXECUTE PROCEDURE a_ins_release_label_mirror();
83 |
84 | CREATE TRIGGER a_upd_release_label_mirror AFTER UPDATE ON release_label
85 | FOR EACH ROW EXECUTE PROCEDURE a_upd_release_label_mirror();
86 |
87 | CREATE TRIGGER a_del_release_label_mirror AFTER DELETE ON release_label
88 | FOR EACH ROW EXECUTE PROCEDURE a_del_release_label_mirror();
89 |
90 | CREATE TRIGGER a_ins_track_mirror AFTER INSERT ON track
91 | FOR EACH ROW EXECUTE PROCEDURE a_ins_track_mirror();
92 |
93 | CREATE TRIGGER a_upd_track_mirror AFTER UPDATE ON track
94 | FOR EACH ROW EXECUTE PROCEDURE a_upd_track_mirror();
95 |
96 | CREATE TRIGGER a_del_track_mirror AFTER DELETE ON track
97 | FOR EACH ROW EXECUTE PROCEDURE a_del_track_mirror();
98 |
99 | CREATE CONSTRAINT TRIGGER apply_artist_release_group_pending_updates_mirror
100 | AFTER INSERT OR UPDATE OR DELETE ON release DEFERRABLE INITIALLY DEFERRED
101 | FOR EACH ROW EXECUTE PROCEDURE apply_artist_release_group_pending_updates();
102 |
103 | CREATE CONSTRAINT TRIGGER apply_artist_release_pending_updates_mirror
104 | AFTER INSERT OR UPDATE OR DELETE ON release DEFERRABLE INITIALLY DEFERRED
105 | FOR EACH ROW EXECUTE PROCEDURE apply_artist_release_pending_updates();
106 |
107 | CREATE CONSTRAINT TRIGGER apply_artist_release_pending_updates_mirror
108 | AFTER INSERT OR UPDATE OR DELETE ON release_country DEFERRABLE INITIALLY DEFERRED
109 | FOR EACH ROW EXECUTE PROCEDURE apply_artist_release_pending_updates();
110 |
111 | CREATE CONSTRAINT TRIGGER apply_artist_release_pending_updates_mirror
112 | AFTER INSERT OR UPDATE OR DELETE ON release_first_release_date DEFERRABLE INITIALLY DEFERRED
113 | FOR EACH ROW EXECUTE PROCEDURE apply_artist_release_pending_updates();
114 |
115 | CREATE CONSTRAINT TRIGGER apply_artist_release_group_pending_updates_mirror
116 | AFTER INSERT OR UPDATE OR DELETE ON release_group DEFERRABLE INITIALLY DEFERRED
117 | FOR EACH ROW EXECUTE PROCEDURE apply_artist_release_group_pending_updates();
118 |
119 | CREATE CONSTRAINT TRIGGER apply_artist_release_group_pending_updates_mirror
120 | AFTER UPDATE ON release_group_meta DEFERRABLE INITIALLY DEFERRED
121 | FOR EACH ROW EXECUTE PROCEDURE apply_artist_release_group_pending_updates();
122 |
123 | CREATE CONSTRAINT TRIGGER apply_artist_release_group_pending_updates_mirror
124 | AFTER UPDATE ON release_group_primary_type DEFERRABLE INITIALLY DEFERRED
125 | FOR EACH ROW
126 | WHEN (OLD.child_order IS DISTINCT FROM NEW.child_order)
127 | EXECUTE PROCEDURE apply_artist_release_group_pending_updates();
128 |
129 | CREATE CONSTRAINT TRIGGER apply_artist_release_group_pending_updates_mirror
130 | AFTER UPDATE ON release_group_secondary_type DEFERRABLE INITIALLY DEFERRED
131 | FOR EACH ROW
132 | WHEN (OLD.child_order IS DISTINCT FROM NEW.child_order)
133 | EXECUTE PROCEDURE apply_artist_release_group_pending_updates();
134 |
135 | CREATE CONSTRAINT TRIGGER apply_artist_release_group_pending_updates_mirror
136 | AFTER INSERT OR DELETE ON release_group_secondary_type_join DEFERRABLE INITIALLY DEFERRED
137 | FOR EACH ROW EXECUTE PROCEDURE apply_artist_release_group_pending_updates();
138 |
139 | CREATE CONSTRAINT TRIGGER apply_artist_release_pending_updates_mirror
140 | AFTER INSERT OR UPDATE OR DELETE ON release_label DEFERRABLE INITIALLY DEFERRED
141 | FOR EACH ROW EXECUTE PROCEDURE apply_artist_release_pending_updates();
142 |
143 | CREATE CONSTRAINT TRIGGER apply_artist_release_group_pending_updates_mirror
144 | AFTER INSERT OR UPDATE OR DELETE ON track DEFERRABLE INITIALLY DEFERRED
145 | FOR EACH ROW EXECUTE PROCEDURE apply_artist_release_group_pending_updates();
146 |
147 | CREATE CONSTRAINT TRIGGER apply_artist_release_pending_updates_mirror
148 | AFTER INSERT OR UPDATE OR DELETE ON track DEFERRABLE INITIALLY DEFERRED
149 | FOR EACH ROW EXECUTE PROCEDURE apply_artist_release_pending_updates();
150 |
151 | COMMIT;
152 |
--------------------------------------------------------------------------------
/mbdata/sql/CreateSearchConfiguration.sql:
--------------------------------------------------------------------------------
1 | \set ON_ERROR_STOP 1
2 |
3 | SET search_path = musicbrainz, public;
4 |
5 | BEGIN;
6 |
7 | CREATE TEXT SEARCH CONFIGURATION mb_simple (COPY = pg_catalog.simple);
8 | ALTER TEXT SEARCH CONFIGURATION mb_simple
9 | ALTER MAPPING FOR word, numword, hword, numhword, hword_part, hword_numpart
10 | WITH unaccent, simple;
11 |
12 | COMMIT;
13 |
--------------------------------------------------------------------------------
/mbdata/sql/CreateSearchIndexes.sql:
--------------------------------------------------------------------------------
1 | \unset ON_ERROR_STOP
2 |
3 | CREATE INDEX artist_idx_txt ON artist USING gin(musicbrainz.mb_simple_tsvector(name));
4 | CREATE INDEX artist_idx_txt_sort ON artist USING gin(musicbrainz.mb_simple_tsvector(sort_name));
5 |
6 | CREATE INDEX artist_alias_idx_txt ON artist_alias USING gin(musicbrainz.mb_simple_tsvector(name));
7 | CREATE INDEX artist_alias_idx_txt_sort ON artist_alias USING gin(musicbrainz.mb_simple_tsvector(sort_name));
8 |
9 | CREATE INDEX artist_credit_idx_txt ON artist_credit USING gin(musicbrainz.mb_simple_tsvector(name));
10 | CREATE INDEX artist_credit_name_idx_txt ON artist_credit_name USING gin(musicbrainz.mb_simple_tsvector(name));
11 |
12 | CREATE INDEX event_idx_txt ON event USING gin(musicbrainz.mb_simple_tsvector(name));
13 |
14 | CREATE INDEX event_alias_idx_txt ON event_alias USING gin(musicbrainz.mb_simple_tsvector(name));
15 | CREATE INDEX event_alias_idx_txt_sort ON event_alias USING gin(musicbrainz.mb_simple_tsvector(sort_name));
16 |
17 | CREATE INDEX instrument_idx_txt ON instrument USING gin(musicbrainz.mb_simple_tsvector(name));
18 |
19 | CREATE INDEX label_idx_txt ON label USING gin(musicbrainz.mb_simple_tsvector(name));
20 |
21 | CREATE INDEX label_alias_idx_txt ON label_alias USING gin(musicbrainz.mb_simple_tsvector(name));
22 | CREATE INDEX label_alias_idx_txt_sort ON label_alias USING gin(musicbrainz.mb_simple_tsvector(sort_name));
23 |
24 | CREATE INDEX release_idx_txt ON release USING gin(musicbrainz.mb_simple_tsvector(name));
25 |
26 | CREATE INDEX release_alias_idx_txt ON release_alias USING gin(musicbrainz.mb_simple_tsvector(name));
27 | CREATE INDEX release_alias_idx_txt_sort ON release_alias USING gin(musicbrainz.mb_simple_tsvector(sort_name));
28 |
29 | CREATE INDEX release_group_idx_txt ON release_group USING gin(musicbrainz.mb_simple_tsvector(name));
30 |
31 | CREATE INDEX release_group_alias_idx_txt ON release_group_alias USING gin(musicbrainz.mb_simple_tsvector(name));
32 | CREATE INDEX release_group_alias_idx_txt_sort ON release_group_alias USING gin(musicbrainz.mb_simple_tsvector(sort_name));
33 |
34 | CREATE INDEX recording_idx_txt ON recording USING gin(musicbrainz.mb_simple_tsvector(name));
35 |
36 | CREATE INDEX recording_alias_idx_txt ON recording_alias USING gin(musicbrainz.mb_simple_tsvector(name));
37 | CREATE INDEX recording_alias_idx_txt_sort ON recording_alias USING gin(musicbrainz.mb_simple_tsvector(sort_name));
38 |
39 | CREATE INDEX series_idx_txt ON series USING gin(musicbrainz.mb_simple_tsvector(name));
40 |
41 | CREATE INDEX series_alias_idx_txt ON series_alias USING gin(musicbrainz.mb_simple_tsvector(name));
42 | CREATE INDEX series_alias_idx_txt_sort ON series_alias USING gin(musicbrainz.mb_simple_tsvector(sort_name));
43 |
44 | CREATE INDEX work_idx_txt ON work USING gin(musicbrainz.mb_simple_tsvector(name));
45 |
46 | CREATE INDEX work_alias_idx_txt ON work_alias USING gin(musicbrainz.mb_simple_tsvector(name));
47 | CREATE INDEX work_alias_idx_txt_sort ON work_alias USING gin(musicbrainz.mb_simple_tsvector(sort_name));
48 |
49 | CREATE INDEX area_idx_name_txt ON area USING gin(musicbrainz.mb_simple_tsvector(name));
50 |
51 | CREATE INDEX area_alias_idx_txt ON area_alias USING gin(musicbrainz.mb_simple_tsvector(name));
52 | CREATE INDEX area_alias_idx_txt_sort ON area_alias USING gin(musicbrainz.mb_simple_tsvector(sort_name));
53 |
54 | CREATE INDEX place_idx_name_txt ON place USING gin(musicbrainz.mb_simple_tsvector(name));
55 |
56 | CREATE INDEX place_alias_idx_txt ON place_alias USING gin(musicbrainz.mb_simple_tsvector(name));
57 | CREATE INDEX place_alias_idx_txt_sort ON place_alias USING gin(musicbrainz.mb_simple_tsvector(sort_name));
58 |
59 | CREATE INDEX tag_idx_name_txt ON tag USING gin(musicbrainz.mb_simple_tsvector(name));
60 |
--------------------------------------------------------------------------------
/mbdata/sql/CreateTypes.sql:
--------------------------------------------------------------------------------
1 | \set ON_ERROR_STOP 1
2 | BEGIN;
3 |
4 | CREATE TYPE cover_art_presence AS ENUM ('absent', 'present', 'darkened');
5 |
6 | CREATE TYPE edit_note_status AS ENUM ('deleted', 'edited');
7 |
8 | CREATE TYPE event_art_presence AS ENUM ('absent', 'present', 'darkened');
9 |
10 | CREATE TYPE fluency AS ENUM (
11 | 'basic',
12 | 'intermediate',
13 | 'advanced',
14 | 'native'
15 | );
16 |
17 | CREATE TYPE oauth_code_challenge_method AS ENUM ('plain', 'S256');
18 |
19 | CREATE TYPE ratable_entity_type AS ENUM (
20 | 'artist',
21 | 'event',
22 | 'label',
23 | 'place',
24 | 'recording',
25 | 'release_group',
26 | 'work'
27 | );
28 |
29 | CREATE TYPE taggable_entity_type AS ENUM (
30 | 'area',
31 | 'artist',
32 | 'event',
33 | 'instrument',
34 | 'label',
35 | 'place',
36 | 'recording',
37 | 'release',
38 | 'release_group',
39 | 'series',
40 | 'work'
41 | );
42 |
43 | COMMIT;
44 |
--------------------------------------------------------------------------------
/mbdata/sql/CreateViews.sql:
--------------------------------------------------------------------------------
1 | \set ON_ERROR_STOP 1
2 |
3 | BEGIN;
4 |
5 | CREATE OR REPLACE VIEW release_event AS
6 | SELECT
7 | release, date_year, date_month, date_day, country
8 | FROM (
9 | SELECT release, date_year, date_month, date_day, country
10 | FROM release_country
11 | UNION ALL
12 | SELECT release, date_year, date_month, date_day, NULL
13 | FROM release_unknown_country
14 | ) as q;
15 |
16 | CREATE OR REPLACE VIEW artist_series AS
17 | SELECT entity0 AS artist,
18 | entity1 AS series,
19 | las.id AS relationship,
20 | link_order,
21 | las.link,
22 | COALESCE(text_value, '') AS text_value
23 | FROM l_artist_series las
24 | JOIN series s ON s.id = las.entity1
25 | JOIN link l ON l.id = las.link
26 | JOIN link_type lt ON (lt.id = l.link_type AND lt.gid = 'd1a845d1-8c03-3191-9454-e4e8d37fa5e0')
27 | LEFT OUTER JOIN link_attribute_text_value latv ON (latv.attribute_type = 788 AND latv.link = l.id)
28 | ORDER BY series, link_order;
29 |
30 | CREATE OR REPLACE VIEW event_series AS
31 | SELECT entity0 AS event,
32 | entity1 AS series,
33 | lrs.id AS relationship,
34 | link_order,
35 | lrs.link,
36 | COALESCE(text_value, '') AS text_value
37 | FROM l_event_series lrs
38 | JOIN series s ON s.id = lrs.entity1
39 | JOIN link l ON l.id = lrs.link
40 | JOIN link_type lt ON (lt.id = l.link_type AND lt.gid = '707d947d-9563-328a-9a7d-0c5b9c3a9791')
41 | LEFT OUTER JOIN link_attribute_text_value latv ON (latv.attribute_type = 788 AND latv.link = l.id)
42 | ORDER BY series, link_order;
43 |
44 | CREATE OR REPLACE VIEW recording_series AS
45 | SELECT entity0 AS recording,
46 | entity1 AS series,
47 | lrs.id AS relationship,
48 | link_order,
49 | lrs.link,
50 | COALESCE(text_value, '') AS text_value
51 | FROM l_recording_series lrs
52 | JOIN series s ON s.id = lrs.entity1
53 | JOIN link l ON l.id = lrs.link
54 | JOIN link_type lt ON (lt.id = l.link_type AND lt.gid = 'ea6f0698-6782-30d6-b16d-293081b66774')
55 | LEFT OUTER JOIN link_attribute_text_value latv ON (latv.attribute_type = 788 AND latv.link = l.id)
56 | ORDER BY series, link_order;
57 |
58 | CREATE OR REPLACE VIEW release_series AS
59 | SELECT entity0 AS release,
60 | entity1 AS series,
61 | lrs.id AS relationship,
62 | link_order,
63 | lrs.link,
64 | COALESCE(text_value, '') AS text_value
65 | FROM l_release_series lrs
66 | JOIN series s ON s.id = lrs.entity1
67 | JOIN link l ON l.id = lrs.link
68 | JOIN link_type lt ON (lt.id = l.link_type AND lt.gid = '3fa29f01-8e13-3e49-9b0a-ad212aa2f81d')
69 | LEFT OUTER JOIN link_attribute_text_value latv ON (latv.attribute_type = 788 AND latv.link = l.id)
70 | ORDER BY series, link_order;
71 |
72 | CREATE OR REPLACE VIEW release_group_series AS
73 | SELECT entity0 AS release_group,
74 | entity1 AS series,
75 | lrgs.id AS relationship,
76 | link_order,
77 | lrgs.link,
78 | COALESCE(text_value, '') AS text_value
79 | FROM l_release_group_series lrgs
80 | JOIN series s ON s.id = lrgs.entity1
81 | JOIN link l ON l.id = lrgs.link
82 | JOIN link_type lt ON (lt.id = l.link_type AND lt.gid = '01018437-91d8-36b9-bf89-3f885d53b5bd')
83 | LEFT OUTER JOIN link_attribute_text_value latv ON (latv.attribute_type = 788 AND latv.link = l.id)
84 | ORDER BY series, link_order;
85 |
86 | CREATE OR REPLACE VIEW work_series AS
87 | SELECT entity1 AS work,
88 | entity0 AS series,
89 | lsw.id AS relationship,
90 | link_order,
91 | lsw.link,
92 | COALESCE(text_value, '') AS text_value
93 | FROM l_series_work lsw
94 | JOIN series s ON s.id = lsw.entity0
95 | JOIN link l ON l.id = lsw.link
96 | JOIN link_type lt ON (lt.id = l.link_type AND lt.gid = 'b0d44366-cdf0-3acb-bee6-0f65a77a6ef0')
97 | LEFT OUTER JOIN link_attribute_text_value latv ON (latv.attribute_type = 788 AND latv.link = l.id)
98 | ORDER BY series, link_order;
99 |
100 | CREATE OR REPLACE VIEW medium_track_durations AS
101 | SELECT
102 | medium.id AS medium,
103 | array_agg(track.length ORDER BY track.position) FILTER (WHERE track.position = 0) AS pregap_length,
104 | array_agg(track.length ORDER BY track.position) FILTER (WHERE track.position > 0 AND track.is_data_track = false) AS cdtoc_track_lengths,
105 | array_agg(track.length ORDER BY track.position) FILTER (WHERE track.is_data_track = true) AS data_track_lengths
106 | FROM medium
107 | JOIN track ON track.medium = medium.id
108 | GROUP BY medium.id;
109 |
110 | COMMIT;
111 |
112 | -- vi: set ts=4 sw=4 et :
113 |
--------------------------------------------------------------------------------
/mbdata/sql/DisableLastUpdatedTriggers.sql:
--------------------------------------------------------------------------------
1 | \set ON_ERROR_STOP 1
2 |
3 | BEGIN;
4 |
5 | DO $$
6 | DECLARE
7 | r record;
8 | BEGIN
9 | FOR r IN (
10 | SELECT *
11 | FROM information_schema.triggers
12 | WHERE action_statement LIKE '%b_upd_last_updated_table%'
13 | ) LOOP
14 | EXECUTE 'ALTER TABLE ' ||
15 | quote_ident(r.event_object_schema) || '.' ||
16 | quote_ident(r.event_object_table) ||
17 | ' DISABLE TRIGGER ' ||
18 | quote_ident(r.trigger_name);
19 | END LOOP;
20 | END $$;
21 |
22 | COMMIT;
23 |
--------------------------------------------------------------------------------
/mbdata/sql/DropAll.sql:
--------------------------------------------------------------------------------
1 | \unset ON_ERROR_STOP
2 |
3 | -- This script is a really quick and dirty way to tear down a database.
4 | -- It's really just a debug / development tool.
5 |
6 | \i admin/sql/DropReplicationTriggers.sql
7 | \i admin/sql/DropTriggers.sql
8 | \i admin/sql/DropMirrorOnlyTriggers.sql
9 | \i admin/sql/DropFunctions.sql
10 | \i admin/sql/DropViews.sql
11 | \i admin/sql/DropFKConstraints.sql
12 | \i admin/sql/DropIndexes.sql
13 | \i admin/sql/DropPrimaryKeys.sql
14 | \i admin/sql/DropTables.sql
15 | \i admin/sql/DropTypes.sql
16 | \i admin/sql/DropCollations.sql
17 |
--------------------------------------------------------------------------------
/mbdata/sql/DropCollateIndexes.sql:
--------------------------------------------------------------------------------
1 | \set ON_ERROR_STOP 1
2 | DROP INDEX artist_credit_idx_musicbrainz_collate;
3 | DROP INDEX artist_credit_name_idx_musicbrainz_collate;
4 | DROP INDEX artist_idx_musicbrainz_collate;
5 | DROP INDEX label_idx_musicbrainz_collate;
6 | DROP INDEX recording_idx_musicbrainz_collate;
7 | DROP INDEX release_group_idx_musicbrainz_collate;
8 | DROP INDEX release_idx_musicbrainz_collate;
9 | DROP INDEX work_idx_musicbrainz_collate;
10 |
--------------------------------------------------------------------------------
/mbdata/sql/DropCollations.sql:
--------------------------------------------------------------------------------
1 | \unset ON_ERROR_STOP
2 |
3 | DROP COLLATION musicbrainz;
4 |
--------------------------------------------------------------------------------
/mbdata/sql/DropFunctions.sql:
--------------------------------------------------------------------------------
1 | -- Automatically generated, do not edit.
2 | \unset ON_ERROR_STOP
3 |
4 | DROP FUNCTION _median(INTEGER[]);
5 | DROP FUNCTION a_del_alternative_medium_track();
6 | DROP FUNCTION a_del_alternative_release_or_track();
7 | DROP FUNCTION a_del_instrument();
8 | DROP FUNCTION a_del_l_area_area_mirror();
9 | DROP FUNCTION a_del_recording();
10 | DROP FUNCTION a_del_release();
11 | DROP FUNCTION a_del_release_event();
12 | DROP FUNCTION a_del_release_group();
13 | DROP FUNCTION a_del_release_group_secondary_type_join();
14 | DROP FUNCTION a_del_release_label();
15 | DROP FUNCTION a_del_track();
16 | DROP FUNCTION a_ins_alternative_medium_track();
17 | DROP FUNCTION a_ins_alternative_release_or_track();
18 | DROP FUNCTION a_ins_artist();
19 | DROP FUNCTION a_ins_edit_note();
20 | DROP FUNCTION a_ins_event();
21 | DROP FUNCTION a_ins_instrument();
22 | DROP FUNCTION a_ins_l_area_area_mirror();
23 | DROP FUNCTION a_ins_label();
24 | DROP FUNCTION a_ins_place();
25 | DROP FUNCTION a_ins_recording();
26 | DROP FUNCTION a_ins_release();
27 | DROP FUNCTION a_ins_release_event();
28 | DROP FUNCTION a_ins_release_group();
29 | DROP FUNCTION a_ins_release_group_secondary_type_join();
30 | DROP FUNCTION a_ins_release_label();
31 | DROP FUNCTION a_ins_track();
32 | DROP FUNCTION a_ins_work();
33 | DROP FUNCTION a_upd_alternative_medium_track();
34 | DROP FUNCTION a_upd_alternative_release_or_track();
35 | DROP FUNCTION a_upd_edit();
36 | DROP FUNCTION a_upd_instrument();
37 | DROP FUNCTION a_upd_l_area_area_mirror();
38 | DROP FUNCTION a_upd_recording();
39 | DROP FUNCTION a_upd_release();
40 | DROP FUNCTION a_upd_release_event();
41 | DROP FUNCTION a_upd_release_group();
42 | DROP FUNCTION a_upd_release_group_primary_type_mirror();
43 | DROP FUNCTION a_upd_release_group_secondary_type_mirror();
44 | DROP FUNCTION a_upd_release_label();
45 | DROP FUNCTION a_upd_track();
46 | DROP FUNCTION apply_artist_release_group_pending_updates();
47 | DROP FUNCTION apply_artist_release_pending_updates();
48 | DROP FUNCTION b_ins_edit_materialize_status();
49 | DROP FUNCTION b_upd_artist_credit_name();
50 | DROP FUNCTION b_upd_last_updated_table();
51 | DROP FUNCTION b_upd_link();
52 | DROP FUNCTION b_upd_link_attribute();
53 | DROP FUNCTION b_upd_link_attribute_credit();
54 | DROP FUNCTION b_upd_link_attribute_text_value();
55 | DROP FUNCTION b_upd_recording();
56 | DROP FUNCTION b_upd_release_group_secondary_type_join();
57 | DROP FUNCTION check_editor_name();
58 | DROP FUNCTION check_has_dates();
59 | DROP FUNCTION controlled_for_whitespace(TEXT);
60 | DROP FUNCTION create_bounding_cube(durations INTEGER[], fuzzy INTEGER);
61 | DROP FUNCTION create_cube_from_durations(durations INTEGER[]);
62 | DROP FUNCTION dec_nullable_artist_credit(row_id integer);
63 | DROP FUNCTION dec_ref_count(tbl varchar, row_id integer, val integer);
64 | DROP FUNCTION del_collection_sub_on_delete();
65 | DROP FUNCTION del_collection_sub_on_private();
66 | DROP FUNCTION delete_orphaned_recordings();
67 | DROP FUNCTION delete_ratings(enttype TEXT, ids INTEGER[]);
68 | DROP FUNCTION delete_unused_aggregate_tag(entity_type taggable_entity_type, entity_id INTEGER, tag_id INTEGER);
69 | DROP FUNCTION delete_unused_tag(tag_id INT);
70 | DROP FUNCTION delete_unused_url(ids INTEGER[]);
71 | DROP FUNCTION deny_deprecated_links();
72 | DROP FUNCTION deny_special_purpose_deletion();
73 | DROP FUNCTION edit_data_type_info(data JSONB);
74 | DROP FUNCTION end_area_implies_ended();
75 | DROP FUNCTION end_date_implies_ended();
76 | DROP FUNCTION ensure_area_attribute_type_allows_text();
77 | DROP FUNCTION ensure_artist_attribute_type_allows_text();
78 | DROP FUNCTION ensure_event_attribute_type_allows_text();
79 | DROP FUNCTION ensure_instrument_attribute_type_allows_text();
80 | DROP FUNCTION ensure_label_attribute_type_allows_text();
81 | DROP FUNCTION ensure_medium_attribute_type_allows_text();
82 | DROP FUNCTION ensure_place_attribute_type_allows_text();
83 | DROP FUNCTION ensure_recording_attribute_type_allows_text();
84 | DROP FUNCTION ensure_release_attribute_type_allows_text();
85 | DROP FUNCTION ensure_release_group_attribute_type_allows_text();
86 | DROP FUNCTION ensure_series_attribute_type_allows_text();
87 | DROP FUNCTION ensure_work_attribute_type_allows_text();
88 | DROP FUNCTION from_hex(t text);
89 | DROP FUNCTION generate_uuid_v3(namespace varchar, name varchar);
90 | DROP FUNCTION generate_uuid_v4();
91 | DROP FUNCTION get_recording_first_release_date_rows(condition TEXT);
92 | DROP FUNCTION get_release_first_release_date_rows(condition TEXT);
93 | DROP FUNCTION inc_nullable_artist_credit(row_id integer);
94 | DROP FUNCTION inc_ref_count(tbl varchar, row_id integer, val integer);
95 | DROP FUNCTION inserting_edits_requires_confirmed_email_address();
96 | DROP FUNCTION integer_date(year SMALLINT, month SMALLINT, day SMALLINT);
97 | DROP FUNCTION materialise_recording_length(recording_id INT);
98 | DROP FUNCTION mb_lower(input text);
99 | DROP FUNCTION mb_simple_tsvector(input text);
100 | DROP FUNCTION median_track_length(recording_id integer);
101 | DROP FUNCTION padded_by_whitespace(TEXT);
102 | DROP FUNCTION prevent_invalid_attributes();
103 | DROP FUNCTION remove_unused_links();
104 | DROP FUNCTION remove_unused_url();
105 | DROP FUNCTION replace_old_sub_on_add();
106 | DROP FUNCTION restore_collection_sub_on_public();
107 | DROP FUNCTION set_recordings_first_release_dates(recording_ids INTEGER[]);
108 | DROP FUNCTION set_release_first_release_date(release_id INTEGER);
109 | DROP FUNCTION set_release_group_first_release_date(release_group_id INTEGER);
110 | DROP FUNCTION set_releases_recordings_first_release_dates(release_ids INTEGER[]);
111 | DROP FUNCTION simplify_search_hints();
112 | DROP FUNCTION track_count_matches_cdtoc(medium, int);
113 | DROP FUNCTION trg_delete_unused_tag();
114 | DROP FUNCTION trg_delete_unused_tag_ref();
115 | DROP FUNCTION update_aggregate_rating(entity_type ratable_entity_type, entity_id INTEGER);
116 | DROP FUNCTION update_aggregate_rating_for_raw_delete();
117 | DROP FUNCTION update_aggregate_rating_for_raw_insert();
118 | DROP FUNCTION update_aggregate_rating_for_raw_update();
119 | DROP FUNCTION update_aggregate_tag_count(entity_type taggable_entity_type, entity_id INTEGER, tag_id INTEGER, count_change SMALLINT);
120 | DROP FUNCTION update_tag_counts_for_raw_delete();
121 | DROP FUNCTION update_tag_counts_for_raw_insert();
122 | DROP FUNCTION update_tag_counts_for_raw_update();
123 |
--------------------------------------------------------------------------------
/mbdata/sql/DropMirrorOnlyFunctions.sql:
--------------------------------------------------------------------------------
1 | -- Automatically generated, do not edit.
2 | \unset ON_ERROR_STOP
3 |
4 | DROP FUNCTION a_del_release_event_mirror();
5 | DROP FUNCTION a_del_release_group_mirror();
6 | DROP FUNCTION a_del_release_group_secondary_type_join_mirror();
7 | DROP FUNCTION a_del_release_label_mirror();
8 | DROP FUNCTION a_del_release_mirror();
9 | DROP FUNCTION a_del_track_mirror();
10 | DROP FUNCTION a_ins_release_event_mirror();
11 | DROP FUNCTION a_ins_release_group_mirror();
12 | DROP FUNCTION a_ins_release_group_secondary_type_join_mirror();
13 | DROP FUNCTION a_ins_release_label_mirror();
14 | DROP FUNCTION a_ins_release_mirror();
15 | DROP FUNCTION a_ins_track_mirror();
16 | DROP FUNCTION a_upd_release_event_mirror();
17 | DROP FUNCTION a_upd_release_group_meta_mirror();
18 | DROP FUNCTION a_upd_release_group_mirror();
19 | DROP FUNCTION a_upd_release_label_mirror();
20 | DROP FUNCTION a_upd_release_mirror();
21 | DROP FUNCTION a_upd_track_mirror();
22 |
--------------------------------------------------------------------------------
/mbdata/sql/DropMirrorOnlyTriggers.sql:
--------------------------------------------------------------------------------
1 | -- Automatically generated, do not edit.
2 | \unset ON_ERROR_STOP
3 |
4 | DROP TRIGGER IF EXISTS a_ins_l_area_area_mirror ON l_area_area;
5 | DROP TRIGGER IF EXISTS a_upd_l_area_area_mirror ON l_area_area;
6 | DROP TRIGGER IF EXISTS a_del_l_area_area_mirror ON l_area_area;
7 | DROP TRIGGER IF EXISTS a_ins_release_mirror ON release;
8 | DROP TRIGGER IF EXISTS a_upd_release_mirror ON release;
9 | DROP TRIGGER IF EXISTS a_del_release_mirror ON release;
10 | DROP TRIGGER IF EXISTS a_ins_release_event_mirror ON release_country;
11 | DROP TRIGGER IF EXISTS a_upd_release_event_mirror ON release_country;
12 | DROP TRIGGER IF EXISTS a_del_release_event_mirror ON release_country;
13 | DROP TRIGGER IF EXISTS a_ins_release_event_mirror ON release_unknown_country;
14 | DROP TRIGGER IF EXISTS a_upd_release_event_mirror ON release_unknown_country;
15 | DROP TRIGGER IF EXISTS a_del_release_event_mirror ON release_unknown_country;
16 | DROP TRIGGER IF EXISTS a_ins_release_group_mirror ON release_group;
17 | DROP TRIGGER IF EXISTS a_upd_release_group_mirror ON release_group;
18 | DROP TRIGGER IF EXISTS a_del_release_group_mirror ON release_group;
19 | DROP TRIGGER IF EXISTS a_upd_release_group_meta_mirror ON release_group_meta;
20 | DROP TRIGGER IF EXISTS a_upd_release_group_primary_type_mirror ON release_group_primary_type;
21 | DROP TRIGGER IF EXISTS a_upd_release_group_secondary_type_mirror ON release_group_secondary_type;
22 | DROP TRIGGER IF EXISTS a_ins_release_group_secondary_type_join_mirror ON release_group_secondary_type_join;
23 | DROP TRIGGER IF EXISTS a_del_release_group_secondary_type_join_mirror ON release_group_secondary_type_join;
24 | DROP TRIGGER IF EXISTS a_ins_release_label_mirror ON release_label;
25 | DROP TRIGGER IF EXISTS a_upd_release_label_mirror ON release_label;
26 | DROP TRIGGER IF EXISTS a_del_release_label_mirror ON release_label;
27 | DROP TRIGGER IF EXISTS a_ins_track_mirror ON track;
28 | DROP TRIGGER IF EXISTS a_upd_track_mirror ON track;
29 | DROP TRIGGER IF EXISTS a_del_track_mirror ON track;
30 | DROP TRIGGER IF EXISTS apply_artist_release_group_pending_updates_mirror ON release;
31 | DROP TRIGGER IF EXISTS apply_artist_release_pending_updates_mirror ON release;
32 | DROP TRIGGER IF EXISTS apply_artist_release_pending_updates_mirror ON release_country;
33 | DROP TRIGGER IF EXISTS apply_artist_release_pending_updates_mirror ON release_first_release_date;
34 | DROP TRIGGER IF EXISTS apply_artist_release_group_pending_updates_mirror ON release_group;
35 | DROP TRIGGER IF EXISTS apply_artist_release_group_pending_updates_mirror ON release_group_meta;
36 | DROP TRIGGER IF EXISTS apply_artist_release_group_pending_updates_mirror ON release_group_primary_type;
37 | DROP TRIGGER IF EXISTS apply_artist_release_group_pending_updates_mirror ON release_group_secondary_type;
38 | DROP TRIGGER IF EXISTS apply_artist_release_group_pending_updates_mirror ON release_group_secondary_type_join;
39 | DROP TRIGGER IF EXISTS apply_artist_release_pending_updates_mirror ON release_label;
40 | DROP TRIGGER IF EXISTS apply_artist_release_group_pending_updates_mirror ON track;
41 | DROP TRIGGER IF EXISTS apply_artist_release_pending_updates_mirror ON track;
42 |
--------------------------------------------------------------------------------
/mbdata/sql/DropSearchIndexes.sql:
--------------------------------------------------------------------------------
1 | -- Automatically generated, do not edit.
2 | \unset ON_ERROR_STOP
3 |
4 | DROP INDEX area_alias_idx_txt;
5 | DROP INDEX area_alias_idx_txt_sort;
6 | DROP INDEX area_idx_name_txt;
7 | DROP INDEX artist_alias_idx_txt;
8 | DROP INDEX artist_alias_idx_txt_sort;
9 | DROP INDEX artist_credit_idx_txt;
10 | DROP INDEX artist_credit_name_idx_txt;
11 | DROP INDEX artist_idx_txt;
12 | DROP INDEX artist_idx_txt_sort;
13 | DROP INDEX event_alias_idx_txt;
14 | DROP INDEX event_alias_idx_txt_sort;
15 | DROP INDEX event_idx_txt;
16 | DROP INDEX instrument_idx_txt;
17 | DROP INDEX label_alias_idx_txt;
18 | DROP INDEX label_alias_idx_txt_sort;
19 | DROP INDEX label_idx_txt;
20 | DROP INDEX place_alias_idx_txt;
21 | DROP INDEX place_alias_idx_txt_sort;
22 | DROP INDEX place_idx_name_txt;
23 | DROP INDEX recording_alias_idx_txt;
24 | DROP INDEX recording_alias_idx_txt_sort;
25 | DROP INDEX recording_idx_txt;
26 | DROP INDEX release_alias_idx_txt;
27 | DROP INDEX release_alias_idx_txt_sort;
28 | DROP INDEX release_group_alias_idx_txt;
29 | DROP INDEX release_group_alias_idx_txt_sort;
30 | DROP INDEX release_group_idx_txt;
31 | DROP INDEX release_idx_txt;
32 | DROP INDEX series_alias_idx_txt;
33 | DROP INDEX series_alias_idx_txt_sort;
34 | DROP INDEX series_idx_txt;
35 | DROP INDEX tag_idx_name_txt;
36 | DROP INDEX work_alias_idx_txt;
37 | DROP INDEX work_alias_idx_txt_sort;
38 | DROP INDEX work_idx_txt;
39 |
--------------------------------------------------------------------------------
/mbdata/sql/DropTypes.sql:
--------------------------------------------------------------------------------
1 | -- Automatically generated, do not edit.
2 | \unset ON_ERROR_STOP
3 |
4 | DROP TYPE IF EXISTS cover_art_presence;
5 | DROP TYPE IF EXISTS edit_note_status;
6 | DROP TYPE IF EXISTS event_art_presence;
7 | DROP TYPE IF EXISTS fluency;
8 | DROP TYPE IF EXISTS oauth_code_challenge_method;
9 | DROP TYPE IF EXISTS ratable_entity_type;
10 | DROP TYPE IF EXISTS taggable_entity_type;
11 |
--------------------------------------------------------------------------------
/mbdata/sql/DropViews.sql:
--------------------------------------------------------------------------------
1 | -- Automatically generated, do not edit.
2 | \unset ON_ERROR_STOP
3 |
4 | DROP VIEW artist_series;
5 | DROP VIEW event_series;
6 | DROP VIEW medium_track_durations;
7 | DROP VIEW recording_series;
8 | DROP VIEW release_event;
9 | DROP VIEW release_group_series;
10 | DROP VIEW release_series;
11 | DROP VIEW work_series;
12 |
--------------------------------------------------------------------------------
/mbdata/sql/EnableLastUpdatedTriggers.sql:
--------------------------------------------------------------------------------
1 | \set ON_ERROR_STOP 1
2 |
3 | BEGIN;
4 |
5 | DO $$
6 | DECLARE
7 | r record;
8 | BEGIN
9 | FOR r IN (
10 | SELECT *
11 | FROM information_schema.triggers
12 | WHERE action_statement LIKE '%b_upd_last_updated_table%'
13 | ) LOOP
14 | EXECUTE 'ALTER TABLE ' ||
15 | quote_ident(r.event_object_schema) || '.' ||
16 | quote_ident(r.event_object_table) ||
17 | ' ENABLE TRIGGER ' ||
18 | quote_ident(r.trigger_name);
19 | END LOOP;
20 | END $$;
21 |
22 | COMMIT;
23 |
--------------------------------------------------------------------------------
/mbdata/sql/Extensions.sql:
--------------------------------------------------------------------------------
1 | \set ON_ERROR_STOP 1
2 | BEGIN;
3 |
4 | CREATE EXTENSION IF NOT EXISTS cube WITH SCHEMA public;
5 | CREATE EXTENSION IF NOT EXISTS earthdistance WITH SCHEMA public;
6 | CREATE EXTENSION IF NOT EXISTS unaccent WITH SCHEMA public;
7 |
8 | -- Substitute public.ll_to_earth for a version that schema-qualifies
9 | -- references to public.cube and public.earth, to avoid errors during
10 | -- inlining/execution of the function while running an autovacuum or
11 | -- pg_upgrade.
12 | --
13 | -- The issue in question arises since postgres 10.3: a change was made to
14 | -- only include pg_catalog in the search_path settings of postgres client
15 | -- programs in order to resolve a security issue. So, since `cube` and
16 | -- `earth` are installed in the public schema, they're invisible in these
17 | -- contexts without the qualification.
18 |
19 | CREATE OR REPLACE FUNCTION musicbrainz.ll_to_earth(float8, float8)
20 | RETURNS public.earth
21 | LANGUAGE SQL
22 | IMMUTABLE STRICT
23 | PARALLEL SAFE
24 | AS 'SELECT public.cube(public.cube(public.cube(public.earth()*cos(radians($1))*cos(radians($2))),public.earth()*cos(radians($1))*sin(radians($2))),public.earth()*sin(radians($1)))::public.earth';
25 |
26 | -- The unaccent function, but IMMUTABLE. Based on a solution provided by
27 | -- Erwin Brandstetter in [1], which removes the dependency on search_path.
28 | -- Warning: changing the unaccent dictionary on the filesystem can still
29 | -- break the IMMUTABLE assumption.
30 | --
31 | -- The answer in [1] suggests that using a C function for immutable_unaccent
32 | -- allows it to be inlined in musicbrainz_unaccent below, and is 10x faster
33 | -- than the fallback. Although this script is meant to execute as a
34 | -- superuser, a fallback is provided specifically for instances where even
35 | -- the "superuser" is restricted in creating C language functions, e.g.
36 | -- Amazon RDS.
37 | --
38 | -- [1] https://stackoverflow.com/a/11007216
39 |
40 | DO $$
41 | BEGIN
42 | CREATE OR REPLACE FUNCTION public.immutable_unaccent(regdictionary, text)
43 | RETURNS text LANGUAGE c IMMUTABLE PARALLEL SAFE STRICT AS
44 | '$libdir/unaccent', 'unaccent_dict';
45 |
46 | CREATE OR REPLACE FUNCTION musicbrainz.musicbrainz_unaccent(text)
47 | RETURNS text LANGUAGE sql IMMUTABLE PARALLEL SAFE STRICT AS
48 | $func$
49 | SELECT public.immutable_unaccent(regdictionary 'public.unaccent', $1)
50 | $func$;
51 | EXCEPTION
52 | WHEN insufficient_privilege THEN
53 | CREATE OR REPLACE FUNCTION musicbrainz.musicbrainz_unaccent(text)
54 | RETURNS text LANGUAGE sql IMMUTABLE PARALLEL SAFE STRICT AS
55 | $func$
56 | SELECT public.unaccent('public.unaccent', $1)
57 | $func$;
58 | END
59 | $$;
60 |
61 | COMMIT;
62 | -- vi: set ts=4 sw=4 et :
63 |
--------------------------------------------------------------------------------
/mbdata/sql/InsertDefaultRows.sql:
--------------------------------------------------------------------------------
1 | \set ON_ERROR_STOP 1
2 |
3 | BEGIN;
4 |
5 | INSERT INTO artist (name, sort_name, gid) VALUES
6 | ('Various Artists', 'Various Artists', '89ad4ac3-39f7-470e-963a-56509c546377'),
7 | ('Deleted Artist', 'Deleted Artist', 'c06aa285-520e-40c0-b776-83d2c9e8a6d1');
8 |
9 | INSERT INTO label (name, gid) VALUES
10 | ('Deleted Label', 'f43e252d-9ebf-4e8e-bba8-36d080756cc1');
11 |
12 | INSERT INTO editor (id, name, password, ha1) VALUES (1, 'Anonymous', '', '');
13 | INSERT INTO editor (id, name, password, ha1) VALUES (2, 'FreeDB', '', '');
14 | INSERT INTO editor (id, name, password, ha1) VALUES (4, 'ModBot', '', '');
15 |
16 | INSERT INTO replication_control VALUES (
17 | 1, -- fixed primary key
18 | 1, -- schema #1
19 | NULL,-- until we pull in a particular dump, we don't know what replication sequence we're at
20 | NULL
21 | );
22 |
23 | INSERT INTO release_group_primary_type VALUES (1, 'Album', null, 1, null, 'f529b476-6e62-324f-b0aa-1f3e33d313fc');
24 | INSERT INTO release_group_primary_type VALUES (2, 'Single', null, 2, null, 'd6038452-8ee0-3f68-affc-2de9a1ede0b9');
25 |
26 | INSERT INTO release_status VALUES (1, 'Official', null, 1, null, '4e304316-386d-3409-af2e-78857eec5cfe');
27 |
28 | COMMIT;
29 |
30 | -- vi: set ts=4 sw=4 et :
31 |
--------------------------------------------------------------------------------
/mbdata/sql/ReplicationSetup.sql:
--------------------------------------------------------------------------------
1 | \set ON_ERROR_STOP 1
2 | SET search_path = musicbrainz;
3 |
4 | BEGIN;
5 |
6 | -- To "install" the pending.so function, execute this as user postgres
7 | -- Normally this is done by InitDb.pl so you don't really have to worry about it.
8 | --CREATE FUNCTION "recordchange" () RETURNS trigger AS
9 | --'$libdir/pending', 'recordchange' LANGUAGE C;
10 |
11 | CREATE AGGREGATE array_cat_agg(int2[]) (
12 | sfunc = array_cat,
13 | stype = int2[],
14 | initcond = '{}'
15 | );
16 |
17 | CREATE TABLE dbmirror_Pending (
18 | SeqId serial,
19 | TableName varchar NOT NULL,
20 | Op character,
21 | XID int4 NOT NULL,
22 | PRIMARY KEY (SeqId)
23 | );
24 |
25 | CREATE INDEX dbmirror_Pending_XID_Index ON dbmirror_Pending (XID);
26 |
27 | CREATE TABLE dbmirror_PendingData (
28 | SeqId int4 NOT NULL,
29 | IsKey bool NOT NULL,
30 | Data varchar,
31 | PRIMARY KEY (SeqId, IsKey) ,
32 | FOREIGN KEY (SeqId) REFERENCES dbmirror_Pending (SeqId) ON UPDATE CASCADE ON DELETE CASCADE
33 | );
34 |
35 | COMMIT;
36 |
37 | -- vi: set ts=4 sw=4 et :
38 |
--------------------------------------------------------------------------------
/mbdata/sql/caa/CreateEditFKConstraints.sql:
--------------------------------------------------------------------------------
1 | \set ON_ERROR_STOP 1
2 |
3 | SET search_path = 'cover_art_archive';
4 |
5 | ALTER TABLE cover_art
6 | ADD CONSTRAINT cover_art_fk_edit
7 | FOREIGN KEY (edit)
8 | REFERENCES musicbrainz.edit(id);
9 |
--------------------------------------------------------------------------------
/mbdata/sql/caa/CreateFKConstraints.sql:
--------------------------------------------------------------------------------
1 | -- Automatically generated, do not edit.
2 | \set ON_ERROR_STOP 1
3 |
4 | SET search_path = 'cover_art_archive';
5 |
6 | ALTER TABLE art_type
7 | ADD CONSTRAINT art_type_fk_parent
8 | FOREIGN KEY (parent)
9 | REFERENCES cover_art_archive.art_type(id);
10 |
11 | ALTER TABLE cover_art
12 | ADD CONSTRAINT cover_art_fk_release
13 | FOREIGN KEY (release)
14 | REFERENCES musicbrainz.release(id)
15 | ON DELETE CASCADE;
16 |
17 | ALTER TABLE cover_art
18 | ADD CONSTRAINT cover_art_fk_mime_type
19 | FOREIGN KEY (mime_type)
20 | REFERENCES cover_art_archive.image_type(mime_type);
21 |
22 | ALTER TABLE cover_art_type
23 | ADD CONSTRAINT cover_art_type_fk_id
24 | FOREIGN KEY (id)
25 | REFERENCES cover_art_archive.cover_art(id)
26 | ON DELETE CASCADE;
27 |
28 | ALTER TABLE cover_art_type
29 | ADD CONSTRAINT cover_art_type_fk_type_id
30 | FOREIGN KEY (type_id)
31 | REFERENCES cover_art_archive.art_type(id);
32 |
33 | ALTER TABLE release_group_cover_art
34 | ADD CONSTRAINT release_group_cover_art_fk_release_group
35 | FOREIGN KEY (release_group)
36 | REFERENCES musicbrainz.release_group(id);
37 |
38 | ALTER TABLE release_group_cover_art
39 | ADD CONSTRAINT release_group_cover_art_fk_release
40 | FOREIGN KEY (release)
41 | REFERENCES musicbrainz.release(id);
42 |
43 |
--------------------------------------------------------------------------------
/mbdata/sql/caa/CreateFunctions.sql:
--------------------------------------------------------------------------------
1 | BEGIN;
2 |
3 | SET search_path = 'cover_art_archive';
4 |
5 | CREATE OR REPLACE FUNCTION materialize_caa_presence() RETURNS trigger AS $$
6 | BEGIN
7 | -- On delete, set the presence flag to 'absent' if there's no more
8 | -- cover art
9 | IF TG_OP = 'DELETE' THEN
10 | IF NOT EXISTS (
11 | SELECT TRUE FROM cover_art_archive.cover_art
12 | WHERE release = OLD.release
13 | ) THEN
14 | UPDATE musicbrainz.release_meta
15 | SET cover_art_presence = 'absent'
16 | WHERE id = OLD.release;
17 | END IF;
18 | END IF;
19 |
20 | -- On insert, set the presence flag to 'present' if it was previously
21 | -- 'absent'
22 | IF TG_OP = 'INSERT' THEN
23 | CASE (
24 | SELECT cover_art_presence FROM musicbrainz.release_meta
25 | WHERE id = NEW.release
26 | )
27 | WHEN 'absent' THEN
28 | UPDATE musicbrainz.release_meta
29 | SET cover_art_presence = 'present'
30 | WHERE id = NEW.release;
31 | WHEN 'darkened' THEN
32 | RAISE EXCEPTION 'This release has been darkened and cannot have new cover art';
33 | ELSE
34 | END CASE;
35 | END IF;
36 |
37 | RETURN NULL;
38 | END;
39 | $$ LANGUAGE 'plpgsql';
40 |
41 | CREATE OR REPLACE FUNCTION resequence_positions(release_id INT) RETURNS void AS $$
42 | BEGIN
43 | UPDATE cover_art_archive.cover_art
44 | SET ordering = recalculated.row_number
45 | FROM (
46 | SELECT *,
47 | row_number() OVER (PARTITION BY release ORDER BY ordering ASC)
48 | FROM cover_art_archive.cover_art
49 | WHERE cover_art.release = release_id
50 | ) recalculated
51 | WHERE recalculated.id = cover_art.id AND
52 | recalculated.row_number != cover_art.ordering;
53 | END;
54 | $$ LANGUAGE 'plpgsql';
55 |
56 | CREATE OR REPLACE FUNCTION resequence_cover_art_trigger() RETURNS trigger AS $$
57 | BEGIN
58 | IF TG_OP = 'INSERT' OR TG_OP = 'UPDATE' THEN
59 | PERFORM cover_art_archive.resequence_positions(NEW.release);
60 | END IF;
61 |
62 | IF (TG_OP = 'DELETE') OR
63 | (TG_OP = 'UPDATE' AND NEW.release != OLD.release)
64 | THEN
65 | PERFORM cover_art_archive.resequence_positions(OLD.release);
66 | END IF;
67 |
68 | RETURN NULL;
69 | END;
70 | $$ LANGUAGE 'plpgsql';
71 |
72 | COMMIT;
73 |
--------------------------------------------------------------------------------
/mbdata/sql/caa/CreateIndexes.sql:
--------------------------------------------------------------------------------
1 | \set ON_ERROR_STOP 1
2 |
3 | BEGIN;
4 |
5 | SET search_path = 'cover_art_archive';
6 |
7 | CREATE INDEX cover_art_idx_release ON cover_art (release);
8 | CREATE UNIQUE INDEX art_type_idx_gid ON art_type (gid);
9 |
10 | COMMIT;
11 |
--------------------------------------------------------------------------------
/mbdata/sql/caa/CreatePrimaryKeys.sql:
--------------------------------------------------------------------------------
1 | -- Automatically generated, do not edit.
2 | \set ON_ERROR_STOP 1
3 |
4 | SET search_path = 'cover_art_archive';
5 |
6 | ALTER TABLE art_type ADD CONSTRAINT art_type_pkey PRIMARY KEY (id);
7 | ALTER TABLE cover_art ADD CONSTRAINT cover_art_pkey PRIMARY KEY (id);
8 | ALTER TABLE cover_art_type ADD CONSTRAINT cover_art_type_pkey PRIMARY KEY (id, type_id);
9 | ALTER TABLE image_type ADD CONSTRAINT image_type_pkey PRIMARY KEY (mime_type);
10 | ALTER TABLE release_group_cover_art ADD CONSTRAINT release_group_cover_art_pkey PRIMARY KEY (release_group);
11 |
--------------------------------------------------------------------------------
/mbdata/sql/caa/CreateReplicationTriggers.sql:
--------------------------------------------------------------------------------
1 | -- Automatically generated, do not edit.
2 | \set ON_ERROR_STOP 1
3 |
4 | SET search_path = 'cover_art_archive', musicbrainz, public;
5 |
6 | BEGIN;
7 |
8 | CREATE TRIGGER "reptg_art_type"
9 | AFTER INSERT OR DELETE OR UPDATE ON "art_type"
10 | FOR EACH ROW EXECUTE PROCEDURE "recordchange" ('verbose');
11 |
12 | CREATE TRIGGER "reptg_cover_art"
13 | AFTER INSERT OR DELETE OR UPDATE ON "cover_art"
14 | FOR EACH ROW EXECUTE PROCEDURE "recordchange" ('verbose');
15 |
16 | CREATE TRIGGER "reptg_cover_art_type"
17 | AFTER INSERT OR DELETE OR UPDATE ON "cover_art_type"
18 | FOR EACH ROW EXECUTE PROCEDURE "recordchange" ('verbose');
19 |
20 | CREATE TRIGGER "reptg_image_type"
21 | AFTER INSERT OR DELETE OR UPDATE ON "image_type"
22 | FOR EACH ROW EXECUTE PROCEDURE "recordchange" ('verbose');
23 |
24 | CREATE TRIGGER "reptg_release_group_cover_art"
25 | AFTER INSERT OR DELETE OR UPDATE ON "release_group_cover_art"
26 | FOR EACH ROW EXECUTE PROCEDURE "recordchange" ('verbose');
27 |
28 | COMMIT;
29 |
--------------------------------------------------------------------------------
/mbdata/sql/caa/CreateReplicationTriggers2.sql:
--------------------------------------------------------------------------------
1 | -- Automatically generated, do not edit.
2 | \set ON_ERROR_STOP 1
3 |
4 | SET search_path = 'cover_art_archive', musicbrainz, public;
5 |
6 | BEGIN;
7 |
8 | CREATE TRIGGER reptg2_art_type
9 | AFTER INSERT OR DELETE OR UPDATE ON art_type
10 | FOR EACH ROW EXECUTE PROCEDURE dbmirror2.recordchange();
11 |
12 | CREATE TRIGGER reptg2_cover_art
13 | AFTER INSERT OR DELETE OR UPDATE ON cover_art
14 | FOR EACH ROW EXECUTE PROCEDURE dbmirror2.recordchange();
15 |
16 | CREATE TRIGGER reptg2_cover_art_type
17 | AFTER INSERT OR DELETE OR UPDATE ON cover_art_type
18 | FOR EACH ROW EXECUTE PROCEDURE dbmirror2.recordchange();
19 |
20 | CREATE TRIGGER reptg2_image_type
21 | AFTER INSERT OR DELETE OR UPDATE ON image_type
22 | FOR EACH ROW EXECUTE PROCEDURE dbmirror2.recordchange();
23 |
24 | CREATE TRIGGER reptg2_release_group_cover_art
25 | AFTER INSERT OR DELETE OR UPDATE ON release_group_cover_art
26 | FOR EACH ROW EXECUTE PROCEDURE dbmirror2.recordchange();
27 |
28 | COMMIT;
29 |
--------------------------------------------------------------------------------
/mbdata/sql/caa/CreateTables.sql:
--------------------------------------------------------------------------------
1 | \set ON_ERROR_STOP 1
2 |
3 | BEGIN;
4 |
5 | SET search_path = 'cover_art_archive';
6 |
7 | CREATE TABLE art_type ( -- replicate (verbose)
8 | id SERIAL NOT NULL, -- PK
9 | name TEXT NOT NULL,
10 | parent INTEGER, -- references cover_art_archive.art_type.id
11 | child_order INTEGER NOT NULL DEFAULT 0,
12 | description TEXT,
13 | gid uuid NOT NULL
14 | );
15 |
16 | CREATE TABLE image_type ( -- replicate (verbose)
17 | mime_type TEXT NOT NULL, -- PK
18 | suffix TEXT NOT NULL
19 | );
20 |
21 | CREATE TABLE cover_art ( -- replicate (verbose)
22 | id BIGINT NOT NULL, -- PK
23 | release INTEGER NOT NULL, -- references musicbrainz.release.id CASCADE
24 | comment TEXT NOT NULL DEFAULT '',
25 | edit INTEGER NOT NULL, -- separately references musicbrainz.edit.id
26 | ordering INTEGER NOT NULL CHECK (ordering > 0),
27 | date_uploaded TIMESTAMP WITH TIME ZONE DEFAULT now() NOT NULL,
28 | edits_pending INTEGER NOT NULL DEFAULT 0 CHECK (edits_pending >= 0),
29 | mime_type TEXT NOT NULL, -- references cover_art_archive.image_type.mime_type
30 | filesize INTEGER,
31 | thumb_250_filesize INTEGER,
32 | thumb_500_filesize INTEGER,
33 | thumb_1200_filesize INTEGER
34 | );
35 |
36 | CREATE TABLE cover_art_type ( -- replicate (verbose)
37 | id BIGINT NOT NULL, -- PK, references cover_art_archive.cover_art.id CASCADE,
38 | type_id INTEGER NOT NULL -- PK, references cover_art_archive.art_type.id,
39 | );
40 |
41 | CREATE TABLE release_group_cover_art ( -- replicate (verbose)
42 | release_group INTEGER NOT NULL, -- PK, references musicbrainz.release_group.id
43 | release INTEGER NOT NULL -- FK, references musicbrainz.release.id
44 | );
45 |
46 | COMMIT;
47 |
--------------------------------------------------------------------------------
/mbdata/sql/caa/CreateTriggers.sql:
--------------------------------------------------------------------------------
1 | BEGIN;
2 |
3 | SET search_path = 'cover_art_archive';
4 |
5 | CREATE TRIGGER update_release_coverart AFTER INSERT OR DELETE
6 | ON cover_art_archive.cover_art
7 | FOR EACH ROW EXECUTE PROCEDURE materialize_caa_presence();
8 |
9 | CREATE CONSTRAINT TRIGGER resquence_cover_art AFTER INSERT OR UPDATE OR DELETE
10 | ON cover_art_archive.cover_art DEFERRABLE INITIALLY DEFERRED
11 | FOR EACH ROW EXECUTE PROCEDURE resequence_cover_art_trigger();
12 |
13 | COMMIT;
14 |
--------------------------------------------------------------------------------
/mbdata/sql/caa/CreateViews.sql:
--------------------------------------------------------------------------------
1 | \set ON_ERROR_STOP 1
2 |
3 | BEGIN;
4 |
5 | SET search_path = 'cover_art_archive';
6 |
7 | CREATE OR REPLACE VIEW index_listing AS
8 | SELECT cover_art.*,
9 | (edit.close_time IS NOT NULL) AS approved,
10 | coalesce(cover_art.id = (SELECT id FROM cover_art_archive.cover_art_type
11 | JOIN cover_art_archive.cover_art ca_front USING (id)
12 | WHERE ca_front.release = cover_art.release
13 | AND type_id = 1
14 | ORDER BY ca_front.ordering
15 | LIMIT 1), FALSE) AS is_front,
16 | coalesce(cover_art.id = (SELECT id FROM cover_art_archive.cover_art_type
17 | JOIN cover_art_archive.cover_art ca_front USING (id)
18 | WHERE ca_front.release = cover_art.release
19 | AND type_id = 2
20 | ORDER BY ca_front.ordering
21 | LIMIT 1), FALSE) AS is_back,
22 | array(SELECT art_type.name
23 | FROM cover_art_archive.cover_art_type
24 | JOIN cover_art_archive.art_type ON cover_art_type.type_id = art_type.id
25 | WHERE cover_art_type.id = cover_art.id) AS types
26 | FROM cover_art_archive.cover_art
27 | LEFT JOIN musicbrainz.edit ON edit.id = cover_art.edit;
28 |
29 | COMMIT;
30 |
--------------------------------------------------------------------------------
/mbdata/sql/caa/DropFKConstraints.sql:
--------------------------------------------------------------------------------
1 | -- Automatically generated, do not edit.
2 | \unset ON_ERROR_STOP
3 |
4 | SET search_path = 'cover_art_archive';
5 |
6 | ALTER TABLE art_type DROP CONSTRAINT IF EXISTS art_type_fk_parent;
7 | ALTER TABLE cover_art DROP CONSTRAINT IF EXISTS cover_art_fk_release;
8 | ALTER TABLE cover_art DROP CONSTRAINT IF EXISTS cover_art_fk_edit;
9 | ALTER TABLE cover_art DROP CONSTRAINT IF EXISTS cover_art_fk_mime_type;
10 | ALTER TABLE cover_art_type DROP CONSTRAINT IF EXISTS cover_art_type_fk_id;
11 | ALTER TABLE cover_art_type DROP CONSTRAINT IF EXISTS cover_art_type_fk_type_id;
12 | ALTER TABLE release_group_cover_art DROP CONSTRAINT IF EXISTS release_group_cover_art_fk_release_group;
13 | ALTER TABLE release_group_cover_art DROP CONSTRAINT IF EXISTS release_group_cover_art_fk_release;
14 |
--------------------------------------------------------------------------------
/mbdata/sql/caa/DropFunctions.sql:
--------------------------------------------------------------------------------
1 | -- Automatically generated, do not edit.
2 | \unset ON_ERROR_STOP
3 |
4 | SET search_path = 'cover_art_archive';
5 |
6 | DROP FUNCTION materialize_caa_presence();
7 | DROP FUNCTION resequence_cover_art_trigger();
8 | DROP FUNCTION resequence_positions(release_id INT);
9 |
--------------------------------------------------------------------------------
/mbdata/sql/caa/DropIndexes.sql:
--------------------------------------------------------------------------------
1 | -- Automatically generated, do not edit.
2 | \unset ON_ERROR_STOP
3 |
4 | SET search_path = 'cover_art_archive';
5 |
6 | DROP INDEX art_type_idx_gid;
7 | DROP INDEX cover_art_idx_release;
8 |
--------------------------------------------------------------------------------
/mbdata/sql/caa/DropPrimaryKeys.sql:
--------------------------------------------------------------------------------
1 | -- Automatically generated, do not edit.
2 | \unset ON_ERROR_STOP
3 |
4 | SET search_path = 'cover_art_archive';
5 |
6 | ALTER TABLE art_type DROP CONSTRAINT IF EXISTS art_type_pkey;
7 | ALTER TABLE cover_art DROP CONSTRAINT IF EXISTS cover_art_pkey;
8 | ALTER TABLE cover_art_type DROP CONSTRAINT IF EXISTS cover_art_type_pkey;
9 | ALTER TABLE image_type DROP CONSTRAINT IF EXISTS image_type_pkey;
10 | ALTER TABLE release_group_cover_art DROP CONSTRAINT IF EXISTS release_group_cover_art_pkey;
11 |
--------------------------------------------------------------------------------
/mbdata/sql/caa/DropReplicationTriggers.sql:
--------------------------------------------------------------------------------
1 | -- Automatically generated, do not edit.
2 | \unset ON_ERROR_STOP
3 |
4 | SET search_path = 'cover_art_archive';
5 |
6 | DROP TRIGGER IF EXISTS reptg_art_type ON art_type;
7 | DROP TRIGGER IF EXISTS reptg_cover_art ON cover_art;
8 | DROP TRIGGER IF EXISTS reptg_cover_art_type ON cover_art_type;
9 | DROP TRIGGER IF EXISTS reptg_image_type ON image_type;
10 | DROP TRIGGER IF EXISTS reptg_release_group_cover_art ON release_group_cover_art;
11 |
--------------------------------------------------------------------------------
/mbdata/sql/caa/DropReplicationTriggers2.sql:
--------------------------------------------------------------------------------
1 | -- Automatically generated, do not edit.
2 | \unset ON_ERROR_STOP
3 |
4 | SET search_path = 'cover_art_archive';
5 |
6 | DROP TRIGGER IF EXISTS reptg2_art_type ON art_type;
7 | DROP TRIGGER IF EXISTS reptg2_cover_art ON cover_art;
8 | DROP TRIGGER IF EXISTS reptg2_cover_art_type ON cover_art_type;
9 | DROP TRIGGER IF EXISTS reptg2_image_type ON image_type;
10 | DROP TRIGGER IF EXISTS reptg2_release_group_cover_art ON release_group_cover_art;
11 |
--------------------------------------------------------------------------------
/mbdata/sql/caa/DropTables.sql:
--------------------------------------------------------------------------------
1 | -- Automatically generated, do not edit.
2 | \unset ON_ERROR_STOP
3 |
4 | SET search_path = 'cover_art_archive';
5 |
6 | DROP TABLE art_type;
7 | DROP TABLE cover_art;
8 | DROP TABLE cover_art_type;
9 | DROP TABLE image_type;
10 | DROP TABLE release_group_cover_art;
11 |
--------------------------------------------------------------------------------
/mbdata/sql/caa/DropTriggers.sql:
--------------------------------------------------------------------------------
1 | -- Automatically generated, do not edit.
2 | \unset ON_ERROR_STOP
3 |
4 | SET search_path = 'cover_art_archive';
5 |
6 | DROP TRIGGER IF EXISTS update_release_coverart ON cover_art_archive.cover_art;
7 | DROP TRIGGER IF EXISTS resquence_cover_art ON cover_art_archive.cover_art;
8 |
--------------------------------------------------------------------------------
/mbdata/sql/caa/DropViews.sql:
--------------------------------------------------------------------------------
1 | -- Automatically generated, do not edit.
2 | \unset ON_ERROR_STOP
3 |
4 | SET search_path = 'cover_art_archive';
5 |
6 | DROP VIEW index_listing;
7 |
--------------------------------------------------------------------------------
/mbdata/sql/caa/SetSequences.sql:
--------------------------------------------------------------------------------
1 | -- Automatically generated, do not edit.
2 | \unset ON_ERROR_STOP
3 |
4 | SET search_path = 'cover_art_archive';
5 |
6 | SELECT setval('art_type_id_seq', COALESCE((SELECT MAX(id) FROM art_type), 0) + 1, FALSE);
7 |
--------------------------------------------------------------------------------
/mbdata/sql/caa/TruncateTables.sql:
--------------------------------------------------------------------------------
1 | -- Automatically generated, do not edit.
2 | \set ON_ERROR_STOP 1
3 |
4 | SET search_path = 'cover_art_archive';
5 |
6 | TRUNCATE TABLE art_type RESTART IDENTITY CASCADE;
7 | TRUNCATE TABLE cover_art RESTART IDENTITY CASCADE;
8 | TRUNCATE TABLE cover_art_type RESTART IDENTITY CASCADE;
9 | TRUNCATE TABLE image_type RESTART IDENTITY CASCADE;
10 | TRUNCATE TABLE release_group_cover_art RESTART IDENTITY CASCADE;
11 |
--------------------------------------------------------------------------------
/mbdata/sql/dbmirror2/MasterSetup.sql:
--------------------------------------------------------------------------------
1 | -- Copyright (C) 2021 MetaBrainz Foundation
2 | -- Licensed under the GPL version 2, or (at your option) any later version:
3 | -- http://www.gnu.org/licenses/gpl-2.0.txt
4 |
5 | BEGIN;
6 |
7 | -- The column_info view allows us to determine whether a column in a given
8 | -- table is part of its primary key, and gives us its position too.
9 | --
10 | -- This view must be refreshed after every schema change; an event trigger
11 | -- in MasterEventTriggerSetup.sql can handle this automatically.
12 | CREATE MATERIALIZED VIEW dbmirror2.column_info (
13 | table_schema,
14 | table_name,
15 | column_name,
16 | position,
17 | is_primary
18 | ) AS
19 | SELECT
20 | c.table_schema,
21 | c.table_name,
22 | c.column_name,
23 | c.ordinal_position,
24 | coalesce((
25 | SELECT TRUE
26 | FROM information_schema.key_column_usage kcu
27 | NATURAL JOIN information_schema.table_constraints tc
28 | WHERE kcu.table_schema = c.table_schema
29 | AND kcu.table_name = c.table_name
30 | AND kcu.column_name = c.column_name
31 | AND tc.constraint_type = 'PRIMARY KEY'
32 | ), FALSE) AS is_primary
33 | FROM information_schema.columns c
34 | NATURAL JOIN information_schema.tables t
35 | WHERE t.table_type = 'BASE TABLE'
36 | AND t.table_schema NOT IN ('dbmirror2', 'information_schema', 'pg_catalog')
37 | WITH DATA;
38 |
39 | CREATE INDEX column_info_idx
40 | ON dbmirror2.column_info (table_schema, table_name, is_primary);
41 |
42 | CREATE FUNCTION dbmirror2.recordchange()
43 | RETURNS trigger AS $$
44 | DECLARE
45 | -- prefixed with an underscore to disambiguate it from the column names
46 | -- pending_data.tablename and pending_keys.tablename
47 | _tablename TEXT;
48 | keys TEXT[];
49 | jsonquery TEXT;
50 | olddata JSON;
51 | newdata JSON;
52 | -- prefixed with 'x' to avoid conflict with column name in queries
53 | xoldctid TID;
54 | nextseqid BIGINT;
55 | -- out-of-order seqid
56 | oooseqid BIGINT;
57 | oootrgdepth INTEGER;
58 | pdcursor NO SCROLL CURSOR (oooseqid INTEGER) FOR
59 | SELECT seqid
60 | FROM dbmirror2.pending_data
61 | WHERE xid = txid_current()
62 | AND seqid >= oooseqid
63 | ORDER BY seqid DESC
64 | FOR UPDATE;
65 | BEGIN
66 | _tablename := (
67 | quote_ident(TG_TABLE_SCHEMA) || '.' || quote_ident(TG_TABLE_NAME)
68 | );
69 |
70 | nextseqid := nextval(
71 | pg_get_serial_sequence('dbmirror2.pending_data', 'seqid')
72 | );
73 |
74 | INSERT INTO dbmirror2.pending_ts (xid, ts)
75 | VALUES (txid_current(), transaction_timestamp())
76 | ON CONFLICT DO NOTHING;
77 |
78 | jsonquery := (
79 | SELECT format(
80 | 'SELECT json_build_object(%1$s)',
81 | array_to_string(
82 | array_agg(
83 | format('%1$L, ($1).%1$I', column_name) ORDER BY position
84 | ),
85 | ', '
86 | )
87 | )
88 | FROM dbmirror2.column_info
89 | WHERE table_schema = TG_TABLE_SCHEMA AND table_name = TG_TABLE_NAME
90 | );
91 |
92 | IF TG_OP != 'INSERT' THEN
93 | EXECUTE jsonquery INTO olddata USING OLD;
94 |
95 | xoldctid := OLD.ctid;
96 | END IF;
97 |
98 | IF TG_OP != 'DELETE' THEN
99 | EXECUTE jsonquery INTO newdata USING NEW;
100 |
101 | -- Detect out-of-order operations caused by cascading triggers.
102 | --
103 | -- When row-level AFTER triggers are cascaded, the innermost trigger
104 | -- runs first. This means we may potentially see an UPDATE or DELETE
105 | -- of a row version that hasn't been added yet.
106 | --
107 | -- We detect this by storing OLD.ctid for every operation. (The ctid
108 | -- is a tuple describing the physical location of the row version. We
109 | -- only need this to be stable for the lifetime of the current
110 | -- transaction.) We then check if there's a previous operation whose
111 | -- OLD ctid equals our NEW ctid; these are then known to be out-of-
112 | -- order. This previous operation's seqid is assigned to `oooseqid`
113 | -- ("out-of-order seqid").
114 | --
115 | -- The order is fixed by shifting the sequence IDs from the current
116 | -- transaction until they're corrected. The current-last operation
117 | -- assumes `nextseqid`, the second-to-last assumes the seqid of the
118 | -- last, and so on until `oooseqid` is unused. We then insert our new
119 | -- operation with `oooseqid`.
120 | --
121 | -- Since we're never modifying `pending_data` rows inserted by other
122 | -- transactions, this shifting should be safe.
123 | SELECT seqid, trgdepth INTO oooseqid, oootrgdepth
124 | FROM dbmirror2.pending_data
125 | WHERE xid = txid_current()
126 | AND tablename = _tablename
127 | AND oldctid = NEW.ctid;
128 |
129 | IF FOUND THEN
130 | IF oootrgdepth IS NOT NULL AND oootrgdepth <= pg_trigger_depth() THEN
131 | -- This should never happen! Cascading triggers are the only
132 | -- known way for operations to arrive out of order. This
133 | -- warning must be investigated if it's ever logged.
134 | RAISE WARNING 'oootrgdepth (%) <= pg_trigger_depth() (%) (% ON %, OLD: %, NEW: %)',
135 | oootrgdepth, pg_trigger_depth(), TG_OP, _tablename, OLD, NEW;
136 | END IF;
137 |
138 | FOR pdrecord IN pdcursor (oooseqid := oooseqid) LOOP
139 | UPDATE dbmirror2.pending_data
140 | SET seqid = nextseqid
141 | WHERE CURRENT OF pdcursor;
142 |
143 | nextseqid := pdrecord.seqid;
144 | END LOOP;
145 |
146 | ASSERT (nextseqid = oooseqid);
147 | END IF;
148 | END IF;
149 |
150 | INSERT INTO dbmirror2.pending_data
151 | (seqid, tablename, op, xid, olddata, newdata, oldctid, trgdepth)
152 | VALUES (
153 | nextseqid,
154 | _tablename,
155 | lower(left(TG_OP, 1)),
156 | txid_current(),
157 | olddata,
158 | newdata,
159 | xoldctid,
160 | pg_trigger_depth()
161 | );
162 |
163 | RETURN NULL;
164 | END;
165 | $$ LANGUAGE plpgsql;
166 |
167 | COMMIT;
168 |
--------------------------------------------------------------------------------
/mbdata/sql/dbmirror2/README:
--------------------------------------------------------------------------------
1 | ReplicationSetup.sql and MasterSetup.sql are copied from
2 | https://github.com/metabrainz/dbmirror2, commit eda9923. (These are the only
3 | two files we need, and submodules are "difficult.")
4 |
5 | This is not a fork; please do not make any changes to the files here without
6 | first submitting them upstream to dbmirror2. They should exactly mirror the
7 | commit mentioned in the first paragraph.
8 |
--------------------------------------------------------------------------------
/mbdata/sql/dbmirror2/RefreshColumnInfo.sql:
--------------------------------------------------------------------------------
1 | \set ON_ERROR_STOP 1
2 |
3 | BEGIN;
4 |
5 | DO $$
6 | BEGIN
7 | PERFORM 1 FROM pg_matviews
8 | WHERE schemaname = 'dbmirror2'
9 | AND matviewname = 'column_info';
10 |
11 | IF FOUND THEN
12 | REFRESH MATERIALIZED VIEW dbmirror2.column_info;
13 | END IF;
14 | END $$;
15 |
16 | COMMIT;
17 |
--------------------------------------------------------------------------------
/mbdata/sql/dbmirror2/ReplicationSetup.sql:
--------------------------------------------------------------------------------
1 | -- Copyright (C) 2021 MetaBrainz Foundation
2 | -- Licensed under the GPL version 2, or (at your option) any later version:
3 | -- http://www.gnu.org/licenses/gpl-2.0.txt
4 |
5 | BEGIN;
6 |
7 | -- The pending_keys tables serves two purposes:
8 | -- 1. Stores the primary keys associated with each table.
9 | -- 2. Allows quickly checking if a particular table has changed
10 | -- in the packet.
11 | CREATE TABLE dbmirror2.pending_keys (
12 | tablename TEXT,
13 | keys TEXT[] NOT NULL
14 | );
15 |
16 | ALTER TABLE dbmirror2.pending_keys
17 | ADD CONSTRAINT pending_keys_pkey
18 | PRIMARY KEY (tablename);
19 |
20 | CREATE TABLE dbmirror2.pending_ts (
21 | xid BIGINT,
22 | ts TIMESTAMP WITH TIME ZONE NOT NULL
23 | );
24 |
25 | ALTER TABLE dbmirror2.pending_ts
26 | ADD CONSTRAINT pending_ts_pkey
27 | PRIMARY KEY (xid);
28 |
29 | CREATE TABLE dbmirror2.pending_data (
30 | seqid BIGSERIAL,
31 | tablename TEXT NOT NULL CONSTRAINT tablename_exists CHECK (to_regclass(tablename) IS NOT NULL),
32 | op "char" NOT NULL CONSTRAINT op_in_diu CHECK (op IN ('d', 'i', 'u')),
33 | xid BIGINT NOT NULL,
34 | -- We use JSON over JSONB because there is no need to perform
35 | -- operations on the data; this additionally lets us store the
36 | -- keys in column-order, which makes the packets much easier
37 | -- to read while debugging.
38 | olddata JSON CONSTRAINT olddata_is_null_for_inserts CHECK ((olddata IS NULL) = (op = 'i')),
39 | newdata JSON CONSTRAINT newdata_is_null_for_deletes CHECK ((newdata IS NULL) = (op = 'd')),
40 | oldctid TID,
41 | trgdepth INTEGER
42 | );
43 |
44 | ALTER TABLE dbmirror2.pending_data
45 | ADD CONSTRAINT pending_data_pkey
46 | PRIMARY KEY (seqid);
47 |
48 | CREATE INDEX pending_data_idx_xid_seqid
49 | ON dbmirror2.pending_data (xid, seqid);
50 |
51 | CREATE INDEX pending_data_idx_oldctid_xid
52 | ON dbmirror2.pending_data (oldctid, xid);
53 |
54 | COMMIT;
55 |
--------------------------------------------------------------------------------
/mbdata/sql/documentation/DropFunctions.sql:
--------------------------------------------------------------------------------
1 | -- Automatically generated, do not edit.
2 | \unset ON_ERROR_STOP
3 |
4 |
--------------------------------------------------------------------------------
/mbdata/sql/documentation/DropIndexes.sql:
--------------------------------------------------------------------------------
1 | -- Automatically generated, do not edit.
2 | \unset ON_ERROR_STOP
3 |
4 |
--------------------------------------------------------------------------------
/mbdata/sql/documentation/DropReplicationTriggers.sql:
--------------------------------------------------------------------------------
1 | -- Automatically generated, do not edit.
2 | \unset ON_ERROR_STOP
3 |
4 | SET search_path = 'documentation';
5 |
6 | DROP TRIGGER IF EXISTS reptg_l_area_area_example ON l_area_area_example;
7 | DROP TRIGGER IF EXISTS reptg_l_area_artist_example ON l_area_artist_example;
8 | DROP TRIGGER IF EXISTS reptg_l_area_event_example ON l_area_event_example;
9 | DROP TRIGGER IF EXISTS reptg_l_area_genre_example ON l_area_genre_example;
10 | DROP TRIGGER IF EXISTS reptg_l_area_instrument_example ON l_area_instrument_example;
11 | DROP TRIGGER IF EXISTS reptg_l_area_label_example ON l_area_label_example;
12 | DROP TRIGGER IF EXISTS reptg_l_area_mood_example ON l_area_mood_example;
13 | DROP TRIGGER IF EXISTS reptg_l_area_place_example ON l_area_place_example;
14 | DROP TRIGGER IF EXISTS reptg_l_area_recording_example ON l_area_recording_example;
15 | DROP TRIGGER IF EXISTS reptg_l_area_release_example ON l_area_release_example;
16 | DROP TRIGGER IF EXISTS reptg_l_area_release_group_example ON l_area_release_group_example;
17 | DROP TRIGGER IF EXISTS reptg_l_area_series_example ON l_area_series_example;
18 | DROP TRIGGER IF EXISTS reptg_l_area_url_example ON l_area_url_example;
19 | DROP TRIGGER IF EXISTS reptg_l_area_work_example ON l_area_work_example;
20 | DROP TRIGGER IF EXISTS reptg_l_artist_artist_example ON l_artist_artist_example;
21 | DROP TRIGGER IF EXISTS reptg_l_artist_event_example ON l_artist_event_example;
22 | DROP TRIGGER IF EXISTS reptg_l_artist_genre_example ON l_artist_genre_example;
23 | DROP TRIGGER IF EXISTS reptg_l_artist_instrument_example ON l_artist_instrument_example;
24 | DROP TRIGGER IF EXISTS reptg_l_artist_label_example ON l_artist_label_example;
25 | DROP TRIGGER IF EXISTS reptg_l_artist_mood_example ON l_artist_mood_example;
26 | DROP TRIGGER IF EXISTS reptg_l_artist_place_example ON l_artist_place_example;
27 | DROP TRIGGER IF EXISTS reptg_l_artist_recording_example ON l_artist_recording_example;
28 | DROP TRIGGER IF EXISTS reptg_l_artist_release_example ON l_artist_release_example;
29 | DROP TRIGGER IF EXISTS reptg_l_artist_release_group_example ON l_artist_release_group_example;
30 | DROP TRIGGER IF EXISTS reptg_l_artist_series_example ON l_artist_series_example;
31 | DROP TRIGGER IF EXISTS reptg_l_artist_url_example ON l_artist_url_example;
32 | DROP TRIGGER IF EXISTS reptg_l_artist_work_example ON l_artist_work_example;
33 | DROP TRIGGER IF EXISTS reptg_l_event_event_example ON l_event_event_example;
34 | DROP TRIGGER IF EXISTS reptg_l_event_genre_example ON l_event_genre_example;
35 | DROP TRIGGER IF EXISTS reptg_l_event_instrument_example ON l_event_instrument_example;
36 | DROP TRIGGER IF EXISTS reptg_l_event_label_example ON l_event_label_example;
37 | DROP TRIGGER IF EXISTS reptg_l_event_mood_example ON l_event_mood_example;
38 | DROP TRIGGER IF EXISTS reptg_l_event_place_example ON l_event_place_example;
39 | DROP TRIGGER IF EXISTS reptg_l_event_recording_example ON l_event_recording_example;
40 | DROP TRIGGER IF EXISTS reptg_l_event_release_example ON l_event_release_example;
41 | DROP TRIGGER IF EXISTS reptg_l_event_release_group_example ON l_event_release_group_example;
42 | DROP TRIGGER IF EXISTS reptg_l_event_series_example ON l_event_series_example;
43 | DROP TRIGGER IF EXISTS reptg_l_event_url_example ON l_event_url_example;
44 | DROP TRIGGER IF EXISTS reptg_l_event_work_example ON l_event_work_example;
45 | DROP TRIGGER IF EXISTS reptg_l_genre_genre_example ON l_genre_genre_example;
46 | DROP TRIGGER IF EXISTS reptg_l_genre_instrument_example ON l_genre_instrument_example;
47 | DROP TRIGGER IF EXISTS reptg_l_genre_label_example ON l_genre_label_example;
48 | DROP TRIGGER IF EXISTS reptg_l_genre_mood_example ON l_genre_mood_example;
49 | DROP TRIGGER IF EXISTS reptg_l_genre_place_example ON l_genre_place_example;
50 | DROP TRIGGER IF EXISTS reptg_l_genre_recording_example ON l_genre_recording_example;
51 | DROP TRIGGER IF EXISTS reptg_l_genre_release_example ON l_genre_release_example;
52 | DROP TRIGGER IF EXISTS reptg_l_genre_release_group_example ON l_genre_release_group_example;
53 | DROP TRIGGER IF EXISTS reptg_l_genre_series_example ON l_genre_series_example;
54 | DROP TRIGGER IF EXISTS reptg_l_genre_url_example ON l_genre_url_example;
55 | DROP TRIGGER IF EXISTS reptg_l_genre_work_example ON l_genre_work_example;
56 | DROP TRIGGER IF EXISTS reptg_l_instrument_instrument_example ON l_instrument_instrument_example;
57 | DROP TRIGGER IF EXISTS reptg_l_instrument_label_example ON l_instrument_label_example;
58 | DROP TRIGGER IF EXISTS reptg_l_instrument_mood_example ON l_instrument_mood_example;
59 | DROP TRIGGER IF EXISTS reptg_l_instrument_place_example ON l_instrument_place_example;
60 | DROP TRIGGER IF EXISTS reptg_l_instrument_recording_example ON l_instrument_recording_example;
61 | DROP TRIGGER IF EXISTS reptg_l_instrument_release_example ON l_instrument_release_example;
62 | DROP TRIGGER IF EXISTS reptg_l_instrument_release_group_example ON l_instrument_release_group_example;
63 | DROP TRIGGER IF EXISTS reptg_l_instrument_series_example ON l_instrument_series_example;
64 | DROP TRIGGER IF EXISTS reptg_l_instrument_url_example ON l_instrument_url_example;
65 | DROP TRIGGER IF EXISTS reptg_l_instrument_work_example ON l_instrument_work_example;
66 | DROP TRIGGER IF EXISTS reptg_l_label_label_example ON l_label_label_example;
67 | DROP TRIGGER IF EXISTS reptg_l_label_mood_example ON l_label_mood_example;
68 | DROP TRIGGER IF EXISTS reptg_l_label_place_example ON l_label_place_example;
69 | DROP TRIGGER IF EXISTS reptg_l_label_recording_example ON l_label_recording_example;
70 | DROP TRIGGER IF EXISTS reptg_l_label_release_example ON l_label_release_example;
71 | DROP TRIGGER IF EXISTS reptg_l_label_release_group_example ON l_label_release_group_example;
72 | DROP TRIGGER IF EXISTS reptg_l_label_series_example ON l_label_series_example;
73 | DROP TRIGGER IF EXISTS reptg_l_label_url_example ON l_label_url_example;
74 | DROP TRIGGER IF EXISTS reptg_l_label_work_example ON l_label_work_example;
75 | DROP TRIGGER IF EXISTS reptg_l_mood_mood_example ON l_mood_mood_example;
76 | DROP TRIGGER IF EXISTS reptg_l_mood_place_example ON l_mood_place_example;
77 | DROP TRIGGER IF EXISTS reptg_l_mood_recording_example ON l_mood_recording_example;
78 | DROP TRIGGER IF EXISTS reptg_l_mood_release_example ON l_mood_release_example;
79 | DROP TRIGGER IF EXISTS reptg_l_mood_release_group_example ON l_mood_release_group_example;
80 | DROP TRIGGER IF EXISTS reptg_l_mood_series_example ON l_mood_series_example;
81 | DROP TRIGGER IF EXISTS reptg_l_mood_url_example ON l_mood_url_example;
82 | DROP TRIGGER IF EXISTS reptg_l_mood_work_example ON l_mood_work_example;
83 | DROP TRIGGER IF EXISTS reptg_l_place_place_example ON l_place_place_example;
84 | DROP TRIGGER IF EXISTS reptg_l_place_recording_example ON l_place_recording_example;
85 | DROP TRIGGER IF EXISTS reptg_l_place_release_example ON l_place_release_example;
86 | DROP TRIGGER IF EXISTS reptg_l_place_release_group_example ON l_place_release_group_example;
87 | DROP TRIGGER IF EXISTS reptg_l_place_series_example ON l_place_series_example;
88 | DROP TRIGGER IF EXISTS reptg_l_place_url_example ON l_place_url_example;
89 | DROP TRIGGER IF EXISTS reptg_l_place_work_example ON l_place_work_example;
90 | DROP TRIGGER IF EXISTS reptg_l_recording_recording_example ON l_recording_recording_example;
91 | DROP TRIGGER IF EXISTS reptg_l_recording_release_example ON l_recording_release_example;
92 | DROP TRIGGER IF EXISTS reptg_l_recording_release_group_example ON l_recording_release_group_example;
93 | DROP TRIGGER IF EXISTS reptg_l_recording_series_example ON l_recording_series_example;
94 | DROP TRIGGER IF EXISTS reptg_l_recording_url_example ON l_recording_url_example;
95 | DROP TRIGGER IF EXISTS reptg_l_recording_work_example ON l_recording_work_example;
96 | DROP TRIGGER IF EXISTS reptg_l_release_group_release_group_example ON l_release_group_release_group_example;
97 | DROP TRIGGER IF EXISTS reptg_l_release_group_series_example ON l_release_group_series_example;
98 | DROP TRIGGER IF EXISTS reptg_l_release_group_url_example ON l_release_group_url_example;
99 | DROP TRIGGER IF EXISTS reptg_l_release_group_work_example ON l_release_group_work_example;
100 | DROP TRIGGER IF EXISTS reptg_l_release_release_example ON l_release_release_example;
101 | DROP TRIGGER IF EXISTS reptg_l_release_release_group_example ON l_release_release_group_example;
102 | DROP TRIGGER IF EXISTS reptg_l_release_series_example ON l_release_series_example;
103 | DROP TRIGGER IF EXISTS reptg_l_release_url_example ON l_release_url_example;
104 | DROP TRIGGER IF EXISTS reptg_l_release_work_example ON l_release_work_example;
105 | DROP TRIGGER IF EXISTS reptg_l_series_series_example ON l_series_series_example;
106 | DROP TRIGGER IF EXISTS reptg_l_series_url_example ON l_series_url_example;
107 | DROP TRIGGER IF EXISTS reptg_l_series_work_example ON l_series_work_example;
108 | DROP TRIGGER IF EXISTS reptg_l_url_url_example ON l_url_url_example;
109 | DROP TRIGGER IF EXISTS reptg_l_url_work_example ON l_url_work_example;
110 | DROP TRIGGER IF EXISTS reptg_l_work_work_example ON l_work_work_example;
111 | DROP TRIGGER IF EXISTS reptg_link_type_documentation ON link_type_documentation;
112 |
--------------------------------------------------------------------------------
/mbdata/sql/documentation/DropReplicationTriggers2.sql:
--------------------------------------------------------------------------------
1 | -- Automatically generated, do not edit.
2 | \unset ON_ERROR_STOP
3 |
4 | SET search_path = 'documentation';
5 |
6 | DROP TRIGGER IF EXISTS reptg2_l_area_area_example ON l_area_area_example;
7 | DROP TRIGGER IF EXISTS reptg2_l_area_artist_example ON l_area_artist_example;
8 | DROP TRIGGER IF EXISTS reptg2_l_area_event_example ON l_area_event_example;
9 | DROP TRIGGER IF EXISTS reptg2_l_area_genre_example ON l_area_genre_example;
10 | DROP TRIGGER IF EXISTS reptg2_l_area_instrument_example ON l_area_instrument_example;
11 | DROP TRIGGER IF EXISTS reptg2_l_area_label_example ON l_area_label_example;
12 | DROP TRIGGER IF EXISTS reptg2_l_area_mood_example ON l_area_mood_example;
13 | DROP TRIGGER IF EXISTS reptg2_l_area_place_example ON l_area_place_example;
14 | DROP TRIGGER IF EXISTS reptg2_l_area_recording_example ON l_area_recording_example;
15 | DROP TRIGGER IF EXISTS reptg2_l_area_release_example ON l_area_release_example;
16 | DROP TRIGGER IF EXISTS reptg2_l_area_release_group_example ON l_area_release_group_example;
17 | DROP TRIGGER IF EXISTS reptg2_l_area_series_example ON l_area_series_example;
18 | DROP TRIGGER IF EXISTS reptg2_l_area_url_example ON l_area_url_example;
19 | DROP TRIGGER IF EXISTS reptg2_l_area_work_example ON l_area_work_example;
20 | DROP TRIGGER IF EXISTS reptg2_l_artist_artist_example ON l_artist_artist_example;
21 | DROP TRIGGER IF EXISTS reptg2_l_artist_event_example ON l_artist_event_example;
22 | DROP TRIGGER IF EXISTS reptg2_l_artist_genre_example ON l_artist_genre_example;
23 | DROP TRIGGER IF EXISTS reptg2_l_artist_instrument_example ON l_artist_instrument_example;
24 | DROP TRIGGER IF EXISTS reptg2_l_artist_label_example ON l_artist_label_example;
25 | DROP TRIGGER IF EXISTS reptg2_l_artist_mood_example ON l_artist_mood_example;
26 | DROP TRIGGER IF EXISTS reptg2_l_artist_place_example ON l_artist_place_example;
27 | DROP TRIGGER IF EXISTS reptg2_l_artist_recording_example ON l_artist_recording_example;
28 | DROP TRIGGER IF EXISTS reptg2_l_artist_release_example ON l_artist_release_example;
29 | DROP TRIGGER IF EXISTS reptg2_l_artist_release_group_example ON l_artist_release_group_example;
30 | DROP TRIGGER IF EXISTS reptg2_l_artist_series_example ON l_artist_series_example;
31 | DROP TRIGGER IF EXISTS reptg2_l_artist_url_example ON l_artist_url_example;
32 | DROP TRIGGER IF EXISTS reptg2_l_artist_work_example ON l_artist_work_example;
33 | DROP TRIGGER IF EXISTS reptg2_l_event_event_example ON l_event_event_example;
34 | DROP TRIGGER IF EXISTS reptg2_l_event_genre_example ON l_event_genre_example;
35 | DROP TRIGGER IF EXISTS reptg2_l_event_instrument_example ON l_event_instrument_example;
36 | DROP TRIGGER IF EXISTS reptg2_l_event_label_example ON l_event_label_example;
37 | DROP TRIGGER IF EXISTS reptg2_l_event_mood_example ON l_event_mood_example;
38 | DROP TRIGGER IF EXISTS reptg2_l_event_place_example ON l_event_place_example;
39 | DROP TRIGGER IF EXISTS reptg2_l_event_recording_example ON l_event_recording_example;
40 | DROP TRIGGER IF EXISTS reptg2_l_event_release_example ON l_event_release_example;
41 | DROP TRIGGER IF EXISTS reptg2_l_event_release_group_example ON l_event_release_group_example;
42 | DROP TRIGGER IF EXISTS reptg2_l_event_series_example ON l_event_series_example;
43 | DROP TRIGGER IF EXISTS reptg2_l_event_url_example ON l_event_url_example;
44 | DROP TRIGGER IF EXISTS reptg2_l_event_work_example ON l_event_work_example;
45 | DROP TRIGGER IF EXISTS reptg2_l_genre_genre_example ON l_genre_genre_example;
46 | DROP TRIGGER IF EXISTS reptg2_l_genre_instrument_example ON l_genre_instrument_example;
47 | DROP TRIGGER IF EXISTS reptg2_l_genre_label_example ON l_genre_label_example;
48 | DROP TRIGGER IF EXISTS reptg2_l_genre_mood_example ON l_genre_mood_example;
49 | DROP TRIGGER IF EXISTS reptg2_l_genre_place_example ON l_genre_place_example;
50 | DROP TRIGGER IF EXISTS reptg2_l_genre_recording_example ON l_genre_recording_example;
51 | DROP TRIGGER IF EXISTS reptg2_l_genre_release_example ON l_genre_release_example;
52 | DROP TRIGGER IF EXISTS reptg2_l_genre_release_group_example ON l_genre_release_group_example;
53 | DROP TRIGGER IF EXISTS reptg2_l_genre_series_example ON l_genre_series_example;
54 | DROP TRIGGER IF EXISTS reptg2_l_genre_url_example ON l_genre_url_example;
55 | DROP TRIGGER IF EXISTS reptg2_l_genre_work_example ON l_genre_work_example;
56 | DROP TRIGGER IF EXISTS reptg2_l_instrument_instrument_example ON l_instrument_instrument_example;
57 | DROP TRIGGER IF EXISTS reptg2_l_instrument_label_example ON l_instrument_label_example;
58 | DROP TRIGGER IF EXISTS reptg2_l_instrument_mood_example ON l_instrument_mood_example;
59 | DROP TRIGGER IF EXISTS reptg2_l_instrument_place_example ON l_instrument_place_example;
60 | DROP TRIGGER IF EXISTS reptg2_l_instrument_recording_example ON l_instrument_recording_example;
61 | DROP TRIGGER IF EXISTS reptg2_l_instrument_release_example ON l_instrument_release_example;
62 | DROP TRIGGER IF EXISTS reptg2_l_instrument_release_group_example ON l_instrument_release_group_example;
63 | DROP TRIGGER IF EXISTS reptg2_l_instrument_series_example ON l_instrument_series_example;
64 | DROP TRIGGER IF EXISTS reptg2_l_instrument_url_example ON l_instrument_url_example;
65 | DROP TRIGGER IF EXISTS reptg2_l_instrument_work_example ON l_instrument_work_example;
66 | DROP TRIGGER IF EXISTS reptg2_l_label_label_example ON l_label_label_example;
67 | DROP TRIGGER IF EXISTS reptg2_l_label_mood_example ON l_label_mood_example;
68 | DROP TRIGGER IF EXISTS reptg2_l_label_place_example ON l_label_place_example;
69 | DROP TRIGGER IF EXISTS reptg2_l_label_recording_example ON l_label_recording_example;
70 | DROP TRIGGER IF EXISTS reptg2_l_label_release_example ON l_label_release_example;
71 | DROP TRIGGER IF EXISTS reptg2_l_label_release_group_example ON l_label_release_group_example;
72 | DROP TRIGGER IF EXISTS reptg2_l_label_series_example ON l_label_series_example;
73 | DROP TRIGGER IF EXISTS reptg2_l_label_url_example ON l_label_url_example;
74 | DROP TRIGGER IF EXISTS reptg2_l_label_work_example ON l_label_work_example;
75 | DROP TRIGGER IF EXISTS reptg2_l_mood_mood_example ON l_mood_mood_example;
76 | DROP TRIGGER IF EXISTS reptg2_l_mood_place_example ON l_mood_place_example;
77 | DROP TRIGGER IF EXISTS reptg2_l_mood_recording_example ON l_mood_recording_example;
78 | DROP TRIGGER IF EXISTS reptg2_l_mood_release_example ON l_mood_release_example;
79 | DROP TRIGGER IF EXISTS reptg2_l_mood_release_group_example ON l_mood_release_group_example;
80 | DROP TRIGGER IF EXISTS reptg2_l_mood_series_example ON l_mood_series_example;
81 | DROP TRIGGER IF EXISTS reptg2_l_mood_url_example ON l_mood_url_example;
82 | DROP TRIGGER IF EXISTS reptg2_l_mood_work_example ON l_mood_work_example;
83 | DROP TRIGGER IF EXISTS reptg2_l_place_place_example ON l_place_place_example;
84 | DROP TRIGGER IF EXISTS reptg2_l_place_recording_example ON l_place_recording_example;
85 | DROP TRIGGER IF EXISTS reptg2_l_place_release_example ON l_place_release_example;
86 | DROP TRIGGER IF EXISTS reptg2_l_place_release_group_example ON l_place_release_group_example;
87 | DROP TRIGGER IF EXISTS reptg2_l_place_series_example ON l_place_series_example;
88 | DROP TRIGGER IF EXISTS reptg2_l_place_url_example ON l_place_url_example;
89 | DROP TRIGGER IF EXISTS reptg2_l_place_work_example ON l_place_work_example;
90 | DROP TRIGGER IF EXISTS reptg2_l_recording_recording_example ON l_recording_recording_example;
91 | DROP TRIGGER IF EXISTS reptg2_l_recording_release_example ON l_recording_release_example;
92 | DROP TRIGGER IF EXISTS reptg2_l_recording_release_group_example ON l_recording_release_group_example;
93 | DROP TRIGGER IF EXISTS reptg2_l_recording_series_example ON l_recording_series_example;
94 | DROP TRIGGER IF EXISTS reptg2_l_recording_url_example ON l_recording_url_example;
95 | DROP TRIGGER IF EXISTS reptg2_l_recording_work_example ON l_recording_work_example;
96 | DROP TRIGGER IF EXISTS reptg2_l_release_group_release_group_example ON l_release_group_release_group_example;
97 | DROP TRIGGER IF EXISTS reptg2_l_release_group_series_example ON l_release_group_series_example;
98 | DROP TRIGGER IF EXISTS reptg2_l_release_group_url_example ON l_release_group_url_example;
99 | DROP TRIGGER IF EXISTS reptg2_l_release_group_work_example ON l_release_group_work_example;
100 | DROP TRIGGER IF EXISTS reptg2_l_release_release_example ON l_release_release_example;
101 | DROP TRIGGER IF EXISTS reptg2_l_release_release_group_example ON l_release_release_group_example;
102 | DROP TRIGGER IF EXISTS reptg2_l_release_series_example ON l_release_series_example;
103 | DROP TRIGGER IF EXISTS reptg2_l_release_url_example ON l_release_url_example;
104 | DROP TRIGGER IF EXISTS reptg2_l_release_work_example ON l_release_work_example;
105 | DROP TRIGGER IF EXISTS reptg2_l_series_series_example ON l_series_series_example;
106 | DROP TRIGGER IF EXISTS reptg2_l_series_url_example ON l_series_url_example;
107 | DROP TRIGGER IF EXISTS reptg2_l_series_work_example ON l_series_work_example;
108 | DROP TRIGGER IF EXISTS reptg2_l_url_url_example ON l_url_url_example;
109 | DROP TRIGGER IF EXISTS reptg2_l_url_work_example ON l_url_work_example;
110 | DROP TRIGGER IF EXISTS reptg2_l_work_work_example ON l_work_work_example;
111 | DROP TRIGGER IF EXISTS reptg2_link_type_documentation ON link_type_documentation;
112 |
--------------------------------------------------------------------------------
/mbdata/sql/documentation/DropSearchIndexes.sql:
--------------------------------------------------------------------------------
1 | -- Automatically generated, do not edit.
2 | \unset ON_ERROR_STOP
3 |
4 |
--------------------------------------------------------------------------------
/mbdata/sql/documentation/DropTables.sql:
--------------------------------------------------------------------------------
1 | -- Automatically generated, do not edit.
2 | \unset ON_ERROR_STOP
3 |
4 | SET search_path = 'documentation';
5 |
6 | DROP TABLE l_area_area_example;
7 | DROP TABLE l_area_artist_example;
8 | DROP TABLE l_area_event_example;
9 | DROP TABLE l_area_genre_example;
10 | DROP TABLE l_area_instrument_example;
11 | DROP TABLE l_area_label_example;
12 | DROP TABLE l_area_mood_example;
13 | DROP TABLE l_area_place_example;
14 | DROP TABLE l_area_recording_example;
15 | DROP TABLE l_area_release_example;
16 | DROP TABLE l_area_release_group_example;
17 | DROP TABLE l_area_series_example;
18 | DROP TABLE l_area_url_example;
19 | DROP TABLE l_area_work_example;
20 | DROP TABLE l_artist_artist_example;
21 | DROP TABLE l_artist_event_example;
22 | DROP TABLE l_artist_genre_example;
23 | DROP TABLE l_artist_instrument_example;
24 | DROP TABLE l_artist_label_example;
25 | DROP TABLE l_artist_mood_example;
26 | DROP TABLE l_artist_place_example;
27 | DROP TABLE l_artist_recording_example;
28 | DROP TABLE l_artist_release_example;
29 | DROP TABLE l_artist_release_group_example;
30 | DROP TABLE l_artist_series_example;
31 | DROP TABLE l_artist_url_example;
32 | DROP TABLE l_artist_work_example;
33 | DROP TABLE l_event_event_example;
34 | DROP TABLE l_event_genre_example;
35 | DROP TABLE l_event_instrument_example;
36 | DROP TABLE l_event_label_example;
37 | DROP TABLE l_event_mood_example;
38 | DROP TABLE l_event_place_example;
39 | DROP TABLE l_event_recording_example;
40 | DROP TABLE l_event_release_example;
41 | DROP TABLE l_event_release_group_example;
42 | DROP TABLE l_event_series_example;
43 | DROP TABLE l_event_url_example;
44 | DROP TABLE l_event_work_example;
45 | DROP TABLE l_genre_genre_example;
46 | DROP TABLE l_genre_instrument_example;
47 | DROP TABLE l_genre_label_example;
48 | DROP TABLE l_genre_mood_example;
49 | DROP TABLE l_genre_place_example;
50 | DROP TABLE l_genre_recording_example;
51 | DROP TABLE l_genre_release_example;
52 | DROP TABLE l_genre_release_group_example;
53 | DROP TABLE l_genre_series_example;
54 | DROP TABLE l_genre_url_example;
55 | DROP TABLE l_genre_work_example;
56 | DROP TABLE l_instrument_instrument_example;
57 | DROP TABLE l_instrument_label_example;
58 | DROP TABLE l_instrument_mood_example;
59 | DROP TABLE l_instrument_place_example;
60 | DROP TABLE l_instrument_recording_example;
61 | DROP TABLE l_instrument_release_example;
62 | DROP TABLE l_instrument_release_group_example;
63 | DROP TABLE l_instrument_series_example;
64 | DROP TABLE l_instrument_url_example;
65 | DROP TABLE l_instrument_work_example;
66 | DROP TABLE l_label_label_example;
67 | DROP TABLE l_label_mood_example;
68 | DROP TABLE l_label_place_example;
69 | DROP TABLE l_label_recording_example;
70 | DROP TABLE l_label_release_example;
71 | DROP TABLE l_label_release_group_example;
72 | DROP TABLE l_label_series_example;
73 | DROP TABLE l_label_url_example;
74 | DROP TABLE l_label_work_example;
75 | DROP TABLE l_mood_mood_example;
76 | DROP TABLE l_mood_place_example;
77 | DROP TABLE l_mood_recording_example;
78 | DROP TABLE l_mood_release_example;
79 | DROP TABLE l_mood_release_group_example;
80 | DROP TABLE l_mood_series_example;
81 | DROP TABLE l_mood_url_example;
82 | DROP TABLE l_mood_work_example;
83 | DROP TABLE l_place_place_example;
84 | DROP TABLE l_place_recording_example;
85 | DROP TABLE l_place_release_example;
86 | DROP TABLE l_place_release_group_example;
87 | DROP TABLE l_place_series_example;
88 | DROP TABLE l_place_url_example;
89 | DROP TABLE l_place_work_example;
90 | DROP TABLE l_recording_recording_example;
91 | DROP TABLE l_recording_release_example;
92 | DROP TABLE l_recording_release_group_example;
93 | DROP TABLE l_recording_series_example;
94 | DROP TABLE l_recording_url_example;
95 | DROP TABLE l_recording_work_example;
96 | DROP TABLE l_release_group_release_group_example;
97 | DROP TABLE l_release_group_series_example;
98 | DROP TABLE l_release_group_url_example;
99 | DROP TABLE l_release_group_work_example;
100 | DROP TABLE l_release_release_example;
101 | DROP TABLE l_release_release_group_example;
102 | DROP TABLE l_release_series_example;
103 | DROP TABLE l_release_url_example;
104 | DROP TABLE l_release_work_example;
105 | DROP TABLE l_series_series_example;
106 | DROP TABLE l_series_url_example;
107 | DROP TABLE l_series_work_example;
108 | DROP TABLE l_url_url_example;
109 | DROP TABLE l_url_work_example;
110 | DROP TABLE l_work_work_example;
111 | DROP TABLE link_type_documentation;
112 |
--------------------------------------------------------------------------------
/mbdata/sql/documentation/DropTriggers.sql:
--------------------------------------------------------------------------------
1 | -- Automatically generated, do not edit.
2 | \unset ON_ERROR_STOP
3 |
4 |
--------------------------------------------------------------------------------
/mbdata/sql/documentation/DropViews.sql:
--------------------------------------------------------------------------------
1 | -- Automatically generated, do not edit.
2 | \unset ON_ERROR_STOP
3 |
4 |
--------------------------------------------------------------------------------
/mbdata/sql/documentation/SetSequences.sql:
--------------------------------------------------------------------------------
1 | -- Automatically generated, do not edit.
2 | \unset ON_ERROR_STOP
3 |
4 |
--------------------------------------------------------------------------------
/mbdata/sql/documentation/TruncateTables.sql:
--------------------------------------------------------------------------------
1 | -- Automatically generated, do not edit.
2 | \set ON_ERROR_STOP 1
3 |
4 | SET search_path = 'documentation';
5 |
6 | TRUNCATE TABLE l_area_area_example RESTART IDENTITY CASCADE;
7 | TRUNCATE TABLE l_area_artist_example RESTART IDENTITY CASCADE;
8 | TRUNCATE TABLE l_area_event_example RESTART IDENTITY CASCADE;
9 | TRUNCATE TABLE l_area_genre_example RESTART IDENTITY CASCADE;
10 | TRUNCATE TABLE l_area_instrument_example RESTART IDENTITY CASCADE;
11 | TRUNCATE TABLE l_area_label_example RESTART IDENTITY CASCADE;
12 | TRUNCATE TABLE l_area_mood_example RESTART IDENTITY CASCADE;
13 | TRUNCATE TABLE l_area_place_example RESTART IDENTITY CASCADE;
14 | TRUNCATE TABLE l_area_recording_example RESTART IDENTITY CASCADE;
15 | TRUNCATE TABLE l_area_release_example RESTART IDENTITY CASCADE;
16 | TRUNCATE TABLE l_area_release_group_example RESTART IDENTITY CASCADE;
17 | TRUNCATE TABLE l_area_series_example RESTART IDENTITY CASCADE;
18 | TRUNCATE TABLE l_area_url_example RESTART IDENTITY CASCADE;
19 | TRUNCATE TABLE l_area_work_example RESTART IDENTITY CASCADE;
20 | TRUNCATE TABLE l_artist_artist_example RESTART IDENTITY CASCADE;
21 | TRUNCATE TABLE l_artist_event_example RESTART IDENTITY CASCADE;
22 | TRUNCATE TABLE l_artist_genre_example RESTART IDENTITY CASCADE;
23 | TRUNCATE TABLE l_artist_instrument_example RESTART IDENTITY CASCADE;
24 | TRUNCATE TABLE l_artist_label_example RESTART IDENTITY CASCADE;
25 | TRUNCATE TABLE l_artist_mood_example RESTART IDENTITY CASCADE;
26 | TRUNCATE TABLE l_artist_place_example RESTART IDENTITY CASCADE;
27 | TRUNCATE TABLE l_artist_recording_example RESTART IDENTITY CASCADE;
28 | TRUNCATE TABLE l_artist_release_example RESTART IDENTITY CASCADE;
29 | TRUNCATE TABLE l_artist_release_group_example RESTART IDENTITY CASCADE;
30 | TRUNCATE TABLE l_artist_series_example RESTART IDENTITY CASCADE;
31 | TRUNCATE TABLE l_artist_url_example RESTART IDENTITY CASCADE;
32 | TRUNCATE TABLE l_artist_work_example RESTART IDENTITY CASCADE;
33 | TRUNCATE TABLE l_event_event_example RESTART IDENTITY CASCADE;
34 | TRUNCATE TABLE l_event_genre_example RESTART IDENTITY CASCADE;
35 | TRUNCATE TABLE l_event_instrument_example RESTART IDENTITY CASCADE;
36 | TRUNCATE TABLE l_event_label_example RESTART IDENTITY CASCADE;
37 | TRUNCATE TABLE l_event_mood_example RESTART IDENTITY CASCADE;
38 | TRUNCATE TABLE l_event_place_example RESTART IDENTITY CASCADE;
39 | TRUNCATE TABLE l_event_recording_example RESTART IDENTITY CASCADE;
40 | TRUNCATE TABLE l_event_release_example RESTART IDENTITY CASCADE;
41 | TRUNCATE TABLE l_event_release_group_example RESTART IDENTITY CASCADE;
42 | TRUNCATE TABLE l_event_series_example RESTART IDENTITY CASCADE;
43 | TRUNCATE TABLE l_event_url_example RESTART IDENTITY CASCADE;
44 | TRUNCATE TABLE l_event_work_example RESTART IDENTITY CASCADE;
45 | TRUNCATE TABLE l_genre_genre_example RESTART IDENTITY CASCADE;
46 | TRUNCATE TABLE l_genre_instrument_example RESTART IDENTITY CASCADE;
47 | TRUNCATE TABLE l_genre_label_example RESTART IDENTITY CASCADE;
48 | TRUNCATE TABLE l_genre_mood_example RESTART IDENTITY CASCADE;
49 | TRUNCATE TABLE l_genre_place_example RESTART IDENTITY CASCADE;
50 | TRUNCATE TABLE l_genre_recording_example RESTART IDENTITY CASCADE;
51 | TRUNCATE TABLE l_genre_release_example RESTART IDENTITY CASCADE;
52 | TRUNCATE TABLE l_genre_release_group_example RESTART IDENTITY CASCADE;
53 | TRUNCATE TABLE l_genre_series_example RESTART IDENTITY CASCADE;
54 | TRUNCATE TABLE l_genre_url_example RESTART IDENTITY CASCADE;
55 | TRUNCATE TABLE l_genre_work_example RESTART IDENTITY CASCADE;
56 | TRUNCATE TABLE l_instrument_instrument_example RESTART IDENTITY CASCADE;
57 | TRUNCATE TABLE l_instrument_label_example RESTART IDENTITY CASCADE;
58 | TRUNCATE TABLE l_instrument_mood_example RESTART IDENTITY CASCADE;
59 | TRUNCATE TABLE l_instrument_place_example RESTART IDENTITY CASCADE;
60 | TRUNCATE TABLE l_instrument_recording_example RESTART IDENTITY CASCADE;
61 | TRUNCATE TABLE l_instrument_release_example RESTART IDENTITY CASCADE;
62 | TRUNCATE TABLE l_instrument_release_group_example RESTART IDENTITY CASCADE;
63 | TRUNCATE TABLE l_instrument_series_example RESTART IDENTITY CASCADE;
64 | TRUNCATE TABLE l_instrument_url_example RESTART IDENTITY CASCADE;
65 | TRUNCATE TABLE l_instrument_work_example RESTART IDENTITY CASCADE;
66 | TRUNCATE TABLE l_label_label_example RESTART IDENTITY CASCADE;
67 | TRUNCATE TABLE l_label_mood_example RESTART IDENTITY CASCADE;
68 | TRUNCATE TABLE l_label_place_example RESTART IDENTITY CASCADE;
69 | TRUNCATE TABLE l_label_recording_example RESTART IDENTITY CASCADE;
70 | TRUNCATE TABLE l_label_release_example RESTART IDENTITY CASCADE;
71 | TRUNCATE TABLE l_label_release_group_example RESTART IDENTITY CASCADE;
72 | TRUNCATE TABLE l_label_series_example RESTART IDENTITY CASCADE;
73 | TRUNCATE TABLE l_label_url_example RESTART IDENTITY CASCADE;
74 | TRUNCATE TABLE l_label_work_example RESTART IDENTITY CASCADE;
75 | TRUNCATE TABLE l_mood_mood_example RESTART IDENTITY CASCADE;
76 | TRUNCATE TABLE l_mood_place_example RESTART IDENTITY CASCADE;
77 | TRUNCATE TABLE l_mood_recording_example RESTART IDENTITY CASCADE;
78 | TRUNCATE TABLE l_mood_release_example RESTART IDENTITY CASCADE;
79 | TRUNCATE TABLE l_mood_release_group_example RESTART IDENTITY CASCADE;
80 | TRUNCATE TABLE l_mood_series_example RESTART IDENTITY CASCADE;
81 | TRUNCATE TABLE l_mood_url_example RESTART IDENTITY CASCADE;
82 | TRUNCATE TABLE l_mood_work_example RESTART IDENTITY CASCADE;
83 | TRUNCATE TABLE l_place_place_example RESTART IDENTITY CASCADE;
84 | TRUNCATE TABLE l_place_recording_example RESTART IDENTITY CASCADE;
85 | TRUNCATE TABLE l_place_release_example RESTART IDENTITY CASCADE;
86 | TRUNCATE TABLE l_place_release_group_example RESTART IDENTITY CASCADE;
87 | TRUNCATE TABLE l_place_series_example RESTART IDENTITY CASCADE;
88 | TRUNCATE TABLE l_place_url_example RESTART IDENTITY CASCADE;
89 | TRUNCATE TABLE l_place_work_example RESTART IDENTITY CASCADE;
90 | TRUNCATE TABLE l_recording_recording_example RESTART IDENTITY CASCADE;
91 | TRUNCATE TABLE l_recording_release_example RESTART IDENTITY CASCADE;
92 | TRUNCATE TABLE l_recording_release_group_example RESTART IDENTITY CASCADE;
93 | TRUNCATE TABLE l_recording_series_example RESTART IDENTITY CASCADE;
94 | TRUNCATE TABLE l_recording_url_example RESTART IDENTITY CASCADE;
95 | TRUNCATE TABLE l_recording_work_example RESTART IDENTITY CASCADE;
96 | TRUNCATE TABLE l_release_group_release_group_example RESTART IDENTITY CASCADE;
97 | TRUNCATE TABLE l_release_group_series_example RESTART IDENTITY CASCADE;
98 | TRUNCATE TABLE l_release_group_url_example RESTART IDENTITY CASCADE;
99 | TRUNCATE TABLE l_release_group_work_example RESTART IDENTITY CASCADE;
100 | TRUNCATE TABLE l_release_release_example RESTART IDENTITY CASCADE;
101 | TRUNCATE TABLE l_release_release_group_example RESTART IDENTITY CASCADE;
102 | TRUNCATE TABLE l_release_series_example RESTART IDENTITY CASCADE;
103 | TRUNCATE TABLE l_release_url_example RESTART IDENTITY CASCADE;
104 | TRUNCATE TABLE l_release_work_example RESTART IDENTITY CASCADE;
105 | TRUNCATE TABLE l_series_series_example RESTART IDENTITY CASCADE;
106 | TRUNCATE TABLE l_series_url_example RESTART IDENTITY CASCADE;
107 | TRUNCATE TABLE l_series_work_example RESTART IDENTITY CASCADE;
108 | TRUNCATE TABLE l_url_url_example RESTART IDENTITY CASCADE;
109 | TRUNCATE TABLE l_url_work_example RESTART IDENTITY CASCADE;
110 | TRUNCATE TABLE l_work_work_example RESTART IDENTITY CASCADE;
111 | TRUNCATE TABLE link_type_documentation RESTART IDENTITY CASCADE;
112 |
--------------------------------------------------------------------------------
/mbdata/sql/eaa/CreateEditFKConstraints.sql:
--------------------------------------------------------------------------------
1 | \set ON_ERROR_STOP 1
2 |
3 | SET search_path = 'event_art_archive';
4 |
5 | ALTER TABLE event_art
6 | ADD CONSTRAINT event_art_fk_edit
7 | FOREIGN KEY (edit)
8 | REFERENCES musicbrainz.edit(id);
9 |
--------------------------------------------------------------------------------
/mbdata/sql/eaa/CreateFKConstraints.sql:
--------------------------------------------------------------------------------
1 | -- Automatically generated, do not edit.
2 | \set ON_ERROR_STOP 1
3 |
4 | SET search_path = 'event_art_archive';
5 |
6 | ALTER TABLE art_type
7 | ADD CONSTRAINT art_type_fk_parent
8 | FOREIGN KEY (parent)
9 | REFERENCES event_art_archive.art_type(id);
10 |
11 | ALTER TABLE event_art
12 | ADD CONSTRAINT event_art_fk_event
13 | FOREIGN KEY (event)
14 | REFERENCES musicbrainz.event(id)
15 | ON DELETE CASCADE;
16 |
17 | ALTER TABLE event_art
18 | ADD CONSTRAINT event_art_fk_mime_type
19 | FOREIGN KEY (mime_type)
20 | REFERENCES cover_art_archive.image_type(mime_type);
21 |
22 | ALTER TABLE event_art_type
23 | ADD CONSTRAINT event_art_type_fk_id
24 | FOREIGN KEY (id)
25 | REFERENCES event_art_archive.event_art(id)
26 | ON DELETE CASCADE;
27 |
28 | ALTER TABLE event_art_type
29 | ADD CONSTRAINT event_art_type_fk_type_id
30 | FOREIGN KEY (type_id)
31 | REFERENCES event_art_archive.art_type(id);
32 |
33 |
--------------------------------------------------------------------------------
/mbdata/sql/eaa/CreateFunctions.sql:
--------------------------------------------------------------------------------
1 | BEGIN;
2 |
3 | SET search_path = 'event_art_archive';
4 |
5 | CREATE OR REPLACE FUNCTION materialize_eaa_presence() RETURNS trigger AS $$
6 | BEGIN
7 | -- On delete, set the presence flag to 'absent' if there's no more
8 | -- event art
9 | IF TG_OP = 'DELETE' THEN
10 | IF NOT EXISTS (
11 | SELECT TRUE FROM event_art_archive.event_art
12 | WHERE event = OLD.event
13 | ) THEN
14 | UPDATE musicbrainz.event_meta
15 | SET event_art_presence = 'absent'
16 | WHERE id = OLD.event;
17 | END IF;
18 | END IF;
19 |
20 | -- On insert, set the presence flag to 'present' if it was previously
21 | -- 'absent'
22 | IF TG_OP = 'INSERT' THEN
23 | CASE (
24 | SELECT event_art_presence FROM musicbrainz.event_meta
25 | WHERE id = NEW.event
26 | )
27 | WHEN 'absent' THEN
28 | UPDATE musicbrainz.event_meta
29 | SET event_art_presence = 'present'
30 | WHERE id = NEW.event;
31 | WHEN 'darkened' THEN
32 | RAISE EXCEPTION 'This event has been darkened and cannot have new event art';
33 | ELSE
34 | END CASE;
35 | END IF;
36 |
37 | RETURN NULL;
38 | END;
39 | $$ LANGUAGE 'plpgsql';
40 |
41 | CREATE OR REPLACE FUNCTION resequence_positions(event_id INT) RETURNS void AS $$
42 | BEGIN
43 | UPDATE event_art_archive.event_art
44 | SET ordering = recalculated.row_number
45 | FROM (
46 | SELECT *,
47 | row_number() OVER (PARTITION BY event ORDER BY ordering ASC)
48 | FROM event_art_archive.event_art
49 | WHERE event_art.event = event_id
50 | ) recalculated
51 | WHERE recalculated.id = event_art.id AND
52 | recalculated.row_number != event_art.ordering;
53 | END;
54 | $$ LANGUAGE 'plpgsql';
55 |
56 | CREATE OR REPLACE FUNCTION resequence_event_art_trigger() RETURNS trigger AS $$
57 | BEGIN
58 | IF TG_OP = 'INSERT' OR TG_OP = 'UPDATE' THEN
59 | PERFORM event_art_archive.resequence_positions(NEW.event);
60 | END IF;
61 |
62 | IF (TG_OP = 'DELETE') OR
63 | (TG_OP = 'UPDATE' AND NEW.event != OLD.event)
64 | THEN
65 | PERFORM event_art_archive.resequence_positions(OLD.event);
66 | END IF;
67 |
68 | RETURN NULL;
69 | END;
70 | $$ LANGUAGE 'plpgsql';
71 |
72 | COMMIT;
73 |
--------------------------------------------------------------------------------
/mbdata/sql/eaa/CreateIndexes.sql:
--------------------------------------------------------------------------------
1 | \set ON_ERROR_STOP 1
2 |
3 | BEGIN;
4 |
5 | SET search_path = 'event_art_archive';
6 |
7 | CREATE INDEX event_art_idx_event ON event_art (event);
8 | CREATE UNIQUE INDEX art_type_idx_gid ON art_type (gid);
9 |
10 | COMMIT;
11 |
--------------------------------------------------------------------------------
/mbdata/sql/eaa/CreatePrimaryKeys.sql:
--------------------------------------------------------------------------------
1 | -- Automatically generated, do not edit.
2 | \set ON_ERROR_STOP 1
3 |
4 | SET search_path = 'event_art_archive';
5 |
6 | ALTER TABLE art_type ADD CONSTRAINT art_type_pkey PRIMARY KEY (id);
7 | ALTER TABLE event_art ADD CONSTRAINT event_art_pkey PRIMARY KEY (id);
8 | ALTER TABLE event_art_type ADD CONSTRAINT event_art_type_pkey PRIMARY KEY (id, type_id);
9 |
--------------------------------------------------------------------------------
/mbdata/sql/eaa/CreateReplicationTriggers.sql:
--------------------------------------------------------------------------------
1 | -- Automatically generated, do not edit.
2 | \set ON_ERROR_STOP 1
3 |
4 | SET search_path = 'event_art_archive', musicbrainz, public;
5 |
6 | BEGIN;
7 |
8 | CREATE TRIGGER "reptg_art_type"
9 | AFTER INSERT OR DELETE OR UPDATE ON "art_type"
10 | FOR EACH ROW EXECUTE PROCEDURE "recordchange" ('verbose');
11 |
12 | CREATE TRIGGER "reptg_event_art"
13 | AFTER INSERT OR DELETE OR UPDATE ON "event_art"
14 | FOR EACH ROW EXECUTE PROCEDURE "recordchange" ('verbose');
15 |
16 | CREATE TRIGGER "reptg_event_art_type"
17 | AFTER INSERT OR DELETE OR UPDATE ON "event_art_type"
18 | FOR EACH ROW EXECUTE PROCEDURE "recordchange" ('verbose');
19 |
20 | COMMIT;
21 |
--------------------------------------------------------------------------------
/mbdata/sql/eaa/CreateReplicationTriggers2.sql:
--------------------------------------------------------------------------------
1 | -- Automatically generated, do not edit.
2 | \set ON_ERROR_STOP 1
3 |
4 | SET search_path = 'event_art_archive', musicbrainz, public;
5 |
6 | BEGIN;
7 |
8 | CREATE TRIGGER reptg2_art_type
9 | AFTER INSERT OR DELETE OR UPDATE ON art_type
10 | FOR EACH ROW EXECUTE PROCEDURE dbmirror2.recordchange();
11 |
12 | CREATE TRIGGER reptg2_event_art
13 | AFTER INSERT OR DELETE OR UPDATE ON event_art
14 | FOR EACH ROW EXECUTE PROCEDURE dbmirror2.recordchange();
15 |
16 | CREATE TRIGGER reptg2_event_art_type
17 | AFTER INSERT OR DELETE OR UPDATE ON event_art_type
18 | FOR EACH ROW EXECUTE PROCEDURE dbmirror2.recordchange();
19 |
20 | COMMIT;
21 |
--------------------------------------------------------------------------------
/mbdata/sql/eaa/CreateTables.sql:
--------------------------------------------------------------------------------
1 | \set ON_ERROR_STOP 1
2 |
3 | BEGIN;
4 |
5 | SET search_path = 'event_art_archive';
6 |
7 | CREATE TABLE art_type ( -- replicate (verbose)
8 | id SERIAL NOT NULL, -- PK
9 | name TEXT NOT NULL,
10 | parent INTEGER, -- references event_art_archive.art_type.id
11 | child_order INTEGER NOT NULL DEFAULT 0,
12 | description TEXT,
13 | gid uuid NOT NULL
14 | );
15 |
16 | CREATE TABLE event_art ( -- replicate (verbose)
17 | id BIGINT NOT NULL, -- PK
18 | event INTEGER NOT NULL, -- references musicbrainz.event.id CASCADE
19 | comment TEXT NOT NULL DEFAULT '',
20 | edit INTEGER NOT NULL, -- separately references musicbrainz.edit.id
21 | ordering INTEGER NOT NULL CHECK (ordering > 0),
22 | date_uploaded TIMESTAMP WITH TIME ZONE DEFAULT now() NOT NULL,
23 | edits_pending INTEGER NOT NULL DEFAULT 0 CHECK (edits_pending >= 0),
24 | mime_type TEXT NOT NULL, -- references cover_art_archive.image_type.mime_type
25 | filesize INTEGER,
26 | thumb_250_filesize INTEGER,
27 | thumb_500_filesize INTEGER,
28 | thumb_1200_filesize INTEGER
29 | );
30 |
31 | CREATE TABLE event_art_type ( -- replicate (verbose)
32 | id BIGINT NOT NULL, -- PK, references event_art_archive.event_art.id CASCADE,
33 | type_id INTEGER NOT NULL -- PK, references event_art_archive.art_type.id,
34 | );
35 |
36 | COMMIT;
37 |
--------------------------------------------------------------------------------
/mbdata/sql/eaa/CreateTriggers.sql:
--------------------------------------------------------------------------------
1 | BEGIN;
2 |
3 | SET search_path = 'event_art_archive';
4 |
5 | CREATE TRIGGER update_event_art AFTER INSERT OR DELETE
6 | ON event_art_archive.event_art
7 | FOR EACH ROW EXECUTE PROCEDURE materialize_eaa_presence();
8 |
9 | CREATE CONSTRAINT TRIGGER resquence_event_art AFTER INSERT OR UPDATE OR DELETE
10 | ON event_art_archive.event_art DEFERRABLE INITIALLY DEFERRED
11 | FOR EACH ROW EXECUTE PROCEDURE resequence_event_art_trigger();
12 |
13 | COMMIT;
14 |
--------------------------------------------------------------------------------
/mbdata/sql/eaa/CreateViews.sql:
--------------------------------------------------------------------------------
1 | \set ON_ERROR_STOP 1
2 |
3 | BEGIN;
4 |
5 | SET search_path = 'event_art_archive';
6 |
7 | CREATE OR REPLACE VIEW index_listing AS
8 | SELECT event_art.*,
9 | (edit.close_time IS NOT NULL) AS approved,
10 | coalesce(event_art.id = (SELECT id FROM event_art_archive.event_art_type
11 | JOIN event_art_archive.event_art ea_front USING (id)
12 | WHERE ea_front.event = event_art.event
13 | AND type_id = 1
14 | ORDER BY ea_front.ordering
15 | LIMIT 1), FALSE) AS is_front,
16 | array(SELECT art_type.name
17 | FROM event_art_archive.event_art_type
18 | JOIN event_art_archive.art_type ON event_art_type.type_id = art_type.id
19 | WHERE event_art_type.id = event_art.id) AS types
20 | FROM event_art_archive.event_art
21 | LEFT JOIN musicbrainz.edit ON edit.id = event_art.edit;
22 |
23 | COMMIT;
24 |
--------------------------------------------------------------------------------
/mbdata/sql/eaa/DropFKConstraints.sql:
--------------------------------------------------------------------------------
1 | -- Automatically generated, do not edit.
2 | \unset ON_ERROR_STOP
3 |
4 | SET search_path = 'event_art_archive';
5 |
6 | ALTER TABLE art_type DROP CONSTRAINT IF EXISTS art_type_fk_parent;
7 | ALTER TABLE event_art DROP CONSTRAINT IF EXISTS event_art_fk_event;
8 | ALTER TABLE event_art DROP CONSTRAINT IF EXISTS event_art_fk_edit;
9 | ALTER TABLE event_art DROP CONSTRAINT IF EXISTS event_art_fk_mime_type;
10 | ALTER TABLE event_art_type DROP CONSTRAINT IF EXISTS event_art_type_fk_id;
11 | ALTER TABLE event_art_type DROP CONSTRAINT IF EXISTS event_art_type_fk_type_id;
12 |
--------------------------------------------------------------------------------
/mbdata/sql/eaa/DropFunctions.sql:
--------------------------------------------------------------------------------
1 | -- Automatically generated, do not edit.
2 | \unset ON_ERROR_STOP
3 |
4 | SET search_path = 'event_art_archive';
5 |
6 | DROP FUNCTION materialize_eaa_presence();
7 | DROP FUNCTION resequence_event_art_trigger();
8 | DROP FUNCTION resequence_positions(event_id INT);
9 |
--------------------------------------------------------------------------------
/mbdata/sql/eaa/DropIndexes.sql:
--------------------------------------------------------------------------------
1 | -- Automatically generated, do not edit.
2 | \unset ON_ERROR_STOP
3 |
4 | SET search_path = 'event_art_archive';
5 |
6 | DROP INDEX art_type_idx_gid;
7 | DROP INDEX event_art_idx_event;
8 |
--------------------------------------------------------------------------------
/mbdata/sql/eaa/DropPrimaryKeys.sql:
--------------------------------------------------------------------------------
1 | -- Automatically generated, do not edit.
2 | \unset ON_ERROR_STOP
3 |
4 | SET search_path = 'event_art_archive';
5 |
6 | ALTER TABLE art_type DROP CONSTRAINT IF EXISTS art_type_pkey;
7 | ALTER TABLE event_art DROP CONSTRAINT IF EXISTS event_art_pkey;
8 | ALTER TABLE event_art_type DROP CONSTRAINT IF EXISTS event_art_type_pkey;
9 |
--------------------------------------------------------------------------------
/mbdata/sql/eaa/DropReplicationTriggers.sql:
--------------------------------------------------------------------------------
1 | -- Automatically generated, do not edit.
2 | \unset ON_ERROR_STOP
3 |
4 | SET search_path = 'event_art_archive';
5 |
6 | DROP TRIGGER IF EXISTS reptg_art_type ON art_type;
7 | DROP TRIGGER IF EXISTS reptg_event_art ON event_art;
8 | DROP TRIGGER IF EXISTS reptg_event_art_type ON event_art_type;
9 |
--------------------------------------------------------------------------------
/mbdata/sql/eaa/DropReplicationTriggers2.sql:
--------------------------------------------------------------------------------
1 | -- Automatically generated, do not edit.
2 | \unset ON_ERROR_STOP
3 |
4 | SET search_path = 'event_art_archive';
5 |
6 | DROP TRIGGER IF EXISTS reptg2_art_type ON art_type;
7 | DROP TRIGGER IF EXISTS reptg2_event_art ON event_art;
8 | DROP TRIGGER IF EXISTS reptg2_event_art_type ON event_art_type;
9 |
--------------------------------------------------------------------------------
/mbdata/sql/eaa/DropTables.sql:
--------------------------------------------------------------------------------
1 | -- Automatically generated, do not edit.
2 | \unset ON_ERROR_STOP
3 |
4 | SET search_path = 'event_art_archive';
5 |
6 | DROP TABLE art_type;
7 | DROP TABLE event_art;
8 | DROP TABLE event_art_type;
9 |
--------------------------------------------------------------------------------
/mbdata/sql/eaa/DropTriggers.sql:
--------------------------------------------------------------------------------
1 | -- Automatically generated, do not edit.
2 | \unset ON_ERROR_STOP
3 |
4 | SET search_path = 'event_art_archive';
5 |
6 | DROP TRIGGER IF EXISTS update_event_art ON event_art_archive.event_art;
7 | DROP TRIGGER IF EXISTS resquence_event_art ON event_art_archive.event_art;
8 |
--------------------------------------------------------------------------------
/mbdata/sql/eaa/DropViews.sql:
--------------------------------------------------------------------------------
1 | -- Automatically generated, do not edit.
2 | \unset ON_ERROR_STOP
3 |
4 | SET search_path = 'event_art_archive';
5 |
6 | DROP VIEW index_listing;
7 |
--------------------------------------------------------------------------------
/mbdata/sql/eaa/SetSequences.sql:
--------------------------------------------------------------------------------
1 | -- Automatically generated, do not edit.
2 | \unset ON_ERROR_STOP
3 |
4 | SET search_path = 'event_art_archive';
5 |
6 | SELECT setval('art_type_id_seq', COALESCE((SELECT MAX(id) FROM art_type), 0) + 1, FALSE);
7 |
--------------------------------------------------------------------------------
/mbdata/sql/eaa/TruncateTables.sql:
--------------------------------------------------------------------------------
1 | -- Automatically generated, do not edit.
2 | \set ON_ERROR_STOP 1
3 |
4 | SET search_path = 'event_art_archive';
5 |
6 | TRUNCATE TABLE art_type RESTART IDENTITY CASCADE;
7 | TRUNCATE TABLE event_art RESTART IDENTITY CASCADE;
8 | TRUNCATE TABLE event_art_type RESTART IDENTITY CASCADE;
9 |
--------------------------------------------------------------------------------
/mbdata/sql/json_dump/CreateIndexes.sql:
--------------------------------------------------------------------------------
1 | \set ON_ERROR_STOP 1
2 |
3 | BEGIN;
4 |
5 | SET search_path = json_dump;
6 |
7 | CREATE UNIQUE INDEX tmp_checked_entities_idx_uniq ON tmp_checked_entities (id, entity_type);
8 |
9 | CREATE INDEX deleted_entities_idx_replication_sequence ON deleted_entities (replication_sequence);
10 |
11 | COMMIT;
12 |
--------------------------------------------------------------------------------
/mbdata/sql/json_dump/CreatePrimaryKeys.sql:
--------------------------------------------------------------------------------
1 | -- Automatically generated, do not edit.
2 | \set ON_ERROR_STOP 1
3 |
4 | SET search_path = json_dump, public;
5 |
6 | ALTER TABLE area_json ADD CONSTRAINT area_json_pkey PRIMARY KEY (id, replication_sequence);
7 | ALTER TABLE artist_json ADD CONSTRAINT artist_json_pkey PRIMARY KEY (id, replication_sequence);
8 | ALTER TABLE deleted_entities ADD CONSTRAINT deleted_entities_pkey PRIMARY KEY (entity_type, id);
9 | ALTER TABLE event_json ADD CONSTRAINT event_json_pkey PRIMARY KEY (id, replication_sequence);
10 | ALTER TABLE instrument_json ADD CONSTRAINT instrument_json_pkey PRIMARY KEY (id, replication_sequence);
11 | ALTER TABLE label_json ADD CONSTRAINT label_json_pkey PRIMARY KEY (id, replication_sequence);
12 | ALTER TABLE place_json ADD CONSTRAINT place_json_pkey PRIMARY KEY (id, replication_sequence);
13 | ALTER TABLE recording_json ADD CONSTRAINT recording_json_pkey PRIMARY KEY (id, replication_sequence);
14 | ALTER TABLE release_group_json ADD CONSTRAINT release_group_json_pkey PRIMARY KEY (id, replication_sequence);
15 | ALTER TABLE release_json ADD CONSTRAINT release_json_pkey PRIMARY KEY (id, replication_sequence);
16 | ALTER TABLE series_json ADD CONSTRAINT series_json_pkey PRIMARY KEY (id, replication_sequence);
17 | ALTER TABLE work_json ADD CONSTRAINT work_json_pkey PRIMARY KEY (id, replication_sequence);
18 |
--------------------------------------------------------------------------------
/mbdata/sql/json_dump/CreateTables.sql:
--------------------------------------------------------------------------------
1 | \set ON_ERROR_STOP 1
2 |
3 | BEGIN;
4 |
5 | SET search_path = json_dump, public;
6 |
7 | CREATE TABLE control (
8 | last_processed_replication_sequence INTEGER,
9 | full_json_dump_replication_sequence INTEGER
10 | );
11 |
12 | CREATE TABLE tmp_checked_entities (
13 | id INTEGER NOT NULL,
14 | entity_type VARCHAR(50) NOT NULL
15 | );
16 |
17 | CREATE TABLE deleted_entities (
18 | entity_type VARCHAR(50) NOT NULL, -- PK
19 | id INTEGER NOT NULL, -- PK
20 | replication_sequence INTEGER NOT NULL
21 | );
22 |
23 | CREATE TABLE area_json (
24 | id INTEGER NOT NULL, -- PK
25 | replication_sequence INTEGER NOT NULL, -- PK
26 | json JSONB NOT NULL,
27 | last_modified TIMESTAMP WITH TIME ZONE
28 | );
29 |
30 | CREATE TABLE artist_json (
31 | id INTEGER NOT NULL, -- PK
32 | replication_sequence INTEGER NOT NULL, -- PK
33 | json JSONB NOT NULL,
34 | last_modified TIMESTAMP WITH TIME ZONE
35 | );
36 |
37 | CREATE TABLE event_json (
38 | id INTEGER NOT NULL, -- PK
39 | replication_sequence INTEGER NOT NULL, -- PK
40 | json JSONB NOT NULL,
41 | last_modified TIMESTAMP WITH TIME ZONE
42 | );
43 |
44 | CREATE TABLE instrument_json (
45 | id INTEGER NOT NULL, -- PK
46 | replication_sequence INTEGER NOT NULL, -- PK
47 | json JSONB NOT NULL,
48 | last_modified TIMESTAMP WITH TIME ZONE
49 | );
50 |
51 | CREATE TABLE label_json (
52 | id INTEGER NOT NULL, -- PK
53 | replication_sequence INTEGER NOT NULL, -- PK
54 | json JSONB NOT NULL,
55 | last_modified TIMESTAMP WITH TIME ZONE
56 | );
57 |
58 | CREATE TABLE place_json (
59 | id INTEGER NOT NULL, -- PK
60 | replication_sequence INTEGER NOT NULL, -- PK
61 | json JSONB NOT NULL,
62 | last_modified TIMESTAMP WITH TIME ZONE
63 | );
64 |
65 | CREATE TABLE recording_json (
66 | id INTEGER NOT NULL, -- PK
67 | replication_sequence INTEGER NOT NULL, -- PK
68 | json JSONB NOT NULL,
69 | last_modified TIMESTAMP WITH TIME ZONE
70 | );
71 |
72 | CREATE TABLE release_json (
73 | id INTEGER NOT NULL, -- PK
74 | replication_sequence INTEGER NOT NULL, -- PK
75 | json JSONB NOT NULL,
76 | last_modified TIMESTAMP WITH TIME ZONE
77 | );
78 |
79 | CREATE TABLE release_group_json (
80 | id INTEGER NOT NULL, -- PK
81 | replication_sequence INTEGER NOT NULL, -- PK
82 | json JSONB NOT NULL,
83 | last_modified TIMESTAMP WITH TIME ZONE
84 | );
85 |
86 | CREATE TABLE series_json (
87 | id INTEGER NOT NULL, -- PK
88 | replication_sequence INTEGER NOT NULL, -- PK
89 | json JSONB NOT NULL,
90 | last_modified TIMESTAMP WITH TIME ZONE
91 | );
92 |
93 | CREATE TABLE work_json (
94 | id INTEGER NOT NULL, -- PK
95 | replication_sequence INTEGER NOT NULL, -- PK
96 | json JSONB NOT NULL,
97 | last_modified TIMESTAMP WITH TIME ZONE
98 | );
99 |
100 | COMMIT;
101 |
--------------------------------------------------------------------------------
/mbdata/sql/json_dump/DropFKConstraints.sql:
--------------------------------------------------------------------------------
1 | -- Automatically generated, do not edit.
2 | \unset ON_ERROR_STOP
3 |
4 | SET search_path = json_dump, public;
5 |
6 | ALTER TABLE area_lastmod DROP CONSTRAINT IF EXISTS area_lastmod_fk_id;
7 | ALTER TABLE artist_lastmod DROP CONSTRAINT IF EXISTS artist_lastmod_fk_id;
8 | ALTER TABLE event_lastmod DROP CONSTRAINT IF EXISTS event_lastmod_fk_id;
9 | ALTER TABLE instrument_lastmod DROP CONSTRAINT IF EXISTS instrument_lastmod_fk_id;
10 | ALTER TABLE label_lastmod DROP CONSTRAINT IF EXISTS label_lastmod_fk_id;
11 | ALTER TABLE place_lastmod DROP CONSTRAINT IF EXISTS place_lastmod_fk_id;
12 | ALTER TABLE recording_lastmod DROP CONSTRAINT IF EXISTS recording_lastmod_fk_id;
13 | ALTER TABLE release_group_lastmod DROP CONSTRAINT IF EXISTS release_group_lastmod_fk_id;
14 | ALTER TABLE release_lastmod DROP CONSTRAINT IF EXISTS release_lastmod_fk_id;
15 | ALTER TABLE series_lastmod DROP CONSTRAINT IF EXISTS series_lastmod_fk_id;
16 | ALTER TABLE work_lastmod DROP CONSTRAINT IF EXISTS work_lastmod_fk_id;
17 |
--------------------------------------------------------------------------------
/mbdata/sql/json_dump/DropIndexes.sql:
--------------------------------------------------------------------------------
1 | -- Automatically generated, do not edit.
2 | \unset ON_ERROR_STOP
3 |
4 | SET search_path = json_dump, public;
5 |
6 | DROP INDEX deleted_entities_idx_replication_sequence;
7 | DROP INDEX tmp_checked_entities_idx_uniq;
8 |
--------------------------------------------------------------------------------
/mbdata/sql/json_dump/DropPrimaryKeys.sql:
--------------------------------------------------------------------------------
1 | -- Automatically generated, do not edit.
2 | \unset ON_ERROR_STOP
3 |
4 | SET search_path = json_dump, public;
5 |
6 | ALTER TABLE area_json DROP CONSTRAINT IF EXISTS area_json_pkey;
7 | ALTER TABLE artist_json DROP CONSTRAINT IF EXISTS artist_json_pkey;
8 | ALTER TABLE deleted_entities DROP CONSTRAINT IF EXISTS deleted_entities_pkey;
9 | ALTER TABLE event_json DROP CONSTRAINT IF EXISTS event_json_pkey;
10 | ALTER TABLE instrument_json DROP CONSTRAINT IF EXISTS instrument_json_pkey;
11 | ALTER TABLE label_json DROP CONSTRAINT IF EXISTS label_json_pkey;
12 | ALTER TABLE place_json DROP CONSTRAINT IF EXISTS place_json_pkey;
13 | ALTER TABLE recording_json DROP CONSTRAINT IF EXISTS recording_json_pkey;
14 | ALTER TABLE release_group_json DROP CONSTRAINT IF EXISTS release_group_json_pkey;
15 | ALTER TABLE release_json DROP CONSTRAINT IF EXISTS release_json_pkey;
16 | ALTER TABLE series_json DROP CONSTRAINT IF EXISTS series_json_pkey;
17 | ALTER TABLE work_json DROP CONSTRAINT IF EXISTS work_json_pkey;
18 |
--------------------------------------------------------------------------------
/mbdata/sql/json_dump/DropTables.sql:
--------------------------------------------------------------------------------
1 | -- Automatically generated, do not edit.
2 | \unset ON_ERROR_STOP
3 |
4 | SET search_path = json_dump, public;
5 |
6 | DROP TABLE area_json;
7 | DROP TABLE artist_json;
8 | DROP TABLE control;
9 | DROP TABLE deleted_entities;
10 | DROP TABLE event_json;
11 | DROP TABLE instrument_json;
12 | DROP TABLE label_json;
13 | DROP TABLE place_json;
14 | DROP TABLE recording_json;
15 | DROP TABLE release_group_json;
16 | DROP TABLE release_json;
17 | DROP TABLE series_json;
18 | DROP TABLE tmp_checked_entities;
19 | DROP TABLE work_json;
20 |
--------------------------------------------------------------------------------
/mbdata/sql/json_dump/TruncateTables.sql:
--------------------------------------------------------------------------------
1 | -- Automatically generated, do not edit.
2 | \set ON_ERROR_STOP 1
3 |
4 | SET search_path = json_dump, public;
5 |
6 | TRUNCATE TABLE area_json RESTART IDENTITY CASCADE;
7 | TRUNCATE TABLE artist_json RESTART IDENTITY CASCADE;
8 | TRUNCATE TABLE control RESTART IDENTITY CASCADE;
9 | TRUNCATE TABLE deleted_entities RESTART IDENTITY CASCADE;
10 | TRUNCATE TABLE event_json RESTART IDENTITY CASCADE;
11 | TRUNCATE TABLE instrument_json RESTART IDENTITY CASCADE;
12 | TRUNCATE TABLE label_json RESTART IDENTITY CASCADE;
13 | TRUNCATE TABLE place_json RESTART IDENTITY CASCADE;
14 | TRUNCATE TABLE recording_json RESTART IDENTITY CASCADE;
15 | TRUNCATE TABLE release_group_json RESTART IDENTITY CASCADE;
16 | TRUNCATE TABLE release_json RESTART IDENTITY CASCADE;
17 | TRUNCATE TABLE series_json RESTART IDENTITY CASCADE;
18 | TRUNCATE TABLE tmp_checked_entities RESTART IDENTITY CASCADE;
19 | TRUNCATE TABLE work_json RESTART IDENTITY CASCADE;
20 |
--------------------------------------------------------------------------------
/mbdata/sql/report/CreateTables.sql:
--------------------------------------------------------------------------------
1 | BEGIN;
2 |
3 | SET search_path = report;
4 |
5 | CREATE TABLE report.index (
6 | report_name TEXT NOT NULL PRIMARY KEY,
7 | generated_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now()
8 | );
9 |
10 | COMMIT;
11 |
--------------------------------------------------------------------------------
/mbdata/sql/report/TruncateTables.sql:
--------------------------------------------------------------------------------
1 | -- Automatically generated, do not edit.
2 | \set ON_ERROR_STOP 1
3 |
4 | SET search_path = report;
5 |
6 |
--------------------------------------------------------------------------------
/mbdata/sql/sitemaps/CreateFKConstraints.sql:
--------------------------------------------------------------------------------
1 | -- Automatically generated, do not edit.
2 | \set ON_ERROR_STOP 1
3 |
4 | SET search_path = 'sitemaps';
5 |
6 | ALTER TABLE artist_lastmod
7 | ADD CONSTRAINT artist_lastmod_fk_id
8 | FOREIGN KEY (id)
9 | REFERENCES musicbrainz.artist(id)
10 | ON DELETE CASCADE;
11 |
12 | ALTER TABLE label_lastmod
13 | ADD CONSTRAINT label_lastmod_fk_id
14 | FOREIGN KEY (id)
15 | REFERENCES musicbrainz.label(id)
16 | ON DELETE CASCADE;
17 |
18 | ALTER TABLE place_lastmod
19 | ADD CONSTRAINT place_lastmod_fk_id
20 | FOREIGN KEY (id)
21 | REFERENCES musicbrainz.place(id)
22 | ON DELETE CASCADE;
23 |
24 | ALTER TABLE recording_lastmod
25 | ADD CONSTRAINT recording_lastmod_fk_id
26 | FOREIGN KEY (id)
27 | REFERENCES musicbrainz.recording(id)
28 | ON DELETE CASCADE;
29 |
30 | ALTER TABLE release_group_lastmod
31 | ADD CONSTRAINT release_group_lastmod_fk_id
32 | FOREIGN KEY (id)
33 | REFERENCES musicbrainz.release_group(id)
34 | ON DELETE CASCADE;
35 |
36 | ALTER TABLE release_lastmod
37 | ADD CONSTRAINT release_lastmod_fk_id
38 | FOREIGN KEY (id)
39 | REFERENCES musicbrainz.release(id)
40 | ON DELETE CASCADE;
41 |
42 | ALTER TABLE work_lastmod
43 | ADD CONSTRAINT work_lastmod_fk_id
44 | FOREIGN KEY (id)
45 | REFERENCES musicbrainz.work(id)
46 | ON DELETE CASCADE;
47 |
48 |
--------------------------------------------------------------------------------
/mbdata/sql/sitemaps/CreateIndexes.sql:
--------------------------------------------------------------------------------
1 | \set ON_ERROR_STOP 1
2 |
3 | BEGIN;
4 |
5 | SET search_path = 'sitemaps';
6 |
7 | CREATE UNIQUE INDEX artist_lastmod_idx_url ON artist_lastmod (url);
8 | CREATE UNIQUE INDEX tmp_checked_entities_idx_uniq ON tmp_checked_entities (id, entity_type);
9 | CREATE UNIQUE INDEX label_lastmod_idx_url ON label_lastmod (url);
10 | CREATE UNIQUE INDEX place_lastmod_idx_url ON place_lastmod (url);
11 | CREATE UNIQUE INDEX recording_lastmod_idx_url ON recording_lastmod (url);
12 | CREATE UNIQUE INDEX release_lastmod_idx_url ON release_lastmod (url);
13 | CREATE UNIQUE INDEX release_group_lastmod_idx_url ON release_group_lastmod (url);
14 | CREATE UNIQUE INDEX work_lastmod_idx_url ON work_lastmod (url);
15 |
16 | COMMIT;
17 |
--------------------------------------------------------------------------------
/mbdata/sql/sitemaps/CreateTables.sql:
--------------------------------------------------------------------------------
1 | \set ON_ERROR_STOP 1
2 |
3 | BEGIN;
4 |
5 | SET search_path = 'sitemaps';
6 |
7 | CREATE TABLE control (
8 | last_processed_replication_sequence INTEGER,
9 | overall_sitemaps_replication_sequence INTEGER,
10 | building_overall_sitemaps BOOLEAN NOT NULL
11 | );
12 |
13 | CREATE TABLE tmp_checked_entities (
14 | id INTEGER NOT NULL,
15 | entity_type VARCHAR(50) NOT NULL
16 | );
17 |
18 | CREATE TABLE artist_lastmod (
19 | id INTEGER NOT NULL, -- FK, references musicbrainz.artist.id CASCADE
20 | url VARCHAR(128) NOT NULL,
21 | paginated BOOLEAN NOT NULL,
22 | sitemap_suffix_key VARCHAR(50) NOT NULL,
23 | jsonld_sha1 BYTEA NOT NULL,
24 | last_modified TIMESTAMP WITH TIME ZONE NOT NULL,
25 | replication_sequence INTEGER NOT NULL
26 | );
27 |
28 | CREATE TABLE label_lastmod (
29 | id INTEGER NOT NULL, -- FK, references musicbrainz.label.id CASCADE
30 | url VARCHAR(128) NOT NULL,
31 | paginated BOOLEAN NOT NULL,
32 | sitemap_suffix_key VARCHAR(50) NOT NULL,
33 | jsonld_sha1 BYTEA NOT NULL,
34 | last_modified TIMESTAMP WITH TIME ZONE NOT NULL,
35 | replication_sequence INTEGER NOT NULL
36 | );
37 |
38 | CREATE TABLE place_lastmod (
39 | id INTEGER NOT NULL, -- FK, references musicbrainz.place.id CASCADE
40 | url VARCHAR(128) NOT NULL,
41 | paginated BOOLEAN NOT NULL,
42 | sitemap_suffix_key VARCHAR(50) NOT NULL,
43 | jsonld_sha1 BYTEA NOT NULL,
44 | last_modified TIMESTAMP WITH TIME ZONE NOT NULL,
45 | replication_sequence INTEGER NOT NULL
46 | );
47 |
48 | CREATE TABLE recording_lastmod (
49 | id INTEGER NOT NULL, -- FK, references musicbrainz.recording.id CASCADE
50 | url VARCHAR(128) NOT NULL,
51 | paginated BOOLEAN NOT NULL,
52 | sitemap_suffix_key VARCHAR(50) NOT NULL,
53 | jsonld_sha1 BYTEA NOT NULL,
54 | last_modified TIMESTAMP WITH TIME ZONE NOT NULL,
55 | replication_sequence INTEGER NOT NULL
56 | );
57 |
58 | CREATE TABLE release_lastmod (
59 | id INTEGER NOT NULL, -- FK, references musicbrainz.release.id CASCADE
60 | url VARCHAR(128) NOT NULL,
61 | paginated BOOLEAN NOT NULL,
62 | sitemap_suffix_key VARCHAR(50) NOT NULL,
63 | jsonld_sha1 BYTEA NOT NULL,
64 | last_modified TIMESTAMP WITH TIME ZONE NOT NULL,
65 | replication_sequence INTEGER NOT NULL
66 | );
67 |
68 | CREATE TABLE release_group_lastmod (
69 | id INTEGER NOT NULL, -- FK, references musicbrainz.release_group.id CASCADE
70 | url VARCHAR(128) NOT NULL,
71 | paginated BOOLEAN NOT NULL,
72 | sitemap_suffix_key VARCHAR(50) NOT NULL,
73 | jsonld_sha1 BYTEA NOT NULL,
74 | last_modified TIMESTAMP WITH TIME ZONE NOT NULL,
75 | replication_sequence INTEGER NOT NULL
76 | );
77 |
78 | CREATE TABLE work_lastmod (
79 | id INTEGER NOT NULL, -- FK, references musicbrainz.work.id CASCADE
80 | url VARCHAR(128) NOT NULL,
81 | paginated BOOLEAN NOT NULL,
82 | sitemap_suffix_key VARCHAR(50) NOT NULL,
83 | jsonld_sha1 BYTEA NOT NULL,
84 | last_modified TIMESTAMP WITH TIME ZONE NOT NULL,
85 | replication_sequence INTEGER NOT NULL
86 | );
87 |
88 | COMMIT;
89 |
--------------------------------------------------------------------------------
/mbdata/sql/sitemaps/DropFKConstraints.sql:
--------------------------------------------------------------------------------
1 | -- Automatically generated, do not edit.
2 | \unset ON_ERROR_STOP
3 |
4 | SET search_path = 'sitemaps';
5 |
6 | ALTER TABLE artist_lastmod DROP CONSTRAINT IF EXISTS artist_lastmod_fk_id;
7 | ALTER TABLE label_lastmod DROP CONSTRAINT IF EXISTS label_lastmod_fk_id;
8 | ALTER TABLE place_lastmod DROP CONSTRAINT IF EXISTS place_lastmod_fk_id;
9 | ALTER TABLE recording_lastmod DROP CONSTRAINT IF EXISTS recording_lastmod_fk_id;
10 | ALTER TABLE release_group_lastmod DROP CONSTRAINT IF EXISTS release_group_lastmod_fk_id;
11 | ALTER TABLE release_lastmod DROP CONSTRAINT IF EXISTS release_lastmod_fk_id;
12 | ALTER TABLE work_lastmod DROP CONSTRAINT IF EXISTS work_lastmod_fk_id;
13 |
--------------------------------------------------------------------------------
/mbdata/sql/sitemaps/DropIndexes.sql:
--------------------------------------------------------------------------------
1 | -- Automatically generated, do not edit.
2 | \unset ON_ERROR_STOP
3 |
4 | SET search_path = 'sitemaps';
5 |
6 | DROP INDEX artist_lastmod_idx_url;
7 | DROP INDEX label_lastmod_idx_url;
8 | DROP INDEX place_lastmod_idx_url;
9 | DROP INDEX recording_lastmod_idx_url;
10 | DROP INDEX release_group_lastmod_idx_url;
11 | DROP INDEX release_lastmod_idx_url;
12 | DROP INDEX tmp_checked_entities_idx_uniq;
13 | DROP INDEX work_lastmod_idx_url;
14 |
--------------------------------------------------------------------------------
/mbdata/sql/sitemaps/DropTables.sql:
--------------------------------------------------------------------------------
1 | -- Automatically generated, do not edit.
2 | \unset ON_ERROR_STOP
3 |
4 | SET search_path = 'sitemaps';
5 |
6 | DROP TABLE artist_lastmod;
7 | DROP TABLE control;
8 | DROP TABLE label_lastmod;
9 | DROP TABLE place_lastmod;
10 | DROP TABLE recording_lastmod;
11 | DROP TABLE release_group_lastmod;
12 | DROP TABLE release_lastmod;
13 | DROP TABLE tmp_checked_entities;
14 | DROP TABLE work_lastmod;
15 |
--------------------------------------------------------------------------------
/mbdata/sql/sitemaps/TruncateTables.sql:
--------------------------------------------------------------------------------
1 | -- Automatically generated, do not edit.
2 | \set ON_ERROR_STOP 1
3 |
4 | SET search_path = 'sitemaps';
5 |
6 | TRUNCATE TABLE artist_lastmod RESTART IDENTITY CASCADE;
7 | TRUNCATE TABLE control RESTART IDENTITY CASCADE;
8 | TRUNCATE TABLE label_lastmod RESTART IDENTITY CASCADE;
9 | TRUNCATE TABLE place_lastmod RESTART IDENTITY CASCADE;
10 | TRUNCATE TABLE recording_lastmod RESTART IDENTITY CASCADE;
11 | TRUNCATE TABLE release_group_lastmod RESTART IDENTITY CASCADE;
12 | TRUNCATE TABLE release_lastmod RESTART IDENTITY CASCADE;
13 | TRUNCATE TABLE tmp_checked_entities RESTART IDENTITY CASCADE;
14 | TRUNCATE TABLE work_lastmod RESTART IDENTITY CASCADE;
15 |
--------------------------------------------------------------------------------
/mbdata/sql/statistics/CreateIndexes.sql:
--------------------------------------------------------------------------------
1 | SET search_path = 'statistics';
2 |
3 | \set ON_ERROR_STOP 1
4 | BEGIN;
5 |
6 | CREATE INDEX statistic_name ON statistic (name);
7 | CREATE UNIQUE INDEX statistic_name_date_collected ON statistic (name, date_collected);
8 |
9 | COMMIT;
10 |
11 | -- vi: set ts=4 sw=4 et :
12 |
--------------------------------------------------------------------------------
/mbdata/sql/statistics/CreatePrimaryKeys.sql:
--------------------------------------------------------------------------------
1 | -- Automatically generated, do not edit.
2 | \set ON_ERROR_STOP 1
3 |
4 | SET search_path = 'statistics';
5 |
6 | ALTER TABLE statistic ADD CONSTRAINT statistic_pkey PRIMARY KEY (id);
7 | ALTER TABLE statistic_event ADD CONSTRAINT statistic_event_pkey PRIMARY KEY (date);
8 |
--------------------------------------------------------------------------------
/mbdata/sql/statistics/CreateReplicationTriggers.sql:
--------------------------------------------------------------------------------
1 | -- Automatically generated, do not edit.
2 | \set ON_ERROR_STOP 1
3 |
4 | SET search_path = 'statistics', musicbrainz, public;
5 |
6 | BEGIN;
7 |
8 | CREATE TRIGGER "reptg_statistic"
9 | AFTER INSERT OR DELETE OR UPDATE ON "statistic"
10 | FOR EACH ROW EXECUTE PROCEDURE "recordchange" ();
11 |
12 | CREATE TRIGGER "reptg_statistic_event"
13 | AFTER INSERT OR DELETE OR UPDATE ON "statistic_event"
14 | FOR EACH ROW EXECUTE PROCEDURE "recordchange" ();
15 |
16 | COMMIT;
17 |
--------------------------------------------------------------------------------
/mbdata/sql/statistics/CreateReplicationTriggers2.sql:
--------------------------------------------------------------------------------
1 | -- Automatically generated, do not edit.
2 | \set ON_ERROR_STOP 1
3 |
4 | SET search_path = 'statistics', musicbrainz, public;
5 |
6 | BEGIN;
7 |
8 | CREATE TRIGGER reptg2_statistic
9 | AFTER INSERT OR DELETE OR UPDATE ON statistic
10 | FOR EACH ROW EXECUTE PROCEDURE dbmirror2.recordchange();
11 |
12 | CREATE TRIGGER reptg2_statistic_event
13 | AFTER INSERT OR DELETE OR UPDATE ON statistic_event
14 | FOR EACH ROW EXECUTE PROCEDURE dbmirror2.recordchange();
15 |
16 | COMMIT;
17 |
--------------------------------------------------------------------------------
/mbdata/sql/statistics/CreateTables.sql:
--------------------------------------------------------------------------------
1 | BEGIN;
2 |
3 | SET search_path = 'statistics';
4 |
5 | CREATE TABLE statistic ( -- replicate
6 | id SERIAL,
7 | name VARCHAR(100) NOT NULL,
8 | value INTEGER NOT NULL,
9 | date_collected date NOT NULL DEFAULT NOW()
10 | );
11 |
12 | CREATE TABLE statistic_event ( -- replicate
13 | date DATE NOT NULL CHECK (date >= '2000-01-01'), -- PK
14 | title TEXT NOT NULL,
15 | link TEXT NOT NULL,
16 | description TEXT NOT NULL
17 | );
18 |
19 | COMMIT;
20 |
--------------------------------------------------------------------------------
/mbdata/sql/statistics/DropIndexes.sql:
--------------------------------------------------------------------------------
1 | -- Automatically generated, do not edit.
2 | \unset ON_ERROR_STOP
3 |
4 | SET search_path = 'statistics';
5 |
6 | DROP INDEX statistic_name;
7 | DROP INDEX statistic_name_date_collected;
8 |
--------------------------------------------------------------------------------
/mbdata/sql/statistics/DropPrimaryKeys.sql:
--------------------------------------------------------------------------------
1 | -- Automatically generated, do not edit.
2 | \unset ON_ERROR_STOP
3 |
4 | SET search_path = 'statistics';
5 |
6 | ALTER TABLE statistic DROP CONSTRAINT IF EXISTS statistic_pkey;
7 | ALTER TABLE statistic_event DROP CONSTRAINT IF EXISTS statistic_event_pkey;
8 |
--------------------------------------------------------------------------------
/mbdata/sql/statistics/DropReplicationTriggers.sql:
--------------------------------------------------------------------------------
1 | -- Automatically generated, do not edit.
2 | \unset ON_ERROR_STOP
3 |
4 | SET search_path = 'statistics';
5 |
6 | DROP TRIGGER IF EXISTS reptg_statistic ON statistic;
7 | DROP TRIGGER IF EXISTS reptg_statistic_event ON statistic_event;
8 |
--------------------------------------------------------------------------------
/mbdata/sql/statistics/DropReplicationTriggers2.sql:
--------------------------------------------------------------------------------
1 | -- Automatically generated, do not edit.
2 | \unset ON_ERROR_STOP
3 |
4 | SET search_path = 'statistics';
5 |
6 | DROP TRIGGER IF EXISTS reptg2_statistic ON statistic;
7 | DROP TRIGGER IF EXISTS reptg2_statistic_event ON statistic_event;
8 |
--------------------------------------------------------------------------------
/mbdata/sql/statistics/DropTables.sql:
--------------------------------------------------------------------------------
1 | -- Automatically generated, do not edit.
2 | \unset ON_ERROR_STOP
3 |
4 | SET search_path = 'statistics';
5 |
6 | DROP TABLE statistic;
7 | DROP TABLE statistic_event;
8 |
--------------------------------------------------------------------------------
/mbdata/sql/statistics/SetSequences.sql:
--------------------------------------------------------------------------------
1 | -- Automatically generated, do not edit.
2 | \unset ON_ERROR_STOP
3 |
4 | SET search_path = 'statistics';
5 |
6 | SELECT setval('statistic_id_seq', COALESCE((SELECT MAX(id) FROM statistic), 0) + 1, FALSE);
7 |
--------------------------------------------------------------------------------
/mbdata/sql/statistics/TruncateTables.sql:
--------------------------------------------------------------------------------
1 | -- Automatically generated, do not edit.
2 | \set ON_ERROR_STOP 1
3 |
4 | SET search_path = 'statistics';
5 |
6 | TRUNCATE TABLE statistic RESTART IDENTITY CASCADE;
7 | TRUNCATE TABLE statistic_event RESTART IDENTITY CASCADE;
8 |
--------------------------------------------------------------------------------
/mbdata/sql/wikidocs/CreatePrimaryKeys.sql:
--------------------------------------------------------------------------------
1 | -- Automatically generated, do not edit.
2 | \set ON_ERROR_STOP 1
3 |
4 | SET search_path = 'wikidocs';
5 |
6 | ALTER TABLE wikidocs_index ADD CONSTRAINT wikidocs_index_pkey PRIMARY KEY (page_name);
7 |
--------------------------------------------------------------------------------
/mbdata/sql/wikidocs/CreateReplicationTriggers.sql:
--------------------------------------------------------------------------------
1 | -- Automatically generated, do not edit.
2 | \set ON_ERROR_STOP 1
3 |
4 | SET search_path = 'wikidocs', musicbrainz, public;
5 |
6 | BEGIN;
7 |
8 | CREATE TRIGGER "reptg_wikidocs_index"
9 | AFTER INSERT OR DELETE OR UPDATE ON "wikidocs_index"
10 | FOR EACH ROW EXECUTE PROCEDURE "recordchange" ();
11 |
12 | COMMIT;
13 |
--------------------------------------------------------------------------------
/mbdata/sql/wikidocs/CreateReplicationTriggers2.sql:
--------------------------------------------------------------------------------
1 | -- Automatically generated, do not edit.
2 | \set ON_ERROR_STOP 1
3 |
4 | SET search_path = 'wikidocs', musicbrainz, public;
5 |
6 | BEGIN;
7 |
8 | CREATE TRIGGER reptg2_wikidocs_index
9 | AFTER INSERT OR DELETE OR UPDATE ON wikidocs_index
10 | FOR EACH ROW EXECUTE PROCEDURE dbmirror2.recordchange();
11 |
12 | COMMIT;
13 |
--------------------------------------------------------------------------------
/mbdata/sql/wikidocs/CreateTables.sql:
--------------------------------------------------------------------------------
1 | BEGIN;
2 |
3 | SET search_path = 'wikidocs';
4 |
5 | CREATE TABLE wikidocs_index ( -- replicate
6 | page_name TEXT NOT NULL, -- PK
7 | revision INTEGER NOT NULL
8 | );
9 |
10 | COMMIT;
11 |
--------------------------------------------------------------------------------
/mbdata/sql/wikidocs/DropPrimaryKeys.sql:
--------------------------------------------------------------------------------
1 | -- Automatically generated, do not edit.
2 | \unset ON_ERROR_STOP
3 |
4 | SET search_path = 'wikidocs';
5 |
6 | ALTER TABLE wikidocs_index DROP CONSTRAINT IF EXISTS wikidocs_index_pkey;
7 |
--------------------------------------------------------------------------------
/mbdata/sql/wikidocs/DropReplicationTriggers.sql:
--------------------------------------------------------------------------------
1 | -- Automatically generated, do not edit.
2 | \unset ON_ERROR_STOP
3 |
4 | SET search_path = 'wikidocs';
5 |
6 | DROP TRIGGER IF EXISTS reptg_wikidocs_index ON wikidocs_index;
7 |
--------------------------------------------------------------------------------
/mbdata/sql/wikidocs/DropReplicationTriggers2.sql:
--------------------------------------------------------------------------------
1 | -- Automatically generated, do not edit.
2 | \unset ON_ERROR_STOP
3 |
4 | SET search_path = 'wikidocs';
5 |
6 | DROP TRIGGER IF EXISTS reptg2_wikidocs_index ON wikidocs_index;
7 |
--------------------------------------------------------------------------------
/mbdata/sql/wikidocs/DropTables.sql:
--------------------------------------------------------------------------------
1 | -- Automatically generated, do not edit.
2 | \unset ON_ERROR_STOP
3 |
4 | SET search_path = 'wikidocs';
5 |
6 | DROP TABLE wikidocs_index;
7 |
--------------------------------------------------------------------------------
/mbdata/sql/wikidocs/TruncateTables.sql:
--------------------------------------------------------------------------------
1 | -- Automatically generated, do not edit.
2 | \set ON_ERROR_STOP 1
3 |
4 | SET search_path = 'wikidocs';
5 |
6 | TRUNCATE TABLE wikidocs_index RESTART IDENTITY CASCADE;
7 |
--------------------------------------------------------------------------------
/mbdata/tests/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/metabrainz/mbdata/648c34e19327fbc12ccfec6f363f456315da1024/mbdata/tests/__init__.py
--------------------------------------------------------------------------------
/mbdata/tests/test_tools_genmodels.py:
--------------------------------------------------------------------------------
1 | import pytest
2 |
3 | from mbdata.tools.genmodels import (
4 | format_model_name,
5 | parse_sql,
6 | convert_expression_to_python,
7 | )
8 |
9 |
10 | @pytest.mark.parametrize(
11 | "table_name, model_name",
12 | [
13 | ('artist', 'Artist'),
14 | ('recording_isrc', 'RecordingISRC'),
15 | ('l_artist_artist', 'LinkArtistArtist'),
16 | ('iso_3166_1', 'ISO31661'),
17 | ]
18 | )
19 | def test_format_model_name(table_name, model_name):
20 | assert format_model_name(table_name) == model_name
21 |
22 |
23 | def test_parse_create_tables_sql():
24 | sql = '''
25 | CREATE TABLE release (
26 | id SERIAL, -- PK
27 | name VARCHAR NOT NULL
28 | );
29 |
30 | SET search_path = 'cover_art_archive';
31 |
32 | CREATE TYPE COVER_ART_TYPE AS ENUM ('front', 'back');
33 |
34 | CREATE TABLE cover_art (
35 | id SERIAL, -- PK
36 | release INTEGER NOT NULL, -- references musicbrainz.release.id
37 | type COVER_ART_TYPE
38 | );
39 | '''
40 |
41 | tables, types, indexes = parse_sql(sql)
42 |
43 | assert 1 == len(types)
44 |
45 | assert 'cover_art_archive' == types[0].schema
46 | assert 'COVER_ART_TYPE' == types[0].name
47 | assert ['front', 'back'] == types[0].labels
48 |
49 | assert 2 == len(tables)
50 |
51 | assert 'musicbrainz' == tables[0].schema
52 | assert 'release' == tables[0].name
53 | assert 2 == len(tables[0].columns)
54 | assert 'id' == tables[0].columns[0].name
55 | assert 'SERIAL' == tables[0].columns[0].type
56 | assert True is tables[0].columns[0].primary_key
57 | assert None is tables[0].columns[0].foreign_key
58 | assert 'name' == tables[0].columns[1].name
59 | assert 'VARCHAR' == tables[0].columns[1].type
60 | assert False is tables[0].columns[1].primary_key
61 | assert None is tables[0].columns[1].foreign_key
62 |
63 | assert 'cover_art_archive' == tables[1].schema
64 | assert 'cover_art' == tables[1].name
65 | assert 3 == len(tables[1].columns)
66 | assert 'id' == tables[1].columns[0].name
67 | assert 'SERIAL' == tables[1].columns[0].type
68 | assert True is tables[1].columns[0].primary_key
69 | assert None is tables[1].columns[0].foreign_key
70 | assert 'release' == tables[1].columns[1].name
71 | assert 'INTEGER' == tables[1].columns[1].type
72 | assert False is tables[1].columns[1].primary_key
73 | assert 'musicbrainz' == tables[1].columns[1].foreign_key.schema
74 | assert 'release' == tables[1].columns[1].foreign_key.table
75 | assert 'id' == tables[1].columns[1].foreign_key.column
76 | assert 'type' == tables[1].columns[2].name
77 | assert 'COVER_ART_TYPE' == tables[1].columns[2].type
78 | assert False is tables[1].columns[2].primary_key
79 | assert None is tables[1].columns[2].foreign_key
80 |
81 |
82 | def test_expression_to_python_binary_op_compare():
83 | sql = '''CREATE TABLE table (id SERIAL CHECK (id >= 0));'''
84 | tables, types, indexes = parse_sql(sql)
85 |
86 | assert 1 == len(tables)
87 | assert 1 == len(tables[0].columns)
88 | check = tables[0].columns[0].check_constraint
89 |
90 | assert "sql.literal_column('id') >= sql.text('0')" == convert_expression_to_python(check.text)
91 |
92 |
93 | def test_expression_to_python_is_null():
94 | sql = '''CREATE TABLE table (id SERIAL CHECK (id IS NULL));'''
95 | tables, types, indexes = parse_sql(sql)
96 |
97 | assert 1 == len(tables)
98 | assert 1 == len(tables[0].columns)
99 | check = tables[0].columns[0].check_constraint
100 |
101 | check.text._pprint_tree()
102 | assert "sql.literal_column('id') == None" == convert_expression_to_python(check.text)
103 |
104 |
105 | def test_expression_to_python_is_not_null():
106 | sql = '''CREATE TABLE table (id SERIAL CHECK (id IS NOT NULL));'''
107 | tables, types, indexes = parse_sql(sql)
108 |
109 | assert 1 == len(tables)
110 | assert 1 == len(tables[0].columns)
111 | check = tables[0].columns[0].check_constraint
112 |
113 | check.text._pprint_tree()
114 | assert "sql.literal_column('id') != None" == convert_expression_to_python(check.text)
115 |
116 |
117 | def test_expression_to_python_nested_op():
118 | sql = '''CREATE TABLE table (id SERIAL CHECK (((a IS NOT NULL OR b IS NOT NULL) AND c = TRUE) OR ((a IS NULL AND a IS NULL))));'''
119 | tables, types, indexes = parse_sql(sql)
120 |
121 | assert 1 == len(tables)
122 | assert 1 == len(tables[0].columns)
123 | check = tables[0].columns[0].check_constraint
124 |
125 | expected = (
126 | "sql.or_((sql.and_((sql.or_(sql.literal_column('a') != None, sql.literal_column('b') != None)), "
127 | "sql.literal_column('c') == sql.true())), ((sql.and_(sql.literal_column('a') == None, sql.literal_column('a') == None))))"
128 | )
129 | assert expected == convert_expression_to_python(check.text)
130 |
131 |
132 | def test_expression_to_python_special_name():
133 | sql = '''CREATE TABLE table (length INTEGER CHECK (length IS NULL OR length > 0));'''
134 | tables, types, indexes = parse_sql(sql)
135 |
136 | assert 1 == len(tables)
137 | assert 1 == len(tables[0].columns)
138 | check = tables[0].columns[0].check_constraint
139 |
140 | check.text._pprint_tree()
141 | expected = "sql.or_(sql.text('length') == None, sql.text('length') > sql.text('0'))"
142 | assert expected == convert_expression_to_python(check.text)
143 |
144 |
145 | def test_expression_to_python_special_name_2():
146 | sql = '''CREATE TABLE table (date DATE NOT NULL CHECK (date >= '2000-01-01'));'''
147 | tables, types, indexes = parse_sql(sql)
148 |
149 | assert 1 == len(tables)
150 | assert 1 == len(tables[0].columns)
151 | check = tables[0].columns[0].check_constraint
152 |
153 | check.text._pprint_tree()
154 | expected = "sql.text('date') >= sql.text(\"'2000-01-01'\")"
155 | assert expected == convert_expression_to_python(check.text)
156 |
157 |
158 | def test_expression_to_python_regex_op():
159 | sql = '''CREATE TABLE table (id SERIAL CHECK (id ~ E'^\\\\d{11}$'));'''
160 | tables, types, indexes = parse_sql(sql)
161 |
162 | assert 1 == len(tables)
163 | assert 1 == len(tables[0].columns)
164 | check = tables[0].columns[0].check_constraint
165 |
166 | expected = "regexp(sql.literal_column('id'), '^\\d{11}$')"
167 | assert expected == convert_expression_to_python(check.text)
168 |
--------------------------------------------------------------------------------
/mbdata/tests/test_utils_sql.py:
--------------------------------------------------------------------------------
1 | from __future__ import print_function
2 | import sys
3 | from six import StringIO
4 | import sqlparse
5 | from sqlparse import tokens as T
6 | from sqlparse.sql import Token, TokenList, Parenthesis
7 | from mbdata.utils.sql import (
8 | group_parentheses,
9 | parse_statements,
10 | Set,
11 | CreateTable,
12 | CreateType,
13 | CreateIndex,
14 | )
15 |
16 |
17 | def test_group_parentheses():
18 | tokens = [
19 | Token(T.Keyword, 'CREATE'),
20 | Token(T.Whitespace, ' '),
21 | Token(T.Keyword, 'TABLE'),
22 | Token(T.Whitespace, ' '),
23 | Token(T.Name, 'table_name'),
24 | Token(T.Whitespace, ' '),
25 | Token(T.Punctuation, '('),
26 | Token(T.Name, 'id'),
27 | Token(T.Whitespace, ' '),
28 | Token(T.Keyword, 'SERIAL'),
29 | Token(T.Whitespace, ' '),
30 | Token(T.Keyword, 'CHECK'),
31 | Token(T.Punctuation, '('),
32 | Token(T.Name, 'id'),
33 | Token(T.Operator, '='),
34 | Token(T.Number, '0'),
35 | Token(T.Punctuation, ')'),
36 | Token(T.Punctuation, ')'),
37 | Token(T.Punctuation, ';'),
38 | ]
39 |
40 | expected_tokens = TokenList([
41 | Token(T.Keyword, 'CREATE'),
42 | Token(T.Keyword, 'TABLE'),
43 | Token(T.Name, 'table_name'),
44 | Parenthesis([
45 | Token(T.Punctuation, '('),
46 | Token(T.Name, 'id'),
47 | Token(T.Keyword, 'SERIAL'),
48 | Token(T.Keyword, 'CHECK'),
49 | Parenthesis([
50 | Token(T.Punctuation, '('),
51 | Token(T.Name, 'id'),
52 | Token(T.Operator, '='),
53 | Token(T.Number, '0'),
54 | Token(T.Punctuation, ')'),
55 | ]),
56 | Token(T.Punctuation, ')'),
57 | ]),
58 | Token(T.Punctuation, ';'),
59 | ])
60 |
61 | grouped_tokens = group_parentheses(tokens)
62 |
63 | stdout = sys.stdout
64 | try:
65 | sys.stdout = StringIO()
66 | expected_tokens._pprint_tree()
67 | a = sys.stdout.getvalue()
68 | sys.stdout = StringIO()
69 | grouped_tokens._pprint_tree()
70 | b = sys.stdout.getvalue()
71 | finally:
72 | sys.stdout = stdout
73 |
74 | assert a == b
75 |
76 |
77 | def test_parse_statements():
78 | sql = '''
79 | SET search_path = 'cover_art_archive';
80 |
81 | CREATE TABLE table_name (
82 | id SERIAL, -- PK
83 | name VARCHAR
84 | );
85 |
86 | CREATE TYPE FLUENCY AS ENUM ('basic', 'intermediate', 'advanced', 'native');
87 | '''
88 | statements = sqlparse.parse(sql)
89 | for statement in statements:
90 | statement._pprint_tree()
91 | print()
92 | statements = parse_statements(statements)
93 | for statement in statements:
94 | print(repr(statement))
95 |
96 |
97 | def test_set_statement():
98 | sql = "SET search_path = 'cover_art_archive';"
99 | statement = next(parse_statements(sqlparse.parse(sql)))
100 |
101 | assert isinstance(statement, Set)
102 | assert 'search_path' == statement.get_name()
103 | assert 'cover_art_archive' == statement.get_value()
104 |
105 |
106 | def test_set_statement_without_quotes():
107 | sql = "SET search_path = cover_art_archive;"
108 | statement = next(parse_statements(sqlparse.parse(sql)))
109 |
110 | assert isinstance(statement, Set)
111 | assert 'search_path' == statement.get_name()
112 | assert 'cover_art_archive' == statement.get_value()
113 |
114 |
115 | def test_set_statement_with_to():
116 | sql = "SET search_path TO 'cover_art_archive';"
117 | statement = next(parse_statements(sqlparse.parse(sql)))
118 |
119 | assert isinstance(statement, Set)
120 | assert 'search_path' == statement.get_name()
121 | assert 'cover_art_archive' == statement.get_value()
122 |
123 |
124 | def test_create_type_statement():
125 | sql = "CREATE TYPE FLUENCY AS ENUM ('basic', 'intermediate');"
126 | statement = next(parse_statements(sqlparse.parse(sql)))
127 |
128 | assert isinstance(statement, CreateType)
129 | assert 'FLUENCY' == statement.get_name()
130 | assert ['basic', 'intermediate'] == statement.get_enum_labels()
131 |
132 |
133 | def test_create_table_statement():
134 | sql = '''
135 | CREATE TABLE table_name (
136 | id SERIAL, -- PK
137 | name VARCHAR(100) NOT NULL,
138 | created TIMESTAMP WITH TIME ZONE DEFAULT now() NOT NULL
139 | );
140 | '''
141 | statement = next(parse_statements(sqlparse.parse(sql)))
142 |
143 | assert isinstance(statement, CreateTable)
144 | assert 'table_name' == statement.get_name()
145 |
146 | columns = list(statement.get_columns())
147 | assert 3 == len(columns)
148 |
149 | column = columns[0]
150 | assert 'id' == column.get_name()
151 | assert 'SERIAL' == column.get_type()
152 | assert None is column.get_default_value()
153 | assert ['-- PK'] == column.get_comments()
154 | assert False is column.is_not_null()
155 | assert None is column.get_check_constraint()
156 |
157 | column = columns[1]
158 | assert 'name' == column.get_name()
159 | assert 'VARCHAR(100)' == column.get_type()
160 | assert None is column.get_default_value()
161 | assert [] == column.get_comments()
162 | assert True is column.is_not_null()
163 | assert None is column.get_check_constraint()
164 |
165 | column = columns[2]
166 | assert 'created' == column.get_name()
167 | assert 'TIMESTAMP WITH TIME ZONE' == column.get_type()
168 | assert 'now()' == column.get_default_value()
169 | assert [] == column.get_comments()
170 | assert True is column.is_not_null()
171 | assert None is column.get_check_constraint()
172 |
173 |
174 | def test_create_table_statement_check_constraint():
175 | sql = '''CREATE TABLE table_name (column INTEGER(2) NOT NULL DEFAULT 0 CHECK (edits_pending > 0)); '''
176 | statement = next(parse_statements(sqlparse.parse(sql)))
177 |
178 | assert isinstance(statement, CreateTable)
179 | columns = list(statement.get_columns())
180 | assert 1 == len(columns)
181 |
182 | column = columns[0]
183 | check = column.get_check_constraint()
184 | assert check
185 | assert None is check.get_name()
186 | assert 'edits_pending>0' == str(check.get_body())
187 |
188 |
189 | def test_create_table_statement_named_check_constraint():
190 | sql = '''CREATE TABLE table_name (column INTEGER(2) NOT NULL DEFAULT 0 CONSTRAINT check_column CHECK (edits_pending > 0)); '''
191 | statement = next(parse_statements(sqlparse.parse(sql)))
192 |
193 | assert isinstance(statement, CreateTable)
194 | columns = list(statement.get_columns())
195 | assert 1 == len(columns)
196 |
197 | column = columns[0]
198 | check = column.get_check_constraint()
199 | assert check
200 | assert 'check_column' == check.get_name()
201 | assert 'edits_pending>0' == str(check.get_body())
202 |
203 |
204 | def test_create_index():
205 | sql = '''CREATE INDEX statistic_name ON statistic (name); '''
206 | statement = next(parse_statements(sqlparse.parse(sql)))
207 |
208 | assert isinstance(statement, CreateIndex)
209 | assert 'statistic_name' == statement.get_name()
210 | assert 'statistic' == statement.get_table()
211 | assert ['name'] == statement.get_columns()
212 | assert not statement.is_unique()
213 |
214 |
215 | def test_create_unique_index():
216 | sql = '''CREATE UNIQUE INDEX statistic_name_date_collected ON statistic (name, date_collected); '''
217 | statement = next(parse_statements(sqlparse.parse(sql)))
218 |
219 | statement._pprint_tree()
220 |
221 | assert isinstance(statement, CreateIndex)
222 | assert 'statistic_name_date_collected' == statement.get_name()
223 | assert 'statistic' == statement.get_table()
224 | assert ['name', 'date_collected'] == statement.get_columns()
225 | assert statement.is_unique()
226 |
--------------------------------------------------------------------------------
/mbdata/tools/__init__.py:
--------------------------------------------------------------------------------
1 | # Copyright (C) 2013 Lukas Lalinsky
2 | # Distributed under the MIT license, see the LICENSE file for details.
3 |
4 |
--------------------------------------------------------------------------------
/mbdata/tools/dump_sample_data.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | from __future__ import print_function
4 | import sys
5 | import argparse
6 | import datetime
7 | import re
8 | import unicodedata
9 | from sqlalchemy import create_engine, inspect
10 | from sqlalchemy.orm import sessionmaker
11 | from sqlalchemy.orm.session import object_session
12 | from sqlalchemy.orm.collections import InstrumentedList
13 | from mbdata.models import (
14 | Area,
15 | Artist,
16 | Label,
17 | LinkAreaArea,
18 | Place,
19 | Recording,
20 | Release,
21 | ReleaseGroup,
22 | Work,
23 | URL,
24 | )
25 | from mbdata.utils.models import query_links
26 | from typing import Dict, Set
27 |
28 |
29 | RELEASE_GIDS = [
30 | '89b1b3ca-07cd-4f67-b9a7-3a3ba86d7149',
31 | '7643ee96-fe19-4b76-aa9a-e8af7d0e9d73',
32 | ]
33 |
34 | PLACE_GIDS = [
35 | 'bd55aeb7-19d1-4607-a500-14b8479d3fed', # Abbey Road Studios
36 | ]
37 |
38 | LABEL_GIDS = [
39 | 'ecc049d0-88a6-4806-a5b7-0f1367a7d6e1', # Studio Ghibli
40 | ]
41 |
42 |
43 | counters = {} # type: Dict[str, int]
44 | in_progress = set() # type: Set[str]
45 | models = set() # type: Set[str]
46 |
47 |
48 | _unaccent_dict = {u'Æ': u'AE', u'æ': u'ae', u'Œ': u'OE', u'œ': u'oe', u'ß': 'ss'}
49 | _re_latin_letter = re.compile(r"^(LATIN [A-Z]+ LETTER [A-Z]+) WITH")
50 |
51 |
52 | def unaccent(string):
53 | result = []
54 | for char in string:
55 | if char in _unaccent_dict:
56 | char = _unaccent_dict[char]
57 | else:
58 | try:
59 | name = unicodedata.name(char)
60 | match = _re_latin_letter.search(name)
61 | if match:
62 | char = unicodedata.lookup(match.group(1))
63 | except Exception:
64 | pass
65 | result.append(char)
66 | return "".join(result)
67 |
68 |
69 | def name_to_variable(name):
70 | return re.sub('_+', '_', re.sub('[^0-9a-z]', '_', unaccent(name).lower())).strip('_')
71 |
72 |
73 | def generate_name(obj):
74 | name = obj.__class__.__name__.lower()
75 | if hasattr(obj, 'name') and obj.name:
76 | suffix = name_to_variable(obj.name)
77 | if not suffix and hasattr(obj, 'sort_name') and obj.sort_name:
78 | suffix = name_to_variable(obj.sort_name)
79 | if suffix:
80 | name = '{0}_{1}'.format(name, suffix)
81 | elif name not in counters:
82 | counters[name] = 0
83 |
84 | if name in counters:
85 | counters[name] += 1
86 | name += '_{0}'.format(counters[name])
87 | else:
88 | counters[name] = 0
89 |
90 | return name
91 |
92 |
93 | def dump_value(value):
94 | if isinstance(value, datetime.datetime):
95 | value = value.replace(tzinfo=None)
96 | return repr(value)
97 |
98 |
99 | def find_name(output, names, obj):
100 | state = inspect(obj)
101 | mapper = state.mapper
102 |
103 | key = state.identity_key
104 | if key in in_progress:
105 | return None
106 |
107 | if key in names:
108 | return names[key]
109 |
110 | in_progress.add(key)
111 | models.add(obj.__class__.__name__)
112 |
113 | name = generate_name(obj)
114 |
115 | code = []
116 | code.append('{0} = {1}()'.format(name, obj.__class__.__name__))
117 |
118 | for attr in mapper.column_attrs:
119 | if sum([len(column.foreign_keys) for column in attr.columns]):
120 | continue
121 | value = getattr(obj, attr.key)
122 | if value is None:
123 | continue
124 | code.append('{0}.{1} = {2}'.format(name, attr.key, dump_value(value)))
125 |
126 | for attr in sorted(mapper.relationships, key=lambda attr: attr.key):
127 | value = getattr(obj, attr.key, None)
128 | if value is None:
129 | continue
130 | if isinstance(value, InstrumentedList):
131 | value_names = []
132 | for item in value:
133 | value_name = find_name(output, names, item)
134 | if value_name is not None:
135 | value_names.append(value_name)
136 | if value_names:
137 | code.append('{0}.{1} = ['.format(name, attr.key))
138 | for value_name in value_names:
139 | code.append(' {0},'.format(value_name))
140 | code.append(']')
141 | else:
142 | value_name = find_name(output, names, value)
143 | if value_name is not None:
144 | code.append('{0}.{1} = {2}'.format(name, attr.key, value_name))
145 |
146 | code.append('session.add({0})'.format(name))
147 |
148 | output.append('\n'.join(code))
149 |
150 | names[key] = name
151 | in_progress.remove(key)
152 |
153 | # special case -- dump parent relationships for areas
154 | if isinstance(obj, Area):
155 | session = object_session(obj)
156 | query = session.query(LinkAreaArea).\
157 | filter(LinkAreaArea.entity1_id == obj.id)
158 | for sub_obj in query:
159 | find_name(output, names, sub_obj)
160 |
161 | # special case -- dump artist/place/label/url relationships for "music" entities
162 | if isinstance(obj, (ReleaseGroup, Release, Recording, Work)):
163 | for target_model in (Artist, Place, Label, URL):
164 | for sub_obj in query_links(obj, target_model):
165 | find_name(output, names, sub_obj)
166 |
167 | # special case -- dump work relationships for recordings and works
168 | if isinstance(obj, (Recording, Work)):
169 | for sub_obj in query_links(obj, Work):
170 | find_name(output, names, sub_obj)
171 |
172 | return name
173 |
174 |
175 | def dump_sample_data(session):
176 | output = []
177 | names = {}
178 |
179 | queries = [
180 | session.query(Release).filter(Release.gid.in_(RELEASE_GIDS)),
181 | session.query(Place).filter(Place.gid.in_(PLACE_GIDS)),
182 | session.query(Label).filter(Label.gid.in_(LABEL_GIDS)),
183 | ]
184 | for query in queries:
185 | for item in query:
186 | find_name(output, names, item)
187 |
188 | print('import datetime')
189 | models_to_import = list(sorted(models))
190 | while models_to_import:
191 | print('from mbdata.models import {0}'.format(', '.join(models_to_import[:5])))
192 | models_to_import = models_to_import[5:]
193 | print()
194 | print()
195 |
196 | print('def create_sample_data(session):')
197 |
198 | for line in '\n\n'.join(output).splitlines():
199 | if not line:
200 | print()
201 | else:
202 | print(' ' + line)
203 |
204 | print()
205 | print(' session.commit()')
206 |
207 |
208 | if __name__ == '__main__':
209 | parser = argparse.ArgumentParser()
210 | parser.add_argument('-d', dest='db_uri')
211 | args = parser.parse_args()
212 |
213 | engine = create_engine(args.db_uri)
214 | Session = sessionmaker(bind=engine)
215 | session = Session()
216 |
217 | dump_sample_data(session)
218 |
--------------------------------------------------------------------------------
/mbdata/types.py:
--------------------------------------------------------------------------------
1 | # Copyright (C) 2013 Lukas Lalinsky
2 | # Distributed under the MIT license, see the LICENSE file for details.
3 |
4 | import re
5 | from sqlalchemy.ext.compiler import compiles
6 | from sqlalchemy.types import UserDefinedType
7 | from sqlalchemy.sql.expression import ClauseElement, TextClause
8 | try:
9 | from sqlalchemy.dialects.postgresql import UUID, SMALLINT, BIGINT, JSONB
10 | except ImportError:
11 | from sqlalchemy.dialects.postgres import UUID, SMALLINT, BIGINT, JSONB
12 |
13 |
14 | @compiles(UUID, 'sqlite')
15 | def visit_uuid_sqlite(element, compiler, **kwargs):
16 | return 'CHAR(32)'
17 |
18 |
19 | # XXX this should really serialize/deserialize to JSON
20 | @compiles(JSONB, 'sqlite')
21 | def visit_jsonb_sqlite(element, compiler, **kwargs):
22 | return 'TEXT'
23 |
24 |
25 | class regexp(ClauseElement):
26 | def __init__(self, column, pattern):
27 | self.column = column
28 | self.pattern = TextClause(pattern)
29 |
30 |
31 | @compiles(regexp)
32 | def visit_regexp(element, compiler, **kwargs):
33 | return '{0} REGEXP {1}'.format(
34 | compiler.process(element.column),
35 | compiler.process(element.pattern))
36 |
37 |
38 | @compiles(regexp, 'postgresql')
39 | def visit_regexp_postgresql(element, compiler, **kwargs):
40 | return '{0} ~ {1}'.format(
41 | compiler.process(element.column),
42 | compiler.process(element.pattern))
43 |
44 |
45 | class PartialDate(object):
46 |
47 | __slots__ = ('year', 'month', 'day')
48 |
49 | def __init__(self, year=None, month=None, day=None):
50 | self.year = year
51 | self.month = month
52 | self.day = day
53 |
54 | def __composite_values__(self):
55 | return self.year, self.month, self.day
56 |
57 | def __iter__(self):
58 | yield self.year
59 | yield self.month
60 | yield self.day
61 |
62 | def __repr__(self):
63 | return "{0.__class__.__name__}(year={0.year}, month={0.month}, day={0.day})".format(self)
64 |
65 | def __eq__(self, other):
66 | return isinstance(other, PartialDate) and \
67 | other.year == self.year and \
68 | other.month == self.month and \
69 | other.day == self.day
70 |
71 | def __hash__(self):
72 | return hash((self.year, self.month, self.day))
73 |
74 | def __ne__(self, other):
75 | return not self.__eq__(other)
76 |
77 | def __bool__(self):
78 | return bool(self.year or self.month or self.day)
79 |
80 | __nonzero__ = __bool__
81 |
82 |
83 | class Point(UserDefinedType):
84 |
85 | # pylint: disable=W0223
86 | # pylint: disable=R0201
87 |
88 | def get_col_spec(self):
89 | return 'POINT'
90 |
91 | def bind_processor(self, dialect):
92 | def process(value):
93 | if value is None:
94 | return None
95 | return '({0},{1})'.format(value[0], value[1])
96 | return process
97 |
98 | def result_processor(self, dialect, coltype):
99 | def process(value):
100 | if value is None:
101 | return None
102 | match = re.match(r'\((-?[0-9.]+),(-?[0-9.]+)\)', value)
103 | return tuple([float(x) for x in match.groups()])
104 | return process
105 |
106 |
107 | class Cube(UserDefinedType):
108 |
109 | # pylint: disable=W0223
110 | # pylint: disable=R0201
111 |
112 | def get_col_spec(self):
113 | return 'CUBE'
114 |
115 | def bind_processor(self, dialect):
116 | def process(value):
117 | if value is None:
118 | return None
119 | return value
120 | return process
121 |
122 | def result_processor(self, dialect, coltype):
123 | def process(value):
124 | if value is None:
125 | return None
126 | return value
127 | return process
128 |
129 |
--------------------------------------------------------------------------------
/mbdata/utils/__init__.py:
--------------------------------------------------------------------------------
1 | # Copyright (C) 2013 Lukas Lalinsky
2 | # Distributed under the MIT license, see the LICENSE file for details.
3 |
4 | NO_SCHEMAS = {
5 | 'musicbrainz': None,
6 | 'cover_art_archive': None,
7 | 'wikidocs': None,
8 | 'statistics': None,
9 | 'documentation': None,
10 | }
11 |
12 | SINGLE_MUSICBRAINZ_SCHEMA = {
13 | 'musicbrainz': 'musicbrainz',
14 | 'cover_art_archive': 'musicbrainz',
15 | 'wikidocs': 'musicbrainz',
16 | 'statistics': 'musicbrainz',
17 | 'documentation': 'musicbrainz',
18 | }
19 |
20 |
21 | def patch_model_schemas(mapping):
22 | """Update mbdata.models to use different schema names
23 |
24 | The function accepts a dictionary with schema name mapping
25 | and updates the schema for all MusicBrainz tables.
26 |
27 | If you want to use the default schema:
28 |
29 | >>> patch_model_schemas(NO_SCHEMAS)
30 |
31 | If you have just one 'musicbrainz' schema:
32 |
33 | >>> patch_model_schemas(SINGLE_MUSICBRAINZ_SCHEMA)
34 |
35 | """
36 | from mbdata.models import Base
37 |
38 | for table in Base.metadata.sorted_tables:
39 | if table.schema is None:
40 | continue
41 | table.schema = mapping.get(table.schema, table.schema)
42 |
43 |
44 | def get_something_by_gid(query, redirect_model, gid):
45 | artist = query.filter_by(gid=gid).first()
46 | if artist is None:
47 | subquery = query.session.query(redirect_model.redirect_id).\
48 | filter_by(gid=gid)
49 | artist = query.filter(redirect_model.redirect.property.primaryjoin.left.in_(subquery)).first()
50 | return artist
51 |
52 |
--------------------------------------------------------------------------------
/mbdata/utils/models.py:
--------------------------------------------------------------------------------
1 | from mbdata import models
2 | from sqlalchemy import inspect
3 | from sqlalchemy.orm.session import object_session
4 |
5 |
6 | ENTITY_TYPES = {
7 | 'artist': models.Artist,
8 | 'label': models.Label,
9 | 'place': models.Place,
10 | 'release_group': models.ReleaseGroup,
11 | 'release': models.Release,
12 | 'url': models.URL,
13 | 'work': models.Work,
14 | }
15 |
16 |
17 | def get_entity_type_model(type):
18 | return ENTITY_TYPES[type]
19 |
20 |
21 | def get_link_model(entity0, entity1):
22 | names = sorted([entity0.__name__, entity1.__name__])
23 | assert all(hasattr(models, name) for name in names)
24 | return getattr(models, 'Link{0}{1}'.format(*names))
25 |
26 |
27 | def get_link_target(link, source):
28 | model = inspect(link).mapper.class_
29 | source_model = inspect(source).mapper.class_
30 |
31 | if source_model != model.entity0.property.mapper.class_:
32 | return link.entity0
33 |
34 | if source_model != model.entity1.property.mapper.class_:
35 | return link.entity1
36 |
37 | if source.id != link.entity0_id:
38 | return link.entity0
39 |
40 | if source.id != link.entity1_id:
41 | return link.entity1
42 |
43 |
44 | def query_links(obj, target_model):
45 | session = object_session(obj)
46 | model = get_link_model(inspect(obj).mapper.class_, target_model)
47 | query = session.query(model)
48 |
49 | if isinstance(obj, model.entity0.property.mapper.class_):
50 | query = query.filter_by(entity0=obj)
51 |
52 | if isinstance(obj, model.entity1.property.mapper.class_):
53 | query = query.filter_by(entity1=obj)
54 |
55 | return query
56 |
57 |
--------------------------------------------------------------------------------
/pyproject.toml:
--------------------------------------------------------------------------------
1 | [project]
2 | name = "mbdata"
3 | description = "MusicBrainz Database Tools"
4 | readme = "README.rst"
5 | authors = [
6 | { name = "MetaBrainz Foundation", email = "support@metabrainz.org"},
7 | { name = "Lukáš Lalinský", email = ""},
8 | ]
9 | license = "MIT"
10 | dynamic = ["version"]
11 |
12 | [tool.poetry]
13 | version = "0.0.0"
14 |
15 | [tool.poetry.dependencies]
16 | python = "^3.7"
17 | SQLAlchemy = {version = "^1.4.29", optional = true}
18 | lxml = {version = "^4.9.1", optional = true}
19 | six = "^1.16.0"
20 |
21 | [tool.poetry.group.dev.dependencies]
22 | flake8 = "^5.0.0"
23 | psycopg2 = "^2.9.2"
24 | sqlparse = "^0.4.4"
25 | pytest = "^7.2.0"
26 | mypy = "^0.991"
27 | types-six = "^1.16.21"
28 | types-psycopg2 = "^2.9.21"
29 |
30 | [tool.poetry.extras]
31 | search = ["lxml"]
32 | models = ["SQLAlchemy"]
33 |
34 | [tool.poetry-dynamic-versioning]
35 | enable = true
36 |
37 | [build-system]
38 | requires = ["poetry-core>=2.0.0,<3.0.0", "poetry-dynamic-versioning>=1.0.0,<2.0.0"]
39 | build-backend = "poetry_dynamic_versioning.backend"
40 |
--------------------------------------------------------------------------------
/scripts/create_sample_db.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 |
3 | from __future__ import print_function
4 | import os
5 | import sys
6 |
7 | import argparse
8 | from sqlalchemy import create_engine
9 | from sqlalchemy.orm import sessionmaker
10 |
11 | import mbdata.config
12 | mbdata.config.configure(schema=None)
13 | mbdata.config.freeze()
14 |
15 | from mbdata.sample_data import create_sample_data # noqa: E402
16 | from mbdata.models import Base # noqa: E402
17 |
18 |
19 | parser = argparse.ArgumentParser(add_help=True,
20 | description='Create a small sample database.')
21 | parser.add_argument('file', help='path of the db-file')
22 | parser.add_argument('--overwrite', '-o', action='store_true',
23 | default=False, help='silently overwrite db-file')
24 | args = parser.parse_args()
25 |
26 | if os.path.isfile(args.file):
27 | if args.overwrite:
28 | os.remove(args.file)
29 | else:
30 | print("Error: Database file already exists. You may want to use the '-o' flag.", file=sys.stderr)
31 | sys.exit(1)
32 |
33 | engine = create_engine('sqlite:///' + args.file)
34 | Base.metadata.create_all(engine)
35 |
36 | Session = sessionmaker(bind=engine)
37 | session = Session()
38 | create_sample_data(session)
39 |
--------------------------------------------------------------------------------
/scripts/create_solr_home.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 |
3 | import os
4 | import argparse
5 |
6 | from mbdata.search import create_solr_home
7 |
8 | parser = argparse.ArgumentParser()
9 | parser.add_argument('-d', '--directory', required=True)
10 | args = parser.parse_args()
11 |
12 | # TODO allow custom core name
13 | # TODO allow creating just a core in an existing Solr home
14 |
15 | create_solr_home(args.directory)
16 | print(open(os.path.join(args.directory, 'README.txt')).read())
17 |
18 |
--------------------------------------------------------------------------------
/scripts/dump_sample_data.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | python -m mbdata.tools.dump_sample_data -d "$1" >mbdata/sample_data.py
4 |
5 |
--------------------------------------------------------------------------------
/scripts/export_solr_triggers.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 |
3 | import argparse
4 |
5 | from sqlalchemy import create_engine
6 | from sqlalchemy.orm import sessionmaker
7 |
8 | import settings
9 | from mbdata.search import export_triggers
10 |
11 |
12 | parser = argparse.ArgumentParser()
13 | args = parser.parse_args()
14 |
15 | engine = create_engine(settings.DATABASE_URI, echo=False)
16 | Session = sessionmaker(bind=engine)
17 | db = Session()
18 |
19 | export_triggers(db)
20 |
21 |
--------------------------------------------------------------------------------
/scripts/update_models.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | python -m mbdata.tools.genmodels \
4 | mbdata/sql/CreateTypes.sql \
5 | mbdata/sql/CreateTables.sql \
6 | mbdata/sql/caa/CreateTables.sql \
7 | mbdata/sql/wikidocs/CreateTables.sql \
8 | mbdata/sql/documentation/CreateTables.sql \
9 | mbdata/sql/statistics/CreateTables.sql \
10 | >mbdata/models.py
11 |
--------------------------------------------------------------------------------
/scripts/update_sql.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | cd $(dirname $0)/../mbdata
4 |
5 | GIT_TARGET="${1:-v-2024-05-13-schema-change}"
6 |
7 | rm -rf sql
8 |
9 | rm -rf /tmp/mbserver-clone
10 | mkdir /tmp/mbserver-clone
11 |
12 | curl -L -o "/tmp/mbserver-clone/$GIT_TARGET.tar.gz" "https://github.com/metabrainz/musicbrainz-server/archive/$GIT_TARGET.tar.gz"
13 | tar -x -f "/tmp/mbserver-clone/$GIT_TARGET.tar.gz" --strip-components=2 --wildcards "musicbrainz-server-$GIT_TARGET/admin/sql/*"
14 | rm -rf /tmp/mbserver-clone
15 |
16 | echo '\set ON_ERROR_STOP 1' >sql/CreateCollateIndexes.sql
17 | echo 'BEGIN;' >>sql/CreateCollateIndexes.sql
18 | grep _collate sql/CreateIndexes.sql >> sql/CreateCollateIndexes.sql
19 | echo 'COMMIT;' >>sql/CreateCollateIndexes.sql
20 |
21 | echo '\set ON_ERROR_STOP 1' >sql/DropCollateIndexes.sql
22 | grep _collate sql/DropIndexes.sql >> sql/DropCollateIndexes.sql
23 |
24 | mv sql/CreateIndexes.sql sql/CreateIndexes.sql.remove
25 | grep -v _collate sql/CreateIndexes.sql.remove >> sql/CreateIndexes.sql
26 | rm sql/CreateIndexes.sql.remove
27 |
28 | mv sql/DropIndexes.sql sql/DropIndexes.sql.remove
29 | grep -v _collate sql/DropIndexes.sql.remove >> sql/DropIndexes.sql
30 | rm sql/DropIndexes.sql.remove
31 |
32 | rm -rf sql/updates
33 |
--------------------------------------------------------------------------------
/scripts/upload_to_pypi.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | set -ex
4 |
5 | rm -rf dist/
6 | python setup.py sdist
7 | twine upload dist/mbdata-*.tar.gz
8 |
--------------------------------------------------------------------------------
/settings.py.sample:
--------------------------------------------------------------------------------
1 | DATABASE_URI = 'postgresql://musicbrainz:FIXME@127.0.0.1/musicbrainz'
2 |
3 | SOLR_URI = 'http://127.0.0.1:8983/solr/musicbrainz'
4 |
5 |
--------------------------------------------------------------------------------