Searching for a known path in OrientDB - path

I'm experimenting with the idea of storing a DNS hierarchy in an OrientDB graph and am having trouble finding the appropriate place to add a new vertex for a given domain.
I am starting with this structure:
CREATE CLASS Zone EXTENDS V
CREATE CLASS Subdomain_of EXTENDS E
CREATE VERTEX Zone CONTENT {name: '.'} #12:0
CREATE VERTEX Zone CONTENT {name: 'com'} #12:1
CREATE VERTEX Zone CONTENT {name: 'net'} #12:2
CREATE VERTEX Zone CONTENT {name: 'org'} #12:3
CREATE VERTEX Zone CONTENT {name: 'example'} #12:4
CREATE VERTEX Zone CONTENT {name: 'www'} #12:5
CREATE EDGE Subdomain FROM #12:1 TO #12:0
CREATE EDGE Subdomain FROM #12:2 TO #12:0
CREATE EDGE Subdomain FROM #12:3 TO #12:0
CREATE EDGE Subdomain FROM #12:4 TO #12:1
CREATE EDGE Subdomain FROM #12:5 TO #12:4
Example DNS Hierarchy
I want to create a saved function that will take a domain name string as input and add relevant subdomains to the graph.
Imagine I want to add domain "mail.example.com". The function would need to first search to see if the path .com.example.mail existed - if not, it should then check .com.example and add a new vertex for "mail" with a subdomain edge to the "example" vertex.
Is there a way to search for a leaf node, based upon a specific path? Something akin to Neo4j/Cypher syntax:
MATCH
(:Zone {name: ‘.’})<-[Subdomain]-(:Zone {name: ‘com’})<-[:Subdomain]-(a:Zone {name: ‘example’})
RETURN (ID(a))
Thanks,
Charles

With this Java function should add the new vertices if not already present.
public class DomainInternet {
static final String REMOTE = "remote:localhost/";
static final String NOMEDB = "domain"; // 2.1.9 community
static final String CURRENTPATH = REMOTE + NOMEDB;
public static void main(String[] args) {
OrientGraphNoTx g = new OrientGraphFactory(CURRENTPATH).getNoTx();
addDomain(g, "mail.example.com");
System.out.println("End!");
}
public static void addDomain(OrientGraphNoTx g, String newDomain) {
// ---------------------check if path is already present
// put in a list the single word
List<String> listDomain = new ArrayList<String>(Arrays.asList(newDomain.split("([.])")));
//reverse = "com; example; mail"
Collections.reverse(listDomain);
//set variable used by query to find if domain is already present
Iterable<Vertex> level = null;
List<OrientVertex> listaVertex = new ArrayList<OrientVertex>();
String queryFirst = "select expand(in('Subdomain_of')) from Zone where name = ";
String name = "";
boolean finded = false;
//set variable used by add new domain
OrientVertex addVertex;
String nodePrec = ".";
for(int i=0; i<listDomain.size(); i++) {
//from "."
level = g.command(new OSQLSynchQuery<Vertex>(queryFirst+"'"+nodePrec+"'")).execute();
CollectionUtils.addAll(listaVertex, level.iterator());
for (int ind = 0; ind<listaVertex.size(); ind++) {
name = listaVertex.get(ind).getProperty("name");
if(name.equals(listDomain.get(i))){
finded = true;
break;
}
}
// if not finded
if (!finded) {
//add vertex
addVertex = g.addVertex("class:Zone");
addVertex.setProperties("name", listDomain.get(i));
//add edge
Map<String, Vertex> vertices = new HashMap<String, Vertex>();
for (Vertex v : g.getVertices()){
vertices.put(v.getProperty("name").toString(), v);
}
g.addEdge("class:Subdomain_of", vertices.get(listDomain.get(i)), vertices.get(nodePrec), "Subdomain_of");
}
//set new name for next link
nodePrec = listDomain.get(i);
listaVertex.clear();
finded = false;
}
g.shutdown();
}
}
EDIT 1
The same function made in JAVASCRIPT
Create a new JS function (named for example 'AddNewDomain')
Add the parameter named 'nameNewDomain';
var gdb = orient.getGraphNoTx();
print("Insert new domain: '" + nameNewDomain + "'");
// ---------------------check if path is already present
var listDomain = nameNewDomain.split('.');
listDomain.reverse();
var listaVertex;
var queryFirst = "select expand(in('Subdomain_of')) from Zone where name = ";
var name = "";
var finded = false;
var nodePrec = ".";
for (i = 0; i < listDomain.length; i++) {
// from "."
listaVertex = gdb.command("sql", queryFirst + "'" + nodePrec + "'");
for (ind = 0; ind < listaVertex.length; ind++) {
name = listaVertex[ind].getProperty("name");
if (name.equals(listDomain[i])) {
finded = true;
break;
}
}
// if not finded
if (!finded) {
// add vertex
gdb.command("sql", "insert into Zone (name) values('" + listDomain[i] + "')");
// add edge
gdb.command("sql", "create edge Subdomain_of from (select from Zone where name = '" + listDomain[i]
+ "') to (select from Zone where name = '" + nodePrec + "')");
}
// set new name for next link
nodePrec = listDomain[i];
listaVertex = "";
finded = false;
}
In the Tab 'browse' in studio, recall the function:
select AddDomain("mail3.example2.com")

