浏览代码

AMBARI-20886. Create idempotent Ambari DB Schema SQL script for AzureDB

Attila Doroszlai 8 年之前
父节点
当前提交
928f80908d

+ 13 - 0
ambari-server/pom.xml

@@ -669,6 +669,19 @@
               <goal>exec</goal>
               <goal>exec</goal>
             </goals>
             </goals>
           </execution>
           </execution>
+          <execution>
+            <configuration>
+              <executable>${project.basedir}/src/main/sh/azuredb_create_generator.sh</executable>
+              <arguments>
+                <argument>${project.basedir}</argument>
+              </arguments>
+            </configuration>
+            <id>azuredb-gen</id>
+            <phase>generate-resources</phase>
+            <goals>
+              <goal>exec</goal>
+            </goals>
+          </execution>
         </executions>
         </executions>
       </plugin>
       </plugin>
       <plugin>
       <plugin>

+ 5 - 0
ambari-server/src/main/assemblies/server.xml

@@ -332,6 +332,11 @@
       <source>src/main/resources/Ambari-DDL-MySQL-DROP.sql</source>
       <source>src/main/resources/Ambari-DDL-MySQL-DROP.sql</source>
       <outputDirectory>/var/lib/ambari-server/resources</outputDirectory>
       <outputDirectory>/var/lib/ambari-server/resources</outputDirectory>
     </file>
     </file>
+    <file>
+      <fileMode>755</fileMode>
+      <source>target/classes/Ambari-DDL-AzureDB-CREATE.sql</source>
+      <outputDirectory>/var/lib/ambari-server/resources</outputDirectory>
+    </file>
     <file>
     <file>
       <fileMode>755</fileMode>
       <fileMode>755</fileMode>
       <source>target/classes/Ambari-DDL-SQLServer-CREATE.sql</source>
       <source>target/classes/Ambari-DDL-SQLServer-CREATE.sql</source>

+ 81 - 0
ambari-server/src/main/python/azuredb_create_generator.py

@@ -0,0 +1,81 @@
+#!/usr/bin/env python
+
+'''
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+'''
+
+# This script transforms SQLServer "create" SQL to idempotent SQL for AzureDB.
+# It is a filter, ie. it expects input on stdin, and prints output on stdout.
+
+import fileinput
+import re
+from textwrap import dedent
+
+input_sql = "".join(fileinput.input())
+input_statements = re.split(';', input_sql)
+statements = []
+for statement in input_statements:
+  # wrap "CREATE TABLE" in IF for existence check
+  statement = re.sub(
+    "CREATE TABLE ([^\s(]+).*",
+    dedent('''\
+      IF NOT EXISTS (SELECT 1 FROM sys.objects WHERE object_id = OBJECT_ID('dbo.\g<1>') AND type = 'U')
+      BEGIN
+      \g<0>
+      END
+      '''),
+    statement,
+    flags = re.DOTALL | re.IGNORECASE)
+
+  # wrap "CREATE INDEX" in IF for existence check
+  statement = re.sub("CREATE(?: NONCLUSTERED)? INDEX ([^ (]+).*",
+    dedent('''\
+      IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE name = '\g<1>')
+      BEGIN
+      \g<0>
+      END
+      '''),
+    statement,
+    flags = re.DOTALL | re.IGNORECASE)
+
+  # wrap "ALTER TABLE ... ADD CONSTRAINT ... FOREIGN KEY" in IF for existence check
+  statement = re.sub("ALTER TABLE \S+ ADD CONSTRAINT (\S+) FOREIGN KEY.*",
+    dedent('''\
+      IF NOT EXISTS (SELECT 1 FROM sys.objects WHERE object_id = OBJECT_ID('\g<1>') AND type = 'F')
+      BEGIN
+      \g<0>
+      END
+      '''),
+    statement,
+    flags = re.DOTALL | re.IGNORECASE)
+
+  statements.append(statement)
+
+# find all INSERT statements, create a matching DELETE in reverse order, only one per table
+sql = "".join(statements)
+inserts = re.findall("INSERT INTO ([^ (]+)", sql, flags = re.IGNORECASE)
+tables = set()
+deletes = []
+for table in inserts:
+  if table not in tables:
+    deletes.append("  DELETE {0};".format(table))
+    tables.add(table)
+deletes.reverse()
+delete_sql = "\n".join(deletes)
+sql = re.sub("BEGIN TRANSACTION", "\g<0>\n" + delete_sql, sql, count=1)
+
+print sql

+ 1 - 0
ambari-server/src/main/resources/.gitignore

@@ -0,0 +1 @@
+Ambari-DDL-AzureDB-CREATE.sql

+ 26 - 0
ambari-server/src/main/sh/azuredb_create_generator.sh

@@ -0,0 +1,26 @@
+#!/usr/bin/env bash
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Creates an idempotent SQL script for AzureDB from the SQLServer "create" script.
+
+sql_dir="$1"/src/main/resources
+script_dir="$1"/src/main/python
+
+[[ -e "$sql_dir"/Ambari-DDL-SQLServer-CREATE.sql ]] || exit 1
+[[ -x "$script_dir"/azuredb_create_generator.py ]] || exit 2
+
+cat "$sql_dir"/Ambari-DDL-SQLServer-CREATE.sql | "$script_dir"/azuredb_create_generator.py > "$sql_dir"/Ambari-DDL-AzureDB-CREATE.sql