How to do CRUD operations on multiple tables in SQLite database in Flutter? - database

I am building a money budgeting app where the user can split their monthly salary in 5 areas: food, social, education, travel, savings. I have a register and log in screen. This is in Flutter/dart and I'm using sqlite.
Some of the data to store:
id, username, password, email, monthly_salary, food_initial, food_final, social_initial, social_final, education_initial, education_final, travel_initial, travel_final, savings_initial, savings_final
The 'initial' refers to a value that the user will input for themselves based on the division of the monthly salary. (ie. $5000 a month/5 containers = 1000 for each container. but, the user can edit this value of 1000 as their initial budgeted money). The 'final' refers to the user's remaining money (under the assumption they don't go over) for that container.
The initial and final values get reset at the end of the month. However, I would like to save their previous month's final values so the user can see a backlog of what they did.
I initially had 2 tables for my database. One was for the USER_DATA and the other was BUDGETS table. However, after struggling to figure out how to do CRUD operations for two tables, I decided to make it all into one table. But, after experiencing trouble with one table, I want to move back to more than one table. I'm confused now on:
1. How to use CRUD operations when having more than one table on DB?
2. Do I have to build a new model class in order to have more than one table?
3. How to save some of the user's data on database, but have to wait for the rest of the information to come in (later on while they're using the app)?
When making the constructor for the model class, and then referring to the model class in the UI, it requires me to bring in all of the parameters I have, but I don't have all of those values ready yet. The user still needs to register before they can input their salary and etc. Would I have to use the Future class to get over this hurdle?
I've watched a lot of videos on others building their databases in sqlite and with Flutter but all of them usually do a simple To-Do list app where they will need to fill in every column of the table and I haven't seen one yet that includes several tables. (ie. columns: id, description, priority, date)
--
I think have a good basis now on the UI side and using TextFormFields to access the information, but connecting the database/creating it properly is confusing me.
I am also considering writing the database in a .sql file now before proceeding. I have been teaching myself Flutter through tutorials (as background knowledge).
I know this is a bit long and all over the place, but I would greatly appreciate anyone who has experience with the sqlite environment in Flutter to please help me understand how to do this correctly.
Thank you. Also, if there is any more clarification/code needed, let me know.
Model class:
import 'dart:core';
class UserData {
//user table
int _userid;
String _username;
String _password;
String _email;
String _first_name;
String _last_name;
String _date;
int _month_id;
bool _subtract; //did the user subtract money from their funds? true/false
double _month_salary;
String _log_details;
/////////////budget table
double _edu_budget_initial;
double _edu_budget_final;
double _travel_budget_initial;
double _travel_budget_final;
double _living_budget_initial;
double _living_budget_final;
double _savings_budget_initial;
double _savings_budget_final;
double _social_budget_initial;
double _social_budget_final;
// using [___] around your user's data entry makes it optional in the table
// otherwise, these are all required fields
UserData(
this._username,
this._email,
this._first_name,
this._last_name,
this._password,
this._date,
this._month_id,
this._subtract,
this._month_salary,
this._log_details,
this._edu_budget_final,
this._edu_budget_initial,
this._living_budget_final,
this._living_budget_initial,
this._savings_budget_final,
this._savings_budget_initial,
this._social_budget_final,
this._social_budget_initial,
this._travel_budget_final,
this._travel_budget_initial);
//created a Named Constructor for the ability to create multiple constructors in one class
UserData.withId(
this._userid,
this._username,
this._password,
this._first_name,
this._last_name,
this._email,
this._date,
this._month_id,
this._subtract,
this._month_salary,
this._log_details,
this._edu_budget_final,
this._edu_budget_initial,
this._living_budget_final,
this._living_budget_initial,
this._savings_budget_final,
this._savings_budget_initial,
this._social_budget_final,
this._social_budget_initial,
this._travel_budget_final,
this._travel_budget_initial);
//UserData.budgetTable(this.date, this.month_id, this.log_details, this.edu_budget_final, this.edu_budget_initial, this.living_budget_final, this.living_budget_initial,
//this.month_salary, this.savings_budget_final, this.savings_budget_initial, this.social_budget_final,
//this.social_budget_initial, this.travel_budget_final, this.travel_budget_initial);
//getters:
//userdata table
int get userid => _userid;
String get username => _username;
String get password => _password;
String get email => _email;
String get firstname => _first_name;
String get lastname => _last_name;
String get date => _date;
//budget table
int get month_id => _month_id;
bool get subtract => _subtract;
double get month_salary => _month_salary;
String get log_details => _log_details;
double get living_budget_initial => _living_budget_initial;
double get living_budget_final => _living_budget_final;
double get social_budget_initial => _social_budget_initial;
double get social_budget_final => _social_budget_final;
double get edu_budget_initial => _edu_budget_initial;
double get edu_budget_final => _edu_budget_final;
double get travel_budget_initial => _travel_budget_initial;
double get travel_budget_final => _travel_budget_final;
double get savings_budget_initial => _savings_budget_initial;
double get savings_budget_final => _savings_budget_final;
//setters:
/*
set userid(int newUserID) {
//adding condition before storing what user put in
if (newUserID <= 12) {
this._userid = newUserID;
}
}
*/
set username(String newUsername) {
if (newUsername.length <= 30) {
this._username = newUsername;
}
}
set password(String newPassword) {
if (newPassword.length <= 30)
this._password = newPassword;
}
set email(String newEmail) {
if (newEmail.length <= 50)
this._email = newEmail;
}
set first_name(String newFirstName) {
if (newFirstName.length <= 30)
this._first_name = newFirstName;
}
set last_name(String newLastName) {
if (newLastName.length <= 30)
this._last_name = newLastName;
}
set month_id(int newMonthId) {
if (newMonthId <= 12) {
this._month_id = newMonthId;
}
}
set month_salary(double newMonthSalary) {
this._month_salary = newMonthSalary;
}
set date(String newDate) {
this._date = newDate;
}
set log_details(String newLogDetails) {
if (newLogDetails.length <= 255)
this._log_details = newLogDetails;
}
set subtract(bool newSubtract) {
this._subtract = newSubtract;
}
set living_budget_initial(double newLBI) {
if (newLBI <= 10) this._living_budget_initial = newLBI;
}
set living_budget_final(double newLBF) {
if (newLBF <= 10) this._living_budget_final = newLBF;
}
set social_budget_initial(double newSOBI) {
if (newSOBI <= 10) this._social_budget_initial = newSOBI;
}
set social_budget_final(double newSOBF) {
if (newSOBF <= 10) this._social_budget_final = newSOBF;
}
set edu_budget_initial(double newEBI) {
if (newEBI <= 10) this._edu_budget_initial = newEBI;
}
set edu_budget_final(double newEBF) {
if (newEBF <= 10) this._edu_budget_final = newEBF;
}
set travel_budget_initial(double newTBI) {
if (newTBI <= 10) this._travel_budget_initial = newTBI;
}
set travel_budget_final(double newTBF) {
if (newTBF <= 10) this._travel_budget_final = newTBF;
}
set savings_budget_initial(double newSBI) {
if (newSBI <= 10) this._savings_budget_initial = newSBI;
}
set savings_budget_final(double newSBF) {
if (newSBF <= 10) this._savings_budget_final = newSBF;
}
// converting object into Map objects
Map<String, dynamic> toMap() {
var map = Map<String, dynamic>();
var userid;
if (userid != null) {
map['userid'] = _userid;
}
map['userid'] = _userid;
map['username'] = _username;
map['password'] = _password;
map['email'] = _email;
map['first_name'] = _first_name;
map['last_name'] = _last_name;
//
map['month_id'] = _month_id;
map['month_salary'] = _month_salary;
map['date'] = _date;
map['log_details'] = _log_details;
map['subtract'] = _subtract;
map['living_budget_initial'] = _living_budget_initial;
map['living_budget_final'] = _living_budget_final;
map['social_budget_initial'] = _social_budget_initial;
map['social_budget_final'] = _social_budget_final;
map['edu_budget_initial'] = _edu_budget_initial;
map['edu_budget_final'] = _edu_budget_final;
map['travel_budget_initial'] = _travel_budget_initial;
map['travel_budget_final'] = _travel_budget_final;
map['savings_budget_initial'] = _savings_budget_initial;
map['savings_budget_final'] = _savings_budget_final;
return map;
}
//converts map objects into objects
UserData.fromMapObject(Map<String, dynamic> map) {
this._userid = map['userid'];
this._username = map['username'];
this._password = map['password'];
this._email = map['email'];
this.first_name = map['first_name'];
this.last_name = map['last_name'];
//
this._month_id = map['month_id'];
this._month_salary = map['month_salary'];
this._date = map['date'];
this._log_details = map['log_details'];
this._subtract = map['subtract'];
this._living_budget_initial = map['living_budget_initial'];
this._living_budget_final = map['living_budget_final'];
this._social_budget_initial = map['social_budget_initial'];
this._social_budget_final = map['social_budget_final'];
this._edu_budget_initial = map['edu_budget_initial'];
this._edu_budget_final = map['edu_budget_final'];
this._travel_budget_initial = map['travel_budget_initial'];
this._travel_budget_final = map['travel_budget_final'];
this._savings_budget_initial = map['savings_budget_initial'];
this._savings_budget_final = map['savings_budget_final'];
}
}
Database helper class:
import 'package:sqflite/sqflite.dart';
import 'dart:async';
import 'dart:io';
import 'package:path_provider/path_provider.dart';
import 'package:jewell_1/user_data.dart';
class DbHelper {
// Create a private instance of the class
static final DbHelper _dbhelper = new DbHelper._internal();
String DB_name = "user_data.db";
static final int DATABASE_VERSION = 2;
String userDataTable = 'user_data_table';
String colUserId = 'userid';
String colUsername = 'username';
String colPassword = 'password';
String colEmail = 'email';
String colFirstName = 'first_name';
String colLastName = 'last_name';
String colDate = 'date';
String colMonthId = 'month_id';
String colSubtract = 'subtract';
String colMonthSalary = 'month_salary';
String colLogDetails = 'log_details';
String colLBI = 'living_budget_initial';
String colLBF = 'living_budget_final';
String colSOBI = 'social_budget_initial';
String colSOBF = 'social_budget_final';
String colEBI = 'edu_budget_initial';
String colEBF = 'edu_budget_final';
String colTBI = 'travel_budget_initial';
String colTBF = 'travel_budget_final';
String colSBI = 'savings_budget_initial';
String colSBF = 'savings_budget_final';
// Create an empty private named constructor
DbHelper._internal();
// Use the factory to always return the same instance
factory DbHelper() {
return _dbhelper;
}
static Database _db;
Future<Database> get db async {
if (_db == null) {
_db = await initializeDb();
}
return _db;
}
Future<Database> initializeDb() async {
Directory dir = await getApplicationDocumentsDirectory();
String path = dir.path + "todos.db";
var dbTodos = await openDatabase(path, version: DATABASE_VERSION, onCreate: _createDb);
return dbTodos;
}
void _createDb(Database db, int newVersion) async {
await db.execute(
"CREATE TABLE $userDataTable($colUserId INETEGER PRIMARY KEY, $colUsername TEXT," +
"$colPassword TEXT, $colEmail TEXT, $colFirstName TEXT,"
"$colLastName TEXT, $colDate TEXT, $colMonthId INTEGER,"
" $colSubtract BOOLEAN, $colMonthSalary DOUBLE, $colLogDetails TEXT,"
" $colEBI DOUBLE, $colEBF DOUBLE, $colTBI DOUBLE, $colTBF DOUBLE, "
" $colLBI DOUBLE, $colLBF DOUBLE, $colSBI DOUBLE, $colSBF DOUBLE,"
" $colSOBI DOUBLE, $colSOBF DOUBLE)");
}
Future<int> insertData(UserData data) async {
Database db = await this.db;
var result = await db.insert(userDataTable, data.toMap());
return result;
}
Future<List> getDatas() async {
Database db = await this.db;
var result =
await db.rawQuery("SELECT * FROM $userDataTable order by $colUserId ASC");
return result;
}
Future<int> getCount() async {
Database db = await this.db;
var result = Sqflite.firstIntValue(
await db.rawQuery("SELECT COUNT (*) FROM $userDataTable"));
return result;
}
Future<int> updateData(UserData data) async {
var db = await this.db;
var result = await db
.update(userDataTable, data.toMap(), where: "$colUserId=?", whereArgs: [data.userid]);
return result;
}
Future<int> deleteData(int id) async {
int result;
var db = await this.db;
result = await db.rawDelete("DELETE FROM $userDataTable WHERE $colUserId=$id");
return result;
}
}
To be more specific, I am confused on not writing the query of a new table, but rather at this point:
var result = await db.insert(userDataTable, data.toMap());
return result;
The result is only containing my userDataTable and if I create another table, then am I supposed to add another var result? I tried to have:
var result2 = await db.insert(budgetsTable, data.toMap());
This seemed wrong. Also, I didn't know how to return both results.
That was specifically where/when I started to scavenge the internet of people who have made CRUD operations using more than one table on sqlite with Flutter.