Related

Xamarin Android, get contact mobile number by using CursorLoader with selection and selection args

I'm trying to get contact details of a contact that the user picks from the contacts list in Android using Intent as the following code:
Intent Intent = new Intent(Intent.ActionPick, ContactsContract.Contacts.ContentUri);
Intent.SetType(ContactsContract.Contacts.ContentType);
StartActivityForResult(Intent, 3);
Now on the Intent results I run the following code to get specific contact information:
public override void OnActivityResult(int requestCode, int resultCode, Intent data)
{
if (requestCode == 3 && resultCode == -1 && data != null) //result code -1 means OK 0 Means cancelled Result.Ok
{
var ContactData = data.Data;
string ID = "";
string name = "";
string address = "";
byte[] picture = new byte[0];
List<string> numbers = new List<string>();
List<string> emails = new List<string>();
string mobile = "";
string email = "";
string selectionString = "id = ?";
string[] columnsNames = new string[] {
ContactsContract.Contacts.InterfaceConsts.Id,
ContactsContract.Contacts.InterfaceConsts.DisplayName,
ContactsContract.Contacts.InterfaceConsts.PhotoUri
};
var loader = new CursorLoader(Statics.mainActivity, ContactData, null, null, null, null);
var cursor = (ICursor)loader.LoadInBackground();
if (cursor.MoveToFirst())
{
ID = cursor.GetString(cursor.GetColumnIndex(columnsNames[0]));
name = cursor.GetString(cursor.GetColumnIndex(columnsNames[1]));
picture = cursor.GetBlob(cursor.GetColumnIndex(columnsNames[2]));
}
//Store Contact ID
string[] selectionStringArgs = new string[] { ID };
//Phone Numbers
string[] columnsNames2 = new string[] {
ContactsContract.CommonDataKinds.Phone.Number
};
var loader2 = new CursorLoader(Statics.mainActivity, ContactsContract.CommonDataKinds.Phone.ContentUri, columnsNames2, selectionString, selectionStringArgs, null);
var cursor2 = (ICursor)loader2.LoadInBackground();
while (cursor2.MoveToNext())
{
numbers.Add(cursor2.GetString(cursor2.GetColumnIndex(columnsNames2[0])));
}
//Email Address
string[] columnsNames3 = new string[] {
ContactsContract.CommonDataKinds.Email.Address
};
var loader3 = new CursorLoader(Statics.mainActivity, ContactsContract.CommonDataKinds.Email.ContentUri, columnsNames3, selectionString, selectionStringArgs, null);
var cursor3 = (ICursor)loader3.LoadInBackground();
while (cursor3.MoveToNext())
{
emails.Add(cursor3.GetString(cursor3.GetColumnIndex(columnsNames3[0])));
}
int TempRecepitntID = 0;
EmployeesViewModel tempRecipent = new EmployeesViewModel();
TempRecepitntID = Statics.mainActivity.currentViewModel.SelectedChat.ReceiverEmployee;
foreach (EmployeesViewModel evm in Statics.mainActivity.currentViewModel.Employees)
{
if (evm.ID == TempRecepitntID)
tempRecipent = evm;
}
new Android.Support.V7.App.AlertDialog.Builder(Statics.mainActivity)
.SetPositiveButton("Yes", (sender1, args) =>
{
Statics.mainActivity.currentViewModel.AddMessage(picture, tempRecipent, Statics.mainActivity.currentViewModel.SelectedChat.ID, "contact", 0, "", name, numbers[0], mobile, email, address);
})
.SetNegativeButton("No", (sender1, args) =>
{
// cancel
})
.SetMessage("Are you shure you want to send?")
.SetTitle("System Message")
.Show();
}
}
The problem is I want to retrieve only the information of the contact that the user selected but what I get is all other contacts data is retrieved so I tried to use the selection and selectionargs parameters of CursorLoader by setting string selectionString = "id = ?"; and selectionArgs to string[] selectionStringArgs = new string[] { ID }; the ID value is retrieved from the following code :
if (cursor.MoveToFirst())
{
ID = cursor.GetString(cursor.GetColumnIndex(columnsNames[0]));
name = cursor.GetString(cursor.GetColumnIndex(columnsNames[1]));
picture = cursor.GetBlob(cursor.GetColumnIndex(columnsNames[2]));
}
//Store Contact ID
string[] selectionStringArgs = new string[] { ID };
//Phone Numbers
string[] columnsNames2 = new string[] {
ContactsContract.CommonDataKinds.Phone.Number
};
But now it returns 0 results, I couldn't find anything on the internet that applies to Xamarin android, Please help.
Thanks,
Finally I found the solution, I used the following string in the selection parameter of the cursorloader method:
string selectionString = ContactsContract.CommonDataKinds.Phone.InterfaceConsts.ContactId + "=" + ID;
and now only the selected contact numbers are retrieved.
I hope this will help someone else.
In additional information of #TMSL, I add the code afer this bloque
if (cursor.MoveToFirst())
{
ID = cursor.GetString(cursor.GetColumnIndex(columnsNames[0]));
name = cursor.GetString(cursor.GetColumnIndex(columnsNames[1]));
picture = cursor.GetBlob(cursor.GetColumnIndex(columnsNames[2]));
}
Here
selectionString = ContactsContract.CommonDataKinds.Phone.InterfaceConsts.ContactId + "=" + ID;
Then I changed the parameters used in the definition of variable Loader2, converting selectionStringArgs in null.
var loader2 = new CursorLoader(this.Activity, ContactsContract.CommonDataKinds.Phone.ContentUri, columnsNames2, selectionString, null,null);
var cursor2 = (ICursor)loader2.LoadInBackground();
I found this documentation from xamarin guides
Uri – The fully qualified name of the ContentProvider.
Projection – Specification of which columns to select for the cursor.
Selection – Similar to a SQL WHERE clause.
SelectionArgs – Parameters to be substituted in the Selection.
SortOrder – Columns to sort by.
So, the variable selectionStringArgs used in the code from #TMSAL cannot use a value like "contact_id = 2700", because the parameter of CursorLoader SelectionArgs is not a filter but not "Parameters to be substituted in the Selection"
I hope this will help someone else too.

