aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Storage/OpenSim.DataStore.MonoSqlite/MonoSqliteDataStore.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Storage/OpenSim.DataStore.MonoSqlite/MonoSqliteDataStore.cs')
-rw-r--r--OpenSim/Region/Storage/OpenSim.DataStore.MonoSqlite/MonoSqliteDataStore.cs325
1 files changed, 323 insertions, 2 deletions
diff --git a/OpenSim/Region/Storage/OpenSim.DataStore.MonoSqlite/MonoSqliteDataStore.cs b/OpenSim/Region/Storage/OpenSim.DataStore.MonoSqlite/MonoSqliteDataStore.cs
index 0a55582..cc9146d 100644
--- a/OpenSim/Region/Storage/OpenSim.DataStore.MonoSqlite/MonoSqliteDataStore.cs
+++ b/OpenSim/Region/Storage/OpenSim.DataStore.MonoSqlite/MonoSqliteDataStore.cs
@@ -45,11 +45,16 @@ namespace OpenSim.DataStore.MonoSqlite
45 private const string primSelect = "select * from prims"; 45 private const string primSelect = "select * from prims";
46 private const string shapeSelect = "select * from primshapes"; 46 private const string shapeSelect = "select * from primshapes";
47 private const string terrainSelect = "select * from terrain limit 1"; 47 private const string terrainSelect = "select * from terrain limit 1";
48 private const string landSelect = "select * from land";
49 private const string landAccessListSelect = "select * from landaccesslist";
48 50
49 private DataSet ds; 51 private DataSet ds;
50 private SqliteDataAdapter primDa; 52 private SqliteDataAdapter primDa;
51 private SqliteDataAdapter shapeDa; 53 private SqliteDataAdapter shapeDa;
52 private SqliteDataAdapter terrainDa; 54 private SqliteDataAdapter terrainDa;
55 private SqliteDataAdapter landDa;
56 private SqliteDataAdapter landAccessListDa;
57
53 private String m_connectionString; 58 private String m_connectionString;
54 59
55 /*********************************************************************** 60 /***********************************************************************
@@ -78,6 +83,12 @@ namespace OpenSim.DataStore.MonoSqlite
78 SqliteCommand terrainSelectCmd = new SqliteCommand(terrainSelect, conn); 83 SqliteCommand terrainSelectCmd = new SqliteCommand(terrainSelect, conn);
79 terrainDa = new SqliteDataAdapter(terrainSelectCmd); 84 terrainDa = new SqliteDataAdapter(terrainSelectCmd);
80 85
86 SqliteCommand landSelectCmd = new SqliteCommand(landSelect, conn);
87 landDa = new SqliteDataAdapter(landSelectCmd);
88
89 SqliteCommand landAccessListSelectCmd = new SqliteCommand(landAccessListSelect, conn);
90 landAccessListDa = new SqliteDataAdapter(landAccessListSelectCmd);
91
81 // We fill the data set, now we've got copies in memory for the information 92 // We fill the data set, now we've got copies in memory for the information
82 // TODO: see if the linkage actually holds. 93 // TODO: see if the linkage actually holds.
83 // primDa.FillSchema(ds, SchemaType.Source, "PrimSchema"); 94 // primDa.FillSchema(ds, SchemaType.Source, "PrimSchema");
@@ -95,6 +106,12 @@ namespace OpenSim.DataStore.MonoSqlite
95 ds.Tables.Add(createTerrainTable()); 106 ds.Tables.Add(createTerrainTable());
96 setupTerrainCommands(terrainDa, conn); 107 setupTerrainCommands(terrainDa, conn);
97 108
109 ds.Tables.Add(createLandTable());
110 setupLandCommands(landDa, conn);
111
112 ds.Tables.Add(createLandAccessListTable());
113 setupLandAccessCommands(landAccessListDa, conn);
114
98 // WORKAROUND: This is a work around for sqlite on 115 // WORKAROUND: This is a work around for sqlite on
99 // windows, which gets really unhappy with blob columns 116 // windows, which gets really unhappy with blob columns
100 // that have no sample data in them. At some point we 117 // that have no sample data in them. At some point we
@@ -116,6 +133,24 @@ namespace OpenSim.DataStore.MonoSqlite
116 { 133 {
117 MainLog.Instance.Verbose("DATASTORE", "Caught fill error on terrain table"); 134 MainLog.Instance.Verbose("DATASTORE", "Caught fill error on terrain table");
118 } 135 }
136
137 try
138 {
139 landDa.Fill(ds.Tables["land"]);
140 }
141 catch (Exception)
142 {
143 MainLog.Instance.Verbose("DATASTORE", "Caught fill error on land table");
144 }
145
146 try
147 {
148 landAccessListDa.Fill(ds.Tables["landaccesslist"]);
149 }
150 catch (Exception)
151 {
152 MainLog.Instance.Verbose("DATASTORE", "Caught fill error on landaccesslist table");
153 }
119 return; 154 return;
120 } 155 }
121 } 156 }
@@ -346,17 +381,95 @@ namespace OpenSim.DataStore.MonoSqlite
346 } 381 }
347 } 382 }
348 383
349 public void RemoveLandObject(uint id, LLUUID regionUUID) 384 public void RemoveLandObject(LLUUID globalID)
350 { 385 {
386 lock (ds)
387 {
388 SqliteConnection conn = new SqliteConnection(m_connectionString);
389 conn.Open();
390
391 Console.WriteLine("REMOVING LAND WITH ID " + globalID);
392 using (SqliteCommand cmd = new SqliteCommand("delete from land where UUID=:UUID", conn))
393 {
394 cmd.Parameters.Add(new SqliteParameter(":UUID", globalID.ToString()));
395 cmd.ExecuteNonQuery();
396 }
397
398 using (SqliteCommand cmd = new SqliteCommand("delete from landaccesslist where LandUUID=:UUID", conn))
399 {
400 cmd.Parameters.Add(new SqliteParameter(":UUID", globalID.ToString()));
401 cmd.ExecuteNonQuery();
402 }
403 conn.Close();
404 }
351 } 405 }
352 406
353 public void StoreLandObject(Land parcel, LLUUID regionUUID) 407 public void StoreLandObject(Land parcel, LLUUID regionUUID)
354 { 408 {
409 lock (ds)
410 {
411 SqliteConnection conn = new SqliteConnection(m_connectionString);
412 conn.Open();
413
414 Console.WriteLine("STORING LAND TO SQLITE: " + parcel.landData.landName + " (" + parcel.landData.globalID + ")");
415 DataTable land = ds.Tables["land"];
416 DataTable landaccesslist = ds.Tables["landaccesslist"];
417
418 DataRow landRow = land.Rows.Find(parcel.landData.globalID.ToString());
419 if (landRow == null)
420 {
421 landRow = land.NewRow();
422 fillLandRow(landRow, parcel.landData, regionUUID);
423 land.Rows.Add(landRow);
424 }
425 else
426 {
427 fillLandRow(landRow, parcel.landData, regionUUID);
428 }
429
430 using (SqliteCommand cmd = new SqliteCommand("delete from landaccesslist where LandUUID=:LandUUID", conn))
431 {
432 cmd.Parameters.Add(new SqliteParameter(":LandUUID", parcel.landData.globalID.ToString()));
433 cmd.ExecuteNonQuery();
434 }
435
436 foreach (ParcelManager.ParcelAccessEntry entry in parcel.landData.parcelAccessList)
437 {
438 DataRow newAccessRow = landaccesslist.NewRow();
439 fillLandAccessRow(newAccessRow, entry, parcel.landData.globalID);
440 landaccesslist.Rows.Add(newAccessRow);
441 }
442 conn.Close();
443
444 }
445
446 Commit();
355 } 447 }
356 448
357 public List<Framework.LandData> LoadLandObjects(LLUUID regionUUID) 449 public List<Framework.LandData> LoadLandObjects(LLUUID regionUUID)
358 { 450 {
359 return new List<LandData>(); 451 List<LandData> landDataForRegion = new List<LandData>();
452 lock(ds)
453 {
454 DataTable land = ds.Tables["land"];
455 DataTable landaccesslist = ds.Tables["landaccesslist"];
456 string searchExp = "RegionUUID = '" + regionUUID.ToString() + "'";
457 DataRow[] rawDataForRegion = land.Select(searchExp);
458 foreach (DataRow rawDataLand in rawDataForRegion)
459 {
460 LandData newLand = buildLandData(rawDataLand);
461 Console.WriteLine("LOADED NEW LAND FROM SQLITE: " + newLand.landName + " (" + newLand.globalID + ")");
462 string accessListSearchExp = "LandUUID = '" + newLand.globalID.ToString() + "'";
463 DataRow[] rawDataForLandAccessList = landaccesslist.Select(accessListSearchExp);
464 foreach (DataRow rawDataLandAccess in rawDataForLandAccessList)
465 {
466 newLand.parcelAccessList.Add(buildLandAccessData(rawDataLandAccess));
467 }
468
469 landDataForRegion.Add(newLand);
470 }
471 }
472 return landDataForRegion;
360 } 473 }
361 474
362 public void Commit() 475 public void Commit()
@@ -366,6 +479,8 @@ namespace OpenSim.DataStore.MonoSqlite
366 primDa.Update(ds, "prims"); 479 primDa.Update(ds, "prims");
367 shapeDa.Update(ds, "primshapes"); 480 shapeDa.Update(ds, "primshapes");
368 terrainDa.Update(ds, "terrain"); 481 terrainDa.Update(ds, "terrain");
482 landDa.Update(ds, "land");
483 landAccessListDa.Update(ds, "landaccesslist");
369 ds.AcceptChanges(); 484 ds.AcceptChanges();
370 } 485 }
371 } 486 }
@@ -495,6 +610,59 @@ namespace OpenSim.DataStore.MonoSqlite
495 return shapes; 610 return shapes;
496 } 611 }
497 612
613 private DataTable createLandTable()
614 {
615 DataTable land = new DataTable("land");
616 createCol(land, "UUID", typeof(String));
617 createCol(land, "RegionUUID", typeof(String));
618 createCol(land, "LocalLandID", typeof(UInt32));
619
620 // Bitmap is a byte[512]
621 createCol(land, "Bitmap", typeof(Byte[]));
622
623 createCol(land, "Name", typeof(String));
624 createCol(land, "Desc", typeof(String));
625 createCol(land, "OwnerUUID", typeof(String));
626 createCol(land, "IsGroupOwned", typeof(Boolean));
627 createCol(land, "Area", typeof(Int32));
628 createCol(land, "AutionID", typeof(Int32)); //Unemplemented
629 createCol(land, "Category", typeof(Int32)); //Enum libsecondlife.Parcel.ParcelCategory
630 createCol(land, "ClaimDate", typeof(Int32));
631 createCol(land, "ClaimPrice", typeof(Int32));
632 createCol(land, "GroupUUID", typeof(string));
633 createCol(land, "SalePrice", typeof(Int32));
634 createCol(land, "LandStatus", typeof(Int32)); //Enum. libsecondlife.Parcel.ParcelStatus
635 createCol(land, "LandFlags", typeof(UInt32));
636 createCol(land, "LandingType", typeof(Byte));
637 createCol(land, "MediaAutoScale", typeof(Byte));
638 createCol(land, "MediaTextureUUID", typeof(String));
639 createCol(land, "MediaURL", typeof(String));
640 createCol(land, "MusicURL", typeof(String));
641 createCol(land, "PassHours", typeof(Double));
642 createCol(land, "PassPrice", typeof(UInt32));
643 createCol(land, "SnapshotUUID", typeof(String));
644 createCol(land, "UserLocationX", typeof(Double));
645 createCol(land, "UserLocationY", typeof(Double));
646 createCol(land, "UserLocationZ", typeof(Double));
647 createCol(land, "UserLookAtX", typeof(Double));
648 createCol(land, "UserLookAtY", typeof(Double));
649 createCol(land, "UserLookAtZ", typeof(Double));
650
651 land.PrimaryKey = new DataColumn[] { land.Columns["UUID"] };
652
653 return land;
654 }
655
656 private DataTable createLandAccessListTable()
657 {
658 DataTable landaccess = new DataTable("landaccesslist");
659 createCol(landaccess, "LandUUID", typeof(String));
660 createCol(landaccess, "AccessUUID", typeof(String));
661 createCol(landaccess, "Flags", typeof(UInt32));
662
663 return landaccess;
664 }
665
498 /*********************************************************************** 666 /***********************************************************************
499 * 667 *
500 * Convert between ADO.NET <=> OpenSim Objects 668 * Convert between ADO.NET <=> OpenSim Objects
@@ -568,6 +736,54 @@ namespace OpenSim.DataStore.MonoSqlite
568 return prim; 736 return prim;
569 } 737 }
570 738
739 private LandData buildLandData(DataRow row)
740 {
741 LandData newData = new LandData();
742
743 newData.globalID = new LLUUID((String)row["UUID"]);
744 newData.localID= Convert.ToInt32(row["LocalLandID"]);
745
746 // Bitmap is a byte[512]
747 newData.landBitmapByteArray = (Byte[]) row["Bitmap"];
748
749 newData.landName= (String) row["Name"];
750 newData.landDesc= (String) row["Desc"];
751 newData.ownerID= (String) row["OwnerUUID"];
752 newData.isGroupOwned= (Boolean) row["IsGroupOwned"];
753 newData.area= Convert.ToInt32(row["Area"]);
754 newData.auctionID = Convert.ToUInt32(row["AutionID"]); //Unemplemented
755 newData.category= (Parcel.ParcelCategory) Convert.ToInt32(row["Category"]); //Enum libsecondlife.Parcel.ParcelCategory
756 newData.claimDate= Convert.ToInt32(row["ClaimDate"]);
757 newData.claimPrice= Convert.ToInt32(row["ClaimPrice"]);
758 newData.groupID= new LLUUID((String)row["GroupUUID"]);
759 newData.salePrice = Convert.ToInt32(row["SalePrice"]);
760 newData.landStatus= (Parcel.ParcelStatus) Convert.ToInt32(row["LandStatus"]); //Enum. libsecondlife.Parcel.ParcelStatus
761 newData.landFlags= Convert.ToUInt32(row["LandFlags"]);
762 newData.landingType= (Byte) row["LandingType"];
763 newData.mediaAutoScale= (Byte) row["MediaAutoScale"];
764 newData.mediaID= new LLUUID((String)row["MediaTextureUUID"]);
765 newData.mediaURL= (String) row["MediaURL"];
766 newData.musicURL= (String) row["MusicURL"];
767 newData.passHours= Convert.ToSingle(row["PassHours"]);
768 newData.passPrice= Convert.ToInt32(row["PassPrice"]);
769 newData.snapshotID= (String) row["SnapshotUUID"];
770
771 newData.userLocation = new LLVector3(Convert.ToSingle(row["UserLocationX"]),Convert.ToSingle(row["UserLocationY"]), Convert.ToSingle(row["UserLocationZ"]));
772 newData.userLookAt = new LLVector3(Convert.ToSingle(row["UserLookAtX"]),Convert.ToSingle(row["UserLookAtY"]), Convert.ToSingle(row["UserLookAtZ"]));
773 newData.parcelAccessList = new List<ParcelManager.ParcelAccessEntry>();
774
775 return newData;
776 }
777
778 private ParcelManager.ParcelAccessEntry buildLandAccessData(DataRow row)
779 {
780 ParcelManager.ParcelAccessEntry entry = new ParcelManager.ParcelAccessEntry();
781 entry.AgentID = new LLUUID((string)row["LandUUID"]);
782 entry.Flags = (ParcelManager.AccessList)row["Flags"];
783 entry.Time = new DateTime();
784 return entry;
785 }
786
571 private Array serializeTerrain(double[,] val) 787 private Array serializeTerrain(double[,] val)
572 { 788 {
573 MemoryStream str = new MemoryStream(65536*sizeof (double)); 789 MemoryStream str = new MemoryStream(65536*sizeof (double));
@@ -644,6 +860,51 @@ namespace OpenSim.DataStore.MonoSqlite
644 row["RotationW"] = prim.RotationOffset.W; 860 row["RotationW"] = prim.RotationOffset.W;
645 } 861 }
646 862
863 private void fillLandRow(DataRow row, LandData land, LLUUID regionUUID)
864 {
865 row["UUID"] = land.globalID.ToString();
866 row["RegionUUID"] = regionUUID.ToString();
867 row["LocalLandID"] = land.localID;
868
869 // Bitmap is a byte[512]
870 row["Bitmap"] = land.landBitmapByteArray;
871
872 row["Name"] = land.landName;
873 row["Desc"] = land.landDesc;
874 row["OwnerUUID"] = land.ownerID.ToString();
875 row["IsGroupOwned"] = land.isGroupOwned;
876 row["Area"] = land.area;
877 row["AutionID"] = land.auctionID; //Unemplemented
878 row["Category"] = land.category; //Enum libsecondlife.Parcel.ParcelCategory
879 row["ClaimDate"] = land.claimDate;
880 row["ClaimPrice"] = land.claimPrice;
881 row["GroupUUID"] = land.groupID.ToString();
882 row["SalePrice"] = land.salePrice;
883 row["LandStatus"] = land.landStatus; //Enum. libsecondlife.Parcel.ParcelStatus
884 row["LandFlags"] = land.landFlags;
885 row["LandingType"] = land.landingType;
886 row["MediaAutoScale"] = land.mediaAutoScale;
887 row["MediaTextureUUID"] = land.mediaID.ToString();
888 row["MediaURL"] = land.mediaURL;
889 row["MusicURL"] = land.musicURL;
890 row["PassHours"] = land.passHours;
891 row["PassPrice"] = land.passPrice;
892 row["SnapshotUUID"] = land.snapshotID.ToString();
893 row["UserLocationX"] = land.userLocation.X;
894 row["UserLocationY"] = land.userLocation.Y;
895 row["UserLocationZ"] = land.userLocation.Z;
896 row["UserLookAtX"] = land.userLookAt.X;
897 row["UserLookAtY"] = land.userLookAt.Y;
898 row["UserLookAtZ"] = land.userLookAt.Z;
899 }
900
901 private void fillLandAccessRow(DataRow row, ParcelManager.ParcelAccessEntry entry, LLUUID parcelID)
902 {
903 row["LandUUID"] = parcelID.ToString();
904 row["AccessUUID"] = entry.AgentID.ToString();
905 row["Flags"] = entry.Flags;
906 }
907
647 private PrimitiveBaseShape buildShape(DataRow row) 908 private PrimitiveBaseShape buildShape(DataRow row)
648 { 909 {
649 PrimitiveBaseShape s = new PrimitiveBaseShape(); 910 PrimitiveBaseShape s = new PrimitiveBaseShape();
@@ -907,6 +1168,20 @@ namespace OpenSim.DataStore.MonoSqlite
907 da.InsertCommand.Connection = conn; 1168 da.InsertCommand.Connection = conn;
908 } 1169 }
909 1170
1171 private void setupLandCommands(SqliteDataAdapter da, SqliteConnection conn)
1172 {
1173 da.InsertCommand = createInsertCommand("land", ds.Tables["land"]);
1174 da.InsertCommand.Connection = conn;
1175
1176 da.UpdateCommand = createUpdateCommand("land", "UUID=:UUID", ds.Tables["land"]);
1177 da.UpdateCommand.Connection = conn;
1178 }
1179
1180 private void setupLandAccessCommands(SqliteDataAdapter da, SqliteConnection conn)
1181 {
1182 da.InsertCommand = createInsertCommand("landaccesslist", ds.Tables["landaccesslist"]);
1183 da.InsertCommand.Connection = conn;
1184 }
910 private void setupShapeCommands(SqliteDataAdapter da, SqliteConnection conn) 1185 private void setupShapeCommands(SqliteDataAdapter da, SqliteConnection conn)
911 { 1186 {
912 da.InsertCommand = createInsertCommand("primshapes", ds.Tables["primshapes"]); 1187 da.InsertCommand = createInsertCommand("primshapes", ds.Tables["primshapes"]);
@@ -926,10 +1201,15 @@ namespace OpenSim.DataStore.MonoSqlite
926 string createPrims = defineTable(createPrimTable()); 1201 string createPrims = defineTable(createPrimTable());
927 string createShapes = defineTable(createShapeTable()); 1202 string createShapes = defineTable(createShapeTable());
928 string createTerrain = defineTable(createTerrainTable()); 1203 string createTerrain = defineTable(createTerrainTable());
1204 string createLand = defineTable(createLandTable());
1205 string createLandAccessList = defineTable(createLandAccessListTable());
929 1206
930 SqliteCommand pcmd = new SqliteCommand(createPrims, conn); 1207 SqliteCommand pcmd = new SqliteCommand(createPrims, conn);
931 SqliteCommand scmd = new SqliteCommand(createShapes, conn); 1208 SqliteCommand scmd = new SqliteCommand(createShapes, conn);
932 SqliteCommand tcmd = new SqliteCommand(createTerrain, conn); 1209 SqliteCommand tcmd = new SqliteCommand(createTerrain, conn);
1210 SqliteCommand lcmd = new SqliteCommand(createLand, conn);
1211 SqliteCommand lalcmd = new SqliteCommand(createLandAccessList, conn);
1212
933 conn.Open(); 1213 conn.Open();
934 1214
935 try 1215 try
@@ -959,6 +1239,23 @@ namespace OpenSim.DataStore.MonoSqlite
959 MainLog.Instance.Warn("SQLITE", "Terrain Table Already Exists"); 1239 MainLog.Instance.Warn("SQLITE", "Terrain Table Already Exists");
960 } 1240 }
961 1241
1242 try
1243 {
1244 lcmd.ExecuteNonQuery();
1245 }
1246 catch (SqliteSyntaxException)
1247 {
1248 MainLog.Instance.Warn("SQLITE", "Land Table Already Exists");
1249 }
1250
1251 try
1252 {
1253 lalcmd.ExecuteNonQuery();
1254 }
1255 catch (SqliteSyntaxException)
1256 {
1257 MainLog.Instance.Warn("SQLITE", "LandAccessList Table Already Exists");
1258 }
962 conn.Close(); 1259 conn.Close();
963 } 1260 }
964 1261
@@ -970,6 +1267,10 @@ namespace OpenSim.DataStore.MonoSqlite
970 SqliteDataAdapter sDa = new SqliteDataAdapter(shapeSelectCmd); 1267 SqliteDataAdapter sDa = new SqliteDataAdapter(shapeSelectCmd);
971 SqliteCommand terrainSelectCmd = new SqliteCommand(terrainSelect, conn); 1268 SqliteCommand terrainSelectCmd = new SqliteCommand(terrainSelect, conn);
972 SqliteDataAdapter tDa = new SqliteDataAdapter(terrainSelectCmd); 1269 SqliteDataAdapter tDa = new SqliteDataAdapter(terrainSelectCmd);
1270 SqliteCommand landSelectCmd = new SqliteCommand(landSelect, conn);
1271 SqliteDataAdapter lDa = new SqliteDataAdapter(landSelectCmd);
1272 SqliteCommand landAccessListSelectCmd = new SqliteCommand(landAccessListSelect, conn);
1273 SqliteDataAdapter lalDa = new SqliteDataAdapter(landAccessListSelectCmd);
973 1274
974 DataSet tmpDS = new DataSet(); 1275 DataSet tmpDS = new DataSet();
975 try 1276 try
@@ -977,6 +1278,8 @@ namespace OpenSim.DataStore.MonoSqlite
977 pDa.Fill(tmpDS, "prims"); 1278 pDa.Fill(tmpDS, "prims");
978 sDa.Fill(tmpDS, "primshapes"); 1279 sDa.Fill(tmpDS, "primshapes");
979 tDa.Fill(tmpDS, "terrain"); 1280 tDa.Fill(tmpDS, "terrain");
1281 lDa.Fill(tmpDS, "land");
1282 lalDa.Fill(tmpDS, "landaccesslist");
980 } 1283 }
981 catch (SqliteSyntaxException) 1284 catch (SqliteSyntaxException)
982 { 1285 {
@@ -987,6 +1290,8 @@ namespace OpenSim.DataStore.MonoSqlite
987 pDa.Fill(tmpDS, "prims"); 1290 pDa.Fill(tmpDS, "prims");
988 sDa.Fill(tmpDS, "primshapes"); 1291 sDa.Fill(tmpDS, "primshapes");
989 tDa.Fill(tmpDS, "terrain"); 1292 tDa.Fill(tmpDS, "terrain");
1293 lDa.Fill(tmpDS, "land");
1294 lalDa.Fill(tmpDS,"landaccesslist");
990 1295
991 foreach (DataColumn col in createPrimTable().Columns) 1296 foreach (DataColumn col in createPrimTable().Columns)
992 { 1297 {
@@ -1012,6 +1317,22 @@ namespace OpenSim.DataStore.MonoSqlite
1012 return false; 1317 return false;
1013 } 1318 }
1014 } 1319 }
1320 foreach (DataColumn col in createLandTable().Columns)
1321 {
1322 if (!tmpDS.Tables["land"].Columns.Contains(col.ColumnName))
1323 {
1324 MainLog.Instance.Verbose("DATASTORE", "Missing require column:" + col.ColumnName);
1325 return false;
1326 }
1327 }
1328 foreach (DataColumn col in createLandAccessListTable().Columns)
1329 {
1330 if (!tmpDS.Tables["landaccesslist"].Columns.Contains(col.ColumnName))
1331 {
1332 MainLog.Instance.Verbose("DATASTORE", "Missing require column:" + col.ColumnName);
1333 return false;
1334 }
1335 }
1015 return true; 1336 return true;
1016 } 1337 }
1017 1338