Related

Tenant to tenant user migration in Azure Active Directory using Graph API

Is it possible to migrate users using the MS Graph API in Azure AD?
If so, please explain how to migrate users from one tenant to the other using the MS Graph API.
You can export the users with MS Graph. Note, you can't export the passwords. This means that you have to create a new password and share it with the users. Or choose a random password and let the users reset their password using the self-service password rest feature.
Here is an example how to export the users from a directly
public static async Task ListUsers(GraphServiceClient graphClient)
{
Console.WriteLine("Getting list of users...");
DateTime startTime = DateTime.Now;
Dictionary<string, string> usersCollection = new Dictionary<string, string>();
int page = 0;
try
{
// Get all users
var users = await graphClient.Users
.Request()
.Select(e => new
{
e.DisplayName,
e.Id
}).OrderBy("DisplayName")
.GetAsync();
// Iterate over all the users in the directory
var pageIterator = PageIterator<User>
.CreatePageIterator(
graphClient,
users,
// Callback executed for each user in the collection
(user) =>
{
usersCollection.Add(user.DisplayName, user.Id);
return true;
},
// Used to configure subsequent page requests
(req) =>
{
var d = DateTime.Now - startTime;
Console.WriteLine($"{string.Format(TIME_FORMAT, d.Days, d.Hours, d.Minutes, d.Seconds)} users: {usersCollection.Count}");
// Set a variable to the Documents path.
string filePrefix = "0";
if (usersCollection.Count >= 1000000)
{
filePrefix = usersCollection.Count.ToString()[0].ToString();
}
page++;
if (page >= 50)
{
page = 0;
string docPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), $"users_{filePrefix}.json");
System.IO.File.WriteAllTextAsync(docPath, JsonSerializer.Serialize(usersCollection));
}
Thread.Sleep(200);
return req;
}
);
await pageIterator.IterateAsync();
// Write last page
string docPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), $"users_all.json");
System.IO.File.WriteAllTextAsync(docPath, JsonSerializer.Serialize(usersCollection));
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
After you export the users, you can import them back to the other tenant. The following example creates test users. Change the code to set the values from the files you exported earlier. Also, this code uses batch with 20 users in single operation.
public static async Task CreateTestUsers(GraphServiceClient graphClient, AppSettings appSettings, bool addMissingUsers)
{
Console.Write("Enter the from value: ");
int from = int.Parse(Console.ReadLine()!);
Console.Write("Enter the to value: ");
int to = int.Parse(Console.ReadLine()!);
int count = 0;
Console.WriteLine("Starting create test users operation...");
DateTime startTime = DateTime.Now;
Dictionary<string, string> existingUsers = new Dictionary<string, string>();
// Add the missing users
if (addMissingUsers)
{
// Set a variable to the Documents path.
string docPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "users.json");
if (!System.IO.File.Exists(docPath))
{
Console.WriteLine("Can't find the '{docPath}' file.");
}
string usersFile = System.IO.File.ReadAllText(docPath);
existingUsers = JsonSerializer.Deserialize<Dictionary<string, string>>(usersFile);
if (existingUsers == null)
{
Console.WriteLine("Can't deserialize users");
return;
}
Console.WriteLine($"There are {existingUsers.Count} in the directory");
}
List<User> users = new List<User>();
// The batch object
var batchRequestContent = new BatchRequestContent();
for (int i = from; i < to; i++)
{
// 1,000,000
string ID = TEST_USER_PREFIX + i.ToString().PadLeft(7, '0');
if (addMissingUsers)
{
if (existingUsers.ContainsKey(ID))
continue;
}
count++;
try
{
var user = new User
{
DisplayName = ID,
JobTitle = ID.Substring(ID.Length - 1),
Identities = new List<ObjectIdentity>()
{
new ObjectIdentity
{
SignInType = "userName",
Issuer = appSettings.TenantName,
IssuerAssignedId = ID
},
new ObjectIdentity
{
SignInType = "emailAddress",
Issuer = appSettings.TenantName,
IssuerAssignedId = $"{ID}#{TEST_USER_SUFFIX}"
}
},
PasswordProfile = new PasswordProfile
{
Password = "1",
ForceChangePasswordNextSignIn = false
},
PasswordPolicies = "DisablePasswordExpiration,DisableStrongPassword"
};
users.Add(user);
if (addMissingUsers)
{
Console.WriteLine($"Adding missing {ID} user");
}
// POST requests are handled a bit differently
// The SDK request builders generate GET requests, so
// you must get the HttpRequestMessage and convert to a POST
var jsonEvent = graphClient.HttpProvider.Serializer.SerializeAsJsonContent(user);
HttpRequestMessage addUserRequest = graphClient.Users.Request().GetHttpRequestMessage();
addUserRequest.Method = HttpMethod.Post;
addUserRequest.Content = jsonEvent;
if (batchRequestContent.BatchRequestSteps.Count >= BATCH_SIZE)
{
var d = DateTime.Now - startTime;
Console.WriteLine($"{string.Format(TIME_FORMAT, d.Days, d.Hours, d.Minutes, d.Seconds)}, count: {count}, user: {ID}");
// Run sent the batch requests
var returnedResponse = await graphClient.Batch.Request().PostAsync(batchRequestContent);
// Dispose the HTTP request and empty the batch collection
foreach (var step in batchRequestContent.BatchRequestSteps) ((BatchRequestStep)step.Value).Request.Dispose();
batchRequestContent = new BatchRequestContent();
}
// Add the event to the batch operations
batchRequestContent.AddBatchRequestStep(addUserRequest);
// Console.WriteLine($"User '{user.DisplayName}' successfully created.");
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
}

SqfLite No such table (code 1 SQLITE_ERROR)

Maybe this question was already answered but I try to add sqfLite to my project but I get this error:
In my debug console:
no such table: infotable in "SELECT * FROM infotable"
This is my code:
final String infoTable = 'infotable';
final String columnID = '_id';
final String columnName = 'name';
final String columnCivilStatus = 'civil';
final String columnWorking = 'working';
final String columnJobTitle = 'job';
final String columnWorkingDomain = 'workingdomain';
final String columnMonthlyIncome = 'monthlyincome';
class SqfLite {
int id;
int sliderValue;
int monthChoiceChip;
String reasonChoiceChip;
String name;
String civilStatus;
int working;
String jobTitle;
int workingDomain;
String monthlyIncome;
String currency;
Position latitude;
Position longitude;
Map<String, dynamic> toMap() {
var map = <String, dynamic>{
columnCivilStatus: civilStatus,
columnJobTitle: jobTitle,
columnMonthlyIncome: monthlyIncome,
columnWorkingDomain: workingDomain,
columnWorking: working,
columnName: name,
};
if (id != null) {
map[columnID] = id;
}
return map;
}
SqfLite();
SqfLite.fromMap(Map<String, dynamic> map) {
id = map[columnID];
name = map[columnName];
civilStatus = map[columnCivilStatus];
working = map[columnWorking];
jobTitle = map[columnJobTitle];
workingDomain = map[columnWorkingDomain];
monthlyIncome = map[columnMonthlyIncome];
}
}
class SqfLiteProvider {
Database db;
Future open(String path) async {
db = await openDatabase(path, version: 1,
onCreate: (Database db, int version) async {
await db.execute('''
create table $infoTable (
$columnID integer primary key autoincrement,
$columnName text not null,
$columnCivilStatus text not null,
$columnWorking integer not null,
$columnJobTitle text not null,
$columnWorkingDomain integer not null,
$columnMonthlyIncome text not null)
''');
});
}
Future<SqfLite> getSqfLite(int id) async {
List<Map> maps = await db.query(infoTable,
columns: [
columnID,
columnName,
columnCivilStatus,
columnWorking,
columnJobTitle,
columnWorkingDomain,
columnMonthlyIncome,
],
where: '$columnID = ?',
whereArgs: [id]);
if (maps.length > 0) {
return SqfLite.fromMap(maps.first);
}
return null;
}
Future close() async => db.close();
}
I get the error here:
Future<void> openDataBase() async {
db = await openDatabase('infotable.db');
records = await db.query('infotable');
mapRead = records.first;
....
}
I've followed the example from the official page of the plugin
I can't use the latest version because of some pubspec.yaml conflicts.
I've tried to flutter clean and reinstalling the app but it didn't work
You have defined the open method inside SqfLiteProvider, but you are not using it. Instead, you are calling the same openDatabase('infotable.db'); method from sqflite package where the onCreate callback is not defined - you get an error.
So, instead of calling db = await openDatabase('infotable.db'); directly, use the SqfLiteProvider.open() you have defined.

How to access Spans with a SpanNearQuery in solr 6.3

I am trying to build a query parser by ranking the passages containing the terms.
I understand that I need to use SpanNearQuery, but I can't find a way to access Spans even after going through the documentation. The method I got returns null.
I have read https://lucidworks.com/blog/2009/07/18/the-spanquery/ which explains in a good way about the query. This explains how to access spans, but it is for solr 4.0 and unfortunately solr 6.3 doesn't have atomic reader any more.
How can I get the actual spans?
public void process(ResponseBuilder rb) throws IOException {
SolrParams params = rb.req.getParams();
log.warn("in Process");
if (!params.getBool(COMPONENT_NAME, false)) {
return;
}
Query origQuery = rb.getQuery();
// TODO: longer term, we don't have to be a span query, we could re-analyze the document
if (origQuery != null) {
if (origQuery instanceof SpanNearQuery == false) {
throw new SolrException(SolrException.ErrorCode.SERVER_ERROR,
"Illegal query type. The incoming query must be a Lucene SpanNearQuery and it was a " + origQuery.getClass().getName());
}
SpanNearQuery sQuery = (SpanNearQuery) origQuery;
SolrIndexSearcher searcher = rb.req.getSearcher();
IndexReader reader = searcher.getIndexReader();
log.warn("before leaf reader context");
List<LeafReaderContext> ctxs = (List<LeafReaderContext>) reader.leaves();
log.warn("after leaf reader context");
LeafReaderContext ctx = ctxs.get(0);
SpanWeight spanWeight = sQuery.createWeight(searcher, true);
Spans spans = spanWeight.getSpans(ctx, SpanWeight.Postings.POSITIONS);
AtomicReader wrapper = SlowCompositeReaderWrapper.wrap(reader);
Map<Term, TermContext> termContexts = new HashMap<Term, TermContext>();
Spans spans = fleeceQ.getSpans(wrapper.getContext(), new Bits.MatchAllBits(reader.numDocs()), termContexts);
// SpanWeight.Postings[] postings= SpanWeight.Postings.values();
// Spans spans = sQuery.getSpans();
// Assumes the query is a SpanQuery
// Build up the query term weight map and the bi-gram
Map<String, Float> termWeights = new HashMap<String, Float>();
Map<String, Float> bigramWeights = new HashMap<String, Float>();
createWeights(params.get(CommonParams.Q), sQuery, termWeights, bigramWeights, reader);
float adjWeight = params.getFloat(ADJACENT_WEIGHT, DEFAULT_ADJACENT_WEIGHT);
float secondAdjWeight = params.getFloat(SECOND_ADJ_WEIGHT, DEFAULT_SECOND_ADJACENT_WEIGHT);
float bigramWeight = params.getFloat(BIGRAM_WEIGHT, DEFAULT_BIGRAM_WEIGHT);
// get the passages
int primaryWindowSize = params.getInt(OWLParams.PRIMARY_WINDOW_SIZE, DEFAULT_PRIMARY_WINDOW_SIZE);
int adjacentWindowSize = params.getInt(OWLParams.ADJACENT_WINDOW_SIZE, DEFAULT_ADJACENT_WINDOW_SIZE);
int secondaryWindowSize = params.getInt(OWLParams.SECONDARY_WINDOW_SIZE, DEFAULT_SECONDARY_WINDOW_SIZE);
WindowBuildingTVM tvm = new WindowBuildingTVM(primaryWindowSize, adjacentWindowSize, secondaryWindowSize);
PassagePriorityQueue rankedPassages = new PassagePriorityQueue();
// intersect w/ doclist
DocList docList = rb.getResults().docList;
log.warn("Before Spans");
while (spans.nextDoc() != Spans.NO_MORE_DOCS) {
// build up the window
log.warn("Iterating through spans");
if (docList.exists(spans.docID())) {
tvm.spanStart = spans.startPosition();
tvm.spanEnd = spans.endPosition();
// tvm.terms
Terms terms = reader.getTermVector(spans.docID(), sQuery.getField());
tvm.map(terms, spans);
// The entries map contains the window, do some ranking of it
if (tvm.passage.terms.isEmpty() == false) {
log.debug("Candidate: Doc: {} Start: {} End: {} ", new Object[] { spans.docID(), spans.startPosition(), spans.endPosition() });
}
tvm.passage.lDocId = spans.docID();
tvm.passage.field = sQuery.getField();
// score this window
try {
addPassage(tvm.passage, rankedPassages, termWeights, bigramWeights, adjWeight, secondAdjWeight, bigramWeight);
} catch (CloneNotSupportedException e) {
throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, "Internal error cloning Passage", e);
}
// clear out the entries for the next round
tvm.passage.clear();
}
}
}
}