Android; SQLite database Cursor is null. It should not be. I don't know why it is

I had a method which fetched records from an sqlite database but after a while i changed it a little and made a secondary method for fetching specific records with user entered information.
I don't know why but my original method is returning null now.
CardDbAdapter:
public CarddbAdapter open2() throws SQLException {
String myPath = DB_PATH + DB_NAME;
myDatabaseR = SQLiteDatabase.openDatabase(myPath, null,
SQLiteDatabase.OPEN_READONLY);
myDatabaseW = SQLiteDatabase.openDatabase(myPath, null,
SQLiteDatabase.OPEN_READWRITE);
return this;
}
public void MyDatabaseClose() {
myDatabaseW.close();
myDatabaseR.close();
}
public ArrayList<String> getAllCardNames() {
ArrayList<String> returnedAllCardNames;
ArrayList<String> NoResults;
ArrayList<String> NoResults2;
NoResults = new ArrayList<String>();
NoResults.add("cursor is null");
NoResults2 = new ArrayList<String>();
NoResults2.add("No similar cards found.");
returnedAllCardNames = new ArrayList<String>();
/*String sqlquery_cardNames = "SELECT " + KEY_CARDNAME
+ " FROM cards WHERE card_name like '%" + passedName
+ "%' ORDER BY card_name ASC";*/
//String sqlquery_cardNames;
String sqlquery_cardNames = "SELECT DISTINCT card_name FROM cards";
Cursor c_cardNames;
c_cardNames = myDatabaseW.rawQuery(sqlquery_cardNames, null);
c_cardNames.moveToFirst();
if (c_cardNames != null) {
do {
if (c_cardNames.getCount() > 0) {
String returnedName = c_cardNames.getString(c_cardNames
.getColumnIndex(KEY_CARDNAME));
returnedAllCardNames.add(returnedName);
} else {
return NoResults2;
}
} while (c_cardNames.moveToNext());
}
return NoResults;
}
How i am using it:
CarddbAdapter yugiohDB = new CarddbAdapter(this);
yugiohDB.open2();
search_results = (ListView) findViewById(R.id.lvSearchResults);
search_results.setOnItemClickListener(this);
ArrayList<String> returnedCards_list1 = new ArrayList<String>();
returnedCards_list1.addAll(yugiohDB.getAllCardNames());
listAdapter = new ArrayAdapter<String>(SearchMode_Simple.this,
android.R.layout.simple_list_item_1, returnedCards_list1);
search_results.setAdapter(listAdapter);
yugiohDB.MyDatabaseClose();
Any help would be appreciated.
If you would like to see what this is actually supposed to do then download my app called Yugioh Library + Tools. Click the Search Library button from the main menu and then the button Simple Search. It should be displaying a list of cards from the database.
The reason i was changing it is because i'm setting up Spinners so users can choose different trading card sets to choose some which would then list all the cards from that specific set.
Fixed. I forgot to return the string array "returnedAllCardNames" which was holding the names of all process card records after the do while loop.

