I have been using squel as query builder for our project and have to migrate due to it being outdated and vulnerable. The squel doc suggested to use knex, I have bit of trouble trying to use it simply just as querybuilder, as database we are using snowflake and use the native sdk.
If someone could help me with a basic insert query in knex without connection creation.
Also the feature/ability to something similar like below in knex.
const insertQuery: squel.Insert = squel
.insert()
.into('TENANT')
.set('URI', 'dummy')
.set('CREATEDBY', 'ADMIN');
if (uuid != null) {
insertQuery.set('UUID', uuid);
}
so basically create the query dynamically and later pass it snowflake query, values.
Any leads would help a lot. Thanks.
Hopefully this is what you are asking for!
const insertQuery = squel.Insert = squel
.insert()
.into('TENANT')
.set('URI', 'dummy')
.set('CREATEDBY', 'ADMIN');
let sqlNative = insertQuery.toSQL().toNative()
//this is the sql in the format sent to the SQL driver.
console.log(sqlNative)
if (uuid != null) {
insertQuery.set('UUID', uuid);
}
https://github.com/knex/knex/issues/2378
Related
I'm using realmjs DB in my react-native app where I have a schema settings. I want to change a property type of that schema from int to string. So I understand that I need to perform migration and I decided to perform a linear migration. For the migration I followed the example from Realm documentation and ended up doing something like below:
const schemaList = [schemaV1,schemaV2];
let nextSchemaIndex = Realm.schemaVersion(Realm.defaultPath);
while (nextSchemaIndex < schemaList.length) {
const migratedRealm = new Realm(schemaList[nextSchemaIndex++]);
migratedRealm.close();
}
export default new Realm(schemaList[schemaList.length - 1]);
schemaV1 is the old version of the db and schemaV2 is the latest version of the db after changes of property type. The schemaV2 also has a migration function like below:
if (oldRealm.schemaVersion < 1) {
const oldObjects = oldRealm.objects(TBL_MOBILE_SETTING);
const newObjects = newRealm.objects(TBL_MOBILE_SETTING);
for (let i = 0; i < oldObjects.length; i++) {
newObjects[i].module = oldObjects[i].module;
newObjects[i].setting = oldObjects[i].setting;
}
}
But at the end, when I'm trying to run the app, it's crashing with an error message that
Database migration is needed
Does it mean that the migration function in schemaV2 never runs? If so, how to make sure that all the migration functions are running properly? Or am I missing something else?
EDIT
I found that column type change is not allowed in RealmJS and I added a new column and tried to perform migration but still same error.
The problem was what I guessed. The migration function was not being called. I had to create an export const function and call the migration function in the index file cause it's the file which is called at the starting of the app.
I'm current working with Firebase firestore and Next JS. I've googled how to organise a firestore project but most of them (all actually) aren't scalable.
What I have tried to do is to have a folder containing all the Firebase-related components such as configurations and utility methods. I found the most challenging part is to write a general-purpose function to get the collection/document ref that applies all the supported methods, namely .orderBy(), .limit(), .where() and .doc(). It's also really tough to write a transformer that transforms the data returned by the database to another format.
Here's what I have implemented:
Where getDocRef.js is a helper function that puts all those methods mentioned above together, getOnce.js and observe.js expose methods that interact with the database and db.js contains the configurations.
Also, for anyone who interested, here's my naive solution for the .getDocRef() function:
import db from '../db';
/*
Options:
- ref: Specify the ref of a document
- collectionName: Specify the collection name
- queryArgs: Specify the arguments to be passed down to .where()
- orderByArgs: Specify the arguments to be passed down to .orderBy()
- limit: Specify the fetching limit
- docName: Specify the document name/id
*/
export default options => {
const { ref, collectionName, queryArgs, orderByArgs, limit, docName } = options;
if (ref != null) return ref;
const initRef = db.collection(collectionName);
if (docName != null) return initRef.doc(docName);
if (queryArgs != null) {
if (orderByArgs != null) {
if (limit != null)
return initRef
.where(...queryArgs)
.orderBy(...orderByArgs)
.limit(limit);
return initRef.where(...queryArgs).orderBy(...orderByArgs);
}
return initRef.where(...queryArgs);
}
return initRef;
};
So, I would love to know if my current implementation of Firebase is okay. If not, what project structure should I apply? How should I improve my current structure to make it more efficiently? And last but not least is there an alternative to my naive JS solution posted above? Thanks in advance
My personal approach:
Extract all credentials to .env with dotenv package
A directory call /lib/db and two files here:
init.js to initialise the Firebase/firestore
Another class with some methods for CRUD
If your project is getting big, I suggest to extract every collection's related method to a file in /lib/db and organise them there(somehow like state managements).
In Microsoft examples I saw two ways to check if DocumentDb object like Database, DocumentCollection, Document etc. exists :
First is by creating a query:
Database db = client.CreateDatabaseQuery().Where(x => x.Id == DatabaseId).AsEnumerable().FirstOrDefault();
if (db == null)
{
await client.CreateDatabaseAsync(new Database { Id = DatabaseId });
}
The second one is by using "try catch" block:
try
{
await this.client.ReadDatabaseAsync(UriFactory.CreateDatabaseUri(databaseName));
}
catch (DocumentClientException de)
{
if (de.StatusCode == HttpStatusCode.NotFound)
{
await this.client.CreateDatabaseAsync(new Database { Id = databaseName });
}
else
{
throw;
}
}
What is the correct way to do this procedure in terms of performance?
You should use the new CreateDatabaseIfNotExistsAsync in the DocumentDB SDK instead of both these approaches, if that's what you're trying to do.
In terms of server resources (request units), a ReadDocumentAsync is slightly more lightweight than CreateDatabaseQuery, so you should use that when possible.
I've just seen the try/catch example in one of the Microsoft provided sample project and it got me baffled, as it is plain wrong: you don't use try/catch for control flow.
Never.
This is just bad code. The new SDK provides CreateDatabaseIfNotExistsAsync which I can only hope doesn't just hide this shit. In older lib just use the query approach, unless you want to get shouted at by whoever is going to review the code.
I see jslinq, and see tds js libraries for using node and SQL together... So has anyone ever used those technologies together?
I want to be able to write linq to sql queries in a nodejs app...
I've started with JS variant of LINQ to Entities this week. Check UniMapperJS
Example
var comments = await Comment.getAll()
.where(e => e.author.endsWith("something") || e.author.startsWith("somethingElse"))
.orderByDescending("created")
.limit(10)
.skip(0)
.exec();
But cuz of limitation of JS, it was hard to figure out, how to accept variables in where because that arrow functions are parsed as string. I've solved it by "virtual" variable ($) and list of args as last param.
var comments = await Comment.getAll()
.where(e => e.author.endsWith($) || e.author.startsWith($), filter.endsWith, filter.name)
.orderByDescending("created")
.limit(10)
.skip(0)
.select(e => e.author)
.exec();
Today, JayData http://jaydata.org/ do it.
You can use the new ES6 Arrow Function syntax that looks very similar to C# (with a browser that supports it, like lastest Firefox, or a transpiler, like TypeScript or Traceur):
todoDB.Todos
.filter(todo => todo.Completed == true)
.map(todo => todo.Task )
.forEach(taskName => $('#list')
.append('Task: ' + taskName + ' completed'));
The query will be converted to a SQL Query (select Task from Todos where Completed = true) or a $filter URL parameter (http://.../?$filter=Completed%20eq%201&$select=Task), depending of the data source...
You should checkout the edge.js framework, it connects node.js with .Net. One way would be to use the built in T-SQL support in edge, and then use something like linq.js to manipulate the results.
var getTop10Products = edge.func('sql', function () {/*
select top 10 * from Products
*/});
getTop10Product(null, function (error, products) {
if (error) throw error;
console.log(products);
});
Otherwise, you could setup an EF datacontext in a .Net library and call out to that using Linq
var getTop10Product = edge.func(function () {/*
async (input) => {
using (var db = new ProductContext())
{
//Linq to EF query
var query = from b in db.Products
orderby b.Name
select b;
return query.Take(10).ToList();
}
}
*/});
I came across this question today as I was wondering the same thing, and after a little more searching I came across Squel.
Quoting directly from their website:
//this code
squel.select()
.from("students")
.field("name")
.field("MIN(test_score)")
.field("MAX(test_score)")
.field("GROUP_CONCAT(DISTINCT test_score ORDER BY test_score DESC SEPARATOR ' ')")
.group("name")
);
/* will return this SQL query as a string:
SELECT
name,
MIN(test_score),
MAX(test_score),
GROUP_CONCAT(DISTINCT test_score ORDER BY test_score DESC SEPARATOR ' ')
FROM
students
GROUP BY
name
*/
Hopefully this will help anyone who comes across this question while searching.
Good luck!
PS: <Insert standard disclaimer about not generating SQL queries in the browser...>
If you are creating client-side javascript that will send a SQL query to your database you open a whole can of worms - if the browser can dictate the SQL query, and a user can manipulate what comes from the browser, then you are vulnerable to SQL injection attacks.
Bottom line: don't use this in the browser!
This is not possible, at least if you want to create ad-hoc queries in Javascript. Linq (of any flavor) is a compiler technology. A query using Linq syntax or Linq expressions is handled by the C# or VB compiler, not directly interpreted by the database.
A conventional way to do this would be through a web service in C#, using Linq to fetch and store data, and presenting a clean API to clients. Then the client could consume the service through AJAX calls.
I want to rerieve list of Metadata Component's like ApexClass using Salesforce Metadata API's.
I'm getting list of all the Apex Classes(total no is 2246) that are on the Salesforce using the following Code and its taking too much time to retrieve these file names:
ListMetadataQuery query = new ListMetadataQuery();
query.type = "ApexClass";
double asOfVersion = 23.0;
// Assume that the SOAP binding has already been established.
FileProperties[] lmr = metadataService.listMetadata(
new ListMetadataQuery[] { query }, asOfVersion);
if (lmr != null)
{
foreach(FileProperties n in lmr)
{
string filename = n.fileName;
}
}
My requirement is to get list of Metadata Components(Apex Classes) which are developed by my organizasion only so that i can get the Salesforce Metadata Components which are relevant to me and possibly can save my time by not getting all the classes.
How can I Achieve this?
Reply as soon as possible.
Thanks in advance.
I've not used the meta-data API directly, but I'd suggest either trying to filter on the created by field, or use a prefixed name on your classes so you can filter on that.
Not sure if filters are possible though! As for speed, my experience of using the Meta-Data API via Eclipse is that it's always pretty slow and there's not much you can do about it!