plugin/pfs_table_plugin/pfs_example_plugin_employee.cc (248 lines of code) (raw):

/* Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include <mysql/plugin.h> #include <mysql_version.h> #include "pfs_example_employee_name.h" #include "pfs_example_employee_salary.h" #include "pfs_example_machine.h" #include "pfs_example_machines_by_emp_by_mtype.h" /** @page EXAMPLE_PLUGIN An example plugin Plugin Name : pfs_example_plugin_employee \n Source location : plugin/pfs_table_plugin This file contains a definition of the pfs_example_plugin_employee. */ /* clang-format off */ /* Records to be inserted into pfs_example_employee_name table from plugin code */ Ename_Record ename_array[] = { {{1, false}, "foo1", 4, "bar1", 4, true}, {{2, false}, "foo2", 4, "bar2", 4, true}, {{3, false}, "foo3", 4, "bar3", 4, true} }; /* Records to be inserted into pfs_example_employee_salary table from plugin code */ Esalary_Record esalary_array[] = { {{1, false}, {1000, false}, "2013-11-12", 10, "12:02:34", 8, true}, {{2, false}, {2000, false}, "2016-02-29", 10, "12:12:30", 8, true}, {{3, false}, {3000, false}, "2017-03-24", 10, "11:12:50", 8, true} }; /* Records to be inserted into pfs_example_machine table from plugin code */ Machine_Record machine_array[] = { {{1, false}, {DESKTOP, false}, "Lenovo", 6, {1, false}, true}, {{2, false}, {LAPTOP, false}, "Dell", 4, {2, false}, true}, {{3, false}, {MOBILE, false}, "Apple", 5, {1, false}, true}, {{4, false}, {MOBILE, false}, "Samsung", 7, {1, false}, true}, {{5, false}, {LAPTOP, false}, "Lenovo", 6, {2, false}, true}, {{6, false}, {MOBILE, false}, "Nokia", 5, {2, false}, true}, {{7, false}, {LAPTOP, false}, "Apple", 5, {1, false}, true}, {{8, false}, {LAPTOP, false}, "HP", 2, {3, false}, true}, {{9, false}, {DESKTOP, false}, "Apple", 5, {3, false}, true}, }; /* clang-format off */ /* Global handles */ SERVICE_TYPE(registry) *r = NULL; my_h_service h_ret_table_svc = NULL; SERVICE_TYPE(pfs_plugin_table) *table_svc = NULL; /* Collection of table shares to be added to performance schema */ PFS_engine_table_share_proxy* share_list[4]= {NULL, NULL, NULL, NULL}; unsigned int share_list_count= 4; /** * acquire_service_handles does following: * - Acquire the registry service for mysql_server. * - Acquire pfs_plugin_table service implementation. */ bool acquire_service_handles(MYSQL_PLUGIN p) { bool result = false; /* Acquire mysql_server's registry service */ r = mysql_plugin_registry_acquire(); if (!r) { my_plugin_log_message( &p, MY_ERROR_LEVEL, "mysql_plugin_registry_acquire() returns empty"); result = true; goto error; } /* Acquire pfs_plugin_table service */ if (r->acquire("pfs_plugin_table", &h_ret_table_svc)) { my_plugin_log_message( &p, MY_ERROR_LEVEL, "can't find pfs_plugin_table service"); result = true; goto error; } /* Type cast this handler to proper service handle */ table_svc = reinterpret_cast<SERVICE_TYPE(pfs_plugin_table) *>(h_ret_table_svc); error: return result; } /** * release_service_handles does following: * - Release the handle to the pfs_plugin_table service. * - Release the handle to registry service. */ void release_service_handles() { if (r != NULL) { if (h_ret_table_svc != NULL) { /* Release pfs_plugin_table and pfs_plugin_table services */ r->release(h_ret_table_svc); h_ret_table_svc = NULL; table_svc = NULL; } /* Release registry service */ mysql_plugin_registry_release(r); r = NULL; } } /* Prepare and insert rows in pfs_example_employee_name table */ int ename_prepare_insert_row() { int result = 0; Ename_Table_Handle handle; int array_size= sizeof(ename_array) / sizeof(ename_array[0]); for (int i = 0; i < array_size; i++) { strncpy(handle.current_row.f_name, ename_array[i].f_name, ename_array[i].f_name_length); handle.current_row.f_name_length = ename_array[i].f_name_length; strncpy(handle.current_row.l_name, ename_array[i].l_name, ename_array[i].l_name_length); handle.current_row.l_name_length = ename_array[i].l_name_length; handle.current_row.e_number = ename_array[i].e_number; handle.current_row.m_exist = ename_array[i].m_exist; /* Insert a row in the table to be added */ result = ename_write_row_values((PSI_table_handle *)&handle); if (result) break; } return result; } /* Prepare and insert rows in pfs_example_employee_salary table */ int esalary_prepare_insert_row() { int result = 0; Esalary_Table_Handle handle; int array_size= sizeof(esalary_array) / sizeof(esalary_array[0]); for (int i = 0; i < array_size; i++) { strncpy(handle.current_row.e_dob, esalary_array[i].e_dob, esalary_array[i].e_dob_length); handle.current_row.e_dob_length= esalary_array[i].e_dob_length; strncpy(handle.current_row.e_tob, esalary_array[i].e_tob, esalary_array[i].e_tob_length); handle.current_row.e_tob_length= esalary_array[i].e_tob_length; handle.current_row.e_number = esalary_array[i].e_number; handle.current_row.e_salary = esalary_array[i].e_salary; handle.current_row.m_exist = esalary_array[i].m_exist; /* Insert a row in the table to be added */ result = esalary_write_row_values((PSI_table_handle *)&handle); if (result) break; } return result; } /* Prepare and insert rows in pfs_example_machine table */ int machine_prepare_insert_row() { int result = 0; Machine_Table_Handle handle; int array_size= sizeof(machine_array) / sizeof(machine_array[0]); for (int i = 0; i < array_size; i++) { handle.current_row.machine_number = machine_array[i].machine_number; strncpy(handle.current_row.machine_made, machine_array[i].machine_made, machine_array[i].machine_made_length); handle.current_row.machine_made_length = machine_array[i].machine_made_length; handle.current_row.machine_type = machine_array[i].machine_type; handle.current_row.employee_number = machine_array[i].employee_number; handle.current_row.m_exist = machine_array[i].m_exist; /* Insert a row in the table to be added */ result = machine_write_row_values((PSI_table_handle *)&handle); if (result) break; } return result; } /** * pfs_example_func does following : * - Instantiate PFS_engine_table_share_proxy(s). * - Prepare and insert rows in tables from here. * - Acquire pfs_plugin_table service handle. * - Call add_table method of pfs_plugin_table service. * Error messages are written to the server's error log. * In case of success writes a single information message to the server's log. * @retval false success * @retval true failure */ static bool pfs_example_func(MYSQL_PLUGIN p) { bool result = false; /* Instantiate and initialize PFS_engine_table_share_proxy */ init_ename_share(&ename_st_share); init_esalary_share(&esalary_st_share); init_machine_share(&machine_st_share); init_m_by_emp_by_mtype_share(&m_by_emp_by_mtype_st_share); /* From here, prepare rows for tables and insert */ if (ename_prepare_insert_row() || esalary_prepare_insert_row() || machine_prepare_insert_row()) { my_plugin_log_message( &p, MY_ERROR_LEVEL, "Error returned during prepare and insert row."); result = true; goto error; } /* Get pfs_plugin_table service handle. */ result = acquire_service_handles(p); if (result) goto error; /* Prepare the shares list to be passed to the service call */ share_list[0]= &ename_st_share; share_list[1]= &esalary_st_share; share_list[2]= &machine_st_share; share_list[3]= &m_by_emp_by_mtype_st_share; /** * Call add_tables function of pfs_plugin_table service to * add plugin tables in performance schema. */ if (table_svc->add_tables(&share_list[0], share_list_count)) { my_plugin_log_message( &p, MY_ERROR_LEVEL, "Error returned from add_tables()"); result = true; goto error; } return result; error: /* Release service handles. */ release_service_handles(); return result; } /** * Initialize the pfs_example_plugin_employee at server start or plugin * installation. * * - Call pfs_example_func. */ static int pfs_example_plugin_employee_init(void *p) { DBUG_ENTER("pfs_example_plugin_employee_init"); int result = 0; /* Initialize mutexes to be used for table records */ mysql_mutex_init(0, &LOCK_ename_records_array, MY_MUTEX_INIT_FAST); mysql_mutex_init(0, &LOCK_esalary_records_array, MY_MUTEX_INIT_FAST); mysql_mutex_init(0, &LOCK_machine_records_array, MY_MUTEX_INIT_FAST); result = pfs_example_func(reinterpret_cast<MYSQL_PLUGIN>(p)) ? 1 : 0; if (result) { /* Destroy mutexes for table records */ mysql_mutex_destroy(&LOCK_ename_records_array); mysql_mutex_destroy(&LOCK_esalary_records_array); mysql_mutex_destroy(&LOCK_machine_records_array); } DBUG_RETURN(result); } static int pfs_example_plugin_employee_check(void *) { DBUG_ENTER("pfs_example_plugin_employee_check"); if (table_svc != NULL) { if (table_svc->delete_tables(&share_list[0], share_list_count)) { /* Block execution of UNINSTALL PLUGIN. */ DBUG_RETURN(1); } } DBUG_RETURN(0); } /** * Terminate the pfs_example_plugin_employee at server shutdown or plugin * deinstallation. * * - Delete/Drop plugin tables from Performance Schema. * - Release pfs_plugin_table service handle. */ static int pfs_example_plugin_employee_deinit(void *p) { DBUG_ENTER("pfs_example_plugin_employee_deinit"); /** * Call delete_tables function of pfs_plugin_table service to * delete plugin tables from performance schema */ if (table_svc != NULL) { if (table_svc->delete_tables(&share_list[0], share_list_count)) { my_plugin_log_message( &p, MY_ERROR_LEVEL, "Error returned from delete_tables()"); DBUG_RETURN(1); } } else /* Service not found or released */ { DBUG_RETURN(1); } /* Destroy mutexes for table records */ mysql_mutex_destroy(&LOCK_ename_records_array); mysql_mutex_destroy(&LOCK_esalary_records_array); mysql_mutex_destroy(&LOCK_machine_records_array); /* Release service handles. */ release_service_handles(); DBUG_RETURN(0); } static struct st_mysql_daemon pfs_example_plugin_employee = { MYSQL_DAEMON_INTERFACE_VERSION}; /** pfs_example_plugin_employee plugin descriptor */ /* clang-format off */ mysql_declare_plugin(pfs_example_plugin_employee) { MYSQL_DAEMON_PLUGIN, &pfs_example_plugin_employee, "pfs_example_plugin_employee", "Oracle Corporation", "pfs_example_plugin_employee", PLUGIN_LICENSE_GPL, pfs_example_plugin_employee_init, /* Plugin Init */ pfs_example_plugin_employee_check, /* Plugin Check uninstall */ pfs_example_plugin_employee_deinit, /* Plugin Deinit */ 0x0100 /* 1.0 */, NULL, /* status variables */ NULL, /* system variables */ NULL, /* config options */ 0, /* flags */ } mysql_declare_plugin_end; /* clang-format on */