breezejs: overriding displayname

I'm in the process of customizing validation messages. It's working fine using the messageTemplates property. However it uses %displayName% to render the name of the property and I can't find out how to override this value ? Is there anyway to do that ?
I was wanting to do this also but I wanted to use the [DisplayName] attribute from my EF model. I couldn't find anyone that had an example of doing this so after I found a way I thought I would share.
First, I extended the metadata returned from my BreezeController:
[HttpGet]
public string Metadata()
{
// Extend metadata with extra attributes
JObject metadata = JObject.Parse(contextProvider.Metadata());
string nameSpace = metadata["schema"]["namespace"].ToString();
foreach (var entityType in metadata["schema"]["entityType"])
{
string typeName = entityType["name"].ToString();
Type t = Type.GetType(nameSpace + "." + typeName);
foreach (var prop in t.GetProperties())
{
foreach (var attr in prop.CustomAttributes)
{
string name = attr.GetType().Name;
foreach (var p in entityType["property"])
{
if (prop.Name == p["name"].ToString()) {
if (attr.AttributeType.Name == "DisplayNameAttribute") {
DisplayNameAttribute a = (DisplayNameAttribute)Attribute.GetCustomAttribute(prop, typeof(DisplayNameAttribute));
p["displayName"] = a.DisplayName;
break;
}
}
}
}
}
}
return metadata.ToString();
}
Then I added a little javascript after the metadata load to poke the display names from the augmented metadata where Breeze wants to find them.
manager.fetchMetadata().then(function (md) {
angular.forEach(md.schema.entityType, function (et) {
var etype = manager.metadataStore.getEntityType(et.name);
angular.forEach(et.property, function (p) {
var prop = etype.getProperty(p.name);
prop.displayName = p.displayName;
});
});
console.log("starting app");
angular.bootstrap($("#app"), ["app"]);
});
I'm using angular so if you aren't you can ignore the angular stuff and probably get the idea. This seems to work rather nicely. It should be pretty easy to extend this to other model attributes as well like the RegularExpression validation attribute. I'll probably work on that next.
FYI, some of this code is not optimized and could probably be refactored, prettied up a bit but I just got it working and thought I would share. If anyone has any suggestions of a better way let me know. Hopefully Breeze will allow extending the metadata in a more supported way in the future. This does seem like a bit of a hack.
This is not YET well documented but you can simply set the 'displayName' property on any dataProperty and this will override the autogenerated display name and will be used for all validation messages for this property. So
var custType = myEntityManager.metadataStore.getEntityType("Customer");
var dp = custType.getProperty("companyName");
dp.displayName = "My custom display name";
Also, please see "Customize the message templates" at the bottom of this page: Breeze Validation
Following jpcoder request for suggestions, here goes my slightly improved server portion:
JObject metadata = JObject.Parse(contextProvider.Metadata());
string nameSpace = metadata["schema"]["namespace"].ToString();
foreach (var entityType in metadata["schema"]["entityType"])
{
string typeName = entityType["name"].ToString();
Type t = Type.GetType(nameSpace + "." + typeName);
IEnumerable<JToken> metaProps = null;
if (entityType["property"].Type == JTokenType.Object)
metaProps = new[] { entityType["property"] };
else
metaProps = entityType["property"].AsEnumerable();
var props = from p in metaProps
let pname = p["name"].ToString()
let prop = t.GetProperties().SingleOrDefault(prop => prop.Name == pname)
where prop != null
from attr in prop.CustomAttributes
where attr.AttributeType.Name == "DisplayNameAttribute"
select new
{
Prop = p,
DisplayName = ((DisplayNameAttribute)Attribute.GetCustomAttribute(prop, typeof(DisplayNameAttribute))).DisplayName
};
foreach (var p in props)
p.Prop["displayName"] = p.DisplayName;
}
Looking at http://www.breezejs.com/sites/all/apidocs/files/a40_entityMetadata.js.html#l1452,
could this be improved by renaming the existing "name" value to nameOnServer (to satisfy the getDataProperty call) and inserting the DisplayNameAttribute value as "name"?
A necessary change to the server code is that, if your model classes are in different assemblies, you cannot use
Type t = Type.GetType(nameSpace + "." + typeName);
You need the namespace per type (which is in the metadata), and (I think) to use BuildManager to locate the appropriate types in different assemblies. The mapping from cSpaceOSpaceMapping might be achieved more elegantly, but I didn't have time to research the different json formatting options.
JObject metadata = JObject.Parse(UnitOfWork.Metadata());
string EFNameSpace = metadata["schema"]["namespace"].ToString();
string typeNameSpaces = metadata["schema"]["cSpaceOSpaceMapping"].ToString();
typeNameSpaces = "{" + typeNameSpaces.Replace("],[", "]|[").Replace("[", "").Replace("]", "").Replace(",", ":").Replace("|", ",") + "}";
JObject jTypeNameSpaces = JObject.Parse(typeNameSpaces);
foreach (var entityType in metadata["schema"]["entityType"])
{
string typeName = entityType["name"].ToString();
string defaultTypeNameSpace = EFNameSpace + "." + typeName;
string entityTypeNameSpace = jTypeNameSpaces[defaultTypeNameSpace].ToString();
Type t = BuildManager.GetType(entityTypeNameSpace, false);
IEnumerable<JToken> metaProps = null;
if (entityType["property"].Type == JTokenType.Object)
metaProps = new[] { entityType["property"] };
else
metaProps = entityType["property"].AsEnumerable();
var props = from p in metaProps
let pname = p["name"].ToString()
let prop = t.GetProperties().SingleOrDefault(prop => prop.Name == pname)
where prop != null
from attr in prop.CustomAttributes
where attr.AttributeType.Name == "DisplayNameAttribute"
select new
{
Prop = p,
DisplayName = ((DisplayNameAttribute)Attribute.GetCustomAttribute(prop, typeof(DisplayNameAttribute))).DisplayName
};
foreach (var p in props)
{
p.Prop["displayName"] = p.DisplayName;
}
}
JObject metadata = JObject.Parse(this._context.Metadata());
string EFNameSpace = metadata["schema"]["namespace"].ToString();
string typeNameSpaces = metadata["schema"]["cSpaceOSpaceMapping"].ToString();
typeNameSpaces = "{" + typeNameSpaces.Replace("],[", "]|[").Replace("[", "").Replace("]", "").Replace(",", ":").Replace("|", ",") + "}";
JObject jTypeNameSpaces = JObject.Parse(typeNameSpaces);
foreach (var entityType in metadata["schema"]["entityType"])
{
string typeName = entityType["name"].ToString();
string defaultTypeNameSpace = EFNameSpace + "." + typeName;
string entityTypeNameSpace = jTypeNameSpaces[defaultTypeNameSpace].ToString();
Type t = BuildManager.GetType(entityTypeNameSpace, false);
IEnumerable<JToken> metaProps = null;
if (entityType["property"].Type == JTokenType.Object)
metaProps = new[] { entityType["property"] };
else
metaProps = entityType["property"].AsEnumerable();
var props = from p in metaProps
let pname = p["name"].ToString()
let prop = t.GetProperties().SingleOrDefault(prop => prop.Name == pname)
where prop != null
from attr in prop.CustomAttributes
where attr.AttributeType.Name == "DisplayAttribute"
select new
{
Prop = p,
DisplayName = ((DisplayAttribute)Attribute.GetCustomAttribute(prop, typeof(DisplayAttribute))).Name
};
foreach (var p in props)
{
p.Prop["displayName"] = p.DisplayName;
}
}
return metadata.ToString();
Improving jpcoder's answer ...
For me most of my DisplayName changes were to replace "PascalCaseFieldName" or "camelCaseFieldName" with "Upper Case Field Name". So rather than set every property DisplayName on the server, I applied a default function to set displayName.
End result was much less EF annotation required. My TypeScript is:
manager.metadataStore.getEntityTypes().forEach(function (storeEntityType) {
if (!(storeEntityType instanceof breeze.EntityType)) {
throw new Error("loadExtendedMetadata found '" + storeEntityType
+ "' StructuralType that is not an EntityType (e.g. a ComplexType)");
}
var extEntityType = extendedMetadata.entitiesExtended.find((extendedEntityType) => {
return extendedEntityType.shortName + ":#" + extendedEntityType.nameSpace === storeEntityType.name;
});
(storeEntityType as breeze.EntityType).getProperties().forEach((storeProperty) => {
//Both NavigationProperty & DataProperty have displayName & nameOnServer properties
var storeDataProperty = <breeze.DataProperty>storeProperty;
var extProperty;
if (extEntityType) {
extProperty = extEntityType.propertiesExtented.find((extendedProperty) => {
return extendedProperty.name === storeDataProperty.nameOnServer;
});
}
//Smart default: nameOnServer "PascalCaseFieldName" or "camelCaseFieldName" converted to "Upper Case Field Name"
storeDataProperty.displayName = (extProperty && extProperty.displayName)
|| storeDataProperty.nameOnServer.replace(/^./, function (str) {
// first ensure the first character is uppercase
return str.toUpperCase();
// insert a space before all caps, remove first character (added space)
}).replace(/([A-Z])/g, " $1").substring(1);
});
});

