--
-- Workbench Utility Plugins
--


--
-- standard module/plugin functions
-- 

function getModuleInfo()
	return {
		name= "WbUtils",
		author= "MySQL AB.",
		version= "1.0",
		implements= "PluginInterface",
		functions= {
		"getPluginInfo:l<o@app.Plugin>:",
		"copySQLToClipboard:i:o@db.DatabaseObject",
		"copyTableListToClipboard:i:o@db.Catalog",
        "obfuscateCatalog:i:o@db.Catalog",
        "prefixTables:i:o@db.Catalog",
        "generateIndexes:i:o@db.Catalog"
		}
	}
end


-- helper function to create a descriptor for an argument of a specific type of object
function objectPluginInput(type)
	return grtV.newObj("app.PluginObjectInput", {objectStructName= type})
end

function getPluginInfo()
	local l
    local plugin

    -- create the list of plugins that this module exports
	l= new_plugin_list()

    plugin= new_plugin({
		name= "wb.util.copySQLToClipboard",
        	caption= "Copy SQL to Clipboard",
		moduleName= "WbUtils",
		pluginType= "normal", 
		moduleFunctionName= "copySQLToClipboard",
		inputValues= {objectPluginInput("db.DatabaseObject")},
		groups= {"Catalog/Utilities", "Menu/Objects"}
	})
    -- add to the list of plugins
    grtV.insert(l, plugin)

    plugin= new_plugin({
		name= "wb.util.copyTableListToClipboard",
        caption= "Copy Table List to Clipboard",
		moduleName= "WbUtils",
		pluginType= "normal", 
		moduleFunctionName= "copyTableListToClipboard",
		inputValues= {objectPluginInput("db.Catalog")},
		groups= {"Catalog/Utilities", "Menu/Catalog"}
	})
    -- add to the list of plugins
    grtV.insert(l, plugin)

    plugin= new_plugin({
		name= "wb.util.obfuscateCatalog",
        caption= "Obfuscate Object Names in Catalog",
		moduleName= "WbUtils",
		pluginType= "normal", 
		moduleFunctionName= "obfuscateCatalog",
		inputValues= {objectPluginInput("db.Catalog")},
		rating= 100, 
		showProgress= 0,
		groups= {"Catalog/Utilities", "Menu/Utilities"}
	})
    -- add to the list of plugins
    grtV.insert(l, plugin)

    plugin= new_plugin({
		name= "wb.util.prefixTables",
        caption= "Give a Prefix to All Tables in Catalog",
		moduleName= "WbUtils",
		pluginType= "normal", 
		moduleFunctionName= "prefixTables",
		inputValues= {objectPluginInput("db.Catalog")},
		rating= 100, 
		showProgress= 0,
		groups= {"Catalog/Utilities", "Menu/Catalog"}
	})
    -- add to the list of plugins
    grtV.insert(l, plugin)

    plugin= new_plugin({
		name= "wb.util.generateIndexes",
        caption= "Put Indexes on Columns with Usertypes KEY and LookupString",
		moduleName= "WbUtils",
		pluginType= "normal", 
		moduleFunctionName= "generateIndexes",
		inputValues= {objectPluginInput("db.Catalog")},
		rating= 100, 
		showProgress= 0,
		groups= {"Catalog/Utilities", "Menu/Utilities"}
	})
    -- add to the list of plugins
    grtV.insert(l, plugin)

    return l
end

--    
-- implementation
--

function copySQLToClipboard(object)

	local script= DbMySQL:makeCreateScriptForObject(object)
    Workbench:copyToClipboard(script)

	return 0
end


function copyTableListToClipboard(cat)

    local i, j, schema, tbl
	local script = ""
    local separator = ""
    local insert = ""
    
    for i = 1, grtV.getn(cat.schemata) do
        schema = cat.schemata[i]
        for j = 1, grtV.getn(schema.tables) do
            tbl = schema.tables[j]
            insert = insert .. separator .. "`" .. schema.name .. "`.`" .. tbl.name .. "`"
            separator = ", "
        end
    end
    
    Workbench:copyToClipboard(insert)

	return 0
end

local function generateName(name_prefix, map)
    local i
    local name_suffix = 0
    local byte_a = string.byte('a')
    
    while 1 do
        for i = 0, 25 do
            local next_name
            if name_prefix == "" then
                next_name = string.char(byte_a + i) .. name_suffix
            else
                next_name = name_prefix .. name_suffix
            end
            
            if map[next_name] == nil then
                map[next_name] = 1
                return next_name
            end
        end
        
        name_suffix = name_suffix + 1
    end -- while        
end

function obfuscateCatalog(cat)
    local alphabet = {}
    local i
    
    local i, j, schema, tbl
    local schemata_map = {}

    if(Workbench:confirm(
        "Warning",
        "This operation will change names of all schemata and tables in the model. Proceed?") == 0) then
        return
    end

    if(Workbench:confirm(
        "Warning",
        "ATTENTION: This action cannot be undone! Proceed anyway?") == 0) then
        return
    end

    for i = 1, grtV.getn(cat.schemata) do
        local table_map = {}
        schema = cat.schemata[i]
        schema.name = generateName("", schemata_map)

        for j = 1, grtV.getn(schema.tables) do
            tbl = schema.tables[j]
            tbl.name = generateName("", table_map)
        end
    end
end

function prefixTables(cat)
    local prefix = Workbench:input("Please specify the prefix")
    
    if prefix == nil then
        return
    end
    
    local i, j

    for i = 1, grtV.getn(cat.schemata) do
        schema = cat.schemata[i]
        for j = 1, grtV.getn(schema.tables) do
            tbl = schema.tables[j]
            tbl.name = prefix .. tbl.name
        end
    end
end

function generateIndexes(cat)
    local function addToList(list, object)
        list[grtV.getn(list)+1] = object
    end
    
    local function nameMapForList(list)
	local i
	local map = {}
    
	for i = 1, grtV.getn(list) do
		map[list[i].name] = 1
	end
	
	return map
    end
    
    local function createIndex(tbl, col)
        local index_name = generateName("ix", nameMapForList(tbl.indices))
        
        local index = grtV.newObj("db.mysql.Index")
        index.owner = tbl
        index.name = index_name
        
        local index_column = grtV.newObj("db.mysql.IndexColumn")
        index_column.owner = index
        index_column.name = col.name
        index_column.referencedColumn = col
        
        addToList(index.columns, index_column)
        addToList(tbl.indices, index)

        return index
    end
    
    local i, j, k
    
    for i = 1, grtV.getn(cat.schemata) do
        schema = cat.schemata[i]
        for j = 1, grtV.getn(schema.tables) do
            tbl = schema.tables[j]
            for k = 1, grtV.getn(tbl.columns) do
                column = tbl.columns[k]
                if column.userType ~= nil then
                    if column.userType.name == "KEY" then
                        createIndex(tbl, column)
                    elseif column.userType.name == "LookupString" then
                        createIndex(tbl, column)
                    end
                end
            end
        end
    end
end
