Beispiel #1
0
/*
 * loaddb_internal - internal main loaddb function
 *    return: NO_ERROR if successful, error code otherwise
 *    argc(in): argc of main
 *    argv(in): argv of main
 *    dba_mode(in):
 */
static int
loaddb_internal (UTIL_FUNCTION_ARG * arg, int dba_mode)
{
  UTIL_ARG_MAP *arg_map = arg->arg_map;
  int error = NO_ERROR;
  /* set to static to avoid copiler warning (clobbered by longjump) */
  static FILE *schema_file = NULL;
  static FILE *index_file = NULL;
  static FILE *object_file = NULL;
  FILE *error_file = NULL;
  int status = 0;
  int errors, objects, defaults;
#if !defined (LDR_OLD_LOADDB)
  int lastcommit = 0;
#endif /* !LDR_OLD_LOADDB */
  char *passwd;
  /* set to static to avoid copiler warning (clobbered by longjump) */
  static int interrupted = false;
  int au_save = 0;
  extern bool obt_Enable_autoincrement;

  char log_file_name[PATH_MAX];

  LOADDB_INIT_DEBUG ();
  obt_Enable_autoincrement = false;

  Volume = utility_get_option_string_value (arg_map, OPTION_STRING_TABLE, 0);
  Input_file = utility_get_option_string_value (arg_map, OPTION_STRING_TABLE,
						1);
  User_name = utility_get_option_string_value (arg_map, LOAD_USER_S, 0);
  Password = utility_get_option_string_value (arg_map, LOAD_PASSWORD_S, 0);
  Syntax_check = utility_get_option_bool_value (arg_map, LOAD_CHECK_ONLY_S);
  Load_only = utility_get_option_bool_value (arg_map, LOAD_LOAD_ONLY_S);
  Estimated_size = utility_get_option_int_value (arg_map,
						 LOAD_ESTIMATED_SIZE_S);
  Verbose = utility_get_option_bool_value (arg_map, LOAD_VERBOSE_S);
  Disable_statistics =
    utility_get_option_bool_value (arg_map, LOAD_NO_STATISTICS_S);
  Periodic_commit = utility_get_option_int_value (arg_map,
						  LOAD_PERIODIC_COMMIT_S);
  Verbose_commit = Periodic_commit > 0 ? true : false;
  No_oid_hint = utility_get_option_bool_value (arg_map, LOAD_NO_OID_S);
  Schema_file = utility_get_option_string_value (arg_map, LOAD_SCHEMA_FILE_S,
						 0);
  Index_file = utility_get_option_string_value (arg_map, LOAD_INDEX_FILE_S,
						0);
  Object_file = utility_get_option_string_value (arg_map, LOAD_DATA_FILE_S,
						 0);
  Error_file = utility_get_option_string_value (arg_map,
						LOAD_ERROR_CONTROL_FILE_S, 0);
  Ignore_logging = utility_get_option_bool_value (arg_map,
						  LOAD_IGNORE_LOGGING_S);
#if !defined (LDR_OLD_LOADDB)
  Ignore_class_file = utility_get_option_string_value (arg_map,
						       LOAD_IGNORE_CLASS_S,
						       0);
#endif

  Input_file = Input_file ? Input_file : "";
  Schema_file = Schema_file ? Schema_file : "";
  Index_file = Index_file ? Index_file : "";
  Object_file = Object_file ? Object_file : "";
  Error_file = Error_file ? Error_file : "";

  if (ldr_validate_object_file (stderr, arg->argv0))
    {
      goto error_return;
    }

  /* error message log file */
  sprintf (log_file_name, "%s_%s.err", Volume, arg->command_name);
  er_init (log_file_name, ER_NEVER_EXIT);

  if (Index_file[0] != '\0'
      && PRM_SR_NBUFFERS < LOAD_INDEX_MIN_SORT_BUFFER_PAGES)
    {
      sysprm_set_force (PRM_NAME_SR_NBUFFERS,
			LOAD_INDEX_MIN_SORT_BUFFER_PAGES_STRING);
    }
  sysprm_set_force (PRM_NAME_JAVA_STORED_PROCEDURE, "no");

  /* login */
  if (User_name != NULL || !dba_mode)
    {
      (void) db_login (User_name, Password);
      if ((error = db_restart (arg->command_name, true, Volume)))
	{
	  if (error == ER_AU_INVALID_PASSWORD)
	    {
	      /* prompt for password and try again */
	      error = NO_ERROR;
	      passwd = getpass (msgcat_message (MSGCAT_CATALOG_UTILS,
						MSGCAT_UTIL_SET_LOADDB,
						LOADDB_MSG_PASSWORD_PROMPT));
	      if (!strlen (passwd))
		passwd = NULL;
	      (void) db_login (User_name, passwd);
	      error = db_restart (arg->command_name, true, Volume);
	    }
	}
    }
  else
    {
      /* if we're in the protected dba mode, just login without
         authorization */
      AU_DISABLE_PASSWORDS ();
      db_set_client_type (DB_CLIENT_TYPE_ADMIN_UTILITY);
      (void) db_login ("dba", NULL);
      error = db_restart (arg->command_name, true, Volume);
    }

  /* open loaddb log file */
  sprintf (log_file_name, "%s_loaddb.log", Volume);
  loaddb_log_file = fopen (log_file_name, "w+");
  if (loaddb_log_file == NULL)
    {
      printf ("Cannot open log file %s\n", log_file_name);
      status = 2;
      goto error_return;
    }

#if 0
#if !defined (LDR_OLD_LOADDB)

  /* Execute old loaddb if no optimization flag is set true
   * or LOADDB_NOPT is set, we must pass the argv except
   * -no option and invoke execvp() for no optimized loaddb
   */
  if (No_optimization || envvar_get ("LOADDB_NOPT"))
    {

      char **tmp;
      char *lastslash, path[PATH_MAX];
      int i = 1, j = 1;

      tmp = (char **) malloc (sizeof (char *) * (argc + 1));
      tmp[0] = (char *) "loaddb";
      while (j < argc)
	{
	  if (!strcmp (argv[j], "-no"))
	    j++;
	  else
	    tmp[i++] = argv[j++];
	};
      tmp[i] = 0;

      strcpy (path, argv[0]);
      lastslash = strrchr (path, (int) '/');
#if defined(WINDOWS)
      {
	char *p, exec_path[1024], cmd_line[1024 * 8];
	int cp_len = 0;

	db_shutdown ();

	p = envvar_root ();
	if (p == NULL)
	  {
	    printf ("The `CUBRID' environment variable is not set.\n");
	  }
	else
	  {
	    sprintf (exec_path, "%s/migdb_o.exe", p);
	    for (i = 0; tmp[i]; i++)
	      {
		cp_len += sprintf (cmd_line + cp_len, "\"%s\" ", tmp[i]);
	      }
	    if (envvar_get ("FRONT_DEBUG") != NULL)
	      {
		printf ("Executing:%s %s\n", exec_path, cmd_line);
	      }
	    run_proc (exec_path, cmd_line);
	  }
	exit (0);
      }
#else /* !WINDOWS */
      if (lastslash != NULL)
	strcpy (lastslash + 1, "migdb_o");
      else
	strcpy (path, "migdb_o");

      if (execvp (path, tmp) == -1)
	{
	  print_log_msg (1, msgcat_message (MSGCAT_CATALOG_UTILS,
					    MSGCAT_UTIL_SET_LOADDB,
					    LOADDB_MSG_NOPT_ERR));
	  exit (0);
	};
#endif /* WINDOWS */
    }
#endif /* !LDR_OLD_LOADDB */
#endif

  /* check if schema/index/object files exist */
  ldr_check_file_name_and_line_no ();

  if (Schema_file[0] != 0)
    {
      schema_file = fopen (Schema_file, "r");
      if (schema_file == NULL)
	{
	  print_log_msg (1, msgcat_message (MSGCAT_CATALOG_UTILS,
					    MSGCAT_UTIL_SET_LOADDB,
					    LOADDB_MSG_BAD_INFILE),
			 Schema_file);
	  status = 2;
	  goto error_return;
	}
    }
  if (Index_file[0] != 0)
    {
      index_file = fopen (Index_file, "r");
      if (index_file == NULL)
	{
	  print_log_msg (1, msgcat_message (MSGCAT_CATALOG_UTILS,
					    MSGCAT_UTIL_SET_LOADDB,
					    LOADDB_MSG_BAD_INFILE),
			 Index_file);
	  status = 2;
	  goto error_return;
	}
    }
  if (Object_file[0] != 0)
    {
      object_file = fopen_ex (Object_file, "rb");	/* keep out ^Z */

      if (object_file == NULL)
	{
	  print_log_msg (1, msgcat_message (MSGCAT_CATALOG_UTILS,
					    MSGCAT_UTIL_SET_LOADDB,
					    LOADDB_MSG_BAD_INFILE),
			 Object_file);
	  status = 2;
	  goto error_return;
	}
    }

#if !defined (LDR_OLD_LOADDB)
  if (Ignore_class_file)
    {
      int retval;
      retval = get_ignore_class_list (Ignore_class_file);

      if (retval < 0)
	{
	  status = 2;
	  goto error_return;
	}
    }
#endif

  /* Disallow syntax only and load only options together */
  if (Load_only && Syntax_check)
    {
      print_log_msg (1, msgcat_message (MSGCAT_CATALOG_UTILS,
					MSGCAT_UTIL_SET_LOADDB,
					LOADDB_MSG_INCOMPATIBLE_ARGS),
		     "--" LOAD_LOAD_ONLY_L, "--" LOAD_CHECK_ONLY_L);
      status = 1;		/* parsing error */
      goto error_return;
    }

  if (Error_file[0] != 0)
    {
      if (Syntax_check)
	{
	  print_log_msg (1, msgcat_message (MSGCAT_CATALOG_UTILS,
					    MSGCAT_UTIL_SET_LOADDB,
					    LOADDB_MSG_INCOMPATIBLE_ARGS),
			 "--" LOAD_ERROR_CONTROL_FILE_L,
			 "--" LOAD_CHECK_ONLY_L);
	  status = 1;		/* parsing error */
	  goto error_return;
	}
      error_file = fopen_ex (Error_file, "rt");
      if (error_file == NULL)
	{
	  print_log_msg (1, msgcat_message (MSGCAT_CATALOG_UTILS,
					    MSGCAT_UTIL_SET_LOADDB,
					    LOADDB_MSG_BAD_INFILE),
			 Error_file);
	  status = 2;
	  goto error_return;
	}
      er_filter_fileset (error_file);
      fclose (error_file);
    }

  /* check if no log option can be applied */
  if (error
      || (Ignore_logging != 0 && locator_log_force_nologging () != NO_ERROR))
    {
      /* couldn't log in */
      print_log_msg (1, "%s\n", db_error_string (3));
      status = 3;
      db_shutdown ();
      goto error_return;
    }

  /* change "print_key_value_on_unique_error" parameter */
  sysprm_change_server_parameters ("print_key_value_on_unique_error=1");

  /* if schema file is specified, do schema loading */
  if (schema_file != NULL)
    {
      print_log_msg (1, "\nStart schema loading.\n");

      /*
       * CUBRID 8.2 should be compatible with earlier versions of CUBRID.
       * Therefore, we do not perform user authentication when the loader
       * is executing by DBA group user.
       */
      if (au_is_dba_group_member (Au_user))
	{
	  AU_DISABLE (au_save);
	}

      if (ldr_exec_query_from_file (Schema_file, schema_file,
				    &schema_file_start_line,
				    Periodic_commit) != 0)
	{
	  print_log_msg (1, "\nError occurred during schema loading."
			 "\nAborting current transaction...");
	  status = 3;
	  db_shutdown ();
	  print_log_msg (1,
			 " done.\n\nRestart loaddb with '-%c %s:%d' option\n",
			 LOAD_SCHEMA_FILE_S, Schema_file,
			 schema_file_start_line);
	  goto error_return;
	}

      if (au_is_dba_group_member (Au_user))
	{
	  AU_ENABLE (au_save);
	}

      print_log_msg (1, "Schema loading from %s finished.\n", Schema_file);

      /* update catalog statistics */
      AU_DISABLE (au_save);
      sm_update_all_catalog_statistics ();
      AU_ENABLE (au_save);

      print_log_msg (1,
		     "Statistics for Catalog classes have been updated.\n\n");

      db_commit_transaction ();
      fclose (schema_file);
      schema_file = NULL;

    }


  /* if index file is specified, do index creation */

  if (object_file != NULL)
    {
#if defined (SA_MODE)
      locator_Dont_check_foreign_key = true;
#endif
      print_log_msg (1, "\nStart object loading.\n");
      ldr_init (Verbose);

      /* set the flag to indicate what type of interrupts to raise
       * If logging has been disabled set commit flag.
       * If logging is enabled set abort flag.
       */

      if (Ignore_logging)
	Interrupt_type = LDR_STOP_AND_COMMIT_INTERRUPT;
      else
	Interrupt_type = LDR_STOP_AND_ABORT_INTERRUPT;

      if (Periodic_commit)
	{
	  /* register the post commit function */
#if defined(LDR_OLD_LOADDB)
	  ldr_register_post_commit_handler (&loaddb_report_num_of_commits);
#else /* !LDR_OLD_LOADDB */
	  ldr_register_post_commit_handler (&loaddb_report_num_of_commits,
					    NULL);
#endif /* LDR_OLD_LOADDB */
	}

      /* Check if we need to perform syntax checking. */
      if (!Load_only)
	{
	  print_log_msg ((int) Verbose, msgcat_message (MSGCAT_CATALOG_UTILS,
							MSGCAT_UTIL_SET_LOADDB,
							LOADDB_MSG_CHECKING));
	  do_loader_parse (object_file);
#if defined(LDR_OLD_LOADDB)
	  ldr_stats (&errors, &objects, &defaults);
#else /* !LDR_OLD_LOADDB */
	  ldr_stats (&errors, &objects, &defaults, &lastcommit);
#endif /* LDR_OLD_LOADDB */
	}
      else
	errors = 0;

      if (errors)
	print_log_msg (1, msgcat_message (MSGCAT_CATALOG_UTILS,
					  MSGCAT_UTIL_SET_LOADDB,
					  LOADDB_MSG_ERROR_COUNT), errors);
      else if (!Syntax_check)
	{
	  /* now do it for real if there were no errors and we aren't
	     doing a simple syntax check */
	  ldr_start (Periodic_commit);
	  fclose (object_file);
	  object_file = fopen_ex (Object_file, "rb");	/* keep out ^Z */
	  if (object_file != NULL)
	    {
	      print_log_msg ((int) Verbose,
			     msgcat_message (MSGCAT_CATALOG_UTILS,
					     MSGCAT_UTIL_SET_LOADDB,
					     LOADDB_MSG_INSERTING));

	      /* make sure signals are caught */
	      util_arm_signal_handlers (signal_handler, signal_handler);

	      /* register function to call  and jmp environment to longjmp to
	       * after aborting or committing.
	       */
	      ldr_register_post_interrupt_handler
		(&loaddb_get_num_of_inserted_objects, &loaddb_jmp_buf);

	      if (setjmp (loaddb_jmp_buf) != 0)
		{

		  /* We have had an interrupt, the transaction should have
		   * been already been aborted or committed by the loader.
		   * If Total_objects_loaded is -1 an error occurred during
		   * rollback or commit.
		   */
		  if (Total_objects_loaded != -1)
		    print_log_msg (1, msgcat_message (MSGCAT_CATALOG_UTILS,
						      MSGCAT_UTIL_SET_LOADDB,
						      LOADDB_MSG_OBJECT_COUNT),
				   Total_objects_loaded);
#if !defined(LDR_OLD_LOADDB)
		  ldr_stats (&errors, &objects, &defaults, &lastcommit);
		  if (lastcommit > 0)
		    print_log_msg (1, msgcat_message (MSGCAT_CATALOG_UTILS,
						      MSGCAT_UTIL_SET_LOADDB,
						      LOADDB_MSG_LAST_COMMITTED_LINE),
				   lastcommit);
#endif /* !LDR_OLD_LOADDB */
		  interrupted = true;

		}
	      else
		{
		  do_loader_parse (object_file);
#if defined(LDR_OLD_LOADDB)
		  ldr_stats (&errors, &objects, &defaults);
#else /* !LDR_OLD_LOADDB */
		  ldr_stats (&errors, &objects, &defaults, &lastcommit);
#endif /* LDR_OLD_LOADDB */
		  if (errors)
		    {
#if defined(LDR_OLD_LOADDB)
		      print_log_msg (1, msgcat_message (MSGCAT_CATALOG_UTILS,
							MSGCAT_UTIL_SET_LOADDB,
							LOADDB_MSG_ERROR_COUNT),
				     errors);
#else /* !LDR_OLD_LOADDB */
		      if (lastcommit > 0)
			print_log_msg (1,
				       msgcat_message (MSGCAT_CATALOG_UTILS,
						       MSGCAT_UTIL_SET_LOADDB,
						       LOADDB_MSG_LAST_COMMITTED_LINE),
				       lastcommit);
#endif /* LDR_OLD_LOADDB */
		      /*
		       * don't allow the transaction to be committed at
		       * this point, note that if we ever move to a scheme
		       * where we write directly to the heap without the
		       * transaction context, we will have to unwind the
		       * changes made if errors are detected !
		       */
		      db_abort_transaction ();
		    }
		  else
		    {
		      if (objects)
			print_log_msg (1,
				       msgcat_message (MSGCAT_CATALOG_UTILS,
						       MSGCAT_UTIL_SET_LOADDB,
						       LOADDB_MSG_OBJECT_COUNT),
				       objects);
		      if (defaults)
			print_log_msg (1,
				       msgcat_message (MSGCAT_CATALOG_UTILS,
						       MSGCAT_UTIL_SET_LOADDB,
						       LOADDB_MSG_DEFAULT_COUNT),
				       defaults);
		      print_log_msg ((int) Verbose,
				     msgcat_message (MSGCAT_CATALOG_UTILS,
						     MSGCAT_UTIL_SET_LOADDB,
						     LOADDB_MSG_COMMITTING));

		      /* commit the transaction and then update statistics */
		      if (!db_commit_transaction ())
			{
			  if (!Disable_statistics)
			    {
			      if (Verbose)
				print_log_msg (1,
					       msgcat_message
					       (MSGCAT_CATALOG_UTILS,
						MSGCAT_UTIL_SET_LOADDB,
						LOADDB_MSG_UPDATING_STATISTICS));
			      if (!ldr_update_statistics ())
				{
				  /*
				   * would it be faster to update statistics
				   * before the first commit and just have a
				   * single commit ?
				   */
				  print_log_msg ((int) Verbose,
						 msgcat_message
						 (MSGCAT_CATALOG_UTILS,
						  MSGCAT_UTIL_SET_LOADDB,
						  LOADDB_MSG_COMMITTING));
				  (void) db_commit_transaction ();
				}
			    }
			}
		    }
		}
	    }
	}
      ldr_final ();
      if (object_file != NULL)
	{
	  fclose (object_file);
	  object_file = NULL;
	}
    }

  /* create index */
  if (!interrupted && index_file != NULL)
    {
      print_log_msg (1, "\nStart index loading.\n");
      if (ldr_exec_query_from_file (Index_file, index_file,
				    &index_file_start_line,
				    Periodic_commit) != 0)
	{
	  print_log_msg (1, "\nError occurred during index loading."
			 "\nAborting current transaction...");
	  status = 3;
	  db_shutdown ();
	  print_log_msg (1,
			 " done.\n\nRestart loaddb with '-%c %s:%d' option\n",
			 LOAD_INDEX_FILE_S, Index_file,
			 index_file_start_line);
	  goto error_return;
	}
      /* update catalog statistics */
      AU_DISABLE (au_save);
      sm_update_catalog_statistics (CT_INDEX_NAME);
      sm_update_catalog_statistics (CT_INDEXKEY_NAME);
      AU_ENABLE (au_save);

      print_log_msg (1, "Index loading from %s finished.\n", Index_file);
      db_commit_transaction ();
    }
  print_log_msg ((int) Verbose, msgcat_message (MSGCAT_CATALOG_UTILS,
						MSGCAT_UTIL_SET_LOADDB,
						LOADDB_MSG_CLOSING));
  (void) db_shutdown ();

#if !defined (LDR_OLD_LOADDB)
  free_ignoreclasslist ();
#endif
  return (status);
error_return:
  if (schema_file != NULL)
    fclose (schema_file);
  if (object_file != NULL)
    fclose (object_file);
  if (index_file != NULL)
    fclose (index_file);

#if !defined (LDR_OLD_LOADDB)
  free_ignoreclasslist ();
#endif

  return status;
}
Beispiel #2
0
/*
 * ldr_exec_query_from_file - execute queries from file
 *    return: 0 if successful, non-zero otherwise
 *    file_name(in): file path
 *    file(in): FILE *
 *    start_line(in): start line
 *    commit_period(in): commit period
 */