How do i use LinqToExcel to get cell values contained in the excel file

I am using this code to retrieve the receipient name and receipient number but the recpt.receipient_name and recpt.receipient_number are null.
The excel table is of this format
Name Number
andrew 1223
james 12223
dave 454545
//select names from the excel file with specified sheet name
var receipients = from n in messages.Worksheet<BulkSmsModel>(sheetName)
select n;
foreach (var recpt in receipients)
{
BulkSms newRecpt = new BulkSms();
if (recpt.receipient_number.Equals("") == true || recpt.receipient_number == 0)
{
continue;
}
newRecpt.receipient_name = recpt.receipient_name;
newRecpt.receipient_number = Int32.Parse(recpt.receipient_number.ToString());
IBsmsRepo.insertReceipient(newRecpt);
IBsmsRepo.save();
}
After some research I found a way to get the value from excel file with LinqToExcel and get the list of all Cells. Check this MVC C# Sample.
using LinqToExcel;
using Syncfusion.Olap.Reports;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data.OleDb;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace YourProject.Controllers
{
public class DefaultController : Controller
{
// GET: Default1
public ActionResult Index()
{
return View();
}
public dynamic UploadExcel(HttpPostedFileBase FileUpload)
{
string PathToyurDirectory = ConfigurationManager.AppSettings["Path"].ToString();//This can be in Anywhere, but you have to create a variable in WebConfig AppSettings like this <add key="Path" value="~/Doc/"/> This directory in my case is inside App whereI upload the files here, and I Delete it after use it ;
if (FileUpload.ContentType == "application/vnd.ms-excel"
|| FileUpload.ContentType == "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
|| FileUpload.ContentType == "application/vnd.ms-excel.sheet.binary.macroEnabled.12"
)
{
string filename = FileUpload.FileName;
string PathToExcelFile = Server.MapPath(PathToyurDirectory + filename);
// string targetpath = ;
FileUpload.SaveAs(PathToyurDirectory);
var connectionString = string.Empty;
string sheetName = string.Empty;
yourmodel db = new yourmodel();
Employee Employee = New Employee(); //This is your class no matter What.
try
{
if (filename.EndsWith(".xls") || filename.EndsWith(".csv") || filename.EndsWith(".xlsx") || filename.EndsWith(".xlsb"))
{
connectionString = string.Format("Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0};Extended Properties=\"Excel 12.0 Xml;HDR=YES;IMEX=1\";", PathToExcelFile);
sheetName = GetTableName(connectionString);
}
var ExcelFile = new ExcelQueryFactory(PathToExcelFile);
var Data = ExcelFile.Worksheet(sheetName).ToList();
foreach (var item in Data)
{
//if yout excel file does not meet the class estructure.
Employee = new Employee
{
Name = item[1].ToString(),
LastName = item[2].ToString(),
Address = item[3].ToString(),
Phone = item[4].ToString(),
CelPghone = item[5].ToString()
};
db.Employee.Add(Employee);
db.SaveChanges();
}
}
catch (Exception)
{
throw;
}
}
return View();
}
private string GetTableName(string connectionString)
{
// You can return all Sheets for a Dropdown if you want to, for me, I just want the first one;
OleDbConnection oledbconn = new OleDbConnection(connectionString);
oledbconn.Open();
// Get the data table containg the schema guid.
var dt = oledbconn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null);
var sheet = dt.Rows[0]["TABLE_NAME"].ToString().Replace("$", string.Empty);
oledbconn.Close();
return sheet;
}
}
}
Since the property names on the BulkSmsModel class do not correlate directly to the column names in the spreadsheet, you will need to map the property names to the column names.
Assuming messages is the ExcelQueryFactory object, this would be the code.
var messages = new ExcelQueryFactory("excelFileName");
messages.AddMapping<BulkSmsModel>(x => x.receipient_name, "Name");
messages.AddMapping<BulkSmsModel>(x => x.receipient_number, "Number");
var receipients = from n in messages.Worksheet<BulkSmsModel>(sheetName)
select n;

