/*
* 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.
 */

// Code generated by MockGen. DO NOT EDIT.
// Source: internal/pkg/shardingsphere-proxy.go

// Package mock_pkg is a generated GoMock package.
package mock_pkg

import (
	reflect "reflect"

	model "github.com/apache/shardingsphere-on-cloud/pitr/cli/internal/pkg/model"
	gomock "github.com/golang/mock/gomock"
)

// MockIShardingSphereProxy is a mock of IShardingSphereProxy interface.
type MockIShardingSphereProxy struct {
	ctrl     *gomock.Controller
	recorder *MockIShardingSphereProxyMockRecorder
}

// MockIShardingSphereProxyMockRecorder is the mock recorder for MockIShardingSphereProxy.
type MockIShardingSphereProxyMockRecorder struct {
	mock *MockIShardingSphereProxy
}

// NewMockIShardingSphereProxy creates a new mock instance.
func NewMockIShardingSphereProxy(ctrl *gomock.Controller) *MockIShardingSphereProxy {
	mock := &MockIShardingSphereProxy{ctrl: ctrl}
	mock.recorder = &MockIShardingSphereProxyMockRecorder{mock}
	return mock
}

// EXPECT returns an object that allows the caller to indicate expected use.
func (m *MockIShardingSphereProxy) EXPECT() *MockIShardingSphereProxyMockRecorder {
	return m.recorder
}

// DropDatabase mocks base method.
func (m *MockIShardingSphereProxy) DropDatabase(shardingDBName string) error {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "DropDatabase", shardingDBName)
	ret0, _ := ret[0].(error)
	return ret0
}

// DropDatabase indicates an expected call of DropDatabase.
func (mr *MockIShardingSphereProxyMockRecorder) DropDatabase(shardingDBName interface{}) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DropDatabase", reflect.TypeOf((*MockIShardingSphereProxy)(nil).DropDatabase), shardingDBName)
}

// ExportMetaData mocks base method.
func (m *MockIShardingSphereProxy) ExportMetaData() (*model.ClusterInfo, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "ExportMetaData")
	ret0, _ := ret[0].(*model.ClusterInfo)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// ExportMetaData indicates an expected call of ExportMetaData.
func (mr *MockIShardingSphereProxyMockRecorder) ExportMetaData() *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ExportMetaData", reflect.TypeOf((*MockIShardingSphereProxy)(nil).ExportMetaData))
}

// ExportStorageNodes mocks base method.
func (m *MockIShardingSphereProxy) ExportStorageNodes() ([]*model.StorageNode, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "ExportStorageNodes")
	ret0, _ := ret[0].([]*model.StorageNode)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// ExportStorageNodes indicates an expected call of ExportStorageNodes.
func (mr *MockIShardingSphereProxyMockRecorder) ExportStorageNodes() *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ExportStorageNodes", reflect.TypeOf((*MockIShardingSphereProxy)(nil).ExportStorageNodes))
}

// ImportMetaData mocks base method.
func (m *MockIShardingSphereProxy) ImportMetaData(in *model.ClusterInfo) error {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "ImportMetaData", in)
	ret0, _ := ret[0].(error)
	return ret0
}

// ImportMetaData indicates an expected call of ImportMetaData.
func (mr *MockIShardingSphereProxyMockRecorder) ImportMetaData(in interface{}) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ImportMetaData", reflect.TypeOf((*MockIShardingSphereProxy)(nil).ImportMetaData), in)
}

// LockForBackup mocks base method.
func (m *MockIShardingSphereProxy) LockForBackup() error {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "LockForBackup")
	ret0, _ := ret[0].(error)
	return ret0
}

// LockForBackup indicates an expected call of LockForBackup.
func (mr *MockIShardingSphereProxyMockRecorder) LockForBackup() *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LockForBackup", reflect.TypeOf((*MockIShardingSphereProxy)(nil).LockForBackup))
}

// LockForRestore mocks base method.
func (m *MockIShardingSphereProxy) LockForRestore() error {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "LockForRestore")
	ret0, _ := ret[0].(error)
	return ret0
}

// LockForRestore indicates an expected call of LockForRestore.
func (mr *MockIShardingSphereProxyMockRecorder) LockForRestore() *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LockForRestore", reflect.TypeOf((*MockIShardingSphereProxy)(nil).LockForRestore))
}

// Unlock mocks base method.
func (m *MockIShardingSphereProxy) Unlock() error {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "Unlock")
	ret0, _ := ret[0].(error)
	return ret0
}

// Unlock indicates an expected call of Unlock.
func (mr *MockIShardingSphereProxyMockRecorder) Unlock() *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Unlock", reflect.TypeOf((*MockIShardingSphereProxy)(nil).Unlock))
}