static int
ldr_exec_query_from_file (const char *file_name, FILE * input_stream,
			  int *start_line, int commit_period)
{
  DB_SESSION *session = NULL;
  DB_QUERY_RESULT *res = NULL;
  int error = 0;
  int stmt_cnt, stmt_id = 0, stmt_type;
  int executed_cnt = 0;
  int parser_start_line_no;
  int parser_end_line_no = 1;
  int check_line_no = true;

  if ((*start_line) > 1)
    {
      int line_count = *start_line - 1;

      do
	{
	  int c = fgetc (input_stream);
	  if (c == EOF)
	    {
	      print_log_msg (1, msgcat_message (MSGCAT_CATALOG_UTILS,
						MSGCAT_UTIL_SET_LOADDB,
						LOADDB_MSG_UNREACHABLE_LINE),
			     file_name, *start_line);
	      error = ER_GENERIC_ERROR;
	      goto end;
	    }
	  else if (c == '\n')
	    {
	      line_count--;
	    }
	}
      while (line_count > 0);
    }

  check_line_no = false;
  session = db_make_session_for_one_statement_execution (input_stream);
  if (session == NULL)
    {
      print_log_msg (1, "ERROR: %s\n", db_error_string (3));
      error = er_errid ();
      goto end;
    }

  util_arm_signal_handlers (&ldr_exec_query_interrupt_handler,
			    &ldr_exec_query_interrupt_handler);

  while (1)
    {
      if (interrupt_query)
	{
	  if (er_errid () != ER_INTERRUPTED)
	    {
	      er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, ER_INTERRUPTED, 0);
	    }
	  error = er_errid ();
	  db_close_session (session);
	  goto end;
	}
      parser_start_line_no = parser_end_line_no;

      stmt_cnt = db_parse_one_statement (session);
      if (stmt_cnt > 0)
	{
	  db_get_parser_line_col (session, &parser_end_line_no, NULL);
	  stmt_id = db_compile_statement (session);
	}

      if (stmt_cnt <= 0 || stmt_id <= 0)
	{
	  DB_SESSION_ERROR *session_error;
	  int line, col;
	  if ((session_error = db_get_errors (session)) != NULL)
	    {
	      do
		{
		  session_error =
		    db_get_next_error (session_error, &line, &col);
		  if (line >= 0)
		    {
		      print_log_msg (1, "In %s line %d,\n", file_name,
				     line + (*start_line));
		      print_log_msg (1, "ERROR: %s \n", db_error_string (3));
		      error = er_errid ();
		    }
		}
	      while (session_error);
	    }
	  db_close_session (session);
	  break;
	}

      stmt_type = db_get_statement_type (session, stmt_id);

      res = (DB_QUERY_RESULT *) NULL;
      error = db_execute_statement (session, stmt_id, &res);

      if (error < 0)
	{
	  print_log_msg (1, "ERROR: %s\n", db_error_string (3));
	  db_close_session (session);
	  break;
	}
      executed_cnt++;
      error = db_query_end (res);
      if (error < 0)
	{
	  print_log_msg (1, "ERROR: %s\n", db_error_string (3));
	  db_close_session (session);
	  break;
	}

      if (stmt_type == CUBRID_STMT_COMMIT_WORK ||
	  (commit_period && (executed_cnt % commit_period == 0)))
	{
	  db_commit_transaction ();
	  print_log_msg (Verbose_commit,
			 "%8d statements executed. Commit transaction at line %d\n",
			 executed_cnt, parser_end_line_no);
	  *start_line = parser_end_line_no + 1;
	}
      print_log_msg ((int) Verbose, "Total %8d statements executed.\r",
		     executed_cnt);
      fflush (stdout);
    }