Away3D 4.0 Loading dynamic textures for primitives from arrays

I have several arrays storing the attributes needed to build primitives. One array stores the widths, another stores the heights, another the depths, x, y, z etc. I have one more that stores the remote filename for the texture to be applied. After I get my response from the server I attempt to apply the textures to the primitives. When I move the camera to look at the primitive, I am not able to see it. My view seems to freeze up (the view will not update). Once the camera has moved past the primitive, it can see again. Any ideas?
private var loadedBuildingTextures:Object = new Object();
private var map_building_count:Number = 0;
private var loadedBuildings:Number = 0;
public var map_building_widths:Array;
public var map_building_heights:Array;
public var map_building_depths:Array;
public var map_building_xs:Array;
public var map_building_ys:Array;
public var map_building_zs:Array;
public var map_building_textures:Array;
// I POPULATE THE ARRAYS BUT LEFT THAT CODE OUT FOR SIMPLICITY
public function placeBuildings():void {
trace('FUNCTION: placeBuildings() fired');
var buildingsPlaced:Number = 0;
for (var a:Number = 0; a < map_building_count; a++ ) {
loadedBuildingTextures['texture_' + a.toString()] = new BitmapFileMaterial(map_building_textures[a]); // ASSIGNS THE BitmapFileMaterials TO AN OBJECT FOR REFERENCING LATER
loadedBuildingTextures['texture_' + a.toString()].loader.contentLoaderInfo.addEventListener(Event.COMPLETE, postBuildingLoad);
buildingsPlaced++;
}
trace('placed ' + buildingsPlaced.toString() + ' of ' + map_building_count.toString() + ' buildings.'); // OUTPUT = "placed 4 of 4 buildings."
trace('FUNCTION: placeBuildings() completed');
}
public function postBuildingLoad(event : Event):void {
loadedBuildings++;
if (int(loadedBuildings) == int(map_building_count)) {
placeBuildingsStep2();
}
}
public function placeBuildingsStep2():void {
trace('RECEIVED ALL RESPONSES FROM SERVER FOR TEXTURES');
for (var a:Number = 0; a < map_building_count; a++ ) {
cube = new Cube(
loadedBuildingTextures['texture_' + a], // <----- THIS SEEMS TO BE THE PROBLEM
map_building_widths[a], // WIDTH
map_building_heights[a], // HEIGHT
map_building_depths[a], // DEPTH
1, // WIDTH UNITS
1, // HEIGHT UNITS
1, // DEPTH UNITS
true);
cube.x = map_building_xs[a];
cube.y = map_building_ys[a];
cube.z = map_building_zs[a];
view.scene.addChild(cube);
}
}
Although this post is old, it does highlight an important issue. BitmapFileMaterial is more a shortcut to test than a production ready scheme.
I would highly recommend using a loading queue for external assets (like LoaderMax or the new AssetLibrary in 4.0) and then instantiate materials as needed.

Resources