/MongoUtility/Command/CommandExecute.cs

https://github.com/magicdict/MagicMongoDBTool · C# · 464 lines · 322 code · 23 blank · 119 comment · 11 complexity · 4172bb1fa766a2012fe8782eac95a13f MD5 · raw file

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Threading.Tasks;
  4. using MongoDB.Bson;
  5. using MongoDB.Driver;
  6. using MongoUtility.Basic;
  7. using MongoUtility.Core;
  8. using MongoUtility.EventArgs;
  9. namespace MongoUtility.Command
  10. {
  11. /// 注意,有些db.XXXX(xxx) 这样的函数需要 mongoDb.Eval方法才能做
  12. /// 有些RepairDatabase 这样的函数可以简单的执行
  13. /// <summary>
  14. /// </summary>
  15. public static class CommandExecute
  16. {
  17. /// <summary>
  18. /// Command Complete Event
  19. /// </summary>
  20. public static EventHandler<RunCommandEventArgs> RunCommandComplete;
  21. /// <summary>
  22. /// Command Complete
  23. /// </summary>
  24. /// <param name="e"></param>
  25. public static void OnCommandRunComplete(RunCommandEventArgs e)
  26. {
  27. e.Raise(null, ref RunCommandComplete);
  28. }
  29. /// 注意:有些命令可能只能用在mongos上面,例如addshard
  30. /// <summary>
  31. /// 使用Shell Helper命令
  32. /// </summary>
  33. /// <param name="jsShell"></param>
  34. /// <param name="mongoSvr"></param>
  35. /// <returns></returns>
  36. public static CommandResult ExecuteJsShell(string jsShell, MongoServer mongoSvr)
  37. {
  38. var shellCmd = new BsonDocument
  39. {
  40. { "$eval", new BsonJavaScript(jsShell)},
  41. { "nolock", true }
  42. };
  43. //必须nolock
  44. var mongoCmd = new CommandDocument();
  45. mongoCmd.AddRange(shellCmd);
  46. return ExecuteMongoSvrCommand(mongoCmd, mongoSvr);
  47. }
  48. /// <summary>
  49. /// Js Shell 的结果判定
  50. /// </summary>
  51. /// <param name="result"></param>
  52. /// <returns></returns>
  53. public static bool IsShellOk(CommandResult result)
  54. {
  55. if (!result.Response.ToBsonDocument().GetElement("retval").Value.IsBsonDocument)
  56. {
  57. return true;
  58. }
  59. return result.Response.ToBsonDocument().GetElement("retval").Value.AsBsonDocument.GetElement("ok").Value.ToString() == "1";
  60. }
  61. /// <summary>
  62. /// 当前对象的MONGO命令
  63. /// </summary>
  64. /// <param name="mMongoCommand">命令对象</param>
  65. /// <returns></returns>
  66. public static CommandResult ExecuteMongoCommand(MongoCommand mMongoCommand)
  67. {
  68. var resultCommandList = new List<CommandResult>();
  69. var mCommandResult = new CommandResult(new BsonDocument());
  70. switch (mMongoCommand.RunLevel)
  71. {
  72. case EnumMgr.PathLevel.CollectionAndView:
  73. if (string.IsNullOrEmpty(mMongoCommand.CommandString))
  74. {
  75. mCommandResult = ExecuteMongoColCommand(mMongoCommand.CmdDocument,
  76. RuntimeMongoDbContext.GetCurrentCollection());
  77. }
  78. else
  79. {
  80. mCommandResult = ExecuteMongoColCommand(mMongoCommand.CommandString,
  81. RuntimeMongoDbContext.GetCurrentCollection());
  82. }
  83. break;
  84. case EnumMgr.PathLevel.Database:
  85. if (string.IsNullOrEmpty(mMongoCommand.DatabaseName))
  86. {
  87. mCommandResult = ExecuteMongoDBCommand(mMongoCommand.CmdDocument, RuntimeMongoDbContext.GetCurrentDataBase());
  88. }
  89. else
  90. {
  91. var db = RuntimeMongoDbContext.GetCurrentClient().GetDatabase(mMongoCommand.DatabaseName);
  92. mCommandResult = ExecuteMongoDBCommand(mMongoCommand.CmdDocument, db);
  93. }
  94. break;
  95. case EnumMgr.PathLevel.Instance:
  96. mCommandResult = ExecuteMongoSvrCommand(mMongoCommand.CmdDocument,
  97. RuntimeMongoDbContext.GetCurrentServer());
  98. break;
  99. }
  100. resultCommandList.Add(mCommandResult);
  101. return mCommandResult;
  102. }
  103. /// <summary>
  104. /// 执行数据集命令
  105. /// </summary>
  106. /// <param name="commandString"></param>
  107. /// <param name="mongoCol"></param>
  108. /// <returns></returns>
  109. public static CommandResult ExecuteMongoColCommand(string commandString, MongoCollection mongoCol)
  110. {
  111. CommandResult mCommandResult;
  112. var baseCommand = new BsonDocument { { commandString, mongoCol.Name } };
  113. var mongoCmd = new CommandDocument();
  114. mongoCmd.AddRange(baseCommand);
  115. try
  116. {
  117. mCommandResult = mongoCol.Database.RunCommand(mongoCmd);
  118. }
  119. catch (MongoCommandException ex)
  120. {
  121. mCommandResult = new CommandResult(ex.Result);
  122. }
  123. var e = new RunCommandEventArgs
  124. {
  125. CommandString = commandString,
  126. RunLevel = EnumMgr.PathLevel.CollectionAndView,
  127. Result = mCommandResult
  128. };
  129. OnCommandRunComplete(e);
  130. return mCommandResult;
  131. }
  132. /// <summary>
  133. /// 数据集命令
  134. /// </summary>
  135. /// <param name="command">命令关键字</param>
  136. /// <param name="mongoCol">数据集</param>
  137. /// <param name="extendInfo">命令参数</param>
  138. /// <returns></returns>
  139. public static CommandResult ExecuteMongoColCommand(string command, MongoCollection mongoCol,
  140. BsonDocument extendInfo)
  141. {
  142. var executeCommand = new CommandDocument
  143. {
  144. {command, mongoCol.Name}
  145. };
  146. foreach (var item in extendInfo.Elements)
  147. {
  148. executeCommand.Add(item);
  149. }
  150. var mCommandResult = mongoCol.Database.RunCommand(executeCommand);
  151. var e = new RunCommandEventArgs
  152. {
  153. CommandString = executeCommand.ToString(),
  154. RunLevel = EnumMgr.PathLevel.CollectionAndView,
  155. Result = mCommandResult
  156. };
  157. OnCommandRunComplete(e);
  158. return mCommandResult;
  159. }
  160. /// <summary>
  161. /// 执行数据集命令
  162. /// </summary>
  163. /// <param name="cmdDoc"></param>
  164. /// <param name="mongoCol"></param>
  165. /// <returns></returns>
  166. public static CommandResult ExecuteMongoColCommand(CommandDocument cmdDoc, MongoCollection mongoCol)
  167. {
  168. CommandResult mCommandResult;
  169. try
  170. {
  171. mCommandResult = mongoCol.Database.RunCommand(cmdDoc);
  172. }
  173. catch (MongoCommandException ex)
  174. {
  175. mCommandResult = new CommandResult(ex.Result);
  176. }
  177. var e = new RunCommandEventArgs
  178. {
  179. CommandString = cmdDoc.GetElement(0).Value.ToString(),
  180. RunLevel = EnumMgr.PathLevel.Database,
  181. Result = mCommandResult
  182. };
  183. OnCommandRunComplete(e);
  184. return mCommandResult;
  185. }
  186. /// <summary>
  187. /// 执行数据库命令
  188. /// </summary>
  189. /// <param name="mongoCmd"></param>
  190. /// <param name="mongoDb"></param>
  191. /// <returns></returns>
  192. public static CommandResult ExecuteMongoDBCommand(string mongoCmd, MongoDatabase mongoDb)
  193. {
  194. CommandResult mCommandResult;
  195. try
  196. {
  197. mCommandResult = mongoDb.RunCommand(mongoCmd);
  198. }
  199. catch (MongoCommandException ex)
  200. {
  201. mCommandResult = new CommandResult(ex.Result);
  202. }
  203. var e = new RunCommandEventArgs
  204. {
  205. CommandString = mongoCmd,
  206. RunLevel = EnumMgr.PathLevel.Database,
  207. Result = mCommandResult
  208. };
  209. OnCommandRunComplete(e);
  210. return mCommandResult;
  211. }
  212. /// <summary>
  213. /// 执行数据库命令
  214. /// </summary>
  215. /// <param name="mongoCmd"></param>
  216. /// <param name="mongoDb"></param>
  217. /// <returns></returns>
  218. public static CommandResult ExecuteMongoDBCommand(CommandDocument mongoCmd, MongoDatabase mongoDb)
  219. {
  220. CommandResult mCommandResult;
  221. try
  222. {
  223. mCommandResult = mongoDb.RunCommand(mongoCmd);
  224. }
  225. catch (MongoCommandException ex)
  226. {
  227. mCommandResult = new CommandResult(ex.Result);
  228. }
  229. var e = new RunCommandEventArgs
  230. {
  231. CommandString = mongoCmd.ToString(),
  232. RunLevel = EnumMgr.PathLevel.Database,
  233. Result = mCommandResult
  234. };
  235. OnCommandRunComplete(e);
  236. return mCommandResult;
  237. }
  238. /// <summary>
  239. /// </summary>
  240. /// <param name="mongoCmd"></param>
  241. /// <param name="mongoDb"></param>
  242. /// <returns></returns>
  243. public static CommandResult ExecuteMongoDBCommand(CommandDocument mongoCmd, IMongoDatabase mongoDb)
  244. {
  245. CommandResult mCommandResult = null;
  246. try
  247. {
  248. var t = Task.Run(
  249. async () => { mCommandResult = await mongoDb.RunCommandAsync<CommandResult>(mongoCmd); }
  250. );
  251. t.Wait();
  252. }
  253. catch (MongoCommandException ex)
  254. {
  255. mCommandResult = new CommandResult(ex.Result);
  256. }
  257. var e = new RunCommandEventArgs
  258. {
  259. CommandString = mongoCmd.ToString(),
  260. RunLevel = EnumMgr.PathLevel.Database,
  261. Result = mCommandResult
  262. };
  263. OnCommandRunComplete(e);
  264. return mCommandResult;
  265. }
  266. /// <summary>
  267. /// 在指定数据库执行指定命令
  268. /// </summary>
  269. /// <param name="mMongoCommand"></param>
  270. /// <param name="mongoDb"></param>
  271. /// <returns></returns>
  272. public static CommandResult ExecuteMongoDBCommand(MongoCommand mMongoCommand, MongoDatabase mongoDb)
  273. {
  274. var command = new CommandDocument { { mMongoCommand.CommandString, 1 } };
  275. if (mMongoCommand.RunLevel == EnumMgr.PathLevel.Database)
  276. {
  277. return ExecuteMongoDBCommand(command, mongoDb);
  278. }
  279. throw new Exception();
  280. }
  281. /// <summary>
  282. /// 执行MongoCommand
  283. /// </summary>
  284. /// <param name="mongoCmd">命令Command</param>
  285. /// <param name="mongoSvr">目标服务器</param>
  286. /// <returns></returns>
  287. public static CommandResult ExecuteMongoSvrCommand(string mongoCmd, MongoServer mongoSvr)
  288. {
  289. CommandResult mCommandResult = null;
  290. try
  291. {
  292. if (mongoSvr.DatabaseExists(ConstMgr.DatabaseNameAdmin))
  293. {
  294. mCommandResult = mongoSvr.GetDatabase(ConstMgr.DatabaseNameAdmin).RunCommand(mongoCmd);
  295. }
  296. else
  297. {
  298. //Replset的时候,没有Admin数据库
  299. BsonDocument AdminDatabaseNotFound = new BsonDocument
  300. {
  301. { "errmsg", "Admin Database Not Found" }
  302. };
  303. mCommandResult = new CommandResult(AdminDatabaseNotFound);
  304. }
  305. }
  306. catch (MongoCommandException ex)
  307. {
  308. mCommandResult = new CommandResult(ex.Result);
  309. }
  310. catch (TimeoutException)
  311. {
  312. BsonDocument TimeOutDocument = new BsonDocument
  313. {
  314. { "errmsg", "TimeoutException" }
  315. };
  316. mCommandResult = new CommandResult(TimeOutDocument);
  317. }
  318. var e = new RunCommandEventArgs
  319. {
  320. CommandString = mongoCmd,
  321. RunLevel = EnumMgr.PathLevel.Instance,
  322. Result = mCommandResult
  323. };
  324. OnCommandRunComplete(e);
  325. return mCommandResult;
  326. }
  327. /// <summary>
  328. /// 执行MongoCommand
  329. /// </summary>
  330. /// <param name="mCommandDocument">命令Doc</param>
  331. /// <param name="mongoSvr">目标服务器</param>
  332. /// <returns></returns>
  333. public static CommandResult ExecuteMongoSvrCommand(CommandDocument mCommandDocument, MongoServer mongoSvr)
  334. {
  335. CommandResult mCommandResult = null;
  336. try
  337. {
  338. if (mongoSvr.DatabaseExists(ConstMgr.DatabaseNameAdmin))
  339. {
  340. //Repl的时候,会发生超时问题
  341. mCommandResult = mongoSvr.GetDatabase(ConstMgr.DatabaseNameAdmin).RunCommand(mCommandDocument);
  342. }
  343. else
  344. {
  345. //Replset的时候,没有Admin数据库
  346. BsonDocument AdminDatabaseNotFound = new BsonDocument
  347. {
  348. { "errmsg", "Admin Database Not Found" }
  349. };
  350. mCommandResult = new CommandResult(AdminDatabaseNotFound);
  351. }
  352. }
  353. catch (MongoCommandException ex)
  354. {
  355. mCommandResult = new CommandResult(ex.Result);
  356. }
  357. catch (TimeoutException)
  358. {
  359. BsonDocument TimeOutDocument = new BsonDocument
  360. {
  361. { "errmsg", "TimeoutException" }
  362. };
  363. mCommandResult = new CommandResult(TimeOutDocument);
  364. }
  365. var e = new RunCommandEventArgs
  366. {
  367. CommandString = mCommandDocument.ToString(),
  368. RunLevel = EnumMgr.PathLevel.Instance,
  369. Result = mCommandResult
  370. };
  371. OnCommandRunComplete(e);
  372. return mCommandResult;
  373. }
  374. /// <summary>
  375. /// 在指定服务器上执行指定命令
  376. /// </summary>
  377. /// <param name="mMongoCommand"></param>
  378. /// <param name="mongosrv"></param>
  379. /// <returns></returns>
  380. public static CommandResult ExecuteMongoSvrCommand(MongoCommand mMongoCommand, MongoServer mongosrv)
  381. {
  382. var command = new CommandDocument { { mMongoCommand.CommandString, 1 } };
  383. if (mMongoCommand.RunLevel == EnumMgr.PathLevel.Database)
  384. {
  385. throw new Exception();
  386. }
  387. return ExecuteMongoSvrCommand(command, mongosrv);
  388. }
  389. /// <summary>
  390. /// MONGO命令
  391. /// </summary>
  392. public struct MongoCommand
  393. {
  394. /// <summary>
  395. /// </summary>
  396. public CommandDocument CmdDocument;
  397. /// <summary>
  398. /// 命令文
  399. /// </summary>
  400. public string CommandString;
  401. /// <summary>
  402. /// 对象等级
  403. /// </summary>
  404. public EnumMgr.PathLevel RunLevel;
  405. /// <summary>
  406. /// 命令数据库对象名称
  407. /// </summary>
  408. public string DatabaseName;
  409. /// <summary>
  410. /// 命令数据集对象名称
  411. /// </summary>
  412. public string CollectionName;
  413. /// <summary>
  414. /// 初始化
  415. /// </summary>
  416. /// <param name="commandString"></param>
  417. /// <param name="runLevel"></param>
  418. public MongoCommand(string commandString, EnumMgr.PathLevel runLevel, string databaseName = "", string collectionName = "")
  419. {
  420. CommandString = commandString;
  421. RunLevel = runLevel;
  422. CmdDocument = new CommandDocument { { commandString, 1 } };
  423. DatabaseName = databaseName;
  424. CollectionName = collectionName;
  425. }
  426. /// <summary>
  427. /// 初始化
  428. /// </summary>
  429. /// <param name="commandDocument"></param>
  430. /// <param name="runLevel"></param>
  431. public MongoCommand(CommandDocument commandDocument, EnumMgr.PathLevel runLevel, string databaseName = "", string collectionName = "")
  432. {
  433. CmdDocument = commandDocument;
  434. RunLevel = runLevel;
  435. CommandString = string.Empty;
  436. DatabaseName = databaseName;
  437. CollectionName = collectionName;
  438. }
  439. }
  440. }
  441. }