AngularJs, how to set empty string in URL

In the controller I have below function:
#RequestMapping(value = "administrator/listAuthor/{authorName}/{pageNo}", method = { RequestMethod.GET,
RequestMethod.POST }, produces = "application/json")
public List<Author> listAuthors(#PathVariable(value = "authorName") String authorName,
#PathVariable(value = "pageNo") Integer pageNo) {
try {
if (authorName == null) {
authorName = "";
}
if (pageNo == null) {
pageNo = 1;
}
return adminService.listAuthor(authorName, pageNo);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
This function fetches and returns data from mysql database based on "authorName" and "pageNo". For example, when "authorName = a" and "pageNo = 1" I have:
Data I get when "authorName = a" and "pageNo = 1"
Now I want to set "authorName" as ""(empty string), so that I can fetch all the data from mysql database (because the SQL statement "%+""+%" in backend will return all the data).
What can I do if I want to set authorName = empty string?
http://localhost:8080/spring/administrator/listAuthor/{empty string}/1
Thanks in advance!
I don't think that you can encode empty sting to url, what I suggest you to do is to declare some constant that will be your code to empty string - such as null.
Example:
administrator/listAuthor/null/90
Afterwards , on server side, check if authorName is null and set local parameter with empty stirng accordingly.

Get appointments from all Outlook calendars

I'm trying to read appointments from Outlook calendar using ExchangeServiceBinding but my solution takes appointments only from "default" outlook calendar and don't read from "sub calendars/custom calendars". Do you know how to define rest of the calendars or do you know better solution which contains all calendars?
Critical part is that solution shouldn't contain MAPI because of next use in web service.
My current code:
private static List<List<string>> ReadCalendarEvents(string email)
{
List<List<string>> calendarEvents = new List<List<string>>();
// Specify the request version.
esb.RequestServerVersionValue = new RequestServerVersion();
esb.RequestServerVersionValue.Version = ExchangeVersionType.Exchange2007;
// Form the FindItem request.
FindItemType findItemRequest = new FindItemType();
CalendarViewType calendarView = new CalendarViewType();
calendarView.StartDate = DateTime.Now.AddDays(-7);
calendarView.EndDate = DateTime.Now.AddDays(200);
calendarView.MaxEntriesReturned = 1000;
calendarView.MaxEntriesReturnedSpecified = true;
findItemRequest.Item = calendarView;
// Define which item properties are returned in the response.
ItemResponseShapeType itemProperties = new ItemResponseShapeType();
// Use the Default shape for the response.
//itemProperties.BaseShape = DefaultShapeNamesType.IdOnly;
itemProperties.BaseShape = DefaultShapeNamesType.AllProperties;
findItemRequest.ItemShape = itemProperties;
DistinguishedFolderIdType[] folderIDArray = new DistinguishedFolderIdType[1];
folderIDArray[0] = new DistinguishedFolderIdType();
folderIDArray[0].Id = DistinguishedFolderIdNameType.calendar;
//
folderIDArray[0].Mailbox = new EmailAddressType();
folderIDArray[0].Mailbox.EmailAddress = email;
findItemRequest.ParentFolderIds = folderIDArray;
// Define the traversal type.
findItemRequest.Traversal = ItemQueryTraversalType.Shallow;
try
{
// Send the FindItem request and get the response.
FindItemResponseType findItemResponse = esb.FindItem(findItemRequest);
// Access the response message.
ArrayOfResponseMessagesType responseMessages = findItemResponse.ResponseMessages;
ResponseMessageType[] rmta = responseMessages.Items;
int folderNumber = 0;
foreach (ResponseMessageType rmt in rmta)
{
// One FindItemResponseMessageType per folder searched.
FindItemResponseMessageType firmt = rmt as FindItemResponseMessageType;
if (firmt.RootFolder == null)
continue;
FindItemParentType fipt = firmt.RootFolder;
object obj = fipt.Item;
// FindItem contains an array of items.
if (obj is ArrayOfRealItemsType)
{
ArrayOfRealItemsType items =
(obj as ArrayOfRealItemsType);
if (items.Items == null)
{
folderNumber++;
}
else
{
foreach (ItemType it in items.Items)
{
if (it is CalendarItemType)
{
CalendarItemType cal = (CalendarItemType)it;
List<string> ce = new List<string>();
ce.Add(cal.Location);
ce.Add(cal.Start.ToShortDateString() + " " + cal.Start.ToShortTimeString());
ce.Add(cal.End.ToShortDateString() + " " + cal.End.ToShortTimeString());
ce.Add(cal.Subject);
if (cal.Organizer != null)
{
ce.Add(cal.Organizer.Item.Name);
}
calendarEvents.Add(ce);
Console.WriteLine(cal.Subject + " " + cal.Start.ToShortDateString() + " " + cal.Start.ToShortTimeString() + " " + cal.Location);
}
}
folderNumber++;
}
}
}
}
catch (Exception e)
{
throw;
}
finally
{
}
return calendarEvents;
}
In EWS you need to query one folder at a time, for non default folders you will first need to find the FolderId before you can then query the appointments (or items) within a Folder. To find all the Calendar folders in a Mailbox you need to use the FindFolder operation and create a restriction to limit the result to folder with a FolderClass of IPF.Appointment eg
// Create the request and specify the travesal type.
FindFolderType findFolderRequest = new FindFolderType();
findFolderRequest.Traversal = FolderQueryTraversalType.Deep;
// Define the properties that are returned in the response.
FolderResponseShapeType responseShape = new FolderResponseShapeType();
responseShape.BaseShape = DefaultShapeNamesType.Default;
findFolderRequest.FolderShape = responseShape;
// Identify which folders to search.
DistinguishedFolderIdType[] folderIDArray = new DistinguishedFolderIdType[1];
folderIDArray[0] = new DistinguishedFolderIdType();
folderIDArray[0].Id = DistinguishedFolderIdNameType.msgfolderroot;
IsEqualToType iet = new IsEqualToType();
PathToUnindexedFieldType FolderClass = new PathToUnindexedFieldType();
FolderClass.FieldURI = UnindexedFieldURIType.folderFolderClass;
iet.Item = FolderClass;
FieldURIOrConstantType constantType = new FieldURIOrConstantType();
ConstantValueType constantValueType = new ConstantValueType();
constantValueType.Value = "IPF.Appointment";
constantType.Item = constantValueType;
iet.FieldURIOrConstant = constantType;
// Add the folders to search to the request.
RestrictionType restriction = new RestrictionType();
restriction.Item = iet;
findFolderRequest.Restriction = restriction;
findFolderRequest.ParentFolderIds = folderIDArray;
try
{
// Send the request and get the response.
FindFolderResponseType findFolderResponse = esb.FindFolder(findFolderRequest);
// Get the response messages.
ResponseMessageType[] rmta = findFolderResponse.ResponseMessages.Items;
foreach (ResponseMessageType rmt in rmta)
{
// Cast to the correct response message type.
if (((FindFolderResponseMessageType)rmt).ResponseClass == ResponseClassType.Success) {
foreach (FolderType folder in ((FindFolderResponseMessageType)rmt).RootFolder.Folders) {
Console.WriteLine(folder.DisplayName);
}
}
}
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
You also might want to look at using the EWS Managed API which will save you greatly time and the amount of code you need to write
Cheers
Glen

Resources