end:
  if (error < 0)
    {
      db_abort_transaction ();
    }
  else
    {
      *start_line = parser_end_line_no + 1;
      print_log_msg (1, "Total %8d statements executed.\n", executed_cnt);
      fflush (stdout);
      db_commit_transaction ();
    }
  return error;
}
Beispiel #3
0
/*
 * compactdb_start - Compact classes   
 *    return: error code
 *    verbose_flag(in):
 *    delete_old_repr_flag(in): delete old class representations from catalog
 *    input_filename(in): classes file name
 *    input_class_names(in): classes list
 *    input_class_length(in): classes list length
 *    max_processed_space(in): maximum space to process for one iteration
 */
static int
compactdb_start (bool verbose_flag, bool delete_old_repr_flag,
		 char *input_filename,
		 char **input_class_names, int input_class_length,
		 int max_processed_space, int instance_lock_timeout,
		 int class_lock_timeout, DB_TRAN_ISOLATION tran_isolation)
{
  int status = NO_ERROR;
  OID **class_oids = NULL, *next_oid = NULL;
  int i, num_classes = 0;
  LIST_MOPS *class_table = NULL;
  OID last_processed_class_oid, last_processed_oid;
  int *total_objects = NULL, *iteration_total_objects = NULL;
  int *failed_objects = NULL, *iteration_failed_objects = NULL;
  int *modified_objects = NULL, *iteration_modified_objects = NULL;
  char *incomplete_processing = NULL;
  int *big_objects = NULL, *iteration_big_objects = NULL;
  int *initial_last_repr = NULL;
  MOP *class_mops = NULL;
  int last_completed_class_index, temp_index;
  int num_class_mops = 0;
  SM_CLASS *class_ptr = NULL;
  int num_classes_fully_compacted = 0;
  char *class_name = NULL;
  MOP *processed_class_mops = NULL;

  if (input_filename && input_class_names && input_class_length > 0)
    {
      return ER_FAILED;
    }

  status = compact_db_start ();
  if (status != NO_ERROR)
    {
      if (status == ER_COMPACTDB_ALREADY_STARTED)
	{
	  printf (msgcat_message (MSGCAT_CATALOG_UTILS,
				  MSGCAT_UTIL_SET_COMPACTDB,
				  COMPACTDB_MSG_ALREADY_STARTED));
	}

      return ER_FAILED;
    }

  tran_reset_wait_times ((float) class_lock_timeout);
  if (input_class_names && input_class_length > 0)
    {
      status = get_class_mops (input_class_names, input_class_length,
			       &class_mops, &num_class_mops);
      if (status != NO_ERROR)
	{
	  goto error;
	}
    }
  else if (input_filename)
    {
      status = get_class_mops_from_file (input_filename, &class_mops,
					 &num_class_mops);
      if (status != NO_ERROR)
	{
	  goto error;
	}
    }
  else
    {
      class_table =
	locator_get_all_mops (sm_Root_class_mop, DB_FETCH_QUERY_READ);
      if (!class_table)
	{
	  status = ER_FAILED;
	  goto error;
	}

      class_mops = class_table->mops;
      num_class_mops = class_table->num;
    }

  class_oids = (OID **) malloc (DB_SIZEOF (OID *) * (num_class_mops));
  if (class_oids == NULL)
    {
      status = ER_FAILED;
      goto error;
    }

  for (i = 0; i < num_class_mops; i++)
    {
      class_oids[i] = NULL;
    }

  processed_class_mops = (DB_OBJECT **) malloc (DB_SIZEOF (DB_OBJECT *) *
						(num_class_mops));
  if (processed_class_mops == NULL)
    {
      status = ER_FAILED;
      goto error;
    }

  for (i = 0; i < num_class_mops; i++)
    {
      processed_class_mops[i] = NULL;
    }

  num_classes = 0;
  for (i = 0; i < num_class_mops; i++)
    {
      ws_find (class_mops[i], (MOBJ *) & class_ptr);
      if (class_ptr == NULL)
	{
	  continue;
	}

      if (class_ptr->class_type != SM_CLASS_CT)
	{
	  continue;
	}

      class_oids[num_classes] = ws_oid (class_mops[i]);
      if (class_oids[num_classes] != NULL)
	{
	  processed_class_mops[num_classes] = class_mops[i];
	  num_classes++;
	}
    }

  if (num_classes == 0)
    {
      printf (msgcat_message (MSGCAT_CATALOG_UTILS,
			      MSGCAT_UTIL_SET_COMPACTDB,
			      COMPACTDB_MSG_NOTHING_TO_PROCESS));
      goto error;
    }

  total_objects = (int *) malloc (num_classes * sizeof (int));
  if (total_objects == NULL)
    {
      status = ER_FAILED;
      goto error;
    }

  iteration_total_objects = (int *) malloc (num_classes * sizeof (int));
  if (iteration_total_objects == NULL)
    {
      status = ER_FAILED;
      goto error;
    }

  failed_objects = (int *) malloc (num_classes * sizeof (int));
  if (failed_objects == NULL)
    {
      status = ER_FAILED;
      goto error;
    }

  iteration_failed_objects = (int *) malloc (num_classes * sizeof (int));
  if (iteration_failed_objects == NULL)
    {
      status = ER_FAILED;
      goto error;
    }

  modified_objects = (int *) malloc (num_classes * sizeof (int));
  if (modified_objects == NULL)
    {
      status = ER_FAILED;
      goto error;
    }

  iteration_modified_objects = (int *) malloc (num_classes * sizeof (int));
  if (iteration_modified_objects == NULL)
    {
      status = ER_FAILED;
      goto error;
    }

  big_objects = (int *) malloc (num_classes * sizeof (int));
  if (big_objects == NULL)
    {
      status = ER_FAILED;
      goto error;
    }

  iteration_big_objects = (int *) malloc (num_classes * sizeof (int));
  if (iteration_big_objects == NULL)
    {
      status = ER_FAILED;
      goto error;
    }

  initial_last_repr = (int *) malloc (num_classes * sizeof (int));
  if (initial_last_repr == NULL)
    {
      status = ER_FAILED;
      goto error;
    }

  incomplete_processing = (char *) malloc (num_classes * sizeof (char));
  if (incomplete_processing == NULL)
    {
      status = ER_FAILED;
      goto error;
    }

  for (i = 0; i < num_classes; i++)
    {
      total_objects[i] = 0;
      failed_objects[i] = 0;
      modified_objects[i] = 0;
      big_objects[i] = 0;
      incomplete_processing[i] = 0;
      initial_last_repr[i] = NULL_REPRID;
    }

  for (i = 0; i < num_class_mops; i++)
    {
      status = locator_flush_all_instances (class_mops[i], true);
      if (status != NO_ERROR)
	{
	  goto error;
	}
    }

  status = db_commit_transaction ();
  if (status != NO_ERROR)
    {
      goto error;
    }

  COPY_OID (&last_processed_class_oid, class_oids[0]);
  OID_SET_NULL (&last_processed_oid);
  temp_index = -1;
  last_completed_class_index = -1;

  if (verbose_flag)
    {
      printf (msgcat_message (MSGCAT_CATALOG_UTILS,
			      MSGCAT_UTIL_SET_COMPACTDB,
			      COMPACTDB_MSG_PASS1));
    }

  while (true)
    {
      status = db_set_isolation (tran_isolation);
      if (status != NO_ERROR)
	{
	  if (verbose_flag)
	    {
	      printf (msgcat_message (MSGCAT_CATALOG_UTILS,
				      MSGCAT_UTIL_SET_COMPACTDB,
				      COMPACTDB_MSG_ISOLATION_LEVEL_FAILURE));
	    }

	  status = ER_FAILED;
	  goto error;
	}

      status = boot_compact_classes (class_oids, num_classes,
				     max_processed_space,
				     instance_lock_timeout * 1000,
				     class_lock_timeout * 1000,
				     delete_old_repr_flag,
				     &last_processed_class_oid,
				     &last_processed_oid,
				     iteration_total_objects,
				     iteration_failed_objects,
				     iteration_modified_objects,
				     iteration_big_objects,
				     initial_last_repr);

      if (OID_ISNULL (&last_processed_class_oid))
	{
	  temp_index = num_classes;
	}
      else
	{
	  temp_index = find_oid (&last_processed_class_oid,
				 class_oids, num_classes);
	}

      switch (status)
	{
	case NO_ERROR:
	  if (delete_old_repr_flag &&
	      temp_index - 1 > last_completed_class_index)
	    {
	      for (i = last_completed_class_index + 1; i < temp_index; i++)
		{
		  if (initial_last_repr[i] == COMPACTDB_REPR_DELETED)
		    {
		      sm_destroy_representations (processed_class_mops[i]);
		    }
		}
	    }

	  status = db_commit_transaction ();
	  if (status != NO_ERROR)
	    {
	      goto error;
	    }
	  break;

	case ER_LK_UNILATERALLY_ABORTED:
	  status = tran_abort_only_client (false);
	  if (status != NO_ERROR)
	    {
	      goto error;
	    }
	  break;

	case ER_FAILED:
	  status = db_abort_transaction ();
	  if (status != NO_ERROR)
	    {
	      goto error;
	    }
	  break;

	default:
	  db_abort_transaction ();
	  status = ER_FAILED;
	  goto error;
	}

      for (i = 0; i < num_classes; i++)
	{
	  if (iteration_total_objects[i] >= 0)
	    {
	      total_objects[i] += iteration_total_objects[i];
	      failed_objects[i] += iteration_failed_objects[i];
	      modified_objects[i] += iteration_modified_objects[i];
	      big_objects[i] += iteration_big_objects[i];
	    }
	  else
	    {
	      incomplete_processing[i] = iteration_total_objects[i];
	    }
	}

      if (temp_index - 1 > last_completed_class_index)
	{
	  for (i = last_completed_class_index + 1; i < temp_index; i++)
	    {
	      status = db_set_isolation (tran_isolation);
	      if (status != NO_ERROR)
		{
		  if (verbose_flag)
		    {
		      printf (msgcat_message
			      (MSGCAT_CATALOG_UTILS,
			       MSGCAT_UTIL_SET_COMPACTDB,
			       COMPACTDB_MSG_ISOLATION_LEVEL_FAILURE));
		    }

		  status = ER_FAILED;
		  goto error;
		}

	      tran_reset_wait_times ((float) class_lock_timeout);
	      show_statistics
		(class_oids[i],
		 incomplete_processing[i] != COMPACTDB_LOCKED_CLASS,
		 incomplete_processing[i] != COMPACTDB_INVALID_CLASS,
		 incomplete_processing[i] != COMPACTDB_UNPROCESSED_CLASS,
		 total_objects[i], failed_objects[i],
		 modified_objects[i], big_objects[i],
		 delete_old_repr_flag,
		 initial_last_repr[i] == COMPACTDB_REPR_DELETED);

	      db_commit_transaction ();
	    }

	  last_completed_class_index = temp_index - 1;
	}

      if (OID_ISNULL (&last_processed_class_oid))
	{
	  break;
	}
    }

  if (verbose_flag)
    {
      printf (msgcat_message (MSGCAT_CATALOG_UTILS,
			      MSGCAT_UTIL_SET_COMPACTDB,
			      COMPACTDB_MSG_PASS2));
    }
  status = do_reclaim_addresses (class_oids, num_classes,
				 &num_classes_fully_compacted, verbose_flag,
				 (float) class_lock_timeout);
  if (status != NO_ERROR)
    {
      goto error;
    }

  if (verbose_flag)
    {
      printf (msgcat_message (MSGCAT_CATALOG_UTILS,
			      MSGCAT_UTIL_SET_COMPACTDB,
			      COMPACTDB_MSG_PASS3));
    }

  for (i = 0; i < num_classes; i++)
    {
      status = db_set_isolation (tran_isolation);
      if (status != NO_ERROR)
	{
	  if (verbose_flag)
	    {
	      printf (msgcat_message
		      (MSGCAT_CATALOG_UTILS,
		       MSGCAT_UTIL_SET_COMPACTDB,
		       COMPACTDB_MSG_ISOLATION_LEVEL_FAILURE));
	    }

	  status = ER_FAILED;
	  goto error;
	}

      tran_reset_wait_times ((float) class_lock_timeout);

      status = boot_heap_compact (class_oids[i]);
      switch (status)
	{
	case NO_ERROR:
	  status = db_commit_transaction ();
	  if (status != NO_ERROR)
	    {
	      goto error;
	    }
	  break;

	case ER_LK_UNILATERALLY_ABORTED:
	  status = tran_abort_only_client (false);
	  if (status != NO_ERROR)
	    {
	      goto error;
	    }
	  break;

	default:
	  status = db_abort_transaction ();
	  if (status != NO_ERROR)
	    {
	      goto error;
	    }
	  break;
	}

      class_name = get_name_from_class_oid (class_oids[i]);
      if (class_name == NULL)
	{
	  printf (msgcat_message (MSGCAT_CATALOG_UTILS,
				  MSGCAT_UTIL_SET_COMPACTDB,
				  COMPACTDB_MSG_UNKNOWN_CLASS_NAME));
	}
      else
	{
	  printf (msgcat_message (MSGCAT_CATALOG_UTILS,
				  MSGCAT_UTIL_SET_COMPACTDB,
				  COMPACTDB_MSG_CLASS), class_name);
	}

      if (status != NO_ERROR)
	{
	  printf (msgcat_message (MSGCAT_CATALOG_UTILS,
				  MSGCAT_UTIL_SET_COMPACTDB,
				  COMPACTDB_MSG_HEAP_COMPACT_FAILED));
	}
      else
	{
	  printf (msgcat_message (MSGCAT_CATALOG_UTILS,
				  MSGCAT_UTIL_SET_COMPACTDB,
				  COMPACTDB_MSG_HEAP_COMPACT_SUCCEEDED));
	}

      if (class_name)
	{
	  free (class_name);
	  class_name = NULL;
	}

      db_commit_transaction ();
    }

error:
  if (class_oids)
    {
      free_and_init (class_oids);
    }

  if (processed_class_mops)
    {
      free_and_init (processed_class_mops);
    }

  if (total_objects)
    {
      free_and_init (total_objects);
    }

  if (iteration_total_objects)
    {
      free_and_init (iteration_total_objects);
    }

  if (failed_objects)
    {
      free_and_init (failed_objects);
    }

  if (iteration_failed_objects)
    {
      free_and_init (iteration_failed_objects);
    }

  if (modified_objects)
    {
      free_and_init (modified_objects);
    }

  if (iteration_modified_objects)
    {
      free_and_init (iteration_modified_objects);
    }

  if (big_objects)
    {
      free_and_init (big_objects);
    }

  if (iteration_big_objects)
    {
      free_and_init (iteration_big_objects);
    }

  if (initial_last_repr)
    {
      free_and_init (initial_last_repr);
    }

  if (incomplete_processing)
    {
      free_and_init (incomplete_processing);
    }

  if (class_table)
    {
      locator_free_list_mops (class_table);
    }
  else
    {
      if (class_mops)
	{
	  for (i = 0; i < num_class_mops; i++)
	    {
	      class_mops[i] = NULL;
	    }

	  free_and_init (class_mops);
	}
    }

  compact_db_stop ();

  return status;
}
Beispiel #4
0
int main(){
	MYSQL * conn;
	struct gs_comment testComment;
	struct gs_marker testMarker;
   	struct gs_marker * markerPage;
   	Decimal latitude;
   	Decimal longitude;
   	char json[JSON_LENGTH];
   	int numMarkers;
   	int i;
	bzero(json,JSON_LENGTH);

   	conn = _getMySQLConnection();
   	if(!conn){
	  	fprintf(stderr, "%s\n", "Could not connect to mySQL");
	  	close(STDIN_FILENO);
		close(STDOUT_FILENO);
		close(STDERR_FILENO);
	  	return 1;
   	}
   	db_start_transaction(conn);
   	
   	/* Setup referenced comment */
   	gs_comment_ZeroStruct(&testComment);
   	gs_comment_setContent("Test Comment", &testComment);
   	gs_comment_setScopeId(CAMPAIGN_ID, &testComment);
	   
   	db_insertComment(&testComment,conn);

   	latitude = createDecimalFromString( "-44.050");
	longitude= createDecimalFromString( "-44.70");

   
	gs_marker_ZeroStruct(&testMarker);

	gs_marker_setCommentId(1, &testMarker);
	gs_marker_setScopeId(CAMPAIGN_ID, &testMarker);
	gs_marker_setLongitude(longitude, &testMarker);
	gs_marker_setLatitude(latitude, &testMarker);

	db_insertMarker(&testMarker, conn);
	gs_markerNToJSON(testMarker, json, JSON_LENGTH);
	printf("%s\n", json);	

	db_getMarkerById(testMarker.id, &testMarker, conn);
	gs_markerNToJSON(testMarker, json, JSON_LENGTH);
	printf("%s\n", json);	

	markerPage = malloc(RESULTS_PER_PAGE * sizeof(struct gs_marker));
	if(markerPage != NULL){

		numMarkers = db_getMarkers(0, CAMPAIGN_ID, markerPage, conn);
		for(i=0; i < numMarkers; ++i){
			bzero(json,JSON_LENGTH);
			gs_markerNToJSON(markerPage[i], json, JSON_LENGTH);
			printf("%s\n", json);		
		}
		
		free(markerPage);
	}else{	
	  	fprintf(stderr, "%s\n", "Could not allocate enough memory for marker page");
	}

	db_abort_transaction(conn);
   	db_end_transaction(conn);
	mysql_close(conn);
	mysql_library_end();
	
	close(STDIN_FILENO);
	close(STDOUT_FILENO);
	close(STDERR_FILENO);

}
Beispiel #5
0
static int
do_reclaim_class_addresses (const OID class_oid, char **class_name,
			    bool * const any_class_can_be_referenced,
			    bool * const correctly_processed,
			    bool * const addresses_reclaimed,
			    int *const error_while_processing)
{
  DB_OBJECT *class_mop = NULL;
  DB_OBJECT *parent_mop = NULL;
  SM_CLASS *class_ = NULL;
  SM_CLASS *parent_class_ = NULL;
  int error_code = NO_ERROR;
  int skipped_error_code = NO_ERROR;
  bool do_abort_on_error = true;
  bool can_reclaim_addresses = true;
  LIST_MOPS *lmops = NULL;
  HFID *hfid = NULL;

  assert (!OID_ISNULL (&class_oid));
  assert (any_class_can_be_referenced != NULL);
  assert (correctly_processed != NULL);
  assert (addresses_reclaimed != NULL);
  assert (error_while_processing != NULL);
  assert (class_name != NULL);

  *correctly_processed = false;
  *addresses_reclaimed = false;
  *error_while_processing = NO_ERROR;

  error_code = db_commit_transaction ();
  if (error_code != NO_ERROR)
    {
      goto error_exit;
    }

  error_code = db_set_isolation (TRAN_READ_COMMITTED);
  if (error_code != NO_ERROR)
    {
      goto error_exit;
    }

  /*
   * Trying to force an ISX_LOCK on the root class. It somehow happens that
   * we are left with an IX_LOCK in the end...
   */
  if (locator_fetch_class (sm_Root_class_mop, DB_FETCH_QUERY_WRITE) == NULL)
    {
      error_code = ER_FAILED;
      goto error_exit;
    }

  class_mop = db_object ((OID *) (&class_oid));
  if (class_mop == NULL)
    {
      skipped_error_code = ER_FAILED;
      goto error_exit;
    }

  if (!locator_is_class (class_mop, DB_FETCH_WRITE))
    {
      skipped_error_code = ER_FAILED;
      goto error_exit;
    }

  /*
   * We need an X_LOCK on the class to process as early as possible so that
   * other transactions don't add references to it in the schema.
   */
  class_ = (SM_CLASS *) locator_fetch_class (class_mop, DB_FETCH_WRITE);
  if (class_ == NULL)
    {
      skipped_error_code = er_errid ();
      goto error_exit;
    }

  assert (*class_name == NULL);
  *class_name = strdup (class_->header.name);
  if (*class_name == NULL)
    {
      error_code = ER_FAILED;
      goto error_exit;
    }

  if (class_->partition_of != NULL)
    {
      /*
       * If the current class is a partition of a partitioned class we need
       * to get its parent partitioned table and check for references to its
       * parent too. If table tbl has partition tbl__p__p0, a reference to tbl
       * can point to tbl__p__p0 instances too.
       */
      skipped_error_code = do_get_partition_parent (class_mop, &parent_mop);
      if (skipped_error_code != NO_ERROR)
	{
	  goto error_exit;
	}
      if (parent_mop != NULL)
	{
	  parent_class_ =
	    (SM_CLASS *) locator_fetch_class (parent_mop, DB_FETCH_WRITE);
	  if (parent_class_ == NULL)
	    {
	      skipped_error_code = er_errid ();
	      goto error_exit;
	    }
	}
    }

  skipped_error_code = locator_flush_all_instances (class_mop, true);
  if (skipped_error_code != NO_ERROR)
    {
      goto error_exit;
    }

  if (class_->class_type != SM_CLASS_CT)
    {
      can_reclaim_addresses = false;
    }
  else
    {
      hfid = sm_heap ((MOBJ) class_);
      if (HFID_IS_NULL (hfid))
	{
	  can_reclaim_addresses = false;
	}
    }

  if (class_->flags & SM_CLASSFLAG_SYSTEM)
    {
      /*
       * It should be safe to process system classes also but we skip them for
       * now. Please note that class_instances_can_be_referenced () does not
       * check for references from system classes.
       * If this is ever changed please consider the impact of reusing system
       * objects OIDs.
       */
      can_reclaim_addresses = false;
    }
  else if (class_->flags & SM_CLASSFLAG_REUSE_OID)
    {
      /*
       * Nobody should be able to hold references to reusable OID tables so it
       * should be safe to reclaim their OIDs and pages no matter what.
       */
      can_reclaim_addresses = true;
    }
  else
    {
      if (*any_class_can_be_referenced)
	{
	  /*
	   * Some class attribute has OBJECT or SET OF OBJECT as the domain.
	   * This means it can point to instances of any class so we're not
	   * safe reclaiming OIDs.
	   */
	  can_reclaim_addresses = false;
	}
      else
	{
	  bool class_can_be_referenced = false;

	  /*
	   * IS_LOCK should be enough for what we need but
	   * locator_get_all_class_mops seems to lock the instances with the
	   * lock that it has on their class. So we end up with IX_LOCK on all
	   * classes in the schema...
	   */

	  lmops = locator_get_all_class_mops (DB_FETCH_CLREAD_INSTREAD,
					      is_not_system_class);
	  if (lmops == NULL)
	    {
	      skipped_error_code = ER_FAILED;
	      goto error_exit;
	    }

	  skipped_error_code =
	    class_instances_can_be_referenced (class_mop, parent_mop,
					       &class_can_be_referenced,
					       any_class_can_be_referenced,
					       lmops->mops, lmops->num);
	  if (skipped_error_code != NO_ERROR)
	    {
	      goto error_exit;
	    }
	  /*
	   * If some attribute has OBJECT or the current class as its domain
	   * then it's not safe to reclaim the OIDs as some of the references
	   * might point to deleted objects. We skipped the system classes as
	   * they should not point to any instances of the non-system classes.
	   */
	  can_reclaim_addresses = !class_can_be_referenced &&
	    !*any_class_can_be_referenced;
	  if (lmops != NULL)
	    {
	      /*
	       * It should be safe now to release all the locks we hold on the
	       * schema classes (except for the X_LOCK on the current class).
	       * However, we don't currently have a way of releasing those
	       * locks so we're stuck with them till the end of the current
	       * transaction.
	       */
	      locator_free_list_mops (lmops);
	      lmops = NULL;
	    }
	}
    }

  if (can_reclaim_addresses)
    {
      assert (hfid != NULL && !HFID_IS_NULL (hfid));

      skipped_error_code = heap_reclaim_addresses (hfid);
      if (skipped_error_code != NO_ERROR)
	{
	  goto error_exit;
	}
      *addresses_reclaimed = true;
    }

  error_code = db_commit_transaction ();
  if (error_code != NO_ERROR)
    {
      goto error_exit;
    }

  assert (error_code == NO_ERROR && skipped_error_code == NO_ERROR);
  *correctly_processed = true;
  class_mop = NULL;
  class_ = NULL;
  parent_mop = NULL;
  parent_class_ = NULL;
  return error_code;

error_exit:
  *error_while_processing = skipped_error_code;
  class_mop = NULL;
  class_ = NULL;
  parent_mop = NULL;
  parent_class_ = NULL;
  if (lmops != NULL)
    {
      locator_free_list_mops (lmops);
      lmops = NULL;
    }
  if (do_abort_on_error)
    {
      int tmp_error_code = NO_ERROR;

      if (skipped_error_code == ER_LK_UNILATERALLY_ABORTED ||
	  error_code == ER_LK_UNILATERALLY_ABORTED)
	{
	  tmp_error_code = tran_abort_only_client (false);
	}
      else
	{
	  tmp_error_code = db_abort_transaction ();
	}
      if (tmp_error_code != NO_ERROR)
	{
	  if (error_code == NO_ERROR)
	    {
	      error_code = tmp_error_code;
	    }
	}
    }
  if (skipped_error_code == NO_ERROR && error_code == NO_ERROR)
    {
      error_code = ER_FAILED;
    }
  return error_code;
}